[or-cvs] r12732: Allow multiple HashedControlPassword config lines, to suppor (in tor/trunk: . doc src/or)

arma at seul.org arma at seul.org
Sun Dec 9 04:59:28 UTC 2007


Author: arma
Date: 2007-12-08 23:59:27 -0500 (Sat, 08 Dec 2007)
New Revision: 12732

Modified:
   tor/trunk/ChangeLog
   tor/trunk/doc/tor.1.in
   tor/trunk/src/or/config.c
   tor/trunk/src/or/control.c
   tor/trunk/src/or/or.h
Log:
Allow multiple HashedControlPassword config lines, to support
multiple controller passwords.


Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-12-09 04:40:37 UTC (rev 12731)
+++ tor/trunk/ChangeLog	2007-12-09 04:59:27 UTC (rev 12732)
@@ -63,6 +63,8 @@
       ask about source, timestamp of arrival, purpose, etc. We need
       something like this to help Vidalia not do GeoIP lookups on bridge
       addresses.
+    - Allow multiple HashedControlPassword config lines, to support
+      multiple controller passwords.
 
 
 Changes in version 0.2.0.12-alpha - 2007-11-16

Modified: tor/trunk/doc/tor.1.in
===================================================================
--- tor/trunk/doc/tor.1.in	2007-12-09 04:40:37 UTC (rev 12731)
+++ tor/trunk/doc/tor.1.in	2007-12-09 04:59:27 UTC (rev 12732)
@@ -159,7 +159,8 @@
 Don't allow any connections on the control port except when the other process
 knows the password whose one-way hash is \fIhashed_password\fP.  You can
 compute the hash of a password by running "tor --hash-password
-\fIpassword\fP".
+\fIpassword\fP". You can provide several acceptable passwords by using
+more than HashedControlPassword line.
 .LP
 .TP
 \fBCookieAuthentication \fR\fB0\fR|\fB1\fP

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2007-12-09 04:40:37 UTC (rev 12731)
+++ tor/trunk/src/or/config.c	2007-12-09 04:59:27 UTC (rev 12732)
@@ -187,7 +187,7 @@
   V(FetchUselessDescriptors,     BOOL,     "0"),
   V(Group,                       STRING,   NULL),
   V(HardwareAccel,               BOOL,     "0"),
-  V(HashedControlPassword,       STRING,   NULL),
+  V(HashedControlPassword,       LINELIST, NULL),
   V(HidServDirectoryV2,          BOOL,     "0"),
   VAR("HiddenServiceDir",    LINELIST_S, RendConfigLines,    NULL),
   VAR("HiddenServiceExcludeNodes", LINELIST_S, RendConfigLines, NULL),
@@ -2939,8 +2939,13 @@
   }
 
   if (options->HashedControlPassword) {
-    if (decode_hashed_password(NULL, options->HashedControlPassword)<0)
+    smartlist_t *sl = decode_hashed_passwords(options->HashedControlPassword);
+    if (!sl) {
       REJECT("Bad HashedControlPassword: wrong length or bad encoding");
+    } else {
+      SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
+      smartlist_free(sl);
+    }
   }
 
   if (options->ControlListenAddress) {

Modified: tor/trunk/src/or/control.c
===================================================================
--- tor/trunk/src/or/control.c	2007-12-09 04:40:37 UTC (rev 12731)
+++ tor/trunk/src/or/control.c	2007-12-09 04:59:27 UTC (rev 12732)
@@ -912,29 +912,42 @@
   return 0;
 }
 
-/** Decode the hashed, base64'd password stored in <b>hashed</b>.  If
- * <b>buf</b> is provided, store the hashed password in the first
- * S2K_SPECIFIER_LEN+DIGEST_LEN bytes of <b>buf</b>.  Return 0 on
- * success, -1 on failure.
+/** Decode the hashed, base64'd passwords stored in <b>passwords</b>.
+ * Return a smartlist of acceptable passwords (unterminated strings of
+ * length S2K_SPECIFIER_LEN+DIGEST_LEN) on success, or NULL on failure.
  */
-int
-decode_hashed_password(char *buf, const char *hashed)
+smartlist_t *
+decode_hashed_passwords(config_line_t *passwords)
 {
   char decoded[64];
-  if (!strcmpstart(hashed, "16:")) {
-    if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))<0
-        || strlen(hashed+3) != (S2K_SPECIFIER_LEN+DIGEST_LEN)*2) {
-      return -1;
+  config_line_t *cl;
+  smartlist_t *sl = smartlist_create();
+
+  tor_assert(passwords);
+
+  for (cl = passwords; cl; cl = cl->next) {
+    const char *hashed = cl->value;
+
+    if (!strcmpstart(hashed, "16:")) {
+      if (base16_decode(decoded, sizeof(decoded), hashed+3, strlen(hashed+3))<0
+          || strlen(hashed+3) != (S2K_SPECIFIER_LEN+DIGEST_LEN)*2) {
+        goto err;
+      }
+    } else {
+        if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
+            != S2K_SPECIFIER_LEN+DIGEST_LEN) {
+          goto err;
+        }
     }
-  } else {
-      if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed))
-          != S2K_SPECIFIER_LEN+DIGEST_LEN) {
-        return -1;
-      }
+    smartlist_add(sl, tor_memdup(decoded, S2K_SPECIFIER_LEN+DIGEST_LEN));
   }
-  if (buf)
-    memcpy(buf, decoded, S2K_SPECIFIER_LEN+DIGEST_LEN);
-  return 0;
+
+  return sl;
+
+ err:
+  SMARTLIST_FOREACH(sl, char*, cp, tor_free(cp));
+  smartlist_free(sl);
+  return NULL;
 }
 
 /** Called when we get an AUTHENTICATE message.  Check whether the
@@ -953,6 +966,7 @@
   const char *cp;
   int i;
   int bad_cookie=0, bad_password=0;
+  smartlist_t *sl = NULL;
 
   if (TOR_ISXDIGIT(body[0])) {
     cp = body;
@@ -1013,10 +1027,10 @@
   }
 
   if (options->HashedControlPassword) {
-    char expected[S2K_SPECIFIER_LEN+DIGEST_LEN];
     char received[DIGEST_LEN];
     int also_cookie = options->CookieAuthentication;
-    if (decode_hashed_password(expected, options->HashedControlPassword)<0) {
+    sl = decode_hashed_passwords(options->HashedControlPassword);
+    if (!sl) {
       if (!also_cookie) {
         log_warn(LD_CONTROL,
                  "Couldn't decode HashedControlPassword: invalid base16");
@@ -1024,9 +1038,14 @@
       }
       bad_password = 1;
     } else {
-      secret_to_key(received,DIGEST_LEN,password,password_len,expected);
-      if (!memcmp(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
-        goto ok;
+      SMARTLIST_FOREACH(sl, char *, expected,
+      {
+        secret_to_key(received,DIGEST_LEN,password,password_len,expected);
+        if (!memcmp(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
+          goto ok;
+      });
+      SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+      smartlist_free(sl);
 
       if (used_quoted_string)
         errstr = "Password did not match HashedControlPassword value from "
@@ -1060,6 +1079,10 @@
   send_control_done(conn);
   conn->_base.state = CONTROL_CONN_STATE_OPEN;
   tor_free(password);
+  if (sl) { /* clean up */
+    SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
+    smartlist_free(sl);
+  }
   return 0;
 }
 
@@ -2435,8 +2458,7 @@
     char *esc_cfile = esc_for_log(cfile);
     char *methods;
     {
-      int passwd = (options->HashedControlPassword != NULL) &&
-        strlen(options->HashedControlPassword);
+      int passwd = (options->HashedControlPassword != NULL);
       smartlist_t *mlist = smartlist_create();
       if (cookies)
         smartlist_add(mlist, (char*)"COOKIE");

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-12-09 04:40:37 UTC (rev 12731)
+++ tor/trunk/src/or/or.h	2007-12-09 04:59:27 UTC (rev 12732)
@@ -2211,8 +2211,9 @@
                            * interval before hibernation?  0 for "never
                            * hibernate." */
 
-  char *HashedControlPassword; /**< Base64-encoded hash of a password for
-                                * the control system. */
+  /** Base64-encoded hash of accepted passwords for the control system. */
+  config_line_t *HashedControlPassword;
+
   int CookieAuthentication; /**< Boolean: do we enable cookie-based auth for
                              * the control system? */
   char *CookieAuthFile; /**< Location of a cookie authentication file. */
@@ -2920,7 +2921,7 @@
                         const char *status);
 
 int init_cookie_authentication(int enabled);
-int decode_hashed_password(char *buf, const char *hashed);
+smartlist_t *decode_hashed_passwords(config_line_t *passwords);
 void disable_control_logging(void);
 void enable_control_logging(void);
 



More information about the tor-commits mailing list