From 0b36e0a77fc750af85e969efda7bda0931f389d0 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 30 Jun 2009 10:17:16 +0200 Subject: [PATCH] Make allow/deny syntax consistent with that of add/delete After the changes for the add/delete commands, this patch updates allow/deny to use the same syntax and (almost) the same code. --- acl.c | 30 ++++++++---------------------- command.c | 12 ++---------- net.c | 41 +++++++++++++++++++++++++++++++++++++++++ net.h | 2 ++ send_common.c | 5 +++-- 5 files changed, 56 insertions(+), 34 deletions(-) diff --git a/acl.c b/acl.c index 14edcf7d..9bc83c25 100644 --- a/acl.c +++ b/acl.c @@ -136,30 +136,16 @@ char *acl_get_contents(struct list_head *acl) */ void acl_init(struct list_head *acl, char * const *acl_info, int num) { - int i; + char addr[16]; + int mask, i; INIT_LIST_HEAD(acl); - for (i = 0; i < num; i++) { - char *arg = para_strdup(acl_info[i]); - char *p = strchr(arg, '/'); - int netmask; - - if (!p) - goto err; - *p = '\0'; - if (!is_valid_ipv4_address(arg)) - goto err; - netmask = atoi(++p); - if (netmask < 0 || netmask > 32) - goto err; - acl_add_entry(acl, arg, netmask); - goto success; -err: - PARA_CRIT_LOG("syntax error: %s\n", acl_info[i]); -success: - free(arg); - continue; - } + for (i = 0; i < num; i++) + if (parse_cidr(acl_info[i], addr, sizeof(addr), &mask) == NULL) + PARA_CRIT_LOG("ACL syntax error: %s, ignoring\n", + acl_info[i]); + else + acl_add_entry(acl, addr, mask); } /** diff --git a/command.c b/command.c index 1ca54da9..e3b15a5a 100644 --- a/command.c +++ b/command.c @@ -185,17 +185,9 @@ static int check_sender_args(int argc, char * const * argv, struct sender_comman break; case SENDER_DENY: case SENDER_ALLOW: - if (argc != 4 && argc != 5) + if (argc != 4 || parse_cidr(argv[3], scd->host, + sizeof(scd->host), &scd->netmask) == NULL) return -E_COMMAND_SYNTAX; - if (!is_valid_ipv4_address(argv[3])) - return -E_COMMAND_SYNTAX; - scd->netmask = 32; - if (argc == 5) { - scd->netmask = atoi(argv[4]); - if (scd->netmask < 0 || scd->netmask > 32) - return -E_COMMAND_SYNTAX; - } - strncpy(scd->host, argv[3], sizeof(scd->host)); break; case SENDER_ADD: case SENDER_DELETE: diff --git a/net.c b/net.c index 7207e528..ab6a9894 100644 --- a/net.c +++ b/net.c @@ -92,6 +92,47 @@ void disable_crypt(int fd) crypt_data_array[fd].private_data = NULL; } +/** + * Parse and validate IPv4 address/netmask string. + * + * \param cidr Address in CIDR notation + * \param addr Copy of the IPv4 address part of \a cidr + * \param addrlen Size of \a addr in bytes + * \param netmask Value of the netmask part in \a cidr or the + * default of 32 if not specified. + * + * \return Pointer to \a addr if succesful, NULL on error. + * \sa RFC 4632 + */ +char *parse_cidr(const char *cidr, + char *addr, ssize_t addrlen, + int32_t *netmask) +{ + const char *o = cidr; + char *c = addr, *end = c + (addrlen - 1); + + *netmask = 0x20; + + if (cidr == NULL || addrlen < 1) + goto failed; + + for (o = cidr; (*c = *o == '/'? '\0' : *o); c++, o++) + if (c == end) + goto failed; + + if (*o == '/') + if (para_atoi32(++o, netmask) < 0 || + *netmask < 0 || *netmask > 0x20) + goto failed; + + if (is_valid_ipv4_address(addr)) + return addr; +failed: + *addr = '\0'; + return NULL; +} + + /** * Match string as a candidate IPv4 address. * diff --git a/net.h b/net.h index 11b1708f..8b706178 100644 --- a/net.h +++ b/net.h @@ -29,6 +29,8 @@ /** * Functions to parse and validate (parts of) URLs. */ +extern char *parse_cidr(const char *cidr, + char *addr, ssize_t addrlen, int32_t *netmask); extern char *parse_url(const char *url, char *host, ssize_t hostlen, int32_t *port); /** diff --git a/send_common.c b/send_common.c index b8160073..200e59ab 100644 --- a/send_common.c +++ b/send_common.c @@ -389,8 +389,9 @@ char *generic_sender_help(void) { return make_message( "usage: {on|off}\n" - "usage: {allow|deny} IP mask\n" - "example: allow 127.0.0.1 32\n" + "usage: {allow|deny} IP[/netmask]\n" + " where mask defaults to 32\n" + "example: allow 192.168.0.1/24\n" ); } -- 2.39.2