Преглед изворни кода

Allow private:* in routerdescs; not generated yet (because older Tors do not understand it); needs testing.

svn:r6086
Nick Mathewson пре 18 година
родитељ
комит
6a4e304d9e
4 измењених фајлова са 107 додато и 32 уклоњено
  1. 47 31
      src/common/util.c
  2. 2 0
      src/common/util.h
  3. 3 1
      src/or/config.c
  4. 55 0
      src/or/routerparse.c

+ 47 - 31
src/common/util.c

@@ -1440,8 +1440,52 @@ addr_mask_get_bits(uint32_t mask)
   return -1;
 }
 
+/** 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.
+ */
+int
+parse_port_range(const char *port, uint16_t *port_min_out,
+                 uint16_t *port_max_out)
+{
+  tor_assert(port_min_out);
+  tor_assert(port_max_out);
+
+  if (!port || *port == '\0' || strcmp(port, "*") == 0) {
+    *port_min_out = 1;
+    *port_max_out = 65535;
+  } else {
+    char *endptr = NULL;
+    *port_min_out = (uint16_t) tor_parse_long(port, 10, 1, 65535,
+                                              NULL, &endptr);
+    if (*endptr == '-') {
+      port = endptr+1;
+      endptr = NULL;
+      *port_max_out = (uint16_t) tor_parse_long(port, 10, 1, 65535, NULL,
+                                                &endptr);
+      if (*endptr || !*port_max_out) {
+        log_warn(LD_GENERAL,
+                 "Malformed port \"%s\" on address range rejecting.",
+                 port);
+      }
+    } else if (*endptr || !*port_min_out) {
+      log_warn(LD_GENERAL,
+               "Malformed port \"%s\" on address range; rejecting.",
+               port);
+      return -1;
+    } else {
+      *port_max_out = *port_min_out;
+    }
+    if (*port_min_out > *port_max_out) {
+      log_warn(LD_GENERAL, "Insane port range on address policy; rejecting.");
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
 /** Parse a string <b>s</b> in the format of
- * (IP(/mask|/mask-bits)?|*):(*|port(-maxport)?), setting the various
+ * (IP(/mask|/mask-bits)?|*)(:*|port(-maxport)?)?, setting the various
  * *out pointers as appropriate.  Return 0 on success, -1 on failure.
  */
 int
@@ -1510,36 +1554,8 @@ parse_addr_and_port_range(const char *s, uint32_t *addr_out,
     }
   }
 
-  if (!port || strcmp(port, "*") == 0) {
-    *port_min_out = 1;
-    *port_max_out = 65535;
-  } else {
-    endptr = NULL;
-    *port_min_out = (uint16_t) tor_parse_long(port, 10, 1, 65535,
-                                              NULL, &endptr);
-    if (*endptr == '-') {
-      port = endptr+1;
-      endptr = NULL;
-      *port_max_out = (uint16_t) tor_parse_long(port, 10, 1, 65535, NULL,
-                                                &endptr);
-      if (*endptr || !*port_max_out) {
-        log_warn(LD_GENERAL,
-                 "Malformed port \"%s\" on address range rejecting.",
-                 port);
-      }
-    } else if (*endptr || !*port_min_out) {
-      log_warn(LD_GENERAL,
-               "Malformed port \"%s\" on address range; rejecting.",
-               port);
-      goto err;
-    } else {
-      *port_max_out = *port_min_out;
-    }
-    if (*port_min_out > *port_max_out) {
-      log_warn(LD_GENERAL, "Insane port range on address policy; rejecting.");
-      goto err;
-    }
-  }
+  if (parse_port_range(port, port_min_out, port_max_out)<0)
+    goto err;
 
   tor_free(address);
   return 0;

+ 2 - 0
src/common/util.h

@@ -165,6 +165,8 @@ int is_internal_IP(uint32_t ip, int for_listening);
 int is_local_IP(uint32_t ip);
 int parse_addr_port(const char *addrport, char **address, uint32_t *addr,
                     uint16_t *port);
+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,
                               uint16_t *port_max_out);

+ 3 - 1
src/or/config.c

@@ -3299,7 +3299,9 @@ config_parse_addr_policy(config_line_t *cfg,
           log_warn(LD_CONFIG, "Address policy element '%s' can't be expressed "
                    "as a bit prefix.", ent);
         }
-        nextp = &((*nextp)->next);
+        /* Advance nextp to the end of the policy. */
+        while (*nextp)
+          nextp = &((*nextp)->next);
       } else {
         log_warn(LD_CONFIG,"Malformed policy '%s'.", ent);
         r = -1;

+ 55 - 0
src/or/routerparse.c

@@ -151,6 +151,8 @@ static struct {
 /* static function prototypes */
 static int router_add_exit_policy(routerinfo_t *router,directory_token_t *tok);
 static addr_policy_t *router_parse_addr_policy(directory_token_t *tok);
+static addr_policy_t *router_parse_private_addr_policy_private(
+                                               directory_token_t *tok);
 static int router_get_hash_impl(const char *s, char *digest,
                                 const char *start_str, const char *end_str);
 static void token_free(directory_token_t *tok);
@@ -1338,6 +1340,9 @@ router_parse_addr_policy(directory_token_t *tok)
     return NULL;
   arg = tok->args[0];
 
+  if (!strcmpstart(arg,"private"))
+    return router_parse_private_addr_policy_private(tok);
+
   newe = tor_malloc_zero(sizeof(addr_policy_t));
 
   newe->string = tor_malloc(8+strlen(arg));
@@ -1370,6 +1375,56 @@ policy_read_failed:
   return NULL;
 }
 
+/** Parse an exit policy line of the format "accept/reject private:...".
+ * This didn't exist until Tor 0.1.1.15, so nobody should generate it in
+ * router descriptors until earlier versions are obsolete.
+ */
+static addr_policy_t *
+router_parse_private_addr_policy_private(directory_token_t *tok)
+{
+  /* XXXX duplicated from config.c */
+  static const char *private_nets[] = {
+    "0.0.0.0/8", "169.254.0.0/16",
+    "127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12",NULL };
+  char *arg;
+  addr_policy_t *result, **nextp;
+  int net;
+  uint16_t port_min, port_max;
+
+  arg = tok->args[0];
+  if (strcmpstart(arg, "private"))
+    return NULL;
+  arg += strlen("private");
+  arg = (char*) eat_whitespace(arg);
+  if (!arg || *arg != ':')
+    return NULL;
+
+  if (parse_port_range(arg+1, &port_min, &port_max)<0)
+    return NULL;
+
+  nextp = &result;
+  for (net = 0; private_nets[net]; ++net) {
+    size_t len;
+    *nextp = tor_malloc_zero(sizeof(addr_policy_t));
+    (*nextp)->policy_type = (tok->tp == K_REJECT) ? ADDR_POLICY_REJECT
+      : ADDR_POLICY_ACCEPT;
+    len = strlen(arg)+strlen(private_nets[net])+16;
+    (*nextp)->string = tor_malloc(len+1);
+    tor_snprintf((*nextp)->string, len, "%s %s%s",
+                 tok->tp == K_REJECT ? "reject" : "accept",
+                 private_nets[net], arg);
+    if (parse_addr_and_port_range((*nextp)->string + 7,
+                                  &(*nextp)->addr, &(*nextp)->msk,
+                                  &(*nextp)->prt_min, &(*nextp)->prt_max)) {
+      log_warn(LD_BUG, "Couldn't parse an address range we generated!");
+      return NULL;
+    }
+    nextp = &(*nextp)->next;
+  }
+
+  return result;
+}
+
 /** Log and exit if <b>t</b> is malformed */
 void
 assert_addr_policy_ok(addr_policy_t *t)