diff --git a/src/or/rendservice.c b/src/or/rendservice.c index 617e185390..b788593c69 100644 --- a/src/or/rendservice.c +++ b/src/or/rendservice.c @@ -354,6 +354,8 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len) crypt_path_t *cpath = NULL; char serviceid[REND_SERVICE_ID_LEN+1]; char hexcookie[9]; + int version; + int nickname_field_len; base32_encode(serviceid, REND_SERVICE_ID_LEN+1, circuit->rend_pk_digest,10); @@ -367,7 +369,7 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len) } /* min key length plus digest length plus nickname length */ - if (request_len < DIGEST_LEN+REND_COOKIE_LEN+(MAX_NICKNAME_LEN+1)+ + if (request_len < DIGEST_LEN+REND_COOKIE_LEN+(HEX_DIGEST_LEN+2)+ DH_KEY_LEN+42){ log_fn(LOG_WARN, "Got a truncated INTRODUCE2 cell on circ %d", circuit->n_circ_id); @@ -401,19 +403,29 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len) log_fn(LOG_WARN, "Couldn't decrypt INTRODUCE2 cell"); return -1; } - ptr=memchr(buf,0,MAX_NICKNAME_LEN+1); - if (!ptr || ptr == buf) { + if (*buf == 1) { + rp_nickname = buf+1; + nickname_field_len = HEX_DIGEST_LEN+2; + version = 1; + } else { + nickname_field_len = MAX_NICKNAME_LEN+1; + rp_nickname = buf; + version = 0; + } + ptr=memchr(rp_nickname,0,nickname_field_len); + if (!ptr || ptr == rp_nickname) { log_fn(LOG_WARN, "Couldn't find a null-padded nickname in INTRODUCE2 cell"); return -1; } - if ((int)strspn(buf,LEGAL_NICKNAME_CHARACTERS) != ptr-buf) { - log_fn(LOG_WARN, "Nickname in INTRODUCE2 cell contains illegal character."); + if ((version == 0 && !is_legal_nickname(rp_nickname)) || + (version == 1 && !is_legal_nickname_or_hexdigest(rp_nickname)) || + (int)strspn(buf,LEGAL_NICKNAME_CHARACTERS) != ptr-buf) { + log_fn(LOG_WARN, "Bad nickname in INTRODUCE2 cell."); return -1; } - /* Okay, now we know that the nickname is at the start of the buffer. */ - rp_nickname = buf; - ptr = buf+(MAX_NICKNAME_LEN+1); - len -= (MAX_NICKNAME_LEN+1); + /* Okay, now we know that a nickname is at the start of the buffer. */ + ptr = rp_nickname+nickname_field_len; + len -= nickname_field_len; if (len != REND_COOKIE_LEN+DH_KEY_LEN) { log_fn(LOG_WARN, "Bad length for INTRODUCE2 cell."); return -1;