Selaa lähdekoodia

Three new config options (AlternateDirAuthority,
AlternateBridgeAuthority, and AlternateHSAuthority) that let the
user selectively replace the default directory authorities, rather
than the all-or-nothing replacement that DirServer offers.


svn:r12777

Roger Dingledine 16 vuotta sitten
vanhempi
commit
3b2dd8d763
4 muutettua tiedostoa jossa 155 lisäystä ja 44 poistoa
  1. 4 0
      ChangeLog
  2. 5 3
      doc/TODO
  3. 131 39
      src/or/config.c
  4. 15 2
      src/or/or.h

+ 4 - 0
ChangeLog

@@ -29,6 +29,10 @@ Changes in version 0.2.0.13-alpha - 2007-12-??
       downloading new consensus documents. Bridge users now wait until
       downloading new consensus documents. Bridge users now wait until
       the end of the interval, so their bridge will be sure to have a
       the end of the interval, so their bridge will be sure to have a
       new consensus document.
       new consensus document.
+    - Three new config options (AlternateDirAuthority,
+      AlternateBridgeAuthority, and AlternateHSAuthority) that let the
+      user selectively replace the default directory authorities, rather
+      than the all-or-nothing replacement that DirServer offers.
 
 
   o Minor bugfixes:
   o Minor bugfixes:
     - The fix in 0.2.0.12-alpha cleared the "hsdir" flag in v3 network
     - The fix in 0.2.0.12-alpha cleared the "hsdir" flag in v3 network

+ 5 - 3
doc/TODO

@@ -42,14 +42,16 @@ N   * answer by IP/timestamp
       - run a little web server on moria?
       - run a little web server on moria?
 N   d answer by answering email to bridges@torproject
 N   d answer by answering email to bridges@torproject
       - keep track of which addresses have been answered already
       - keep track of which addresses have been answered already
-R   d some sort of reachability testing on bridges
 R - bridge communities
 R - bridge communities
     - spec
     - spec
     - deploy
     - deploy
+      - man page entries for Alternate*Authority config options
+      - make the Alternate*Authority config options pass a "default_type"
+        to parse_dir_server_line() so they don't demand as much redundancy
+      d some sort of reachability testing on bridges
   - interface for letting soat modify flags that authorities assign
   - interface for letting soat modify flags that authorities assign
 R   . spec
 R   . spec
-    - deploy
-    - add an AuthDirBadexit torrc option if we decide we want one.
+    o add an AuthDirBadexit torrc option if we decide we want one.
 S * tor usb windows image (vidalia, polipo, tor, firefox)
 S * tor usb windows image (vidalia, polipo, tor, firefox)
 S/M - vidalia can launch firefox
 S/M - vidalia can launch firefox
     - build a community version of firefox
     - build a community version of firefox

+ 131 - 39
src/or/config.c

@@ -130,6 +130,9 @@ static config_var_t _option_vars[] = {
   V(Address,                     STRING,   NULL),
   V(Address,                     STRING,   NULL),
   V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
   V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
   V(AllowNonRFC953Hostnames,     BOOL,     "0"),
   V(AllowNonRFC953Hostnames,     BOOL,     "0"),
+  V(AlternateBridgeAuthority,    LINELIST, NULL),
+  V(AlternateDirAuthority,       LINELIST, NULL),
+  V(AlternateHSAuthority,        LINELIST, NULL),
   V(AssumeReachable,             BOOL,     "0"),
   V(AssumeReachable,             BOOL,     "0"),
   V(AuthDirBadDir,               LINELIST, NULL),
   V(AuthDirBadDir,               LINELIST, NULL),
   V(AuthDirBadExit,              LINELIST, NULL),
   V(AuthDirBadExit,              LINELIST, NULL),
@@ -590,6 +593,7 @@ static void option_clear(config_format_t *fmt, or_options_t *options,
 static void option_reset(config_format_t *fmt, or_options_t *options,
 static void option_reset(config_format_t *fmt, or_options_t *options,
                          config_var_t *var, int use_defaults);
                          config_var_t *var, int use_defaults);
 static void config_free(config_format_t *fmt, void *options);
 static void config_free(config_format_t *fmt, void *options);
+static int config_lines_eq(config_line_t *a, config_line_t *b);
 static int option_is_same(config_format_t *fmt,
 static int option_is_same(config_format_t *fmt,
                           or_options_t *o1, or_options_t *o2,
                           or_options_t *o1, or_options_t *o2,
                           const char *name);
                           const char *name);
@@ -608,7 +612,9 @@ static int check_nickname_list(const char *lst, const char *name, char **msg);
 static void config_register_addressmaps(or_options_t *options);
 static void config_register_addressmaps(or_options_t *options);
 
 
 static int parse_bridge_line(const char *line, int validate_only);
 static int parse_bridge_line(const char *line, int validate_only);
-static int parse_dir_server_line(const char *line, int validate_only);
+static int parse_dir_server_line(const char *line,
+                                 authority_type_t required_type,
+                                 int validate_only);
 static int parse_redirect_line(smartlist_t *result,
 static int parse_redirect_line(smartlist_t *result,
                                config_line_t *line, char **msg);
                                config_line_t *line, char **msg);
 static int parse_log_severity_range(const char *range, int *min_out,
 static int parse_log_severity_range(const char *range, int *min_out,
@@ -795,9 +801,10 @@ escaped_safe_str(const char *address)
     return escaped(address);
     return escaped(address);
 }
 }
 
 
-/** Add the default directory servers directly into the trusted dir list. */
+/** Add the default directory authorities directly into the trusted dir list,
+ * but only add them insofar as they share bits with <b>type</b>. */
 static void
 static void
-add_default_trusted_dirservers(void)
+add_default_trusted_dir_authorities(authority_type_t type)
 {
 {
   int i;
   int i;
   const char *dirservers[] = {
   const char *dirservers[] = {
@@ -818,7 +825,110 @@ add_default_trusted_dirservers(void)
     NULL
     NULL
   };
   };
   for (i=0; dirservers[i]; i++)
   for (i=0; dirservers[i]; i++)
-    parse_dir_server_line(dirservers[i], 0);
+    parse_dir_server_line(dirservers[i], type, 0);
+}
+
+/** Look at all the config options for using alternate directory
+ * authorities, and make sure none of them are broken. Also, warn the
+ * user if we changed any dangerous ones.
+ */
+static int
+validate_dir_authorities(or_options_t *options, or_options_t *old_options)
+{
+  config_line_t *cl;
+
+  if (options->DirServers &&
+      (options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
+       options->AlternateHSAuthority)) {
+    log_warn(LD_CONFIG,
+             "You cannot set both DirServers and Alternate*Authority.");
+    return -1;
+  }
+
+  /* do we want to complain to the user about being partitionable? */
+  if ((options->DirServers &&
+       (!old_options ||
+        !config_lines_eq(options->DirServers, old_options->DirServers))) ||
+      (options->AlternateDirAuthority &&
+       (!old_options ||
+        !config_lines_eq(options->AlternateDirAuthority,
+                         old_options->AlternateDirAuthority)))) {
+    log_warn(LD_CONFIG,
+             "You have used DirServer or AlternateDirAuthority to "
+             "specify alternate directory authorities in "
+             "your configuration. This is potentially dangerous: it can "
+             "make you look different from all other Tor users, and hurt "
+             "your anonymity. Even if you've specified the same "
+             "authorities as Tor uses by default, the defaults could "
+             "change in the future. Be sure you know what you're doing.");
+  }
+
+  /* Now go through the four ways you can configure an alternate
+   * set of directory authorities, and make sure none are broken. */
+  for (cl = options->DirServers; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 1)<0)
+      return -1;
+  for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 1)<0)
+      return -1;
+  for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 1)<0)
+      return -1;
+  for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 1)<0)
+      return -1;
+  return 0;
+}
+
+/** Look at all the config options and assign new dir authorities
+ * as appropriate.
+ */
+static int
+consider_adding_dir_authorities(or_options_t *options,
+                                or_options_t *old_options)
+{
+  config_line_t *cl;
+  int need_to_update =
+    !smartlist_len(router_get_trusted_dir_servers()) ||
+    !config_lines_eq(options->DirServers, old_options->DirServers) ||
+    !config_lines_eq(options->AlternateBridgeAuthority,
+                     old_options->AlternateBridgeAuthority) ||
+    !config_lines_eq(options->AlternateDirAuthority,
+                     old_options->AlternateDirAuthority) ||
+    !config_lines_eq(options->AlternateHSAuthority,
+                     old_options->AlternateHSAuthority);
+
+  if (!need_to_update)
+    return 0; /* all done */
+
+  /* Start from a clean slate. */
+  clear_trusted_dir_servers();
+
+  if (!options->DirServers) {
+    /* then we may want some of the defaults */
+    authority_type_t type = NO_AUTHORITY;
+    if (!options->AlternateBridgeAuthority)
+      type |= BRIDGE_AUTHORITY;
+    if (!options->AlternateDirAuthority)
+      type |= V2_AUTHORITY | V3_AUTHORITY;
+    if (!options->AlternateHSAuthority)
+      type |= HIDSERV_AUTHORITY;
+    add_default_trusted_dir_authorities(type);
+  }
+
+  for (cl = options->DirServers; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 0)<0)
+      return -1;
+  for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 0)<0)
+      return -1;
+  for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 0)<0)
+      return -1;
+  for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
+    if (parse_dir_server_line(cl->value, 0, 0)<0)
+      return -1;
+  return 0;
 }
 }
 
 
 /** Fetch the active option list, and take actions based on it. All of the
 /** Fetch the active option list, and take actions based on it. All of the
@@ -974,19 +1084,8 @@ options_act(or_options_t *old_options)
   int running_tor = options->command == CMD_RUN_TOR;
   int running_tor = options->command == CMD_RUN_TOR;
   char *msg;
   char *msg;
 
 
-  if (options->DirServers) {
-    clear_trusted_dir_servers();
-    for (cl = options->DirServers; cl; cl = cl->next) {
-      if (parse_dir_server_line(cl->value, 0)<0) {
-        log_warn(LD_BUG,
-                 "Previously validated DirServer line could not be added!");
-        return -1;
-      }
-    }
-  } else {
-    if (!smartlist_len(router_get_trusted_dir_servers()))
-      add_default_trusted_dirservers();
-  }
+  if (consider_adding_dir_authorities(options, old_options) < 0)
+    return -1;
 
 
   if (options->Bridges) {
   if (options->Bridges) {
     clear_bridge_list();
     clear_bridge_list();
@@ -2035,7 +2134,7 @@ resolve_my_address(int warn_severity, or_options_t *options,
   if (is_internal_IP(ntohl(in.s_addr), 0) &&
   if (is_internal_IP(ntohl(in.s_addr), 0) &&
       options->_PublishServerDescriptor) {
       options->_PublishServerDescriptor) {
     /* make sure we're ok with publishing an internal IP */
     /* make sure we're ok with publishing an internal IP */
-    if (!options->DirServers) {
+    if (!options->DirServers && !options->AlternateDirAuthority) {
       /* if they are using the default dirservers, disallow internal IPs
       /* if they are using the default dirservers, disallow internal IPs
        * always. */
        * always. */
       log_fn(warn_severity, LD_CONFIG,
       log_fn(warn_severity, LD_CONFIG,
@@ -3011,20 +3110,8 @@ options_validate(or_options_t *old_options, or_options_t *options,
       return -1;
       return -1;
   }
   }
 
 
-  if (options->DirServers) {
-    if (!old_options ||
-        !config_lines_eq(options->DirServers, old_options->DirServers))
-        COMPLAIN("You have used DirServer to specify directory authorities in "
-                 "your configuration.  This is potentially dangerous: it can "
-                 "make you look different from all other Tor users, and hurt "
-                 "your anonymity.  Even if you've specified the same "
-                 "authorities as Tor uses by default, the defaults could "
-                 "change in the future.  Be sure you know what you're doing.");
-    for (cl = options->DirServers; cl; cl = cl->next) {
-      if (parse_dir_server_line(cl->value, 1)<0)
-        REJECT("DirServer line did not parse. See logs for details.");
-    }
-  }
+  if (validate_dir_authorities(options, old_options) < 0)
+    REJECT("Directory authority line did not parse. See logs for details.");
 
 
   if (options->UseBridges && !options->Bridges)
   if (options->UseBridges && !options->Bridges)
     REJECT("If you set UseBridges, you must specify at least one bridge.");
     REJECT("If you set UseBridges, you must specify at least one bridge.");
@@ -3790,10 +3877,13 @@ parse_bridge_line(const char *line, int validate_only)
 
 
 /** Read the contents of a DirServer line from <b>line</b>.  Return 0
 /** Read the contents of a DirServer line from <b>line</b>.  Return 0
  * if the line is well-formed, and -1 if it isn't.  If
  * if the line is well-formed, and -1 if it isn't.  If
- * <b>validate_only</b> is 0, and the line is well-formed, then add
- * the dirserver described in the line as a valid authority. */
+ * <b>validate_only</b> is 0, and the line is well-formed, and it
+ * shares any bits with <b>required_type</b> or <b>required_type</b>
+ * is 0, then add the dirserver described in the line (minus whatever
+ * bits it's missing) as a valid authority. */
 static int
 static int
-parse_dir_server_line(const char *line, int validate_only)
+parse_dir_server_line(const char *line, authority_type_t required_type,
+                      int validate_only)
 {
 {
   smartlist_t *items = NULL;
   smartlist_t *items = NULL;
   int r;
   int r;
@@ -3893,10 +3983,12 @@ parse_dir_server_line(const char *line, int validate_only)
     goto err;
     goto err;
   }
   }
 
 
-  if (!validate_only) {
-    log_debug(LD_DIR, "Trusted dirserver at %s:%d (%s)", address,
-              (int)dir_port,
-              (char*)smartlist_get(items,0));
+  if (!validate_only && (!required_type || required_type & type)) {
+    if (required_type)
+      type &= required_type; /* pare down what we think of them as an
+                              * authority for. */
+    log_debug(LD_DIR, "Trusted %d dirserver at %s:%d (%s)", (int)type,
+              address, (int)dir_port, (char*)smartlist_get(items,0));
     add_trusted_dir_server(nickname, address, dir_port, or_port, digest,
     add_trusted_dir_server(nickname, address, dir_port, or_port, digest,
                            v3_digest, type);
                            v3_digest, type);
   }
   }

+ 15 - 2
src/or/or.h

@@ -2189,8 +2189,21 @@ typedef struct {
   uint16_t HttpsProxyPort; /**< Parsed port for https proxy, if any */
   uint16_t HttpsProxyPort; /**< Parsed port for https proxy, if any */
   char *HttpsProxyAuthenticator; /**< username:password string, if any */
   char *HttpsProxyAuthenticator; /**< username:password string, if any */
 
 
-  config_line_t *DirServers; /**< List of configuration lines
-                                     * for directory servers. */
+  /** List of configuration lines for replacement directory authorities.
+   * If you just want to replace one class of authority at a time,
+   * use the "Alternate*Authority" options below instead. */
+  config_line_t *DirServers;
+
+  /** If set, use these main (currently v3) directory authorities and
+   * not the default ones. */
+  config_line_t *AlternateDirAuthority;
+
+  /** If set, use these bridge authorities and not the default one. */
+  config_line_t *AlternateBridgeAuthority;
+
+  /** If set, use these HS authorities and not the default ones. */
+  config_line_t *AlternateHSAuthority;
+
   char *MyFamily; /**< Declared family for this OR. */
   char *MyFamily; /**< Declared family for this OR. */
   config_line_t *NodeFamilies; /**< List of config lines for
   config_line_t *NodeFamilies; /**< List of config lines for
                                        * node families */
                                        * node families */