Commit 4a240552 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

r13834@catbus: nickm | 2007-07-19 15:40:42 -0400

 Another patch from croup: drop support for address masks that do not correspond to bit prefixes.  Nobody has used this for a while, and we have given warnings for a long time.


svn:r10881
parent bbbf5042
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
Changes in version 0.2.0.3-alpha - 2007-??-??
  o Removed features:
    - Stop allowing address masks that do not correspond to bit prefixes.
      We have warned about these for a really long time; now it's time
      to reject them. (Patch from croup.)

  o Minor features:
    - Create listener connections before we setuid to the configured User and
      Group.  This way, you can choose port values under 1024, start Tor as
+51 −43
Original line number Diff line number Diff line
@@ -2000,6 +2000,32 @@ addr_mask_get_bits(uint32_t mask)
  return -1;
}

/** Compare two addresses <b>a1</b> and <b>a2</b> for equality under a
 *  etmask of <b>mbits</b> bits.  Return -1, 0, or 1.
 *
 * XXXX020Temporary function to allow masks as bitcounts everywhere.  This
 * will be replaced with an IPv6-aware version as soon as 32-bit addresses are
 * no longer passed around.
 */
int
addr_mask_cmp_bits(uint32_t a1, uint32_t a2, maskbits_t bits)
{
  if (bits > 32)
    bits = 32;
  else if (bits == 0)
    return 0;

  a1 >>= (32-bits);
  a2 >>= (32-bits);

  if (a1 < a2)
    return -1;
  else if (a1 > a2)
    return 1;
  else
    return 0;
}

/** Parse a string <b>s</b> in the format of (*|port(-maxport)?)?, setting the
 * various *out pointers as appropriate.  Return 0 on success, -1 on failure.
 */
@@ -2058,7 +2084,7 @@ parse_port_range(const char *port, uint16_t *port_min_out,
 */
int
parse_addr_and_port_range(const char *s, uint32_t *addr_out,
                          uint32_t *mask_out, uint16_t *port_min_out,
                          maskbits_t *maskbits_out, uint16_t *port_min_out,
                          uint16_t *port_max_out)
{
  char *address;
@@ -2068,7 +2094,7 @@ parse_addr_and_port_range(const char *s, uint32_t *addr_out,

  tor_assert(s);
  tor_assert(addr_out);
  tor_assert(mask_out);
  tor_assert(maskbits_out);
  tor_assert(port_min_out);
  tor_assert(port_max_out);

@@ -2098,9 +2124,9 @@ parse_addr_and_port_range(const char *s, uint32_t *addr_out,

  if (!mask) {
    if (strcmp(address,"*")==0)
      *mask_out = 0;
      *maskbits_out = 0;
    else
      *mask_out = 0xFFFFFFFFu;
      *maskbits_out = 32;
  } else {
    endptr = NULL;
    bits = (int) strtol(mask, &endptr, 10);
@@ -2111,9 +2137,16 @@ parse_addr_and_port_range(const char *s, uint32_t *addr_out,
                 "Bad number of mask bits on address range; rejecting.");
        goto err;
      }
      *mask_out = ~((1u<<(32-bits))-1);
      *maskbits_out = bits;
    } else if (tor_inet_aton(mask, &in) != 0) {
      *mask_out = ntohl(in.s_addr);
      bits = addr_mask_get_bits(ntohl(in.s_addr));
      if (bits < 0) {
        log_warn(LD_GENERAL,
                 "Mask %s on address range isn't a prefix; dropping",
                 escaped(mask));
        goto err;
      }
      *maskbits_out = bits;
    } else {
      log_warn(LD_GENERAL,
               "Malformed mask %s on address range; rejecting.",
@@ -2457,38 +2490,32 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
    return 0;

  if (v_family[0] == AF_INET) { /* Real or mapped IPv4 */
#if 0
    if (mbits >= 32) {
      masked_a = ip4a;
      masked_b = ip4b;
    } else if (mbits == 0) {
      return 0;
    } else {
      masked_a = ip4a & (0xfffffffful << (32-mbits));
      masked_b = ip4b & (0xfffffffful << (32-mbits));
    }
#endif
    if (mbits > 32)
      mbits = 32;
      masked_a = ip4a >> (32-mbits);
      masked_b = ip4b >> (32-mbits);
    }
    if (masked_a < masked_b)
      return -1;
    else if (masked_a > masked_b)
      return 1;
    return 0;
  } else if (v_family[0] == AF_INET6) { /* Real IPv6 */
    maskbits_t lmbits;
    const uint32_t *a1 = IN6_ADDR(addr1)->s6_addr32;
    const uint32_t *a2 = IN6_ADDR(addr2)->s6_addr32;
    for (idx = 0; idx < 4; ++idx) {
      if (!mbits)
      uint32_t masked_a = ntohl(a1[idx]);
      uint32_t masked_b = ntohl(a2[idx]);
      if (!mbits) {
        return 0; /* Mask covers both addresses from here on */
      else if (mbits > 32)
        lmbits = 32;
      else
        lmbits = mbits;

      masked_a = ntohl(a1[idx]) >> (32-lmbits);
      masked_b = ntohl(a2[idx]) >> (32-lmbits);
      } else if (mbits < 32) {
        masked_a >>= (32-mbits);
        masked_b >>= (32-mbits);
      }

      if (masked_a > masked_b)
        return 1;
@@ -2499,25 +2526,6 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
        return 0;
      mbits -= 32;
    }
#if 0
    for (idx = 0; idx < 4; ++idx) {
      if (mbits <= 32*idx) /* Mask covers both addresses from here on */
        return 0;
      if (mbits >= 32*(idx+1)) { /* Mask doesn't affect these 32 bits */
        lmbits = 32;
      } else {
        lmbits = mbits % 32;
      }
      masked_a = ntohl(IN6_ADDR(addr1).s6_addr32[idx]) &
                 (0xfffffffful << (32-lmbits));
      masked_b = ntohl(IN6_ADDR(addr2).s6_addr32[idx]) &
                 (0xfffffffful << (32-lmbits));
      if (masked_a > masked_b)
        return 1;
      if (masked_a < masked_b)
        return -1;
    }
#endif
    return 0;
  }

+2 −1
Original line number Diff line number Diff line
@@ -251,9 +251,10 @@ int parse_addr_port(int severity, const char *addrport, char **address,
int parse_port_range(const char *port, uint16_t *port_min_out,
                     uint16_t *port_max_out);
int parse_addr_and_port_range(const char *s, uint32_t *addr_out,
                              uint32_t *mask_out, uint16_t *port_min_out,
                              maskbits_t *maskbits_out, uint16_t *port_min_out,
                              uint16_t *port_max_out);
int addr_mask_get_bits(uint32_t mask);
int addr_mask_cmp_bits(uint32_t a1, uint32_t a2, maskbits_t bits);
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
char *tor_dup_addr(uint32_t addr) ATTR_MALLOC;
int get_interface_address(int severity, uint32_t *addr);
+2 −2
Original line number Diff line number Diff line
@@ -3562,8 +3562,8 @@ parse_redirect_line(smartlist_t *result, config_line_t *line, char **msg)
    *msg = tor_strdup("Wrong number of elements in RedirectExit line");
    goto err;
  }
  if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,&r->mask,
                                &r->port_min,&r->port_max)) {
  if (parse_addr_and_port_range(smartlist_get(elements,0),&r->addr,
                                &r->maskbits,&r->port_min,&r->port_max)) {
    *msg = tor_strdup("Error parsing source address in RedirectExit line");
    goto err;
  }
+11 −18
Original line number Diff line number Diff line
@@ -917,8 +917,7 @@ client_dns_set_reverse_addressmap(const char *address, const char *v,
 * These options are configured by parse_virtual_addr_network().
 */
static uint32_t virtual_addr_network = 0x7fc00000u;
static uint32_t virtual_addr_netmask = 0xffc00000u;
static int virtual_addr_netmask_bits = 10;
static maskbits_t virtual_addr_netmask_bits = 10;
static uint32_t next_virtual_addr    = 0x7fc00000u;

/** Read a netmask of the form 127.192.0.0/10 from "val", and check whether
@@ -930,11 +929,11 @@ int
parse_virtual_addr_network(const char *val, int validate_only,
                           char **msg)
{
  uint32_t addr, mask;
  uint32_t addr;
  uint16_t port_min, port_max;
  int bits;
  maskbits_t bits;

  if (parse_addr_and_port_range(val, &addr, &mask, &port_min, &port_max)) {
  if (parse_addr_and_port_range(val, &addr, &bits, &port_min, &port_max)) {
    if (msg) *msg = tor_strdup("Error parsing VirtualAddressNetwork");
    return -1;
  }
@@ -944,13 +943,6 @@ parse_virtual_addr_network(const char *val, int validate_only,
    return -1;
  }

  bits = addr_mask_get_bits(mask);
  if (bits < 0) {
    if (msg) *msg = tor_strdup("VirtualAddressNetwork must have a mask that "
                               "can be expressed as a prefix");
    return -1;
  }

  if (bits > 16) {
    if (msg) *msg = tor_strdup("VirtualAddressNetwork expects a /16 "
                               "network or larger");
@@ -960,11 +952,10 @@ parse_virtual_addr_network(const char *val, int validate_only,
  if (validate_only)
    return 0;

  virtual_addr_network = addr & mask;
  virtual_addr_netmask = mask;
  virtual_addr_network = addr & (0xfffffffful << (32-bits));
  virtual_addr_netmask_bits = bits;

  if ((next_virtual_addr & mask) != addr)
  if (addr_mask_cmp_bits(next_virtual_addr, addr, bits))
    next_virtual_addr = addr;

  return 0;
@@ -983,7 +974,8 @@ address_is_in_virtual_range(const char *address)
    return 1;
  } else if (tor_inet_aton(address, &in)) {
    uint32_t addr = ntohl(in.s_addr);
    if ((addr & virtual_addr_netmask) == virtual_addr_network)
    if (!addr_mask_cmp_bits(addr, virtual_addr_network,
                            virtual_addr_netmask_bits))
      return 1;
  }
  return 0;
@@ -1029,7 +1021,8 @@ addressmap_get_virtual_address(int type)
        log_warn(LD_CONFIG, "Ran out of virtual addresses!");
        return NULL;
      }
      if ((next_virtual_addr & virtual_addr_netmask) != virtual_addr_network)
      if (!addr_mask_cmp_bits(next_virtual_addr, virtual_addr_network,
                              virtual_addr_netmask_bits))
        next_virtual_addr = virtual_addr_network;
    }
    return tor_strdup(buf);
@@ -2452,7 +2445,7 @@ connection_exit_connect(edge_connection_t *edge_conn)
  if (redirect_exit_list) {
    SMARTLIST_FOREACH(redirect_exit_list, exit_redirect_t *, r,
    {
      if ((addr&r->mask)==(r->addr&r->mask) &&
      if (!addr_mask_cmp_bits(addr, r->addr, r->maskbits) &&
          (r->port_min <= port) && (port <= r->port_max)) {
        struct in_addr in;
        if (r->is_redirect) {
Loading