diff options
author | Roger Dingledine <arma@torproject.org> | 2007-12-09 04:59:27 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2007-12-09 04:59:27 +0000 |
commit | 6dfd47467eb7628c1d87e0b9235880564b31d85c (patch) | |
tree | 658f3df9f080a3fd7048f82b8f74c3302b152d8e /src/or | |
parent | 9b162ef4302881de7c8da7712fedbdd6da9c95df (diff) | |
download | tor-6dfd47467eb7628c1d87e0b9235880564b31d85c.tar tor-6dfd47467eb7628c1d87e0b9235880564b31d85c.tar.gz |
Allow multiple HashedControlPassword config lines, to support
multiple controller passwords.
svn:r12732
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 9 | ||||
-rw-r--r-- | src/or/control.c | 72 | ||||
-rw-r--r-- | src/or/or.h | 7 |
3 files changed, 58 insertions, 30 deletions
diff --git a/src/or/config.c b/src/or/config.c index d37bb64f7..f6f7b78b6 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -187,7 +187,7 @@ static config_var_t _option_vars[] = { 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 @@ options_validate(or_options_t *old_options, or_options_t *options, } 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) { diff --git a/src/or/control.c b/src/or/control.c index 5bb024ba7..468b622b5 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -912,29 +912,42 @@ handle_control_setevents(control_connection_t *conn, uint32_t len, 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; - } - } else { - if (base64_decode(decoded, sizeof(decoded), hashed, strlen(hashed)) - != S2K_SPECIFIER_LEN+DIGEST_LEN) { - 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; + } + } + 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 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len, 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 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len, } 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 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len, } 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 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len, 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 @@ handle_control_protocolinfo(control_connection_t *conn, uint32_t len, 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"); diff --git a/src/or/or.h b/src/or/or.h index 8aa17a7cf..d8c44e002 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2211,8 +2211,9 @@ typedef struct { * 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 @@ int control_event_guard(const char *nickname, const char *digest, 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); |