From b1fbf9e3292eab73fa448dd6c937e70eb66dc4a7 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 25 Apr 2006 14:08:34 +0200 Subject: [PATCH] A preliminary version of the new ipaccess module. --- lib/Makefile | 1 + lib/ipaccess.c | 161 +++++++++++++++++++++++++------------------------ lib/ipaccess.h | 20 ++++-- 3 files changed, 98 insertions(+), 84 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 216da3c1..8cbf1c98 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -78,6 +78,7 @@ $(o)/lib/redblack-test: $(o)/lib/redblack-test.o $(LIBUCW) $(o)/lib/binheap-test: $(o)/lib/binheap-test.o $(LIBUCW) $(o)/lib/lizard-test: $(o)/lib/lizard-test.o $(LIBUCW) $(o)/lib/kmp-test: $(o)/lib/kmp-test.o $(LIBUCW) $(LIBCHARSET) +$(o)/lib/ipaccess-test: $(o)/lib/ipaccess-test.o $(LIBUCW) TESTS+=$(addprefix $(o)/lib/,regex.test unicode-utf8.test hash-test.test mempool.test stkstring.test slists.test kmp-test.test) $(o)/lib/regex.test: $(o)/lib/regex-t diff --git a/lib/ipaccess.c b/lib/ipaccess.c index 319a99ec..2116f71d 100644 --- a/lib/ipaccess.c +++ b/lib/ipaccess.c @@ -1,115 +1,118 @@ /* * UCW Library -- IP address access lists * - * (c) 1997--2001 Martin Mares + * (c) 1997--2006 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. */ #include "lib/lib.h" -#include "lib/lists.h" +#include "lib/clists.h" #include "lib/conf2.h" -#include "lib/chartype.h" #include "lib/ipaccess.h" -#include -#include -#include +#undef ipaccess_check /* FIXME */ -struct ipaccess_list { - list l; -}; +#include struct ipaccess_entry { - node n; + cnode n; uns allow; u32 addr, mask; }; -struct ipaccess_list * -ipaccess_init(void) -{ - /* Cannot use cfg_malloc() here as the pool can be uninitialized now */ - struct ipaccess_list *l = xmalloc(sizeof(*l)); - - init_list(&l->l); - return l; -} - -// FIXME: replace by cf_parse_ip() static byte * -parse_ip(byte **p, u32 *varp) +ipaccess_cf_ip(uns n UNUSED, byte **pars, struct ipaccess_entry *a) { - while (Cspace(**p)) - (*p)++; - if (!**p) - return "Missing IP address"; - uns x = 0; - if (**p == '0' && *(*p + 1) | 32 == 'X') + byte *c = pars[0]; + CF_JOURNAL_VAR(a->addr); + CF_JOURNAL_VAR(a->mask); + + byte *p = strchr(c, '/'); + if (p) + *p++ = 0; + byte *err = cf_parse_ip(c, &a->addr); + if (err) + return err; + if (p) { - errno = 0; - x = strtoul(*p + 2, (char **)p, 16); - if (errno == ERANGE || x > 0xffffffff) - goto error; + uns len; + if (!cf_parse_int(p, &len) && len <= 32) + a->mask = ~(len == 32 ? 0 : ~0U >> len); + else if (cf_parse_ip(p, &a->mask)) + return "Invalid prefix length or netmask"; } else - for (uns i = 0; i < 4; i++) - { - if (i) - { - while (Cspace(**p)) - (*p)++; - if (*(*p)++ != '.') - goto error; - } - while (Cspace(**p)) - (*p)++; - errno = 0; - uns y = strtoul(*p, (char **)p, 10); - if (errno == ERANGE || y > 255) - goto error; - x = (x << 8) + y; - } - *varp = x; + a->mask = ~0U; return NULL; -error: - return "Invalid IP address"; } -byte * -ipaccess_parse(struct ipaccess_list *l, byte *c, int is_allow) +static byte * +ipaccess_cf_mode(uns n UNUSED, byte **pars, struct ipaccess_entry *a) { - byte *p = strchr(c, '/'); - char *q; - struct ipaccess_entry *a = cf_malloc(sizeof(struct ipaccess_entry)); - unsigned long pxlen; - - a->allow = is_allow; - a->mask = ~0U; - if (p) - { - *p++ = 0; - pxlen = strtoul(p, &q, 10); - if ((!q || !*q) && pxlen <= 32) - { - if (pxlen != 32) - a->mask = ~(~0U >> (uns) pxlen); - } - else if (q = parse_ip(&p, &a->mask)) - return q; - } - add_tail(&l->l, &a->n); - return parse_ip(&c, &a->addr); + CF_JOURNAL_VAR(a->allow); + if (!strcasecmp(pars[0], "allow")) + a->allow = 1; + else if (!strcasecmp(pars[0], "deny")) + a->allow = 0; + else + return "Either `allow' or `deny' expected"; + return NULL; } +struct cf_section ipaccess_cf = { + CF_TYPE(struct ipaccess_entry), + CF_ITEMS { + CF_PARSER("Mode", NULL, ipaccess_cf_mode, 1), + CF_PARSER("IP", NULL, ipaccess_cf_ip, 1), + CF_END + } +}; + int -ipaccess_check(struct ipaccess_list *l, u32 ip) +ipaccess_check(clist *l, u32 ip) { - struct ipaccess_entry *a; - - DO_FOR_ALL(a, l->l) + CLIST_FOR_EACH(struct ipaccess_entry *, a, *l) if (! ((ip ^ a->addr) & a->mask)) return a->allow; return 0; } + +#ifdef TEST + +#include + +static clist t; + +static struct cf_section test_cf = { + CF_ITEMS { + CF_LIST("A", &t, &ipaccess_cf), + CF_END + } +}; + +int main(int argc, char **argv) +{ + cf_declare_section("T", &test_cf, 0); + if (cf_get_opt(argc, argv, CF_SHORT_OPTS, CF_NO_LONG_OPTS, NULL) != -1) + die("Invalid arguments"); + + byte buf[256]; + while (fgets(buf, sizeof(buf), stdin)) + { + byte *c = strchr(buf, '\n'); + if (c) + *c = 0; + u32 ip; + if (cf_parse_ip(buf, &ip)) + puts("Invalid IP address"); + else if (ipaccess_check(&t, ip)) + puts("Allowed"); + else + puts("Denied"); + } + return 0; +} + +#endif diff --git a/lib/ipaccess.h b/lib/ipaccess.h index aedb1587..8e003bdc 100644 --- a/lib/ipaccess.h +++ b/lib/ipaccess.h @@ -1,14 +1,24 @@ /* * UCW Library -- IP address access lists * - * (c) 1997--2001 Martin Mares + * (c) 1997--2006 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. */ -struct ipaccess_list; +#ifndef _UCW_IPACCESS_H +#define _UCW_IPACCESS_H -struct ipaccess_list *ipaccess_init(void); -byte *ipaccess_parse(struct ipaccess_list *l, byte *c, int is_allow); -int ipaccess_check(struct ipaccess_list *l, u32 ip); +#include "lib/clists.h" + +extern struct cf_section ipaccess_cf; +int ipaccess_check(clist *l, u32 ip); + +/* FIXME: Hacks to make older modules compile */ +struct ipaccess_list { }; +#define ipaccess_init() NULL +#define ipaccess_parse(x,y,z) NULL +#define ipaccess_check(x,y) 0 + +#endif -- 2.39.2