|
@ -21,14 +21,13 @@ |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
#include <ipset/ipset.h> |
|
|
#include <ipset/ipset.h> |
|
|
#include <libcork/ds.h> |
|
|
|
|
|
|
|
|
|
|
|
#include "utils.h" |
|
|
#include "utils.h" |
|
|
|
|
|
|
|
|
static struct ip_set acl_ip_set; |
|
|
|
|
|
static struct cork_string_array acl_domain_array; |
|
|
|
|
|
|
|
|
static struct ip_set acl_ipv4_set; |
|
|
|
|
|
static struct ip_set acl_ipv6_set; |
|
|
|
|
|
|
|
|
static void parse_addr_cidr(const char *str, char **host, int *cidr) |
|
|
|
|
|
|
|
|
static void parse_addr_cidr(const char *str, char *host, int *cidr) |
|
|
{ |
|
|
{ |
|
|
int ret = -1, n = 0; |
|
|
int ret = -1, n = 0; |
|
|
char *pch; |
|
|
char *pch; |
|
@ -39,17 +38,13 @@ static void parse_addr_cidr(const char *str, char **host, int *cidr) |
|
|
ret = pch - str; |
|
|
ret = pch - str; |
|
|
pch = strchr(pch + 1, '/'); |
|
|
pch = strchr(pch + 1, '/'); |
|
|
} |
|
|
} |
|
|
if (n > 1) { |
|
|
|
|
|
if (strcmp(str + ret, "]") != 0) { |
|
|
|
|
|
ret = -1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (ret == -1) { |
|
|
if (ret == -1) { |
|
|
*host = strdup(str); |
|
|
|
|
|
|
|
|
strcpy(host, str); |
|
|
*cidr = -1; |
|
|
*cidr = -1; |
|
|
} else { |
|
|
} else { |
|
|
*host = ss_strndup(str, ret); |
|
|
|
|
|
*cidr = atoi(strdup(str + ret + 1)); |
|
|
|
|
|
|
|
|
memcpy(host, str, ret); |
|
|
|
|
|
host[ret] = '\0'; |
|
|
|
|
|
*cidr = atoi(str + ret + 1); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -57,10 +52,8 @@ int init_acl(const char *path) |
|
|
{ |
|
|
{ |
|
|
// initialize ipset |
|
|
// initialize ipset |
|
|
ipset_init_library(); |
|
|
ipset_init_library(); |
|
|
ipset_init(&acl_ip_set); |
|
|
|
|
|
|
|
|
|
|
|
// initialize array |
|
|
|
|
|
cork_string_array_init(&acl_domain_array); |
|
|
|
|
|
|
|
|
ipset_init(&acl_ipv4_set); |
|
|
|
|
|
ipset_init(&acl_ipv6_set); |
|
|
|
|
|
|
|
|
FILE *f = fopen(path, "r"); |
|
|
FILE *f = fopen(path, "r"); |
|
|
if (f == NULL) { |
|
|
if (f == NULL) { |
|
@ -77,27 +70,27 @@ int init_acl(const char *path) |
|
|
line[len - 1] = '\0'; |
|
|
line[len - 1] = '\0'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
char *host = NULL; |
|
|
|
|
|
|
|
|
char host[256]; |
|
|
int cidr; |
|
|
int cidr; |
|
|
parse_addr_cidr(line, &host, &cidr); |
|
|
|
|
|
|
|
|
|
|
|
if (cidr == -1) { |
|
|
|
|
|
cork_string_array_append(&acl_domain_array, host); |
|
|
|
|
|
} else { |
|
|
|
|
|
struct cork_ipv4 addr; |
|
|
|
|
|
int err = cork_ipv4_init(&addr, host); |
|
|
|
|
|
if (!err) { |
|
|
|
|
|
|
|
|
parse_addr_cidr(line, host, &cidr); |
|
|
|
|
|
|
|
|
|
|
|
struct cork_ip addr; |
|
|
|
|
|
int err = cork_ip_init(&addr, host); |
|
|
|
|
|
if (!err) { |
|
|
|
|
|
if (addr.version == 4) { |
|
|
|
|
|
if (cidr >= 0) { |
|
|
|
|
|
ipset_ipv4_add_network(&acl_ipv4_set, &(addr.ip.v4), cidr); |
|
|
|
|
|
} else { |
|
|
|
|
|
ipset_ipv4_add(&acl_ipv4_set, &(addr.ip.v4)); |
|
|
|
|
|
} |
|
|
|
|
|
} else if (addr.version == 6) { |
|
|
if (cidr >= 0) { |
|
|
if (cidr >= 0) { |
|
|
ipset_ipv4_add_network(&acl_ip_set, &addr, cidr); |
|
|
|
|
|
|
|
|
ipset_ipv6_add_network(&acl_ipv6_set, &(addr.ip.v6), cidr); |
|
|
} else { |
|
|
} else { |
|
|
ipset_ipv4_add(&acl_ip_set, &addr); |
|
|
|
|
|
|
|
|
ipset_ipv6_add(&acl_ipv6_set, &(addr.ip.v6)); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (host != NULL) { |
|
|
|
|
|
free(host); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -108,48 +101,23 @@ int init_acl(const char *path) |
|
|
|
|
|
|
|
|
void free_acl(void) |
|
|
void free_acl(void) |
|
|
{ |
|
|
{ |
|
|
ipset_done(&acl_ip_set); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int acl_contains_domain(const char * domain) |
|
|
|
|
|
{ |
|
|
|
|
|
const char **list = acl_domain_array.items; |
|
|
|
|
|
const int size = acl_domain_array.size; |
|
|
|
|
|
const int domain_len = strlen(domain); |
|
|
|
|
|
int i, offset; |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++) { |
|
|
|
|
|
const char *acl_domain = list[i]; |
|
|
|
|
|
const int acl_domain_len = strlen(acl_domain); |
|
|
|
|
|
if (acl_domain_len > domain_len) { |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
int match = true; |
|
|
|
|
|
for (offset = 1; offset <= acl_domain_len; offset++) { |
|
|
|
|
|
if (domain[domain_len - offset] != |
|
|
|
|
|
acl_domain[acl_domain_len - offset]) { |
|
|
|
|
|
match = false; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (match) { |
|
|
|
|
|
return 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
ipset_done(&acl_ipv4_set); |
|
|
|
|
|
ipset_done(&acl_ipv6_set); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int acl_contains_ip(const char * host) |
|
|
int acl_contains_ip(const char * host) |
|
|
{ |
|
|
{ |
|
|
struct cork_ipv4 addr; |
|
|
|
|
|
int err = cork_ipv4_init(&addr, host); |
|
|
|
|
|
|
|
|
struct cork_ip addr; |
|
|
|
|
|
int err = cork_ip_init(&addr, host); |
|
|
if (err) { |
|
|
if (err) { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
struct cork_ip ip; |
|
|
|
|
|
cork_ip_from_ipv4(&ip, &addr); |
|
|
|
|
|
return ipset_contains_ip(&acl_ip_set, &ip); |
|
|
|
|
|
|
|
|
if (addr.version == 4) { |
|
|
|
|
|
return ipset_contains_ipv4(&acl_ipv4_set, &(addr.ip.v4)); |
|
|
|
|
|
} else if (addr.version == 6) { |
|
|
|
|
|
return ipset_contains_ipv6(&acl_ipv6_set, &(addr.ip.v6)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
} |
|
|
} |