[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r12777: Three new config options (AlternateDirAuthority, AlternateBr (in tor/trunk: . doc src/or)



Author: arma
Date: 2007-12-11 23:38:54 -0500 (Tue, 11 Dec 2007)
New Revision: 12777

Modified:
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO
   tor/trunk/src/or/config.c
   tor/trunk/src/or/or.h
Log:
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.


Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-12-12 01:42:57 UTC (rev 12776)
+++ tor/trunk/ChangeLog	2007-12-12 04:38:54 UTC (rev 12777)
@@ -29,6 +29,10 @@
       downloading new consensus documents. Bridge users now wait until
       the end of the interval, so their bridge will be sure to have a
       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:
     - The fix in 0.2.0.12-alpha cleared the "hsdir" flag in v3 network

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-12-12 01:42:57 UTC (rev 12776)
+++ tor/trunk/doc/TODO	2007-12-12 04:38:54 UTC (rev 12777)
@@ -42,14 +42,16 @@
       - run a little web server on moria?
 N   d answer by answering email to bridges@torproject
       - keep track of which addresses have been answered already
-R   d some sort of reachability testing on bridges
 R - bridge communities
     - spec
     - 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
 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/M - vidalia can launch firefox
     - build a community version of firefox

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2007-12-12 01:42:57 UTC (rev 12776)
+++ tor/trunk/src/or/config.c	2007-12-12 04:38:54 UTC (rev 12777)
@@ -130,6 +130,9 @@
   V(Address,                     STRING,   NULL),
   V(AllowInvalidNodes,           CSV,      "middle,rendezvous"),
   V(AllowNonRFC953Hostnames,     BOOL,     "0"),
+  V(AlternateBridgeAuthority,    LINELIST, NULL),
+  V(AlternateDirAuthority,       LINELIST, NULL),
+  V(AlternateHSAuthority,        LINELIST, NULL),
   V(AssumeReachable,             BOOL,     "0"),
   V(AuthDirBadDir,               LINELIST, NULL),
   V(AuthDirBadExit,              LINELIST, NULL),
@@ -590,6 +593,7 @@
 static void option_reset(config_format_t *fmt, or_options_t *options,
                          config_var_t *var, int use_defaults);
 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,
                           or_options_t *o1, or_options_t *o2,
                           const char *name);
@@ -608,7 +612,9 @@
 static void config_register_addressmaps(or_options_t *options);
 
 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,
                                config_line_t *line, char **msg);
 static int parse_log_severity_range(const char *range, int *min_out,
@@ -795,9 +801,10 @@
     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
-add_default_trusted_dirservers(void)
+add_default_trusted_dir_authorities(authority_type_t type)
 {
   int i;
   const char *dirservers[] = {
@@ -818,9 +825,112 @@
     NULL
   };
   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
  * things we do should survive being done repeatedly.  If present,
  * <b>old_options</b> contains the previous value of the options.
@@ -974,19 +1084,8 @@
   int running_tor = options->command == CMD_RUN_TOR;
   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) {
     clear_bridge_list();
@@ -2035,7 +2134,7 @@
   if (is_internal_IP(ntohl(in.s_addr), 0) &&
       options->_PublishServerDescriptor) {
     /* 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
        * always. */
       log_fn(warn_severity, LD_CONFIG,
@@ -3011,20 +3110,8 @@
       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)
     REJECT("If you set UseBridges, you must specify at least one bridge.");
@@ -3790,10 +3877,13 @@
 
 /** 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
- * <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
-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;
   int r;
@@ -3893,10 +3983,12 @@
     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,
                            v3_digest, type);
   }

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-12-12 01:42:57 UTC (rev 12776)
+++ tor/trunk/src/or/or.h	2007-12-12 04:38:54 UTC (rev 12777)
@@ -2189,8 +2189,21 @@
   uint16_t HttpsProxyPort; /**< Parsed port for https proxy, 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. */
   config_line_t *NodeFamilies; /**< List of config lines for
                                        * node families */