diff options
Diffstat (limited to 'src/acl.c')
-rw-r--r-- | src/acl.c | 229 |
1 files changed, 116 insertions, 113 deletions
@@ -1,4 +1,4 @@ -/* $Id: acl.c,v 1.21 2005-07-12 17:39:43 rjkaes Exp $ +/* $Id: acl.c,v 1.22 2005-08-15 03:54:31 rjkaes Exp $ * * This system handles Access Control for use of this daemon. A list of * domains, or IP addresses (including IP blocks) are stored in a list @@ -37,15 +37,15 @@ enum acl_type { ACL_STRING, ACL_NUMERIC }; * entry (like a domain name) or an IP entry. */ struct acl_s { - acl_access_t access; - enum acl_type type; - union { - char* string; + acl_access_t access; + enum acl_type type; + union { + char *string; struct { unsigned char octet[IPV6_LEN]; unsigned char mask[IPV6_LEN]; } ip; - } address; + } address; }; /* @@ -65,11 +65,11 @@ static vector_t access_list = NULL; int insert_acl(char *location, acl_access_t access_type) { - struct acl_s acl; - int i, ret, mask; - char *p, ip_dst[IPV6_LEN]; + struct acl_s acl; + int i, ret, mask; + char *p, ip_dst[IPV6_LEN]; - assert(location != NULL); + assert(location != NULL); /* * If the access list has not been set up, create it. @@ -110,7 +110,7 @@ insert_acl(char *location, acl_access_t access_type) *p = '\0'; if (full_inet_pton(location, ip_dst) <= 0) return -1; - + acl.type = ACL_NUMERIC; memcpy(acl.address.ip.octet, ip_dst, IPV6_LEN); @@ -119,7 +119,8 @@ insert_acl(char *location, acl_access_t access_type) if (mask >= ((i + 1) * 8)) acl.address.ip.mask[i] = 0xff; else - acl.address.ip.mask[i] = 0xff << (8 - (mask - i * 8)); + acl.address.ip.mask[i] = + 0xff << (8 - (mask - i * 8)); } } else { /* In all likelihood a string */ @@ -138,7 +139,6 @@ insert_acl(char *location, acl_access_t access_type) return ret; } - /* * This function is called whenever a "string" access control is found in * the ACL. From here we do both a text based string comparison, along with @@ -149,72 +149,73 @@ insert_acl(char *location, acl_access_t access_type) * -1 if no tests match, so skip */ static int -acl_string_processing(struct acl_s* acl, - const char* ip_address, - const char* string_address) +acl_string_processing(struct acl_s *acl, + const char *ip_address, const char *string_address) { - int match; - struct addrinfo hints, *res, *ressave; - size_t test_length, match_length; - char ipbuf[512]; + int match; + struct addrinfo hints, *res, *ressave; + size_t test_length, match_length; + char ipbuf[512]; assert(acl && acl->type == ACL_STRING); assert(ip_address && strlen(ip_address) > 0); assert(string_address && strlen(string_address) > 0); - /* - * If the first character of the ACL string is a period, we need to - * do a string based test only; otherwise, we can do a reverse - * lookup test as well. - */ - if (acl->address.string[0] != '.') { - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo(acl->address.string, NULL, &hints, &res) != 0) - goto STRING_TEST; - - ressave = res; - - match = FALSE; - do { - get_ip_string(res->ai_addr, ipbuf, sizeof(ipbuf)); - if (strcmp(ip_address, ipbuf) == 0) { - match = TRUE; - break; - } - } while ((res = res->ai_next) != NULL); - - freeaddrinfo(ressave); - - if (match) { - if (acl->access == ACL_DENY) - return 0; - else - return 1; - } - } - -STRING_TEST: - test_length = strlen(string_address); - match_length = strlen(acl->address.string); - - /* - * If the string length is shorter than AC string, return a -1 so - * that the "driver" will skip onto the next control in the list. - */ - if (test_length < match_length) - return -1; - - if (strcasecmp(string_address + (test_length - match_length), acl->address.string) == 0) { - if (acl->access == ACL_DENY) - return 0; - else - return 1; - } - - /* Indicate that no tests succeeded, so skip to next control. */ - return -1; + /* + * If the first character of the ACL string is a period, we need to + * do a string based test only; otherwise, we can do a reverse + * lookup test as well. + */ + if (acl->address.string[0] != '.') { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(acl->address.string, NULL, &hints, &res) != 0) + goto STRING_TEST; + + ressave = res; + + match = FALSE; + do { + get_ip_string(res->ai_addr, ipbuf, sizeof(ipbuf)); + if (strcmp(ip_address, ipbuf) == 0) { + match = TRUE; + break; + } + } while ((res = res->ai_next) != NULL); + + freeaddrinfo(ressave); + + if (match) { + if (acl->access == ACL_DENY) + return 0; + else + return 1; + } + } + + STRING_TEST: + test_length = strlen(string_address); + match_length = strlen(acl->address.string); + + /* + * If the string length is shorter than AC string, return a -1 so + * that the "driver" will skip onto the next control in the list. + */ + if (test_length < match_length) + return -1; + + if (strcasecmp + (string_address + (test_length - match_length), + acl->address.string) == 0) { + if (acl->access == ACL_DENY) + return 0; + else + return 1; + } + + /* Indicate that no tests succeeded, so skip to next control. */ + return -1; } /* @@ -226,30 +227,30 @@ STRING_TEST: * -1 neither allowed nor denied. */ static int -check_numeric_acl(const struct acl_s* acl, const char* ip) +check_numeric_acl(const struct acl_s *acl, const char *ip) { - uint8_t addr[IPV6_LEN], x, y; - int i; + uint8_t addr[IPV6_LEN], x, y; + int i; assert(acl && acl->type == ACL_NUMERIC); assert(ip && strlen(ip) > 0); - if (full_inet_pton(ip, &addr) <= 0) return -1; + if (full_inet_pton(ip, &addr) <= 0) + return -1; - for (i = 0; i != IPV6_LEN; ++i) { + for (i = 0; i != IPV6_LEN; ++i) { x = addr[i] & acl->address.ip.mask[i]; y = acl->address.ip.octet[i] & acl->address.ip.mask[i]; /* If x and y don't match, the IP addresses don't match */ if (x != y) return 0; - } + } - /* The addresses match, return the permission */ - return (acl->access == ACL_ALLOW); + /* The addresses match, return the permission */ + return (acl->access == ACL_ALLOW); } - /* * Checks whether file descriptor is allowed. * @@ -258,48 +259,50 @@ check_numeric_acl(const struct acl_s* acl, const char* ip) * 0 if denied */ int -check_acl(int fd, const char* ip, const char* host) +check_acl(int fd, const char *ip, const char *host) { - struct acl_s* acl; - int perm; + struct acl_s *acl; + int perm; int i; - assert(fd >= 0); - assert(ip != NULL); - assert(host != NULL); + assert(fd >= 0); + assert(ip != NULL); + assert(host != NULL); - /* - * If there is no access list allow everything. - */ - if (!access_list) return 1; + /* + * If there is no access list allow everything. + */ + if (!access_list) + return 1; for (i = 0; i != vector_length(access_list); ++i) { acl = vector_getentry(access_list, i, NULL); switch (acl->type) { - case ACL_STRING: - perm = acl_string_processing(acl, ip, host); - break; - - case ACL_NUMERIC: - if (ip[0] == '\0') continue; - perm = check_numeric_acl(acl, ip); - break; - } + case ACL_STRING: + perm = acl_string_processing(acl, ip, host); + break; + + case ACL_NUMERIC: + if (ip[0] == '\0') + continue; + perm = check_numeric_acl(acl, ip); + break; + } /* * Check the return value too see if the IP address is - * allowed or denied. - */ - if (perm == 0) - break; - else if (perm == 1) - return perm; + * allowed or denied. + */ + if (perm == 0) + break; + else if (perm == 1) + return perm; } - /* - * Deny all connections by default. - */ - log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].", - host, ip); - return 0; + /* + * Deny all connections by default. + */ + log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].", + host, ip); + return 0; } |