Browse Source

Split ReachableAddresses into ReachableDirAddresses and ReachableORAddresses

svn:r6009
Peter Palfrader 19 years ago
parent
commit
5eea6c76df
6 changed files with 143 additions and 51 deletions
  1. 12 2
      doc/TODO
  2. 4 4
      src/or/circuitbuild.c
  3. 117 40
      src/or/config.c
  4. 1 1
      src/or/directory.c
  5. 7 2
      src/or/or.h
  6. 2 2
      src/or/routerlist.c

+ 12 - 2
doc/TODO

@@ -36,7 +36,8 @@ N - building on freebsd 6.0: (with multiple openssl installations)
     - <arma> should we detect if we have a --with-ssl-dir and try the -R
     - <arma> should we detect if we have a --with-ssl-dir and try the -R
       by default, if it works?
       by default, if it works?
 
 
-  - Split into ReachableDirAddresses and ReachableORAddresses
+  o Split into ReachableDirAddresses and ReachableORAddresses
+    - document
 R - Jan 26 10:25:04.832 [warn] add_an_entry_guard(): Tried finding a
 R - Jan 26 10:25:04.832 [warn] add_an_entry_guard(): Tried finding a
     new entry, but failed. Bad news. XXX.
     new entry, but failed. Bad news. XXX.
 N - look at the proposed os x uninstaller:
 N - look at the proposed os x uninstaller:
@@ -91,6 +92,8 @@ R - When we connect to a Tor server, it sends back a signed cell listing
     - non-naming dirservers don't need to have an approved-routers file.
     - non-naming dirservers don't need to have an approved-routers file.
     - What are criteria to be a dirserver?  Write a policy.
     - What are criteria to be a dirserver?  Write a policy.
 
 
+  - Document AuthDirInvalid, AuthDirReject, AuthDirRejectUnlisted
+  - are there other options that we haven't documented so far?
 
 
 Deferred from 0.1.1.x:
 Deferred from 0.1.1.x:
 
 
@@ -110,7 +113,14 @@ N - Display the reasons in 'destroy' and 'truncated' cells under some
     file descriptors for saving files, etc. Otherwise we'll trigger
     file descriptors for saving files, etc. Otherwise we'll trigger
     asserts when we're out of file descriptors and crash.
     asserts when we're out of file descriptors and crash.
 
 
-  - <weasel> it would be nice to support a unix socket for the control thing.
+  X <weasel> it would be nice to support a unix socket for the control thing.
+    The main motivation behind this was that we could let unix permissions
+    take care of the authentication step: everybody who can connect to the
+    socket is authenticated.  However, the linux unix(7) manual page suggests
+    that requiring read/write permissions on the socket in order to use it
+    is Linux specific, and that many BSD-derived systems ignore the permissions
+    on the socket file.  Portable programs should not rely on this feature for
+    security, therefore the motivation for this feature is gone.
 
 
   - the tor client can do the "automatic proxy config url" thing?
   - the tor client can do the "automatic proxy config url" thing?
 
 

+ 4 - 4
src/or/circuitbuild.c

@@ -1518,14 +1518,14 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
     smartlist_add(excluded, r);
     smartlist_add(excluded, r);
     routerlist_add_family(excluded, r);
     routerlist_add_family(excluded, r);
   }
   }
-  if (firewall_is_fascist()) {
+  if (firewall_is_fascist_or()) {
     /* exclude all ORs that listen on the wrong port */
     /* exclude all ORs that listen on the wrong port */
     routerlist_t *rl = router_get_routerlist();
     routerlist_t *rl = router_get_routerlist();
     int i;
     int i;
 
 
     for (i=0; i < smartlist_len(rl->routers); i++) {
     for (i=0; i < smartlist_len(rl->routers); i++) {
       r = smartlist_get(rl->routers, i);
       r = smartlist_get(rl->routers, i);
-      if (!fascist_firewall_allows_address(r->addr,r->or_port))
+      if (!fascist_firewall_allows_address_or(r->addr,r->or_port))
         smartlist_add(excluded, r);
         smartlist_add(excluded, r);
     }
     }
   }
   }
@@ -1717,8 +1717,8 @@ entry_is_live(entry_guard_t *e, int need_uptime, int need_capacity)
     return NULL;
     return NULL;
   if (router_is_unreliable(r, need_uptime, need_capacity, 0))
   if (router_is_unreliable(r, need_uptime, need_capacity, 0))
     return NULL;
     return NULL;
-  if (firewall_is_fascist() &&
-      !fascist_firewall_allows_address(r->addr,r->or_port))
+  if (firewall_is_fascist_or() &&
+      !fascist_firewall_allows_address_or(r->addr,r->or_port))
     return NULL;
     return NULL;
   return r;
   return r;
 }
 }

+ 117 - 40
src/or/config.c

@@ -198,6 +198,8 @@ static config_var_t _option_vars[] = {
   VAR("PidFile",             STRING,   PidFile,              NULL),
   VAR("PidFile",             STRING,   PidFile,              NULL),
   VAR("ProtocolWarnings",    BOOL,     ProtocolWarnings,     "0"),
   VAR("ProtocolWarnings",    BOOL,     ProtocolWarnings,     "0"),
   VAR("ReachableAddresses",  LINELIST, ReachableAddresses,   NULL),
   VAR("ReachableAddresses",  LINELIST, ReachableAddresses,   NULL),
+  VAR("ReachableORAddresses",LINELIST, ReachableORAddresses,   NULL),
+  VAR("ReachableDirAddresses",LINELIST, ReachableDirAddresses,   NULL),
   VAR("RecommendedVersions", LINELIST, RecommendedVersions,  NULL),
   VAR("RecommendedVersions", LINELIST, RecommendedVersions,  NULL),
   VAR("RecommendedClientVersions", LINELIST, RecommendedClientVersions,  NULL),
   VAR("RecommendedClientVersions", LINELIST, RecommendedClientVersions,  NULL),
   VAR("RecommendedServerVersions", LINELIST, RecommendedServerVersions,  NULL),
   VAR("RecommendedServerVersions", LINELIST, RecommendedServerVersions,  NULL),
@@ -431,7 +433,8 @@ static char *torrc_fname = NULL;
 /** Persistent serialized state. */
 /** Persistent serialized state. */
 static or_state_t *global_state = NULL;
 static or_state_t *global_state = NULL;
 /** DOCDOC */
 /** DOCDOC */
-static addr_policy_t *reachable_addr_policy = NULL;
+static addr_policy_t *reachable_or_addr_policy = NULL;
+static addr_policy_t *reachable_dir_addr_policy = NULL;
 
 
 static void *
 static void *
 config_alloc(config_format_t *fmt)
 config_alloc(config_format_t *fmt)
@@ -488,9 +491,13 @@ config_free_all(void)
     global_state = NULL;
     global_state = NULL;
   }
   }
   tor_free(torrc_fname);
   tor_free(torrc_fname);
-  if (reachable_addr_policy) {
-    addr_policy_free(reachable_addr_policy);
-    reachable_addr_policy = NULL;
+  if (reachable_or_addr_policy) {
+    addr_policy_free(reachable_or_addr_policy);
+    reachable_or_addr_policy = NULL;
+  }
+  if (reachable_dir_addr_policy) {
+    addr_policy_free(reachable_dir_addr_policy);
+    reachable_dir_addr_policy = NULL;
   }
   }
 }
 }
 
 
@@ -1830,14 +1837,30 @@ parse_reachable_addresses(void)
 {
 {
   or_options_t *options = get_options();
   or_options_t *options = get_options();
 
 
-  addr_policy_free(reachable_addr_policy);
-  reachable_addr_policy = NULL;
-
-  if (config_parse_addr_policy(options->ReachableAddresses,
-                               &reachable_addr_policy,
+  addr_policy_free(reachable_or_addr_policy);
+  reachable_or_addr_policy = NULL;
+  if (!options->ReachableORAddresses && options->ReachableAddresses)
+    log_notice(LD_CONFIG, "Using ReachableAddresses for "
+                               "ReachableORAddresses");
+  if (config_parse_addr_policy(options->ReachableORAddresses ?
+                               options->ReachableORAddresses :
+                               options->ReachableAddresses,
+                               &reachable_or_addr_policy,
+                               ADDR_POLICY_ACCEPT)) {
+    log_warn(LD_CONFIG, "Error in ReachableORAddresses entry; ignoring.");
+  }
+
+  addr_policy_free(reachable_dir_addr_policy);
+  reachable_dir_addr_policy = NULL;
+  if (!options->ReachableDirAddresses && options->ReachableAddresses)
+    log_notice(LD_CONFIG, "Using ReachableAddresses for "
+                               "ReachableDirAddresses");
+  if (config_parse_addr_policy(options->ReachableDirAddresses ?
+                               options->ReachableDirAddresses :
+                               options->ReachableAddresses,
+                               &reachable_dir_addr_policy,
                                ADDR_POLICY_ACCEPT)) {
                                ADDR_POLICY_ACCEPT)) {
-    log_warn(LD_CONFIG, "Error in ReachableAddresses entry; ignoring.");
-    return;
+    log_warn(LD_CONFIG, "Error in ReachableDirAddresses entry; ignoring.");
   }
   }
 }
 }
 
 
@@ -1845,18 +1868,25 @@ parse_reachable_addresses(void)
  * combination.
  * combination.
  */
  */
 int
 int
-firewall_is_fascist(void)
+firewall_is_fascist_or(void)
 {
 {
-  return reachable_addr_policy ? 1 : 0;
+  return !!reachable_or_addr_policy;
 }
 }
 
 
 /** Return true iff we are configured to think that the local fascist
 /** Return true iff we are configured to think that the local fascist
- * firewall (if any) will allow a connection to <b>addr</b>:<b>port</b>. */
+ * firewall (if any) will allow a connection to <b>addr</b>:<b>port</b>.
+ *
+ * If dir_or_or is 1 then it consults ReachableDirAddresses,
+ * if it is 2, then ReachableORAddresses are consulted.
+ * */
 int
 int
-fascist_firewall_allows_address(uint32_t addr, uint16_t port)
+_fascist_firewall_allows_address(uint32_t addr, uint16_t port, int dir_or_or)
 {
 {
+  assert(dir_or_or == 1 || dir_or_or == 2);
   addr_policy_result_t p = router_compare_addr_to_addr_policy(
   addr_policy_result_t p = router_compare_addr_to_addr_policy(
-               addr, port, reachable_addr_policy);
+               addr, port, dir_or_or == 1 ?
+                           reachable_dir_addr_policy :
+                           reachable_or_addr_policy);
 
 
   switch (p) {
   switch (p) {
     case ADDR_POLICY_PROBABLY_ACCEPTED:
     case ADDR_POLICY_PROBABLY_ACCEPTED:
@@ -1871,6 +1901,18 @@ fascist_firewall_allows_address(uint32_t addr, uint16_t port)
   }
   }
 }
 }
 
 
+int
+fascist_firewall_allows_address_or(uint32_t addr, uint16_t port)
+{
+  return _fascist_firewall_allows_address(addr, port, 2);
+}
+
+int
+fascist_firewall_allows_address_dir(uint32_t addr, uint16_t port)
+{
+  return _fascist_firewall_allows_address(addr, port, 1);
+}
+
 /** Return 0 if every setting in <b>options</b> is reasonable.  Else
 /** Return 0 if every setting in <b>options</b> is reasonable.  Else
  * warn and return -1.  Should have no side effects, except for
  * warn and return -1.  Should have no side effects, except for
  * normalizing the contents of <b>options</b>.
  * normalizing the contents of <b>options</b>.
@@ -1886,6 +1928,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
                  int from_setconf)
                  int from_setconf)
 {
 {
   int result = 0;
   int result = 0;
+  int i;
   config_line_t *cl;
   config_line_t *cl;
   addr_policy_t *addr_policy=NULL;
   addr_policy_t *addr_policy=NULL;
   const char *uname;
   const char *uname;
@@ -2066,16 +2109,16 @@ options_validate(or_options_t *old_options, or_options_t *options,
     result = -1;
     result = -1;
 
 
   if (options->FascistFirewall && !options->ReachableAddresses) {
   if (options->FascistFirewall && !options->ReachableAddresses) {
-    smartlist_t *instead = smartlist_create();
-    config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
-    new_line->key = tor_strdup("ReachableAddresses");
-    /* If we're configured with the old format, we need to prepend some
-     * open ports. */
-    if (!smartlist_len(options->FirewallPorts)) {
-      smartlist_add(options->FirewallPorts, tor_strdup("80"));
-      smartlist_add(options->FirewallPorts, tor_strdup("443"));
-    }
-    SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
+    if (smartlist_len(options->FirewallPorts)) {
+      /* We already have firewall ports set, so migrate them to
+       * ReachableAddresses, which will set ReachableOR and ReachableDir-
+       * Addresses if they aren't set otherwise*/
+      smartlist_t *instead = smartlist_create();
+      config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
+      new_line->key = tor_strdup("ReachableAddresses");
+      /* If we're configured with the old format, we need to prepend some
+       * open ports. */
+      SMARTLIST_FOREACH(options->FirewallPorts, const char *, portno,
       {
       {
         int p = atoi(portno);
         int p = atoi(portno);
         char *s;
         char *s;
@@ -2084,19 +2127,44 @@ options_validate(or_options_t *old_options, or_options_t *options,
         tor_snprintf(s, 16, "*:%d", p);
         tor_snprintf(s, 16, "*:%d", p);
         smartlist_add(instead, s);
         smartlist_add(instead, s);
       });
       });
-    new_line->value = smartlist_join_strings(instead,",",0,NULL);
-    /* These have been deprecated since 0.1.1.5-alpha-cvs */
-    log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall and FirewallPorts "
-        "config options to new format: \"ReachableAddresses %s\"",
-        new_line->value);
-    options->ReachableAddresses = new_line;
-    SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
-    smartlist_free(instead);
+      new_line->value = smartlist_join_strings(instead,",",0,NULL);
+      /* These have been deprecated since 0.1.1.5-alpha-cvs */
+      log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall and FirewallPorts "
+          "config options to new format: \"ReachableAddresses %s\"",
+          new_line->value);
+      options->ReachableAddresses = new_line;
+      SMARTLIST_FOREACH(instead, char *, cp, tor_free(cp));
+      smartlist_free(instead);
+    } else {
+      /* We do not have FirewallPorts set, so add 80 to ReachableDir-,
+       * and 443 to ReachableORAddresses */
+      if (!options->ReachableDirAddresses) {
+        config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
+        new_line->key = tor_strdup("ReachableDirAddresses");
+        new_line->value = tor_strdup("*:80");
+        options->ReachableDirAddresses = new_line;
+        log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
+            "to new format: \"ReachableDirAddresses *:80\"");
+      }
+      if (!options->ReachableORAddresses) {
+        config_line_t *new_line = tor_malloc_zero(sizeof(config_line_t));
+        new_line->key = tor_strdup("ReachableORAddresses");
+        new_line->value = tor_strdup("*:443");
+        options->ReachableORAddresses = new_line;
+        log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
+            "to new format: \"ReachableORAddresses *:443\"");
+      }
+    }
   }
   }
 
 
-  if (options->ReachableAddresses) {
+  for (i=0; i<3; i++){
+    config_line_t **linep = 
+      (i==0) ? &options->ReachableAddresses :
+      (i==1) ? &options->ReachableORAddresses :
+               &options->ReachableDirAddresses;
+    if (!*linep)
+      continue;
     /* We need to end with a reject *:*, not an implicit accept *:* */
     /* We need to end with a reject *:*, not an implicit accept *:* */
-    config_line_t **linep = &options->ReachableAddresses;
     for (;;) {
     for (;;) {
       if (!strcmp((*linep)->value, "reject *:*")) /* already there */
       if (!strcmp((*linep)->value, "reject *:*")) /* already there */
         break;
         break;
@@ -2110,9 +2178,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
     }
     }
   }
   }
 
 
-  if (options->ReachableAddresses && server_mode(options))
+  if ((options->ReachableAddresses ||
+       options->ReachableORAddresses ||
+       options->ReachableDirAddresses) &&
+      server_mode(options))
     REJECT("Servers must be able to freely connect to the rest "
     REJECT("Servers must be able to freely connect to the rest "
-           "of the Internet, so they must not set ReachableAddresses "
+           "of the Internet, so they must not set Reachable*Addresses "
            "or FascistFirewall.");
            "or FascistFirewall.");
 
 
   options->_AllowUnverified = 0;
   options->_AllowUnverified = 0;
@@ -2292,12 +2363,18 @@ options_validate(or_options_t *old_options, or_options_t *options,
   if (config_parse_addr_policy(options->ReachableAddresses, &addr_policy,
   if (config_parse_addr_policy(options->ReachableAddresses, &addr_policy,
                                ADDR_POLICY_ACCEPT))
                                ADDR_POLICY_ACCEPT))
     REJECT("Error in ReachableAddresses entry.");
     REJECT("Error in ReachableAddresses entry.");
+  if (config_parse_addr_policy(options->ReachableORAddresses, &addr_policy,
+                               ADDR_POLICY_ACCEPT))
+    REJECT("Error in ReachableORAddresses entry.");
+  if (config_parse_addr_policy(options->ReachableDirAddresses, &addr_policy,
+                               ADDR_POLICY_ACCEPT))
+    REJECT("Error in ReachableDirAddresses entry.");
   if (config_parse_addr_policy(options->AuthDirReject, &addr_policy,
   if (config_parse_addr_policy(options->AuthDirReject, &addr_policy,
                                ADDR_POLICY_REJECT))
                                ADDR_POLICY_REJECT))
-    REJECT("Error in ReachableAddresses entry.");
+    REJECT("Error in AuthDirReject entry.");
   if (config_parse_addr_policy(options->AuthDirInvalid, &addr_policy,
   if (config_parse_addr_policy(options->AuthDirInvalid, &addr_policy,
                                ADDR_POLICY_REJECT))
                                ADDR_POLICY_REJECT))
-    REJECT("Error in ReachableAddresses entry.");
+    REJECT("Error in AuthDirInvalid entry.");
 
 
   addr_policy_free(addr_policy);
   addr_policy_free(addr_policy);
 
 

+ 1 - 1
src/or/directory.c

@@ -146,7 +146,7 @@ directory_post_to_dirservers(uint8_t purpose, const char *payload,
       if (post_to_v1_only && !ds->is_v1_authority)
       if (post_to_v1_only && !ds->is_v1_authority)
         continue;
         continue;
       post_via_tor = purpose_is_private(purpose) ||
       post_via_tor = purpose_is_private(purpose) ||
-                     !fascist_firewall_allows_address(ds->addr,ds->dir_port);
+                     !fascist_firewall_allows_address_dir(ds->addr,ds->dir_port);
       directory_initiate_command_routerstatus(rs, purpose, post_via_tor,
       directory_initiate_command_routerstatus(rs, purpose, post_via_tor,
                                               NULL, payload, payload_len);
                                               NULL, payload, payload_len);
     });
     });

+ 7 - 2
src/or/or.h

@@ -1278,6 +1278,10 @@ typedef struct {
                                * (strings). */
                                * (strings). */
   config_line_t *ReachableAddresses; /**< Which IP:ports our firewall allows
   config_line_t *ReachableAddresses; /**< Which IP:ports our firewall allows
                                       * (exit policy.) */
                                       * (exit policy.) */
+  config_line_t *ReachableORAddresses; /**< Which IP:ports our firewall allows
+                                        * (exit policy.) */
+  config_line_t *ReachableDirAddresses; /**< Which IP:ports our firewall allows
+                                         * (exit policy.) */
 
 
   /** Application ports that require all nodes in circ to have sufficient
   /** Application ports that require all nodes in circ to have sufficient
    * uptime. */
    * uptime. */
@@ -1613,8 +1617,9 @@ int or_state_save(void);
 
 
 int config_getinfo_helper(const char *question, char **answer);
 int config_getinfo_helper(const char *question, char **answer);
 
 
-int firewall_is_fascist(void);
-int fascist_firewall_allows_address(uint32_t addr, uint16_t port);
+int firewall_is_fascist_or(void);
+int fascist_firewall_allows_address_or(uint32_t addr, uint16_t port);
+int fascist_firewall_allows_address_dir(uint32_t addr, uint16_t port);
 
 
 /********************************* connection.c ***************************/
 /********************************* connection.c ***************************/
 
 

+ 2 - 2
src/or/routerlist.c

@@ -437,7 +437,7 @@ router_pick_directory_server_impl(int requireother, int fascistfirewall,
     if (requireother && router_digest_is_me(status->identity_digest))
     if (requireother && router_digest_is_me(status->identity_digest))
       continue;
       continue;
     if (fascistfirewall) {
     if (fascistfirewall) {
-      if (!fascist_firewall_allows_address(status->addr, status->dir_port))
+      if (!fascist_firewall_allows_address_dir(status->addr, status->dir_port))
         continue;
         continue;
     }
     }
     is_trusted = router_digest_is_trusted_dir(status->identity_digest);
     is_trusted = router_digest_is_trusted_dir(status->identity_digest);
@@ -482,7 +482,7 @@ router_pick_trusteddirserver_impl(int need_v1_authority,
       if (requireother && me && router_digest_is_me(d->digest))
       if (requireother && me && router_digest_is_me(d->digest))
           continue;
           continue;
       if (fascistfirewall) {
       if (fascistfirewall) {
-        if (!fascist_firewall_allows_address(d->addr, d->dir_port))
+        if (!fascist_firewall_allows_address_dir(d->addr, d->dir_port))
           continue;
           continue;
       }
       }
       smartlist_add(sl, &d->fake_status);
       smartlist_add(sl, &d->fake_status);