From: Andre Noll Date: Sat, 4 Jul 2009 14:25:20 +0000 (+0200) Subject: Merge branch 'crypt' into next X-Git-Tag: v0.4.0~76 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=732bf143e456df7fc2e845884fbbdfdaf3fafebc;hp=a18295788a381a5083e42fde7d7615b328bb6509 Merge branch 'crypt' into next --- diff --git a/NEWS b/NEWS index 4d775ecf..dff82086 100644 --- a/NEWS +++ b/NEWS @@ -6,11 +6,13 @@ NEWS ------------------------------------------------- - the new oss writer (supported on *BSD and Linux) + - support for netmask subsets (Gerrit Renker) - the new prebuffer filter - improved signal handling - variable fec output buffer size - --log_color actually works - new ls option: -d (print dates as seconds after the epoch) + - update to gengetopt 2.22.2 ----------------------------------------- 0.3.4 (2009-05-07) "elliptic inheritance" diff --git a/acl.c b/acl.c index 14edcf7d..ffcd1685 100644 --- a/acl.c +++ b/acl.c @@ -90,13 +90,17 @@ static void acl_add_entry(struct list_head *acl, char *addr, int netmask) * \param addr The address to delete. * \param netmask The netmask of the entry to be removed from the list. */ -static void acl_del_entry(struct list_head *acl, char *addr, int netmask) +static void acl_del_entry(struct list_head *acl, char *addr, unsigned netmask) { struct access_info *ai, *tmp; + struct in_addr to_delete; + + inet_pton(AF_INET, addr, &to_delete); list_for_each_entry_safe(ai, tmp, acl, node) { - if (!strcmp(addr, inet_ntoa(ai->addr)) && - ai->netmask == netmask) { + + if (v4_addr_match(to_delete.s_addr, ai->addr.s_addr, + PARA_MIN(netmask, ai->netmask))) { PARA_NOTICE_LOG("removing %s/%i from access list\n", addr, ai->netmask); list_del(&ai->node); @@ -136,30 +140,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/audiod_command.c b/audiod_command.c index 3467dbe1..ca1bff5b 100644 --- a/audiod_command.c +++ b/audiod_command.c @@ -166,23 +166,24 @@ int com_kill(int fd, int argc, char **argv) return ret; } -int com_stat(int fd, __a_unused int argc, __a_unused char **argv) +int com_stat(int fd, int argc, char **argv) { int i, ret; char *buf = NULL; - long unsigned mask = ~0LU; + uint64_t mask = 0; + const uint64_t one = 1; if (argc > 1) { - mask = 0; for (i = 1; i < argc; i++) { ret = stat_item_valid(argv[i]); if (ret < 0) return ret; - mask |= (1 << ret); + mask |= (one << ret); } - } - PARA_INFO_LOG("mask: 0x%lx\n", mask); - if (mask & (1 << SI_PLAY_TIME)) { + } else + mask--; /* set all bits */ + PARA_INFO_LOG("mask: 0x%llx\n", (long long unsigned)mask); + if (mask & (one << SI_PLAY_TIME)) { int slot_num = get_play_time_slot_num(); char *ts = get_time_string(slot_num); if (ts) { @@ -192,7 +193,7 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv) free(ts); } } - if (mask & (1 << SI_AUDIOD_UPTIME)) { + if (mask & (one << SI_AUDIOD_UPTIME)) { char *tmp, *us = uptime_str(); tmp = make_message("%s: %s\n", status_item_list[SI_AUDIOD_UPTIME], us); @@ -202,14 +203,14 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv) goto out; free(tmp); } - if (mask & (1 << SI_AUDIOD_STATUS)) { + if (mask & (one << SI_AUDIOD_STATUS)) { char *s = audiod_status_string(); ret = client_write(fd, s); if (ret < 0) goto out; free(s); } - if (mask & (1 << SI_DECODER_FLAGS)) { + if (mask & (one << SI_DECODER_FLAGS)) { char *df = decoder_flags(); ret = client_write(fd, df); if (ret < 0) @@ -218,7 +219,7 @@ int com_stat(int fd, __a_unused int argc, __a_unused char **argv) } FOR_EACH_STATUS_ITEM(i) { char *tmp, *v; - if (!((1 << i) & mask)) + if (!((one << i) & mask)) continue; v = stat_item_values[i]; tmp = make_message("%s%s%s", buf? buf: "", diff --git a/command.c b/command.c index a14fff8b..fc5b5cac 100644 --- a/command.c +++ b/command.c @@ -183,17 +183,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/grab_client.c b/grab_client.c index ccfdb0c8..9b4ef69c 100644 --- a/grab_client.c +++ b/grab_client.c @@ -82,7 +82,7 @@ static int check_gc_args(struct grab_client *gc) { int i; struct grab_client_args_info *c = gc->conf; - char **mv = grab_client_cmdline_parser_mode_values; + const char **mv = grab_client_cmdline_parser_mode_values; PARA_INFO_LOG("filter_num: %d\n", c->filter_num_arg); for (i = 0; mv[i]; i++) diff --git a/net.c b/net.c index f10afb71..b3588f6d 100644 --- a/net.c +++ b/net.c @@ -36,6 +36,47 @@ #include "string.h" #include "fd.h" +/** + * 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 b85403fd..15412586 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/para.h b/para.h index 112d5fef..d49d7221 100644 --- a/para.h +++ b/para.h @@ -184,7 +184,7 @@ extern const char *status_item_list[]; int stat_item_valid(const char *item); int stat_line_valid(const char *); void stat_client_write(const char *msg, int itemnum); -int stat_client_add(int fd, long unsigned mask); +int stat_client_add(int fd, uint64_t mask); __printf_2_3 void para_log(int, const char*, ...); 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" ); } diff --git a/stat.c b/stat.c index 4ba1b0e8..0306cba4 100644 --- a/stat.c +++ b/stat.c @@ -35,7 +35,7 @@ struct stat_client { /** The stat client's file descriptor. */ int fd; /** Bitmask of those status items the client is interested in. */ - long unsigned item_mask; + uint64_t item_mask; /** Its entry in the list of stat clients. */ struct list_head node; }; @@ -68,7 +68,7 @@ static void dump_stat_client_list(void) * \return Positive value on success, or -E_TOO_MANY_CLIENTS if * the number of connected clients exceeds #MAX_STAT_CLIENTS. */ -int stat_client_add(int fd, long unsigned mask) +int stat_client_add(int fd, uint64_t mask) { struct stat_client *new_client; @@ -103,13 +103,14 @@ void stat_client_write(const char *msg, int itemnum) { struct stat_client *sc, *tmp; size_t len = strlen(msg); + const uint64_t one = 1; if (!initialized || !len) return; list_for_each_entry_safe(sc, tmp, &client_list, node) { int fd = sc->fd, ret; - if (!((1 << itemnum) & sc->item_mask)) + if (!((one << itemnum) & sc->item_mask)) continue; if (write_ok(fd) > 0) { ret = write(fd, msg, len);