Browse Source

Add private:* as an alias in configuration for policies.

svn:r5534
Nick Mathewson 19 years ago
parent
commit
1b770817c0
3 changed files with 70 additions and 11 deletions
  1. 3 2
      doc/TODO
  2. 9 8
      doc/tor.1.in
  3. 58 1
      src/or/config.c

+ 3 - 2
doc/TODO

@@ -94,9 +94,10 @@ N       - Specify and implement it.
     - Implement
 
 N - Destroy and truncated cells should have reasons.
-N*- Add private:* alias in exit policies to make it easier to ban all the
+  o Add private:* alias in exit policies to make it easier to ban all the
     fiddly little 192.168.foo addresses.
-    (AGL had a patch; consider applying it.)
+    o Implement
+    o Document
 
   o warn if listening for SOCKS on public IP.
 

+ 9 - 8
doc/tor.1.in

@@ -387,22 +387,23 @@ For example, "reject 127.0.0.1:*,reject 192.168.1.0/24:*,accept *:*" would
 reject any traffic destined for localhost and any 192.168.1.* address, but
 accept anything else.
 
+To specify all internal networks (including 169.254.0.0/16,
+127.0.0.0/8, 192.168.0.0/16, 10.0.0.0/8, and 172.16.0.0/12), you can use
+the "private" alias instead of an address.  For example, to allow HTTP
+to 127.0.0.1 and block all other connections to internal networks, you
+can say "accept 127.0.0.1:80,reject private:*".  See RFC 3330 for more
+details about internal and reserved IP address space.
+
 This directive can be specified multiple times so you don't have to put
 it all on one line.
 
-See RFC 3330 for more details about internal and reserved IP address
-space. Policies are considered first to last, and the first match wins. If
+Policies are considered first to last, and the first match wins. If
 you want to _replace_ the default exit policy, end your exit policy with
 either a reject *:* or an accept *:*. Otherwise, you're _augmenting_
 (prepending to) the default exit policy. The default exit policy is:
 .PD 0
 .RS 12
-.IP "reject 0.0.0.0/8" 0
-.IP "reject 169.254.0.0/16" 4
-.IP "reject 127.0.0.0/8"
-.IP "reject 192.168.0.0/16"
-.IP "reject 10.0.0.0/8"
-.IP "reject 172.16.0.0/12"
+.IP "reject private:*" 0
 .IP "reject *:25"
 .IP "reject *:119"
 .IP "reject *:135-139"

+ 58 - 1
src/or/config.c

@@ -2745,7 +2745,8 @@ normalize_log_options(or_options_t *options)
   return 0;
 }
 
-#define DEFAULT_EXIT_POLICY "reject 0.0.0.0/8,reject 169.254.0.0/16,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,reject *:25,reject *:119,reject *:135-139,reject *:445,reject *:465,reject *:587,reject *:1214,reject *:4661-4666,reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*"
+
+#define DEFAULT_EXIT_POLICY "reject private:*,reject *:25,reject *:119,reject *:135-139,reject *:445,reject *:465,reject *:587,reject *:1214,reject *:4661-4666,reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*"
 
 /** Add the default exit policy entries to <b>policy</b>
  */
@@ -2772,6 +2773,58 @@ options_append_default_exit_policy(addr_policy_t **policy)
   }
 }
 
+static int
+config_expand_exit_policy_aliases(smartlist_t *entries)
+{
+  static const char *prefixes[] = {
+    "127.0.0.0/8", "192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12",NULL };
+  int i;
+  char *pre=NULL, *post=NULL;
+  int expanded_any = 0;
+  pre = smartlist_join_strings(entries,",",0,NULL);
+  for (i = 0; i < smartlist_len(entries); ++i) {
+    char *v = smartlist_get(entries, i);
+    const char *cp, *ports;
+    int accept;
+    int prefix_idx;
+    accept = !strcasecmpstart(v, "accept");
+    if (!accept && strcasecmpstart(v, "reject")) {
+      warn(LD_CONFIG,"Policy '%s' didn't start with accept or reject.", v);
+      tor_free(pre);
+      return -1;
+    }
+    cp = v+strlen("accept"); /* Yes, they're the same length. */
+    cp = eat_whitespace(cp);
+    if (strcmpstart(cp, "private"))
+      continue; /* No need to expand. */
+    cp += strlen("private");
+    cp = eat_whitespace(cp);
+    if (*cp && *cp != ':')
+      continue; /* It wasn't "private" after all. */
+    ports = cp;
+    /* Okay. We're going to replace entries[i] with a bunch of new entries,
+     * in order. */
+    smartlist_del_keeporder(entries, i);
+    for (prefix_idx = 0; prefixes[prefix_idx]; ++prefix_idx) {
+      size_t replacement_len = 16+strlen(prefixes[prefix_idx])+strlen(ports);
+      char *replacement = tor_malloc(replacement_len);
+      tor_snprintf(replacement, replacement_len, "%s %s%s",
+                   accept?"accept":"reject", prefixes[prefix_idx],
+                   ports);
+      smartlist_insert(entries, i++, replacement);
+    }
+    tor_free(v);
+    expanded_any = 1;
+    --i;
+  }
+  post = smartlist_join_strings(entries,",",0,NULL);
+  if (expanded_any)
+    info(LD_CONFIG, "Expanded '%s' to '%s'", pre, post);
+  tor_free(pre);
+  tor_free(post);
+  return expanded_any;
+}
+
 /**
  * Given a linked list of config lines containing "allow" and "deny" tokens,
  * parse them and append the result to <b>dest</b>.  Return -1 if any tokens
@@ -2797,6 +2850,10 @@ config_parse_addr_policy(config_line_t *cfg,
   entries = smartlist_create();
   for (; cfg; cfg = cfg->next) {
     smartlist_split_string(entries, cfg->value, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+    if (config_expand_exit_policy_aliases(entries)<0) {
+      r = -1;
+      continue;
+    }
     SMARTLIST_FOREACH(entries, const char *, ent,
     {
       debug(LD_CONFIG,"Adding new entry '%s'",ent);