Drop support for v1 rendezvous descriptors, since we never used

them anyway, and the code has probably rotted by now. Based on
patch from Karsten Loesing.


svn:r11496
This commit is contained in:
Roger Dingledine 2007-09-18 21:17:45 +00:00
parent 722aac798e
commit eb9dc12ce9
9 changed files with 46 additions and 174 deletions

View File

@ -27,6 +27,9 @@ Changes in version 0.2.0.7-alpha - 2007-??-??
- Remove the contrib scripts ExerciseServer.py, PathDemo.py,
and TorControl.py, as they use the old v0 controller protocol,
and are obsoleted by TorFlow anyway.
- Drop support for v1 rendezvous descriptors, since we never used
them anyway, and the code has probably rotted by now. Based on
patch from Karsten Loesing.
o Major bugfixes:
- Fix possible segfaults in functions called from

View File

@ -200,6 +200,7 @@ $Id$
[Once Tor 0.1.0.x is obsolete, we can stop generating or using V0
descriptors. -NM]
[This should rather be retarded until V2 descriptors are stable. -KL]
1.3. Bob's OP establishes his introduction points.
@ -282,14 +283,11 @@ $Id$
1.6. Alice's OP retrieves a service descriptor.
Alice opens a stream to a directory server via Tor, and makes an HTTP GET
request for the document '/tor/rendezvous/<z>' or '/tor/rendezvous1/<z>',
where '<z>' is replaced with the encoding of Bob's public key as described
above. (She may re-use old circuits for this.) The directory replies with
a 404 HTTP response if it does not recognize <z>, and otherwise returns
Bob's most recently uploaded service descriptor. (If Alice requests
'rendezvous1', the directory server provides a V1 descriptor or a V0
descriptor if no V1 descriptor is available. If Alice requests
'rendezvous', the directory server returns a V0 descriptor.)
request for the document '/tor/rendezvous/<z>', where '<z>' is replaced
with the encoding of Bob's public key as described above. (She may re-use
old circuits for this.) The directory replies with a 404 HTTP response if
it does not recognize <z>, and otherwise returns Bob's most recently
uploaded service descriptor.
If Alice's OP receives a 404 response, it tries the other directory
servers, and only fails the lookup if none recognize the public key hash.
@ -356,7 +354,7 @@ $Id$
RC Rendezvous cookie [20 octets]
g^x Diffie-Hellman data, part 1 [128 octets]
OR
VER Version byte: set to 3. [1 octet]
VER Version byte: set to 4. [1 octet]
ATYPE An address type (typically 4) [1 octet]
ADDR Rendezvous point's IP address [4 or 16 octets]
PORT Rendezvous point's OR port [2 octets]
@ -373,11 +371,12 @@ $Id$
and must contain EITHER a nickname, or an identity key digest, encoded in
hex, and prefixed with a '$'.
Implementations SHOULD accept all variants, and list the variants they
accept in their V1 descriptor. Implementations should only generate the
variants listed in the service's V1 descriptor; if no V1 descriptor is
available, only the first variant should be generated. No version should
generate the second variant (version byte=1).
Implementations SHOULD accept all variants, although only the first,
unversioned variant SHOULD be generated. If V1 descriptors were used,
implementations SHOULD have listed the variants they accept in their V1
descriptor, and implementations SHOULD only have generated the variants
listed in the service's V1 descriptor. No version SHOULD generate the
second variant (version byte=1).
The hybrid encryption to Bob's PK works just like the hybrid
encryption in CREATE cells (see main spec). Thus the payload of the

View File

@ -1441,7 +1441,7 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
log_info(LD_REND,"Got a hidden service request for ID '%s'",
safe_str(conn->rend_query));
/* see if we already have it cached */
r = rend_cache_lookup_entry(conn->rend_query, -1, &entry);
r = rend_cache_lookup_entry(conn->rend_query, 0, &entry);
if (r<0) {
log_warn(LD_BUG,"Invalid service name '%s'",
safe_str(conn->rend_query));

View File

@ -1515,7 +1515,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
switch (status_code) {
case 200:
if (rend_cache_store(body, body_len, 0) < 0) {
log_warn(LD_REND,"Failed to store rendezvous descriptor.");
log_warn(LD_REND,"Failed to fetch rendezvous descriptor.");
/* alice's ap_stream will notice when connection_mark_for_close
* cleans it up */
} else {
@ -2209,17 +2209,14 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
goto done;
}
if (options->HSAuthoritativeDir &&
(!strcmpstart(url,"/tor/rendezvous/") ||
!strcmpstart(url,"/tor/rendezvous1/"))) {
if (options->HSAuthoritativeDir && !strcmpstart(url,"/tor/rendezvous/")) {
/* rendezvous descriptor fetch */
const char *descp;
size_t desc_len;
int versioned = !strcmpstart(url,"/tor/rendezvous1/");
const char *query = url+strlen("/tor/rendezvous/")+(versioned?1:0);
const char *query = url+strlen("/tor/rendezvous/");
log_info(LD_REND, "Handling rendezvous descriptor get");
switch (rend_cache_lookup_desc(query, versioned?-1:0, &descp, &desc_len)) {
switch (rend_cache_lookup_desc(query, 0, &descp, &desc_len)) {
case 1: /* valid */
write_http_response_header_impl(conn, desc_len,
"application/octet-stream",
@ -2376,7 +2373,6 @@ directory_handle_command_post(dir_connection_t *conn, const char *headers,
/* rendezvous descriptor post */
log_info(LD_REND, "Handling rendezvous descriptor post.");
if (rend_cache_store(body, body_len, 1) < 0) {
// char tmp[1024*2+1];
log_fn(LOG_PROTOCOL_WARN, LD_DIRSERV,
"Rejected rend descriptor (length %d) from %s.",
(int)body_len, conn->_base.address);

View File

@ -3244,7 +3244,7 @@ int rend_client_send_introduction(origin_circuit_t *introcirc,
/** Information used to connect to a hidden service. */
typedef struct rend_service_descriptor_t {
crypto_pk_env_t *pk; /**< This service's public key. */
int version; /**< 0 or 1. */
int version; /**< 0. */
time_t timestamp; /**< Time when the descriptor was generated. */
uint16_t protocols; /**< Bitmask: which rendezvous protocols are supported?
* (We allow bits '0', '1', and '2' to be set.) */
@ -3267,7 +3267,6 @@ void rend_process_relay_cell(circuit_t *circ, int command, size_t length,
void rend_service_descriptor_free(rend_service_descriptor_t *desc);
int rend_encode_service_descriptor(rend_service_descriptor_t *desc,
int version,
crypto_pk_env_t *key,
char **str_out,
size_t *len_out);

View File

@ -69,7 +69,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
tor_assert(!rend_cmp_service_ids(introcirc->rend_query,
rendcirc->rend_query));
if (rend_cache_lookup_entry(introcirc->rend_query, -1, &entry) < 1) {
if (rend_cache_lookup_entry(introcirc->rend_query, 0, &entry) < 1) {
log_warn(LD_REND,
"query %s didn't have valid rend desc in cache. Failing.",
escaped_safe_str(introcirc->rend_query));
@ -281,7 +281,7 @@ rend_client_remove_intro_point(extend_info_t *failed_intro, const char *query)
rend_cache_entry_t *ent;
connection_t *conn;
r = rend_cache_lookup_entry(query, -1, &ent);
r = rend_cache_lookup_entry(query, 0, &ent);
if (r<0) {
log_warn(LD_BUG, "Malformed service ID %s.", escaped_safe_str(query));
return -1;
@ -450,7 +450,7 @@ rend_client_desc_here(const char *query)
if (rend_cmp_service_ids(query, conn->rend_query))
continue;
assert_connection_ok(TO_CONN(conn), now);
if (rend_cache_lookup_entry(conn->rend_query, -1, &entry) == 1 &&
if (rend_cache_lookup_entry(conn->rend_query, 0, &entry) == 1 &&
entry->parsed->n_intro_points > 0) {
/* either this fetch worked, or it failed but there was a
* valid entry from before which we should reuse */
@ -486,7 +486,7 @@ rend_client_get_random_intro(const char *query)
int i;
rend_cache_entry_t *entry;
if (rend_cache_lookup_entry(query, -1, &entry) < 1) {
if (rend_cache_lookup_entry(query, 0, &entry) < 1) {
log_warn(LD_REND,
"Query '%s' didn't have valid rend desc in cache. Failing.",
safe_str(query));

View File

@ -49,7 +49,6 @@ rend_service_descriptor_free(rend_service_descriptor_t *desc)
*/
int
rend_encode_service_descriptor(rend_service_descriptor_t *desc,
int version,
crypto_pk_env_t *key,
char **str_out, size_t *len_out)
{
@ -60,42 +59,17 @@ rend_encode_service_descriptor(rend_service_descriptor_t *desc,
size_t buflen = PK_BYTES*2*(desc->n_intro_points+2);/*Too long, but ok*/
cp = *str_out = tor_malloc(buflen);
end = cp + PK_BYTES*2*(desc->n_intro_points+1);
if (version) {
*(uint8_t*)cp = (uint8_t)0xff;
*(uint8_t*)(cp+1) = (uint8_t)version;
cp += 2;
}
asn1len = crypto_pk_asn1_encode(desc->pk, cp+2, end-(cp+2));
set_uint16(cp, htons((uint16_t)asn1len));
cp += 2+asn1len;
set_uint32(cp, htonl((uint32_t)desc->timestamp));
cp += 4;
if (version == 1) {
set_uint16(cp, htons(desc->protocols));
cp += 2;
}
set_uint16(cp, htons((uint16_t)desc->n_intro_points));
cp += 2;
if (version == 0) {
for (i=0; i < desc->n_intro_points; ++i) {
char *ipoint = (char*)desc->intro_points[i];
strlcpy(cp, ipoint, buflen-(cp-*str_out));
cp += strlen(ipoint)+1;
}
} else {
if (desc->n_intro_points)
tor_assert(desc->intro_point_extend_info);
for (i=0; i < desc->n_intro_points; ++i) {
extend_info_t *info = desc->intro_point_extend_info[i];
int klen;
set_uint32(cp, htonl(info->addr));
set_uint16(cp+4, htons(info->port));
memcpy(cp+6, info->identity_digest, DIGEST_LEN);
klen = crypto_pk_asn1_encode(info->onion_key, cp+6+DIGEST_LEN+2,
(end-(cp+6+DIGEST_LEN+2)));
set_uint16(cp+6+DIGEST_LEN, htons((uint16_t)klen));
cp += 6+DIGEST_LEN+2+klen;
}
for (i=0; i < desc->n_intro_points; ++i) {
char *ipoint = (char*)desc->intro_points[i];
strlcpy(cp, ipoint, buflen-(cp-*str_out));
cp += strlen(ipoint)+1;
}
note_crypto_pk_op(REND_SERVER);
i = crypto_pk_private_sign_digest(key, cp, *str_out, cp-*str_out);
@ -119,18 +93,12 @@ rend_parse_service_descriptor(const char *str, size_t len)
int i;
size_t keylen, asn1len;
const char *end, *cp, *eos;
int version = 0;
result = tor_malloc_zero(sizeof(rend_service_descriptor_t));
cp = str;
end = str+len;
if (end-cp<2) goto truncated;
if (*(uint8_t*)cp == 0xff) {
result->version = version = *(uint8_t*)(cp+1);
cp += 2;
} else {
result->version = version = 0;
}
result->version = 0;
if (end-cp < 2) goto truncated;
asn1len = ntohs(get_uint16(cp));
cp += 2;
@ -141,18 +109,12 @@ rend_parse_service_descriptor(const char *str, size_t len)
if (end-cp < 4) goto truncated;
result->timestamp = (time_t) ntohl(get_uint32(cp));
cp += 4;
if (version == 1) {
if (end-cp < 2) goto truncated;
result->protocols = ntohs(get_uint16(cp));
cp += 2;
} else {
result->protocols = 1;
}
result->protocols = 1;
if (end-cp < 2) goto truncated;
result->n_intro_points = ntohs(get_uint16(cp));
cp += 2;
if (version == 0 && result->n_intro_points != 0) {
if (result->n_intro_points != 0) {
result->intro_points =
tor_malloc_zero(sizeof(char*)*result->n_intro_points);
for (i=0;i<result->n_intro_points;++i) {
@ -162,33 +124,6 @@ rend_parse_service_descriptor(const char *str, size_t len)
result->intro_points[i] = tor_strdup(cp);
cp = eos+1;
}
} else if (version != 0 && result->n_intro_points != 0) {
result->intro_point_extend_info =
tor_malloc_zero(sizeof(extend_info_t*)*result->n_intro_points);
result->intro_points =
tor_malloc_zero(sizeof(char*)*result->n_intro_points);
for (i=0;i<result->n_intro_points;++i) {
extend_info_t *info = result->intro_point_extend_info[i] =
tor_malloc_zero(sizeof(extend_info_t));
int klen;
if (end-cp < 8+DIGEST_LEN) goto truncated;
info->addr = ntohl(get_uint32(cp));
info->port = ntohs(get_uint16(cp+4));
memcpy(info->identity_digest, cp+6, DIGEST_LEN);
info->nickname[0] = '$';
base16_encode(info->nickname+1, sizeof(info->nickname)-1,
info->identity_digest, DIGEST_LEN);
result->intro_points[i] = tor_strdup(info->nickname);
klen = ntohs(get_uint16(cp+6+DIGEST_LEN));
cp += 8+DIGEST_LEN;
if (end-cp < klen) goto truncated;
if (!(info->onion_key = crypto_pk_asn1_decode(cp,klen))) {
log_warn(LD_PROTOCOL,
"Internal error decoding onion key for intro point.");
goto error;
}
cp += klen;
}
}
keylen = crypto_pk_keysize(result->pk);
tor_assert(end-cp >= 0);
@ -307,28 +242,20 @@ rend_valid_service_id(const char *query)
return 1;
}
/** If we have a cached rend_cache_entry_t for the service ID <b>query</b>,
* set *<b>e</b> to that entry and return 1. Else return 0. If
* <b>version</b> is nonnegative, only return an entry in that descriptor
* format version. Otherwise (if <b>version</b> is negative), return the most
* recent format we have.
/** If we have a cached rend_cache_entry_t for the service ID <b>query</b>
* with <b>version</b>, set *<b>e</b> to that entry and return 1.
* Else return 0.
*/
int
rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e)
{
char key[REND_SERVICE_ID_LEN+2]; /* 1<query>\0 or 0<query>\0 */
char key[REND_SERVICE_ID_LEN+2]; /* <version><query>\0 */
tor_assert(rend_cache);
tor_assert(!version);
if (!rend_valid_service_id(query))
return -1;
*e = NULL;
if (version != 0) {
tor_snprintf(key, sizeof(key), "1%s", query);
*e = strmap_get_lc(rend_cache, key);
}
if (!*e && version != 1) {
tor_snprintf(key, sizeof(key), "0%s", query);
*e = strmap_get_lc(rend_cache, key);
}
tor_snprintf(key, sizeof(key), "%d%s", version, query);
*e = strmap_get_lc(rend_cache, key);
if (!*e)
return 0;
return 1;
@ -369,7 +296,7 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
rend_cache_entry_t *e;
rend_service_descriptor_t *parsed;
char query[REND_SERVICE_ID_LEN+1];
char key[REND_SERVICE_ID_LEN+2]; /* 1<query>\0 or 0<query>\0 */
char key[REND_SERVICE_ID_LEN+2]; /* 0<query>\0 */
time_t now;
or_options_t *options = get_options();
tor_assert(rend_cache);
@ -383,7 +310,7 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
rend_service_descriptor_free(parsed);
return -1;
}
tor_snprintf(key, sizeof(key), "%c%s", parsed->version?'1':'0', query);
tor_snprintf(key, sizeof(key), "0%s", query);
now = time(NULL);
if (parsed->timestamp < now-REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) {
log_fn(LOG_PROTOCOL_WARN, LD_REND,

View File

@ -937,7 +937,7 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
* and upload it to all the dirservers.
*/
static void
upload_service_descriptor(rend_service_t *service, int version)
upload_service_descriptor(rend_service_t *service)
{
char *desc;
size_t desc_len;
@ -946,7 +946,6 @@ upload_service_descriptor(rend_service_t *service, int version)
/* Update the descriptor. */
rend_service_update_descriptor(service);
if (rend_encode_service_descriptor(service->desc,
version,
service->private_key,
&desc, &desc_len)<0) {
log_warn(LD_BUG, "Internal error: couldn't encode service descriptor; "
@ -1110,7 +1109,7 @@ rend_consider_services_upload(time_t now)
/* if it's time, or if the directory servers have a wrong service
* descriptor and ours has been stable for 30 seconds, upload a
* new one of each format. */
upload_service_descriptor(service, 0);
upload_service_descriptor(service);
service->next_upload_time = now + rendpostperiod;
}
}

View File

@ -2916,7 +2916,7 @@ test_rend_fns(void)
pk1 = pk_generate(0);
pk2 = pk_generate(1);
/* Test unversioned descriptor */
/* Test unversioned (v0) descriptor */
d1 = tor_malloc_zero(sizeof(rend_service_descriptor_t));
d1->pk = crypto_pk_dup_key(pk1);
now = time(NULL);
@ -2927,7 +2927,7 @@ test_rend_fns(void)
d1->intro_points[0] = tor_strdup("tom");
d1->intro_points[1] = tor_strdup("crow");
d1->intro_points[2] = tor_strdup("joel");
test_assert(! rend_encode_service_descriptor(d1, 0, pk1, &encoded, &len));
test_assert(! rend_encode_service_descriptor(d1, pk1, &encoded, &len));
d2 = rend_parse_service_descriptor(encoded, len);
test_assert(d2);
@ -2945,62 +2945,11 @@ test_rend_fns(void)
rend_service_descriptor_free(d2);
tor_free(encoded);
/* Test versioned descriptor. */
d1 = tor_malloc_zero(sizeof(rend_service_descriptor_t));
d1->pk = crypto_pk_dup_key(pk1);
now = time(NULL);
d1->timestamp = now;
d1->n_intro_points = 2;
d1->version = 1;
d1->protocols = 60;
d1->intro_points = tor_malloc(sizeof(char*)*2);
d1->intro_point_extend_info = tor_malloc(sizeof(extend_info_t*)*2);
d1->intro_points[0] = tor_strdup("tom");
d1->intro_points[1] = tor_strdup("crow");
d1->intro_point_extend_info[0] = tor_malloc_zero(sizeof(extend_info_t));
strlcpy(d1->intro_point_extend_info[0]->nickname, "tom", 4);
d1->intro_point_extend_info[0]->addr = 1234;
d1->intro_point_extend_info[0]->port = 4567;
d1->intro_point_extend_info[0]->onion_key = crypto_pk_dup_key(pk1);
memset(d1->intro_point_extend_info[0]->identity_digest, 'a', DIGEST_LEN);
d1->intro_point_extend_info[1] = tor_malloc_zero(sizeof(extend_info_t));
strlcpy(d1->intro_point_extend_info[1]->nickname, "crow", 5);
d1->intro_point_extend_info[1]->addr = 6060842;
d1->intro_point_extend_info[1]->port = 8000;
d1->intro_point_extend_info[1]->onion_key = crypto_pk_dup_key(pk2);
memset(d1->intro_point_extend_info[1]->identity_digest, 'b', DIGEST_LEN);
test_assert(! rend_encode_service_descriptor(d1, 1, pk1, &encoded, &len));
d2 = rend_parse_service_descriptor(encoded, len);
test_assert(d2);
test_assert(!crypto_pk_cmp_keys(d1->pk, d2->pk));
test_eq(d2->timestamp, now);
test_eq(d2->version, 1);
test_eq(d2->protocols, 60);
test_eq(d2->n_intro_points, 2);
test_streq(d2->intro_points[0], d2->intro_point_extend_info[0]->nickname);
test_streq(d2->intro_points[1], d2->intro_point_extend_info[1]->nickname);
test_eq(d2->intro_point_extend_info[0]->addr, 1234);
test_eq(d2->intro_point_extend_info[0]->port, 4567);
test_assert(!crypto_pk_cmp_keys(pk1,
d2->intro_point_extend_info[0]->onion_key));
test_memeq(d2->intro_point_extend_info[0]->identity_digest,
d1->intro_point_extend_info[0]->identity_digest, DIGEST_LEN);
test_eq(d2->intro_point_extend_info[1]->addr, 6060842);
test_eq(d2->intro_point_extend_info[1]->port, 8000);
test_memeq(d2->intro_point_extend_info[1]->identity_digest,
d1->intro_point_extend_info[1]->identity_digest, DIGEST_LEN);
test_assert(BAD_HOSTNAME == parse_extended_hostname(address1));
test_assert(ONION_HOSTNAME == parse_extended_hostname(address2));
test_assert(EXIT_HOSTNAME == parse_extended_hostname(address3));
test_assert(NORMAL_HOSTNAME == parse_extended_hostname(address4));
rend_service_descriptor_free(d1);
rend_service_descriptor_free(d2);
crypto_free_pk_env(pk1);
crypto_free_pk_env(pk2);
}