add ks_acl

This commit is contained in:
Anthony Minessale 2017-01-25 17:10:50 -06:00
parent fdc1399e96
commit a4acfbd16b
10 changed files with 785 additions and 3 deletions

View File

@ -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

View File

@ -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

View 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:
*/

View File

@ -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

View File

@ -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
View 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:
*/

View File

@ -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

View File

@ -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));
}

View File

@ -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
View 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();
}