forked from Mirrors/freeswitch
add ks_acl
This commit is contained in:
parent
fdc1399e96
commit
a4acfbd16b
@ -18,6 +18,7 @@ libks_la_SOURCES += src/dht/ks_dht_job.c src/dht/ks_dht_search.c src/dht/ks_dht_
|
||||
libks_la_SOURCES += src/dht/ks_dht_bucket.c
|
||||
libks_la_SOURCES += crypt/aeskey.c crypt/aestab.c crypt/sha2.c crypt/twofish.c crypt/aes_modes.c crypt/aescrypt.c crypt/twofish_cfb.c
|
||||
#aes.h aescpp.h brg_endian.h aesopt.h aestab.h brg_types.h sha2.h twofish.h
|
||||
libks_la_SOURCES += src/ks_acl.c
|
||||
|
||||
libks_la_CFLAGS = $(AM_CFLAGS)
|
||||
libks_la_CPPFLAGS = -DPOSIX
|
||||
@ -30,7 +31,7 @@ library_include_HEADERS += src/include/ks_pool.h src/include/simclist.h src/incl
|
||||
library_include_HEADERS += src/include/ks_dso.h src/include/ks_platform.h src/include/ks_types.h # src/include/ks_rng.h src/include/ks_dht.h
|
||||
library_include_HEADERS += src/include/ks_printf.h src/include/ks_hash.h src/include/ks_ssl.h src/include/kws.h
|
||||
library_include_HEADERS += src/utp/utp_internal.h src/utp/utp.h src/utp/utp_types.h src/utp/utp_callbacks.h src/utp/utp_templates.h
|
||||
library_include_HEADERS += src/utp/utp_hash.h src/utp/utp_packedsockaddr.h src/utp/utp_utils.h src/include/ks_utp.h
|
||||
library_include_HEADERS += src/utp/utp_hash.h src/utp/utp_packedsockaddr.h src/utp/utp_utils.h src/include/ks_utp.h src/include/ks_acl.h
|
||||
|
||||
tests: libks.la
|
||||
$(MAKE) -C test tests
|
||||
|
@ -98,7 +98,11 @@ KS_DECLARE(int) ks_toupper(int c);
|
||||
KS_DECLARE(int) ks_tolower(int c);
|
||||
KS_DECLARE(char *) ks_copy_string(char *from_str, const char *to_str, ks_size_t from_str_len);
|
||||
KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...);
|
||||
KS_DECLARE(unsigned int) ks_separate_string(char *buf, const char *delim, char **array, unsigned int arraylen);
|
||||
KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen);
|
||||
KS_DECLARE(unsigned int) ks_separate_string(char *buf, char delim, char **array, unsigned int arraylen);
|
||||
|
||||
#define ks_inet_pton inet_pton
|
||||
|
||||
KS_DECLARE(int) ks_cpu_count(void);
|
||||
static __inline__ int ks_safe_strcasecmp(const char *s1, const char *s2) {
|
||||
if (!(s1 && s2)) {
|
||||
@ -111,6 +115,8 @@ KS_DECLARE(int) ks_cpu_count(void);
|
||||
|
||||
KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set);
|
||||
|
||||
#define ks_str_nil(s) (s ? s : "")
|
||||
|
||||
#include "ks_pool.h"
|
||||
#include "ks_printf.h"
|
||||
#include "ks_json.h"
|
||||
@ -130,6 +136,7 @@ KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set);
|
||||
#include "kws.h"
|
||||
#include "ks_bencode.h"
|
||||
#include "ks_rng.h"
|
||||
#include "ks_acl.h"
|
||||
|
||||
KS_END_EXTERN_C
|
||||
|
||||
|
83
libs/libks/src/include/ks_acl.h
Normal file
83
libs/libks/src/include/ks_acl.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _KS_ACL_H_
|
||||
#define _KS_ACL_H_
|
||||
|
||||
KS_BEGIN_EXTERN_C
|
||||
|
||||
typedef union{
|
||||
uint32_t v4;
|
||||
struct in6_addr v6;
|
||||
} ks_ip_t;
|
||||
|
||||
|
||||
#define switch_network_list_validate_ip(_list, _ip) switch_network_list_validate_ip_token(_list, _ip, NULL);
|
||||
|
||||
#define switch_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net ? _net == _ip : 1)
|
||||
|
||||
|
||||
KS_DECLARE(int) ks_parse_cidr(const char *string, ks_ip_t *ip, ks_ip_t *mask, uint32_t *bitp);
|
||||
KS_DECLARE(ks_status_t) ks_network_list_create(ks_network_list_t **list, const char *name, ks_bool_t default_type,
|
||||
ks_pool_t *pool);
|
||||
KS_DECLARE(ks_status_t) ks_network_list_add_cidr_token(ks_network_list_t *list, const char *cidr_str, ks_bool_t ok, const char *token);
|
||||
#define ks_network_list_add_cidr(_list, _cidr_str, _ok) ks_network_list_add_cidr_token(_list, _cidr_str, _ok, NULL)
|
||||
|
||||
KS_DECLARE(char *) ks_network_ipv4_mapped_ipv6_addr(const char* ip_str);
|
||||
KS_DECLARE(ks_status_t) ks_network_list_add_host_mask(ks_network_list_t *list, const char *host, const char *mask_str, ks_bool_t ok);
|
||||
KS_DECLARE(ks_bool_t) ks_network_list_validate_ip_token(ks_network_list_t *list, uint32_t ip, const char **token);
|
||||
KS_DECLARE(ks_bool_t) ks_network_list_validate_ip6_token(ks_network_list_t *list, ks_ip_t ip, const char **token);
|
||||
|
||||
#define ks_network_list_validate_ip(_list, _ip) ks_network_list_validate_ip_token(_list, _ip, NULL);
|
||||
|
||||
#define ks_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net ? _net == _ip : 1)
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_check_network_list_ip_cidr(const char *ip_str, const char *cidr_str);
|
||||
KS_DECLARE(ks_bool_t) ks_check_network_list_ip_token(const char *ip_str, ks_network_list_t *list, const char **token);
|
||||
#define ks_check_network_list_ip(_i, _l) ks_check_network_list_ip_token(_i, _l, NULL)
|
||||
|
||||
KS_END_EXTERN_C
|
||||
#endif /* defined(_KS_ACL_H_) */
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
||||
|
@ -462,6 +462,7 @@ KS_DECLARE(char *) ks_pstrndup(ks_pool_t *pool, const char *str, size_t len);
|
||||
KS_DECLARE(char *) ks_pstrmemdup(ks_pool_t *pool, const char *str, size_t len);
|
||||
KS_DECLARE(void *) ks_pmemdup(ks_pool_t *pool, const void *buf, size_t len);
|
||||
KS_DECLARE(char *) ks_pstrcat(ks_pool_t *pool, ...);
|
||||
KS_DECLARE(char *) ks_psprintf(ks_pool_t *pool, const char *fmt, ...);
|
||||
|
||||
KS_END_EXTERN_C
|
||||
|
||||
|
@ -212,6 +212,10 @@ typedef void (*ks_flush_fn_t)(ks_q_t *q, void *ptr, void *flush_data);
|
||||
|
||||
typedef struct ks_thread_pool_s ks_thread_pool_t;
|
||||
|
||||
struct ks_network_list;
|
||||
typedef struct ks_network_list ks_network_list_t;
|
||||
|
||||
|
||||
KS_END_EXTERN_C
|
||||
|
||||
#endif /* defined(_KS_TYPES_H_) */
|
||||
|
390
libs/libks/src/ks_acl.c
Normal file
390
libs/libks/src/ks_acl.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2014, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ks.h>
|
||||
|
||||
|
||||
struct ks_network_node {
|
||||
ks_ip_t ip;
|
||||
ks_ip_t mask;
|
||||
uint32_t bits;
|
||||
int family;
|
||||
ks_bool_t ok;
|
||||
char *token;
|
||||
char *str;
|
||||
struct ks_network_node *next;
|
||||
};
|
||||
typedef struct ks_network_node ks_network_node_t;
|
||||
|
||||
struct ks_network_list {
|
||||
struct ks_network_node *node_head;
|
||||
ks_bool_t default_type;
|
||||
ks_pool_t *pool;
|
||||
char *name;
|
||||
};
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) ks_network_list_create(ks_network_list_t **list, const char *name, ks_bool_t default_type,
|
||||
ks_pool_t *pool)
|
||||
{
|
||||
ks_network_list_t *new_list;
|
||||
|
||||
if (!pool) {
|
||||
ks_pool_open(&pool);
|
||||
}
|
||||
|
||||
new_list = ks_pool_alloc(pool, sizeof(**list));
|
||||
new_list->pool = pool;
|
||||
new_list->default_type = default_type;
|
||||
new_list->name = ks_pstrdup(new_list->pool, name);
|
||||
|
||||
*list = new_list;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define IN6_AND_MASK(result, ip, mask) \
|
||||
((uint32_t *) (result))[0] =((const uint32_t *) (ip))[0] & ((const uint32_t *)(mask))[0]; \
|
||||
((uint32_t *) (result))[1] =((const uint32_t *) (ip))[1] & ((const uint32_t *)(mask))[1]; \
|
||||
((uint32_t *) (result))[2] =((const uint32_t *) (ip))[2] & ((const uint32_t *)(mask))[2]; \
|
||||
((uint32_t *) (result))[3] =((const uint32_t *) (ip))[3] & ((const uint32_t *)(mask))[3];
|
||||
KS_DECLARE(ks_bool_t) ks_testv6_subnet(ks_ip_t _ip, ks_ip_t _net, ks_ip_t _mask) {
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&_mask.v6)) {
|
||||
struct in6_addr a, b;
|
||||
IN6_AND_MASK(&a, &_net, &_mask);
|
||||
IN6_AND_MASK(&b, &_ip, &_mask);
|
||||
return !memcmp(&a,&b, sizeof(struct in6_addr));
|
||||
} else {
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&_net.v6)) {
|
||||
return !memcmp(&_net,&_ip,sizeof(struct in6_addr));
|
||||
}
|
||||
else return KS_TRUE;
|
||||
}
|
||||
}
|
||||
KS_DECLARE(ks_bool_t) ks_network_list_validate_ip6_token(ks_network_list_t *list, ks_ip_t ip, const char **token)
|
||||
{
|
||||
ks_network_node_t *node;
|
||||
ks_bool_t ok = list->default_type;
|
||||
uint32_t bits = 0;
|
||||
|
||||
for (node = list->node_head; node; node = node->next) {
|
||||
if (node->family == AF_INET) continue;
|
||||
|
||||
if (node->bits >= bits && ks_testv6_subnet(ip, node->ip, node->mask)) {
|
||||
if (node->ok) {
|
||||
ok = KS_TRUE;
|
||||
} else {
|
||||
ok = KS_FALSE;
|
||||
}
|
||||
|
||||
bits = node->bits;
|
||||
|
||||
if (token) {
|
||||
*token = node->token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_network_list_validate_ip_token(ks_network_list_t *list, uint32_t ip, const char **token)
|
||||
{
|
||||
ks_network_node_t *node;
|
||||
ks_bool_t ok = list->default_type;
|
||||
uint32_t bits = 0;
|
||||
|
||||
for (node = list->node_head; node; node = node->next) {
|
||||
if (node->family == AF_INET6) continue; /* want AF_INET */
|
||||
if (node->bits >= bits && ks_test_subnet(ip, node->ip.v4, node->mask.v4)) {
|
||||
if (node->ok) {
|
||||
ok = KS_TRUE;
|
||||
} else {
|
||||
ok = KS_FALSE;
|
||||
}
|
||||
|
||||
bits = node->bits;
|
||||
|
||||
if (token) {
|
||||
*token = node->token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
KS_DECLARE(char *) ks_network_ipv4_mapped_ipv6_addr(const char* ip_str)
|
||||
{
|
||||
/* ipv4 mapped ipv6 address */
|
||||
|
||||
if (strncasecmp(ip_str, "::ffff:", 7)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return strdup(ip_str + 7);
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(int) ks_parse_cidr(const char *string, ks_ip_t *ip, ks_ip_t *mask, uint32_t *bitp)
|
||||
{
|
||||
char host[128];
|
||||
char *bit_str;
|
||||
int32_t bits;
|
||||
const char *ipv6;
|
||||
ks_ip_t *maskv = mask;
|
||||
ks_ip_t *ipv = ip;
|
||||
|
||||
ks_copy_string(host, string, sizeof(host)-1);
|
||||
bit_str = strchr(host, '/');
|
||||
|
||||
if (!bit_str) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*bit_str++ = '\0';
|
||||
bits = atoi(bit_str);
|
||||
ipv6 = strchr(string, ':');
|
||||
if (ipv6) {
|
||||
int i,n;
|
||||
if (bits < 0 || bits > 128) {
|
||||
return -2;
|
||||
}
|
||||
bits = atoi(bit_str);
|
||||
ks_inet_pton(AF_INET6, host, (unsigned char *)ip);
|
||||
for (n=bits,i=0 ;i < 16; i++){
|
||||
if (n >= 8) {
|
||||
maskv->v6.s6_addr[i] = 0xFF;
|
||||
n -= 8;
|
||||
} else if (n < 8) {
|
||||
maskv->v6.s6_addr[i] = 0xFF & ~(0xFF >> n);
|
||||
n -= n;
|
||||
} else if (n == 0) {
|
||||
maskv->v6.s6_addr[i] = 0x00;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bits < 0 || bits > 32) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
bits = atoi(bit_str);
|
||||
ks_inet_pton(AF_INET, host, (unsigned char *)ip);
|
||||
ipv->v4 = htonl(ipv->v4);
|
||||
|
||||
maskv->v4 = 0xFFFFFFFF & ~(0xFFFFFFFF >> bits);
|
||||
}
|
||||
*bitp = bits;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) ks_network_list_perform_add_cidr_token(ks_network_list_t *list, const char *cidr_str, ks_bool_t ok,
|
||||
const char *token)
|
||||
{
|
||||
ks_ip_t ip, mask;
|
||||
uint32_t bits;
|
||||
ks_network_node_t *node;
|
||||
char *ipv4 = NULL;
|
||||
|
||||
if ((ipv4 = ks_network_ipv4_mapped_ipv6_addr(cidr_str))) {
|
||||
cidr_str = ipv4;
|
||||
}
|
||||
|
||||
if (ks_parse_cidr(cidr_str, &ip, &mask, &bits)) {
|
||||
ks_log(KS_LOG_ERROR, "Error Adding %s (%s) [%s] to list %s\n",
|
||||
cidr_str, ok ? "allow" : "deny", ks_str_nil(token), list->name);
|
||||
ks_safe_free(ipv4);
|
||||
return KS_STATUS_GENERR;
|
||||
}
|
||||
|
||||
node = ks_pool_alloc(list->pool, sizeof(*node));
|
||||
|
||||
node->ip = ip;
|
||||
node->mask = mask;
|
||||
node->ok = ok;
|
||||
node->bits = bits;
|
||||
node->str = ks_pstrdup(list->pool, cidr_str);
|
||||
|
||||
if (strchr(cidr_str,':')) {
|
||||
node->family = AF_INET6;
|
||||
} else {
|
||||
node->family = AF_INET;
|
||||
}
|
||||
|
||||
if (!zstr(token)) {
|
||||
node->token = ks_pstrdup(list->pool, token);
|
||||
}
|
||||
|
||||
node->next = list->node_head;
|
||||
list->node_head = node;
|
||||
|
||||
ks_log(KS_LOG_NOTICE, "Adding %s (%s) [%s] to list %s\n",
|
||||
cidr_str, ok ? "allow" : "deny", ks_str_nil(token), list->name);
|
||||
|
||||
ks_safe_free(ipv4);
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) ks_network_list_add_cidr_token(ks_network_list_t *list, const char *cidr_str, ks_bool_t ok, const char *token)
|
||||
{
|
||||
char *cidr_str_dup = NULL;
|
||||
ks_status_t status = KS_STATUS_SUCCESS;
|
||||
|
||||
if (strchr(cidr_str, ',')) {
|
||||
char *argv[32] = { 0 };
|
||||
int i, argc;
|
||||
cidr_str_dup = strdup(cidr_str);
|
||||
|
||||
ks_assert(cidr_str_dup);
|
||||
if ((argc = ks_separate_string(cidr_str_dup, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
ks_status_t this_status;
|
||||
if ((this_status = ks_network_list_perform_add_cidr_token(list, argv[i], ok, token)) != KS_STATUS_SUCCESS) {
|
||||
status = this_status;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = ks_network_list_perform_add_cidr_token(list, cidr_str, ok, token);
|
||||
}
|
||||
|
||||
ks_safe_free(cidr_str_dup);
|
||||
return status;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) ks_network_list_add_host_mask(ks_network_list_t *list, const char *host, const char *mask_str, ks_bool_t ok)
|
||||
{
|
||||
ks_ip_t ip, mask;
|
||||
ks_network_node_t *node;
|
||||
|
||||
ks_inet_pton(AF_INET, host, &ip);
|
||||
ks_inet_pton(AF_INET, mask_str, &mask);
|
||||
|
||||
node = ks_pool_alloc(list->pool, sizeof(*node));
|
||||
|
||||
node->ip.v4 = ntohl(ip.v4);
|
||||
node->mask.v4 = ntohl(mask.v4);
|
||||
node->ok = ok;
|
||||
|
||||
/* http://graphics.stanford.edu/~seander/bithacks.html */
|
||||
mask.v4 = mask.v4 - ((mask.v4 >> 1) & 0x55555555);
|
||||
mask.v4 = (mask.v4 & 0x33333333) + ((mask.v4 >> 2) & 0x33333333);
|
||||
node->bits = (((mask.v4 + (mask.v4 >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
|
||||
|
||||
node->str = ks_psprintf(list->pool, "%s:%s", host, mask_str);
|
||||
|
||||
node->next = list->node_head;
|
||||
list->node_head = node;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_check_network_list_ip_cidr(const char *ip_str, const char *cidr_str)
|
||||
{
|
||||
ks_ip_t ip, mask, net;
|
||||
uint32_t bits;
|
||||
char *ipv6 = strchr(ip_str,':');
|
||||
ks_bool_t ok = KS_FALSE;
|
||||
char *ipv4 = NULL;
|
||||
|
||||
if ((ipv4 = ks_network_ipv4_mapped_ipv6_addr(ip_str))) {
|
||||
ip_str = ipv4;
|
||||
ipv6 = NULL;
|
||||
}
|
||||
|
||||
if (ipv6) {
|
||||
ks_inet_pton(AF_INET6, ip_str, &ip);
|
||||
} else {
|
||||
ks_inet_pton(AF_INET, ip_str, &ip);
|
||||
ip.v4 = htonl(ip.v4);
|
||||
}
|
||||
|
||||
ks_parse_cidr(cidr_str, &net, &mask, &bits);
|
||||
|
||||
if (ipv6) {
|
||||
ok = ks_testv6_subnet(ip, net, mask);
|
||||
} else {
|
||||
ok = ks_test_subnet(ip.v4, net.v4, mask.v4);
|
||||
}
|
||||
|
||||
ks_safe_free(ipv4);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_bool_t) ks_check_network_list_ip_token(const char *ip_str, ks_network_list_t *list, const char **token)
|
||||
{
|
||||
ks_ip_t ip;
|
||||
char *ipv6 = strchr(ip_str,':');
|
||||
ks_bool_t ok = KS_FALSE;
|
||||
char *ipv4 = NULL;
|
||||
|
||||
if ((ipv4 = ks_network_ipv4_mapped_ipv6_addr(ip_str))) {
|
||||
ip_str = ipv4;
|
||||
ipv6 = NULL;
|
||||
}
|
||||
|
||||
if (ipv6) {
|
||||
ks_inet_pton(AF_INET6, ip_str, &ip);
|
||||
} else {
|
||||
ks_inet_pton(AF_INET, ip_str, &ip);
|
||||
ip.v4 = htonl(ip.v4);
|
||||
}
|
||||
|
||||
|
||||
if (ipv6) {
|
||||
ok = ks_network_list_validate_ip6_token(list, ip, token);
|
||||
} else {
|
||||
ok = ks_network_list_validate_ip_token(list, ip.v4, token);
|
||||
}
|
||||
|
||||
ks_safe_free(ipv4);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
@ -2182,6 +2182,19 @@ KS_DECLARE(char *) ks_pstrcat(ks_pool_t *pool, ...)
|
||||
return result;
|
||||
}
|
||||
|
||||
KS_DECLARE(char *) ks_psprintf(ks_pool_t *pool, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *result;
|
||||
va_start(ap, fmt);
|
||||
result = ks_vpprintf(pool, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
@ -33,6 +33,8 @@
|
||||
|
||||
#include <ks.h>
|
||||
|
||||
#define ESCAPE_META '\\'
|
||||
|
||||
/* Written by Marc Espie, public domain */
|
||||
#define KS_CTYPE_NUM_CHARS 256
|
||||
|
||||
@ -230,7 +232,87 @@ KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(unsigned int) ks_separate_string(char *buf, const char *delim, char **array, unsigned int arraylen)
|
||||
/* Helper function used when separating strings to unescape a character. The
|
||||
supported characters are:
|
||||
|
||||
\n linefeed
|
||||
\r carriage return
|
||||
\t tab
|
||||
\s space
|
||||
|
||||
Any other character is returned as it was received. */
|
||||
static char unescape_char(char escaped)
|
||||
{
|
||||
char unescaped;
|
||||
|
||||
switch (escaped) {
|
||||
case 'n':
|
||||
unescaped = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
unescaped = '\r';
|
||||
break;
|
||||
case 't':
|
||||
unescaped = '\t';
|
||||
break;
|
||||
case 's':
|
||||
unescaped = ' ';
|
||||
break;
|
||||
default:
|
||||
unescaped = escaped;
|
||||
}
|
||||
return unescaped;
|
||||
}
|
||||
|
||||
|
||||
/* Helper function used when separating strings to remove quotes, leading /
|
||||
trailing spaces, and to convert escaped characters. */
|
||||
static char *cleanup_separated_string(char *str, char delim)
|
||||
{
|
||||
char *ptr;
|
||||
char *dest;
|
||||
char *start;
|
||||
char *end = NULL;
|
||||
int inside_quotes = 0;
|
||||
|
||||
/* Skip initial whitespace */
|
||||
for (ptr = str; *ptr == ' '; ++ptr) {
|
||||
}
|
||||
|
||||
for (start = dest = ptr; *ptr; ++ptr) {
|
||||
char e;
|
||||
int esc = 0;
|
||||
|
||||
if (*ptr == ESCAPE_META) {
|
||||
e = *(ptr + 1);
|
||||
if (e == '\'' || e == '"' || (delim && e == delim) || e == ESCAPE_META || (e = unescape_char(*(ptr + 1))) != *(ptr + 1)) {
|
||||
++ptr;
|
||||
*dest++ = e;
|
||||
end = dest;
|
||||
esc++;
|
||||
}
|
||||
}
|
||||
if (!esc) {
|
||||
if (*ptr == '\'' && (inside_quotes || ((ptr+1) && strchr(ptr+1, '\'')))) {
|
||||
if ((inside_quotes = (1 - inside_quotes))) {
|
||||
end = dest;
|
||||
}
|
||||
} else {
|
||||
*dest++ = *ptr;
|
||||
if (*ptr != ' ' || inside_quotes) {
|
||||
end = dest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (end) {
|
||||
*end = '\0';
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
char *d;
|
||||
@ -273,3 +355,129 @@ KS_DECLARE(char *) ks_copy_string(char *from_str, const char *to_str, ks_size_t
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Separate a string using a delimiter that is not a space */
|
||||
static unsigned int separate_string_char_delim(char *buf, char delim, char **array, unsigned int arraylen)
|
||||
{
|
||||
enum tokenizer_state {
|
||||
START,
|
||||
FIND_DELIM
|
||||
} state = START;
|
||||
|
||||
unsigned int count = 0;
|
||||
char *ptr = buf;
|
||||
int inside_quotes = 0;
|
||||
unsigned int i;
|
||||
|
||||
while (*ptr && count < arraylen) {
|
||||
switch (state) {
|
||||
case START:
|
||||
array[count++] = ptr;
|
||||
state = FIND_DELIM;
|
||||
break;
|
||||
|
||||
case FIND_DELIM:
|
||||
/* escaped characters are copied verbatim to the destination string */
|
||||
if (*ptr == ESCAPE_META) {
|
||||
++ptr;
|
||||
} else if (*ptr == '\'' && (inside_quotes || ((ptr+1) && strchr(ptr+1, '\'')))) {
|
||||
inside_quotes = (1 - inside_quotes);
|
||||
} else if (*ptr == delim && !inside_quotes) {
|
||||
*ptr = '\0';
|
||||
state = START;
|
||||
}
|
||||
++ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* strip quotes, escaped chars and leading / trailing spaces */
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
array[i] = cleanup_separated_string(array[i], delim);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Separate a string using a delimiter that is a space */
|
||||
static unsigned int separate_string_blank_delim(char *buf, char **array, unsigned int arraylen)
|
||||
{
|
||||
enum tokenizer_state {
|
||||
START,
|
||||
SKIP_INITIAL_SPACE,
|
||||
FIND_DELIM,
|
||||
SKIP_ENDING_SPACE
|
||||
} state = START;
|
||||
|
||||
unsigned int count = 0;
|
||||
char *ptr = buf;
|
||||
int inside_quotes = 0;
|
||||
unsigned int i;
|
||||
|
||||
while (*ptr && count < arraylen) {
|
||||
switch (state) {
|
||||
case START:
|
||||
array[count++] = ptr;
|
||||
state = SKIP_INITIAL_SPACE;
|
||||
break;
|
||||
|
||||
case SKIP_INITIAL_SPACE:
|
||||
if (*ptr == ' ') {
|
||||
++ptr;
|
||||
} else {
|
||||
state = FIND_DELIM;
|
||||
}
|
||||
break;
|
||||
|
||||
case FIND_DELIM:
|
||||
if (*ptr == ESCAPE_META) {
|
||||
++ptr;
|
||||
} else if (*ptr == '\'') {
|
||||
inside_quotes = (1 - inside_quotes);
|
||||
} else if (*ptr == ' ' && !inside_quotes) {
|
||||
*ptr = '\0';
|
||||
state = SKIP_ENDING_SPACE;
|
||||
}
|
||||
++ptr;
|
||||
break;
|
||||
|
||||
case SKIP_ENDING_SPACE:
|
||||
if (*ptr == ' ') {
|
||||
++ptr;
|
||||
} else {
|
||||
state = START;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* strip quotes, escaped chars and leading / trailing spaces */
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
array[i] = cleanup_separated_string(array[i], 0);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
KS_DECLARE(unsigned int) ks_separate_string(char *buf, char delim, char **array, unsigned int arraylen)
|
||||
{
|
||||
if (!buf || !array || !arraylen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (*buf == '^' && *(buf+1) == '^') {
|
||||
char *p = buf + 2;
|
||||
|
||||
if (p && *p && *(p+1)) {
|
||||
buf = p;
|
||||
delim = *buf++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memset(array, 0, arraylen * sizeof(*array));
|
||||
|
||||
return (delim == ' ' ? separate_string_blank_delim(buf, array, arraylen) : separate_string_char_delim(buf, delim, array, arraylen));
|
||||
}
|
||||
|
@ -14,6 +14,11 @@ testpools_SOURCES = testpools.c tap.c
|
||||
testpools_CFLAGS = $(AM_CFLAGS)
|
||||
testpools_LDADD = $(TEST_LDADD)
|
||||
|
||||
check_PROGRAMS += testacl
|
||||
testacl_SOURCES = testacl.c tap.c
|
||||
testacl_CFLAGS = $(AM_CFLAGS)
|
||||
testacl_LDADD = $(TEST_LDADD)
|
||||
|
||||
check_PROGRAMS += test_thread_pools
|
||||
test_thread_pools_SOURCES = test_thread_pools.c tap.c
|
||||
test_thread_pools_CFLAGS = $(AM_CFLAGS)
|
||||
|
70
libs/libks/test/testacl.c
Normal file
70
libs/libks/test/testacl.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include "ks.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "tap.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ks_pool_t *pool;
|
||||
ks_network_list_t *list = NULL;
|
||||
ks_bool_t match;
|
||||
|
||||
ks_init();
|
||||
|
||||
plan(8);
|
||||
|
||||
ks_pool_open(&pool);
|
||||
|
||||
ks_network_list_create(&list, "test", KS_FALSE, pool);
|
||||
|
||||
|
||||
ks_network_list_add_cidr(list, "10.0.0.0/8", KS_TRUE);
|
||||
ks_network_list_add_cidr(list, "172.16.0.0/12", KS_TRUE);
|
||||
ks_network_list_add_cidr(list, "192.168.0.0/16", KS_TRUE);
|
||||
ks_network_list_add_cidr(list, "fe80::/10", KS_TRUE);
|
||||
|
||||
|
||||
match = ks_check_network_list_ip("192.168.1.1", list);
|
||||
ok(match);
|
||||
|
||||
match = ks_check_network_list_ip("208.34.128.7", list);
|
||||
ok (!match);
|
||||
|
||||
match = ks_check_network_list_ip_cidr("192.168.1.1", "192.168.0.0/16");
|
||||
ok(match);
|
||||
|
||||
match = ks_check_network_list_ip_cidr("208.34.128.7", "192.168.0.0/16");
|
||||
ok (!match);
|
||||
|
||||
|
||||
ks_pool_free(pool, &list);
|
||||
|
||||
|
||||
ks_network_list_create(&list, "test", KS_TRUE, pool);
|
||||
|
||||
ks_network_list_add_cidr(list, "0.0.0.0/0", KS_FALSE);
|
||||
ks_network_list_add_cidr(list, "fe80::/10", KS_FALSE);
|
||||
|
||||
|
||||
match = ks_check_network_list_ip("2637:f368:1281::10", list);
|
||||
ok(match);
|
||||
|
||||
match = ks_check_network_list_ip("fe80::18b7:53b3:51d8:f5cf", list);
|
||||
ok(!match);
|
||||
|
||||
match = ks_check_network_list_ip_cidr("fe80::18b7:53b3:51d8:f5cf", "fe80::/10");
|
||||
ok(match);
|
||||
|
||||
match = ks_check_network_list_ip_cidr("2637:f368:1281::10", "fe80::/10");
|
||||
ok(!match);
|
||||
|
||||
ks_pool_free(pool, &list);
|
||||
|
||||
ks_pool_close(&pool);
|
||||
|
||||
ks_shutdown();
|
||||
|
||||
done_testing();
|
||||
}
|
Loading…
Reference in New Issue
Block a user