diff --git a/ChangeLog b/ChangeLog index 9869479e53..2c46609c55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,11 @@ Changes in version 0.2.0.13-alpha - 2007-11-?? - Don't crash if we get an unexpected value for the PublishServerDescriptor config option. Reported by Matt Edman; bugfix on 0.2.0.9-alpha. + - Our new v2 hidden service descriptor format allows descriptors + that have no introduction points. But Tor crashed when we tried + to build a descriptor with no intro points (and it would have + crashed if we had tried to parse one). Bugfix on 0.2.0.x; patch + by Karsten Loesing. Changes in version 0.2.0.12-alpha - 2007-11-16 diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 80c9de95ea..cf92a2f9a9 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -354,7 +354,8 @@ rend_encode_v2_descriptors(smartlist_t *desc_strs_out, seconds_valid = period * REND_TIME_PERIOD_V2_DESC_VALIDITY + get_seconds_valid(now, service_id); /* Assemble, possibly encrypt, and encode introduction points. */ - if (rend_encode_v2_intro_points(&ipos_base64, desc, descriptor_cookie) < 0) { + if (desc->n_intro_points > 0 && + rend_encode_v2_intro_points(&ipos_base64, desc, descriptor_cookie) < 0) { log_warn(LD_REND, "Encoding of introduction points did not succeed."); tor_free(ipos_base64); return -1; @@ -418,16 +419,12 @@ rend_encode_v2_descriptors(smartlist_t *desc_strs_out, "permanent-key\n%s" "secret-id-part %s\n" "publication-time %s\n" - "protocol-versions %s\n" - "introduction-points\n" - "-----BEGIN MESSAGE-----\n%s" - "-----END MESSAGE-----\n", + "protocol-versions %s\n", desc_id_base32, permanent_key, secret_id_part_base32, published, - protocol_versions_string, - ipos_base64); + protocol_versions_string); tor_free(permanent_key); if (result < 0) { log_warn(LD_BUG, "Descriptor ran out of room."); @@ -435,6 +432,20 @@ rend_encode_v2_descriptors(smartlist_t *desc_strs_out, goto err; } written = result; + /* Add introduction points. */ + if (ipos_base64) { + result = tor_snprintf(desc_str + written, desc_len - written, + "introduction-points\n" + "-----BEGIN MESSAGE-----\n%s" + "-----END MESSAGE-----\n", + ipos_base64); + if (result < 0) { + log_warn(LD_BUG, "could not write introduction points."); + tor_free(desc_str); + goto err; + } + written += result; + } /* Add signature. */ strlcpy(desc_str + written, "signature\n", desc_len - written); written += strlen(desc_str + written); @@ -1075,12 +1086,15 @@ rend_cache_store_v2_desc_as_client(const char *desc, return -1; } /* Decode/decrypt introduction points. */ - if (rend_decrypt_introduction_points(parsed, descriptor_cookie, + if (intro_content && + rend_decrypt_introduction_points(parsed, descriptor_cookie, intro_content, intro_size) < 0) { log_warn(LD_PROTOCOL,"Couldn't decode/decrypt introduction points."); rend_service_descriptor_free(parsed); tor_free(intro_content); return -1; + } else { + parsed->n_intro_points = 0; } /* We don't need the encoded/encrypted introduction points any longer. */ tor_free(intro_content); diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 2e4e7e8597..901686039d 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -324,7 +324,7 @@ static token_rule_t desc_token_table[] = { T1("secret-id-part", R_SECRET_ID_PART, EQ(1), NO_OBJ), T1("publication-time", R_PUBLICATION_TIME, CONCAT_ARGS, NO_OBJ), T1("protocol-versions", R_PROTOCOL_VERSIONS, EQ(1), NO_OBJ), - T1("introduction-points", R_INTRODUCTION_POINTS, NO_ARGS, NEED_OBJ), + T01("introduction-points", R_INTRODUCTION_POINTS, NO_ARGS, NEED_OBJ), T1_END("signature", R_SIGNATURE, NO_ARGS, NEED_OBJ), END_OF_TABLE }; @@ -3232,7 +3232,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, /* Set length of encoded descriptor. */ *encoded_size_out = eos - desc; /* Check min allowed length of token list. */ - if (smartlist_len(tokens) < 8) { + if (smartlist_len(tokens) < 7) { log_warn(LD_REND, "Impossibly short descriptor."); goto err; } @@ -3318,15 +3318,19 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out, smartlist_free(versions); /* Parse encrypted introduction points. Don't verify. */ tok = find_first_by_keyword(tokens, R_INTRODUCTION_POINTS); - tor_assert(tok); - if (strcmp(tok->object_type, "MESSAGE")) { - log_warn(LD_DIR, "Bad object type: introduction points should be of " - "type MESSAGE"); - goto err; + if (tok) { + if (strcmp(tok->object_type, "MESSAGE")) { + log_warn(LD_DIR, "Bad object type: introduction points should be of " + "type MESSAGE"); + goto err; + } + *intro_points_encrypted_out = tok->object_body; + *intro_points_encrypted_size_out = tok->object_size; + tok->object_body = NULL; /* Prevent free. */ + } else { + *intro_points_encrypted_out = NULL; + *intro_points_encrypted_size_out = 0; } - *intro_points_encrypted_out = tok->object_body; - *intro_points_encrypted_size_out = tok->object_size; - tok->object_body = NULL; /* Prevent free. */ /* Parse and verify signature. */ tok = find_first_by_keyword(tokens, R_SIGNATURE); tor_assert(tok);