Commit 2eb7eafc authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

Add a new family-specific syntax for tor_addr_parse_mask_ports

By default, "*" means "All IPv4 addresses" with
tor_addr_parse_mask_ports, so I won't break anything.  But if the new
EXTENDED_STAR flag is provided, then * means "any address", *4 means
"any IPv4 address" (that is, 0.0.0.0/0), and "*6" means "any IPv6
address" (that is, [::]/0).

This is going to let us have a syntax for specifying exit policies in
torrc that won't drive people mad.

Also, add a bunch of unit tests for tor_addr_parse_mask_ports to test
these new features, and to increase coverage.
parent 462ebb27
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -559,9 +559,22 @@ tor_addr_to_PTR_name(char *out, size_t outlen,
 *
 *  Return an address family on success, or -1 if an invalid address string is
 *  provided.
 *
 *  If 'flags & TAPMP_EXTENDED_STAR' is false, then the wildcard address '*'
 *  yield an IPv4 wildcard.
 *
 *  If 'flags & TAPMP_EXTENDED_STAR' is true, then the wildcard address '*'
 *  yields an AF_UNSPEC wildcard address, and the following change is made
 *  in the grammar above:
 *   Address ::= IPv4Address / "[" IPv6Address "]" / "*" / "*4" / "*6"
 *  with the new "*4" and "*6" productions creating a wildcard to match
 *  IPv4 or IPv6 addresses.
 *
 */
int
tor_addr_parse_mask_ports(const char *s, tor_addr_t *addr_out,
tor_addr_parse_mask_ports(const char *s,
                          unsigned flags,
                          tor_addr_t *addr_out,
                          maskbits_t *maskbits_out,
                          uint16_t *port_min_out, uint16_t *port_max_out)
{
@@ -618,8 +631,22 @@ tor_addr_parse_mask_ports(const char *s, tor_addr_t *addr_out,
  memset(addr_out, 0, sizeof(tor_addr_t));

  if (!strcmp(address, "*")) {
    family = AF_INET; /* AF_UNSPEC ???? XXXX_IP6 */
    if (flags & TAPMP_EXTENDED_STAR) {
      family = AF_UNSPEC;
      tor_addr_make_unspec(addr_out);
    } else {
      family = AF_INET;
      tor_addr_from_ipv4h(addr_out, 0);
    }
    any_flag = 1;
  } else if (!strcmp(address, "*4") && (flags & TAPMP_EXTENDED_STAR)) {
    family = AF_INET;
    tor_addr_from_ipv4h(addr_out, 0);
    any_flag = 1;
  } else if (!strcmp(address, "*6") && (flags & TAPMP_EXTENDED_STAR)) {
    static char nil_bytes[16] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
    family = AF_INET6;
    tor_addr_from_ipv6_bytes(addr_out, nil_bytes);
    any_flag = 1;
  } else if (tor_inet_pton(AF_INET6, address, &in6_tmp) > 0) {
    family = AF_INET6;
+2 −1
Original line number Diff line number Diff line
@@ -183,7 +183,8 @@ int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,

int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out,
                        uint16_t *port_out);
int tor_addr_parse_mask_ports(const char *s,
#define TAPMP_EXTENDED_STAR 1
int tor_addr_parse_mask_ports(const char *s, unsigned flags,
                              tor_addr_t *addr_out, maskbits_t *mask_out,
                              uint16_t *port_min_out, uint16_t *port_max_out);
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len,
+1 −0
Original line number Diff line number Diff line
@@ -276,6 +276,7 @@ static config_var_t option_vars_[] = {
  V(HTTPProxyAuthenticator,      STRING,   NULL),
  V(HTTPSProxy,                  STRING,   NULL),
  V(HTTPSProxyAuthenticator,     STRING,   NULL),
  //  V(IPv6EXit,                    BOOL,     "0"),
  VAR("ServerTransportPlugin",   LINELIST, ServerTransportPlugin,  NULL),
  V(Socks4Proxy,                 STRING,   NULL),
  V(Socks5Proxy,                 STRING,   NULL),
+4 −3
Original line number Diff line number Diff line
@@ -87,7 +87,8 @@ policy_expand_private(smartlist_t **policy)
       memcpy(&newpolicy, p, sizeof(addr_policy_t));
       newpolicy.is_private = 0;
       newpolicy.is_canonical = 0;
       if (tor_addr_parse_mask_ports(private_nets[i], &newpolicy.addr,
       if (tor_addr_parse_mask_ports(private_nets[i], 0,
                               &newpolicy.addr,
                               &newpolicy.maskbits, &port_min, &port_max)<0) {
         tor_assert(0);
       }
@@ -1192,7 +1193,7 @@ policy_summary_add_item(smartlist_t *summary, addr_policy_t *p)
     for (i = 0; private_nets[i]; ++i) {
       tor_addr_t addr;
       maskbits_t maskbits;
       if (tor_addr_parse_mask_ports(private_nets[i], &addr,
       if (tor_addr_parse_mask_ports(private_nets[i], 0, &addr,
                                     &maskbits, NULL, NULL)<0) {
         tor_assert(0);
       }
+3 −2
Original line number Diff line number Diff line
@@ -1280,7 +1280,8 @@ find_single_ipv6_orport(const smartlist_t *list,
    uint16_t port_min, port_max;
    tor_assert(t->n_args >= 1);
    /* XXXX Prop186 the full spec allows much more than this. */
    if (tor_addr_parse_mask_ports(t->args[0], &a, &bits, &port_min,
    if (tor_addr_parse_mask_ports(t->args[0], 0,
                                  &a, &bits, &port_min,
                                  &port_max) == AF_INET6 &&
        bits == 128 &&
        port_min == port_max) {
@@ -3737,7 +3738,7 @@ router_parse_addr_policy(directory_token_t *tok)
  else
    newe.policy_type = ADDR_POLICY_ACCEPT;

  if (tor_addr_parse_mask_ports(arg, &newe.addr, &newe.maskbits,
  if (tor_addr_parse_mask_ports(arg, 0, &newe.addr, &newe.maskbits,
                                &newe.prt_min, &newe.prt_max) < 0) {
    log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
    return NULL;
Loading