mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-20 10:12:15 +01:00
revert r12841 and r12842, and commit karsten's "patch 13"
svn:r12900
This commit is contained in:
parent
e710710e87
commit
90fcfade4e
26
src/or/or.h
26
src/or/or.h
@ -3598,6 +3598,13 @@ typedef struct rend_encoded_v2_service_descriptor_t {
|
||||
char *desc_str; /**< Descriptor string. */
|
||||
} rend_encoded_v2_service_descriptor_t;
|
||||
|
||||
/** Introduction point information. */
|
||||
typedef struct rend_intro_point_t {
|
||||
extend_info_t *extend_info; /**< Extend info of this introduction point. */
|
||||
crypto_pk_env_t *intro_key; /**< Introduction key that replaces the service
|
||||
* key, if this descriptor is V2. */
|
||||
} rend_intro_point_t;
|
||||
|
||||
/** Information used to connect to a hidden service. */
|
||||
typedef struct rend_service_descriptor_t {
|
||||
crypto_pk_env_t *pk; /**< This service's public key. */
|
||||
@ -3605,21 +3612,9 @@ typedef struct rend_service_descriptor_t {
|
||||
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.) */
|
||||
int n_intro_points; /**< Number of introduction points. */
|
||||
/** Array of n_intro_points elements for this service's introduction points'
|
||||
* nicknames. Elements are removed from this array if introduction attempts
|
||||
* fail. */
|
||||
char **intro_points;
|
||||
/** Array of n_intro_points elements for this service's introduction points'
|
||||
* extend_infos, or NULL if this descriptor is V0. Elements are removed
|
||||
* from this array if introduction attempts fail. If this array is present,
|
||||
* its elements correspond to the elements of intro_points. */
|
||||
extend_info_t **intro_point_extend_info;
|
||||
strmap_t *intro_keys; /**< map from intro node hexdigest to key; only
|
||||
* used for versioned hidden service descriptors. */
|
||||
|
||||
/* XXXX020 Refactor n_intro_points, intro_points, intro_point_extend_info,
|
||||
* and intro_keys into a list of intro points. */
|
||||
/** List of the service's introduction points. Elements are removed if
|
||||
* introduction attempts fail. */
|
||||
smartlist_t *intro_nodes;
|
||||
} rend_service_descriptor_t;
|
||||
|
||||
int rend_cmp_service_ids(const char *one, const char *two);
|
||||
@ -3637,6 +3632,7 @@ rend_service_descriptor_t *rend_parse_service_descriptor(const char *str,
|
||||
int rend_get_service_id(crypto_pk_env_t *pk, char *out);
|
||||
void rend_encoded_v2_service_descriptor_free(
|
||||
rend_encoded_v2_service_descriptor_t *desc);
|
||||
void rend_intro_point_free(rend_intro_point_t *intro);
|
||||
|
||||
/** A cached rendezvous descriptor. */
|
||||
typedef struct rend_cache_entry_t {
|
||||
|
@ -82,12 +82,15 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
|
||||
if (entry->parsed->version == 0) { /* unversioned descriptor */
|
||||
intro_key = entry->parsed->pk;
|
||||
} else { /* versioned descriptor */
|
||||
char hex_digest[HEX_DIGEST_LEN+2];
|
||||
hex_digest[0] = '$';
|
||||
base16_encode(hex_digest+1, HEX_DIGEST_LEN+1,
|
||||
introcirc->build_state->chosen_exit->identity_digest,
|
||||
DIGEST_LEN);
|
||||
intro_key = strmap_get(entry->parsed->intro_keys, hex_digest);
|
||||
intro_key = NULL;
|
||||
SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
|
||||
intro, {
|
||||
if (!memcmp(introcirc->build_state->chosen_exit->identity_digest,
|
||||
intro->extend_info->identity_digest, DIGEST_LEN)) {
|
||||
intro_key = intro->intro_key;
|
||||
break;
|
||||
}
|
||||
});
|
||||
if (!intro_key) {
|
||||
log_warn(LD_BUG, "Internal error: could not find intro key.");
|
||||
goto err;
|
||||
@ -342,35 +345,17 @@ rend_client_remove_intro_point(extend_info_t *failed_intro, const char *query)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ent->parsed->intro_point_extend_info) {
|
||||
for (i=0; i < ent->parsed->n_intro_points; ++i) {
|
||||
if (!memcmp(failed_intro->identity_digest,
|
||||
ent->parsed->intro_point_extend_info[i]->identity_digest,
|
||||
DIGEST_LEN)) {
|
||||
tor_assert(!strcmp(ent->parsed->intro_points[i],
|
||||
ent->parsed->intro_point_extend_info[i]->nickname));
|
||||
tor_free(ent->parsed->intro_points[i]);
|
||||
extend_info_free(ent->parsed->intro_point_extend_info[i]);
|
||||
--ent->parsed->n_intro_points;
|
||||
ent->parsed->intro_points[i] =
|
||||
ent->parsed->intro_points[ent->parsed->n_intro_points];
|
||||
ent->parsed->intro_point_extend_info[i] =
|
||||
ent->parsed->intro_point_extend_info[ent->parsed->n_intro_points];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i=0; i < ent->parsed->n_intro_points; ++i) {
|
||||
if (!strcasecmp(ent->parsed->intro_points[i], failed_intro->nickname)) {
|
||||
tor_free(ent->parsed->intro_points[i]);
|
||||
ent->parsed->intro_points[i] =
|
||||
ent->parsed->intro_points[--ent->parsed->n_intro_points];
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) {
|
||||
rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i);
|
||||
if (!memcmp(failed_intro->identity_digest,
|
||||
intro->extend_info->identity_digest, DIGEST_LEN)) {
|
||||
rend_intro_point_free(intro);
|
||||
smartlist_del(ent->parsed->intro_nodes, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ent->parsed->n_intro_points) {
|
||||
if (smartlist_len(ent->parsed->intro_nodes) == 0) {
|
||||
log_info(LD_REND,
|
||||
"No more intro points remain for %s. Re-fetching descriptor.",
|
||||
escaped_safe_str(query));
|
||||
@ -388,7 +373,7 @@ rend_client_remove_intro_point(extend_info_t *failed_intro, const char *query)
|
||||
return 0;
|
||||
}
|
||||
log_info(LD_REND,"%d options left for %s.",
|
||||
ent->parsed->n_intro_points, escaped_safe_str(query));
|
||||
smartlist_len(ent->parsed->intro_nodes), escaped_safe_str(query));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -503,7 +488,7 @@ rend_client_desc_here(const char *query)
|
||||
continue;
|
||||
assert_connection_ok(TO_CONN(conn), now);
|
||||
if (rend_cache_lookup_entry(conn->rend_query, -1, &entry) == 1 &&
|
||||
entry->parsed->n_intro_points > 0) {
|
||||
smartlist_len(entry->parsed->intro_nodes) > 0) {
|
||||
/* either this fetch worked, or it failed but there was a
|
||||
* valid entry from before which we should reuse */
|
||||
log_info(LD_REND,"Rend desc is usable. Launching circuits.");
|
||||
@ -537,6 +522,8 @@ rend_client_get_random_intro(const char *query)
|
||||
{
|
||||
int i;
|
||||
rend_cache_entry_t *entry;
|
||||
rend_intro_point_t *intro;
|
||||
routerinfo_t *router;
|
||||
|
||||
if (rend_cache_lookup_entry(query, -1, &entry) < 1) {
|
||||
log_warn(LD_REND,
|
||||
@ -546,26 +533,25 @@ rend_client_get_random_intro(const char *query)
|
||||
}
|
||||
|
||||
again:
|
||||
if (!entry->parsed->n_intro_points)
|
||||
if (smartlist_len(entry->parsed->intro_nodes) == 0)
|
||||
return NULL;
|
||||
|
||||
i = crypto_rand_int(entry->parsed->n_intro_points);
|
||||
|
||||
if (entry->parsed->intro_point_extend_info) {
|
||||
return extend_info_dup(entry->parsed->intro_point_extend_info[i]);
|
||||
} else {
|
||||
/* add the intro point nicknames */
|
||||
char *choice = entry->parsed->intro_points[i];
|
||||
routerinfo_t *router = router_get_by_nickname(choice, 0);
|
||||
i = crypto_rand_int(smartlist_len(entry->parsed->intro_nodes));
|
||||
intro = smartlist_get(entry->parsed->intro_nodes, i);
|
||||
/* Do we need to look up the router or is the extend info complete? */
|
||||
if (!intro->extend_info->onion_key) {
|
||||
router = router_get_by_nickname(intro->extend_info->nickname, 0);
|
||||
if (!router) {
|
||||
log_info(LD_REND, "Unknown router with nickname '%s'; trying another.",
|
||||
choice);
|
||||
tor_free(choice);
|
||||
entry->parsed->intro_points[i] =
|
||||
entry->parsed->intro_points[--entry->parsed->n_intro_points];
|
||||
intro->extend_info->nickname);
|
||||
rend_intro_point_free(intro);
|
||||
smartlist_del(entry->parsed->intro_nodes, i);
|
||||
goto again;
|
||||
}
|
||||
return extend_info_from_router(router);
|
||||
extend_info_free(intro->extend_info);
|
||||
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
intro->extend_info = extend_info_from_router(router);
|
||||
}
|
||||
return extend_info_dup(intro->extend_info);
|
||||
}
|
||||
|
||||
|
@ -20,41 +20,17 @@ rend_cmp_service_ids(const char *one, const char *two)
|
||||
return strcasecmp(one,two);
|
||||
}
|
||||
|
||||
/** Helper: Release the storage held by the intro key in <b>_ent</b>.
|
||||
*/
|
||||
/*XXXX020 there's also one of these in rendservice.c */
|
||||
/* Right. But the only alternative to that (which I know) would be to
|
||||
* write it to or.h. Should I do that? -KL */
|
||||
static void
|
||||
intro_key_free(void *_ent)
|
||||
{
|
||||
crypto_pk_env_t *ent = _ent;
|
||||
crypto_free_pk_env(ent);
|
||||
}
|
||||
|
||||
/** Free the storage held by the service descriptor <b>desc</b>.
|
||||
*/
|
||||
void
|
||||
rend_service_descriptor_free(rend_service_descriptor_t *desc)
|
||||
{
|
||||
int i;
|
||||
if (desc->pk)
|
||||
crypto_free_pk_env(desc->pk);
|
||||
if (desc->intro_points) {
|
||||
for (i=0; i < desc->n_intro_points; ++i) {
|
||||
tor_free(desc->intro_points[i]);
|
||||
}
|
||||
tor_free(desc->intro_points);
|
||||
}
|
||||
if (desc->intro_point_extend_info) {
|
||||
for (i=0; i < desc->n_intro_points; ++i) {
|
||||
if (desc->intro_point_extend_info[i])
|
||||
extend_info_free(desc->intro_point_extend_info[i]);
|
||||
}
|
||||
tor_free(desc->intro_point_extend_info);
|
||||
}
|
||||
if (desc->intro_keys) {
|
||||
strmap_free(desc->intro_keys, intro_key_free);
|
||||
if (desc->intro_nodes) {
|
||||
SMARTLIST_FOREACH(desc->intro_nodes, rend_intro_point_t *, intro,
|
||||
rend_intro_point_free(intro););
|
||||
smartlist_free(desc->intro_nodes);
|
||||
}
|
||||
tor_free(desc);
|
||||
}
|
||||
@ -191,9 +167,9 @@ rend_encode_v2_intro_points(char **ipos_base64,
|
||||
int r = -1;
|
||||
/* Assemble unencrypted list of introduction points. */
|
||||
*ipos_base64 = NULL;
|
||||
unenc_len = desc->n_intro_points * 1000; /* too long, but ok. */
|
||||
unenc_len = smartlist_len(desc->intro_nodes) * 1000; /* too long, but ok. */
|
||||
unenc = tor_malloc_zero(unenc_len);
|
||||
for (i = 0; i < desc->n_intro_points; i++) {
|
||||
for (i = 0; i < smartlist_len(desc->intro_nodes); i++) {
|
||||
char id_base32[REND_INTRO_POINT_ID_LEN_BASE32 + 1];
|
||||
char *onion_key = NULL;
|
||||
size_t onion_key_len;
|
||||
@ -202,9 +178,9 @@ rend_encode_v2_intro_points(char **ipos_base64,
|
||||
char *address = NULL;
|
||||
size_t service_key_len;
|
||||
int res;
|
||||
char hex_digest[HEX_DIGEST_LEN+2]; /* includes $ and NUL. */
|
||||
rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
|
||||
/* Obtain extend info with introduction point details. */
|
||||
extend_info_t *info = desc->intro_point_extend_info[i];
|
||||
extend_info_t *info = intro->extend_info;
|
||||
/* Encode introduction point ID. */
|
||||
base32_encode(id_base32, sizeof(id_base32),
|
||||
info->identity_digest, DIGEST_LEN);
|
||||
@ -215,11 +191,7 @@ rend_encode_v2_intro_points(char **ipos_base64,
|
||||
goto done;
|
||||
}
|
||||
/* Encode intro key. */
|
||||
hex_digest[0] = '$';
|
||||
base16_encode(hex_digest+1, HEX_DIGEST_LEN+1,
|
||||
info->identity_digest,
|
||||
DIGEST_LEN);
|
||||
intro_key = strmap_get(desc->intro_keys, hex_digest);
|
||||
intro_key = intro->intro_key;
|
||||
if (!intro_key ||
|
||||
crypto_pk_write_public_key_to_string(intro_key, &service_key,
|
||||
&service_key_len) < 0) {
|
||||
@ -324,6 +296,17 @@ rend_encoded_v2_service_descriptor_free(
|
||||
tor_free(desc);
|
||||
}
|
||||
|
||||
/** Free the storage held by an introduction point info. */
|
||||
void
|
||||
rend_intro_point_free(rend_intro_point_t *intro)
|
||||
{
|
||||
if (intro->extend_info)
|
||||
extend_info_free(intro->extend_info);
|
||||
if (intro->intro_key)
|
||||
crypto_free_pk_env(intro->intro_key);
|
||||
tor_free(intro);
|
||||
}
|
||||
|
||||
/** Encode a set of rend_encoded_v2_service_descriptor_t's for <b>desc</b>
|
||||
* at time <b>now</b> using <b>descriptor_cookie</b> (may be <b>NULL</b> if
|
||||
* introduction points shall not be encrypted) and <b>period</b> (e.g. 0
|
||||
@ -353,7 +336,7 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
|
||||
seconds_valid = period * REND_TIME_PERIOD_V2_DESC_VALIDITY +
|
||||
get_seconds_valid(now, service_id);
|
||||
/* Assemble, possibly encrypt, and encode introduction points. */
|
||||
if (desc->n_intro_points > 0 &&
|
||||
if (smartlist_len(desc->intro_nodes) > 0 &&
|
||||
rend_encode_v2_intro_points(&ipos_base64, desc, descriptor_cookie) < 0) {
|
||||
log_warn(LD_REND, "Encoding of introduction points did not succeed.");
|
||||
return -1;
|
||||
@ -408,7 +391,8 @@ rend_encode_v2_descriptors(smartlist_t *descs_out,
|
||||
else
|
||||
protocol_versions_string[0]= '\0';
|
||||
/* Assemble complete descriptor. */
|
||||
desc_len = 2000 + desc->n_intro_points * 1000; /* far too long, but ok. */
|
||||
desc_len = 2000 + smartlist_len(desc->intro_nodes) * 1000; /* far too long,
|
||||
but okay.*/
|
||||
enc->desc_str = desc_str = tor_malloc_zero(desc_len);
|
||||
result = tor_snprintf(desc_str, desc_len,
|
||||
"rendezvous-service-descriptor %s\n"
|
||||
@ -503,18 +487,24 @@ rend_encode_service_descriptor(rend_service_descriptor_t *desc,
|
||||
char *end;
|
||||
int i;
|
||||
size_t asn1len;
|
||||
size_t buflen = PK_BYTES*2*(desc->n_intro_points+2);/*Too long, but ok*/
|
||||
size_t buflen =
|
||||
PK_BYTES*2*(smartlist_len(desc->intro_nodes)+2);/*Too long, but ok*/
|
||||
cp = *str_out = tor_malloc(buflen);
|
||||
end = cp + PK_BYTES*2*(desc->n_intro_points+1);
|
||||
end = cp + PK_BYTES*2*(smartlist_len(desc->intro_nodes)+1);
|
||||
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;
|
||||
set_uint16(cp, htons((uint16_t)desc->n_intro_points));
|
||||
set_uint16(cp, htons((uint16_t)smartlist_len(desc->intro_nodes)));
|
||||
cp += 2;
|
||||
for (i=0; i < desc->n_intro_points; ++i) {
|
||||
char *ipoint = (char*)desc->intro_points[i];
|
||||
for (i=0; i < smartlist_len(desc->intro_nodes); ++i) {
|
||||
rend_intro_point_t *intro = smartlist_get(desc->intro_nodes, i);
|
||||
char ipoint[HEX_DIGEST_LEN+2];
|
||||
ipoint[0] = '$';
|
||||
base16_encode(ipoint+1, HEX_DIGEST_LEN+1,
|
||||
intro->extend_info->identity_digest,
|
||||
DIGEST_LEN);
|
||||
strlcpy(cp, ipoint, buflen-(cp-*str_out));
|
||||
cp += strlen(ipoint)+1;
|
||||
}
|
||||
@ -537,9 +527,10 @@ rend_service_descriptor_t *
|
||||
rend_parse_service_descriptor(const char *str, size_t len)
|
||||
{
|
||||
rend_service_descriptor_t *result = NULL;
|
||||
int i;
|
||||
int i, n_intro_points;
|
||||
size_t keylen, asn1len;
|
||||
const char *end, *cp, *eos;
|
||||
rend_intro_point_t *intro;
|
||||
|
||||
result = tor_malloc_zero(sizeof(rend_service_descriptor_t));
|
||||
cp = str;
|
||||
@ -558,19 +549,22 @@ rend_parse_service_descriptor(const char *str, size_t len)
|
||||
cp += 4;
|
||||
result->protocols = 1<<2; /* always use intro format 2 */
|
||||
if (end-cp < 2) goto truncated;
|
||||
result->n_intro_points = ntohs(get_uint16(cp));
|
||||
n_intro_points = ntohs(get_uint16(cp));
|
||||
cp += 2;
|
||||
|
||||
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) {
|
||||
if (end-cp < 2) goto truncated;
|
||||
eos = (const char *)memchr(cp,'\0',end-cp);
|
||||
if (!eos) goto truncated;
|
||||
result->intro_points[i] = tor_strdup(cp);
|
||||
cp = eos+1;
|
||||
}
|
||||
result->intro_nodes = smartlist_create();
|
||||
for (i=0;i<n_intro_points;++i) {
|
||||
if (end-cp < 2) goto truncated;
|
||||
eos = (const char *)memchr(cp,'\0',end-cp);
|
||||
if (!eos) goto truncated;
|
||||
/* Write nickname to extend info, but postpone the lookup whether
|
||||
* we know that router. It's not part of the parsing process. */
|
||||
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
strlcpy(intro->extend_info->nickname, cp,
|
||||
sizeof(intro->extend_info->nickname));
|
||||
smartlist_add(result->intro_nodes, intro);
|
||||
cp = eos+1;
|
||||
}
|
||||
keylen = crypto_pk_keysize(result->pk);
|
||||
tor_assert(end-cp >= 0);
|
||||
@ -1091,7 +1085,7 @@ rend_cache_store_v2_desc_as_client(const char *desc,
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
parsed->n_intro_points = 0;
|
||||
parsed->intro_nodes = smartlist_create();
|
||||
}
|
||||
/* We don't need the encoded/encrypted introduction points any longer. */
|
||||
tor_free(intro_content);
|
||||
|
@ -12,8 +12,9 @@ const char rendservice_c_id[] =
|
||||
|
||||
#include "or.h"
|
||||
|
||||
static origin_circuit_t *find_intro_circuit(routerinfo_t *router,
|
||||
const char *pk_digest);
|
||||
static origin_circuit_t *find_intro_circuit(rend_intro_point_t *intro,
|
||||
const char *pk_digest,
|
||||
int desc_version);
|
||||
|
||||
/** Represents the mapping from a virtual port of a rendezvous service to
|
||||
* a real port on some IP.
|
||||
@ -50,10 +51,8 @@ typedef struct rend_service_t {
|
||||
crypto_pk_env_t *private_key;
|
||||
char service_id[REND_SERVICE_ID_LEN_BASE32+1];
|
||||
char pk_digest[DIGEST_LEN];
|
||||
smartlist_t *intro_nodes; /**< list of hexdigests for intro points we have,
|
||||
smartlist_t *intro_nodes; /**< List of rend_intro_point_t's we have,
|
||||
* or are trying to establish. */
|
||||
strmap_t *intro_keys; /**< map from intro node hexdigest to key; only
|
||||
* used for versioned hidden service descriptors. */
|
||||
time_t intro_period_started;
|
||||
int n_intro_circuits_launched; /**< count of intro circuits we have
|
||||
* established in this period. */
|
||||
@ -78,15 +77,6 @@ num_rend_services(void)
|
||||
return smartlist_len(rend_service_list);
|
||||
}
|
||||
|
||||
/** Helper: Release the storage held by the intro key in <b>_ent</b>.
|
||||
*/
|
||||
static void
|
||||
intro_key_free(void *_ent)
|
||||
{
|
||||
crypto_pk_env_t *ent = _ent;
|
||||
crypto_free_pk_env(ent);
|
||||
}
|
||||
|
||||
/** Release the storage held by <b>service</b>.
|
||||
*/
|
||||
static void
|
||||
@ -98,12 +88,13 @@ rend_service_free(rend_service_t *service)
|
||||
smartlist_free(service->ports);
|
||||
if (service->private_key)
|
||||
crypto_free_pk_env(service->private_key);
|
||||
if (service->intro_keys)
|
||||
strmap_free(service->intro_keys, intro_key_free);
|
||||
if (service->intro_nodes) {
|
||||
SMARTLIST_FOREACH(service->intro_nodes, rend_intro_point_t *, intro,
|
||||
rend_intro_point_free(intro););
|
||||
smartlist_free(service->intro_nodes);
|
||||
}
|
||||
tor_free(service->intro_prefer_nodes);
|
||||
tor_free(service->intro_exclude_nodes);
|
||||
SMARTLIST_FOREACH(service->intro_nodes, void*, p, tor_free(p));
|
||||
smartlist_free(service->intro_nodes);
|
||||
if (service->desc)
|
||||
rend_service_descriptor_free(service->desc);
|
||||
tor_free(service);
|
||||
@ -137,7 +128,6 @@ rend_add_service(rend_service_t *service)
|
||||
if (!service->intro_exclude_nodes)
|
||||
service->intro_exclude_nodes = tor_strdup("");
|
||||
service->intro_nodes = smartlist_create();
|
||||
service->intro_keys = strmap_new();
|
||||
|
||||
/* If the service is configured to publish unversioned (v0) and versioned
|
||||
* descriptors (v2 or higher), split it up into two separate services. */
|
||||
@ -151,7 +141,6 @@ rend_add_service(rend_service_t *service)
|
||||
memcpy(copy, p, sizeof(rend_service_port_config_t));
|
||||
smartlist_add(v0_service->ports, copy);
|
||||
});
|
||||
v0_service->intro_nodes = smartlist_create();
|
||||
v0_service->intro_prefer_nodes = tor_strdup(service->intro_prefer_nodes);
|
||||
v0_service->intro_exclude_nodes = tor_strdup(service->intro_exclude_nodes);
|
||||
v0_service->intro_period_started = service->intro_period_started;
|
||||
@ -273,7 +262,6 @@ rend_config_services(or_options_t *options, int validate_only)
|
||||
service = tor_malloc_zero(sizeof(rend_service_t));
|
||||
service->directory = tor_strdup(line->value);
|
||||
service->ports = smartlist_create();
|
||||
service->intro_nodes = smartlist_create();
|
||||
service->intro_period_started = time(NULL);
|
||||
service->descriptor_version = -1; /**< All descriptor versions. */
|
||||
continue;
|
||||
@ -349,8 +337,7 @@ rend_service_update_descriptor(rend_service_t *service)
|
||||
{
|
||||
rend_service_descriptor_t *d;
|
||||
origin_circuit_t *circ;
|
||||
int i,n;
|
||||
routerinfo_t *router;
|
||||
int i;
|
||||
if (service->desc) {
|
||||
rend_service_descriptor_free(service->desc);
|
||||
service->desc = NULL;
|
||||
@ -359,46 +346,24 @@ rend_service_update_descriptor(rend_service_t *service)
|
||||
d->pk = crypto_pk_dup_key(service->private_key);
|
||||
d->timestamp = time(NULL);
|
||||
d->version = service->descriptor_version;
|
||||
n = smartlist_len(service->intro_nodes);
|
||||
d->n_intro_points = 0;
|
||||
d->intro_points = tor_malloc_zero(sizeof(char*)*n);
|
||||
d->intro_point_extend_info = tor_malloc_zero(sizeof(extend_info_t*)*n);
|
||||
d->intro_nodes = smartlist_create();
|
||||
/* XXXX020 Why should we support the old intro protocol 0? Whoever
|
||||
* understands descriptor version 2 also understands intro protocol 2. */
|
||||
d->protocols = 1 << 2; /*< We only support intro protocol 2. */
|
||||
|
||||
if (service->intro_keys) {
|
||||
/* We need to copy keys so that they're not deleted when we free the
|
||||
* descriptor. */
|
||||
strmap_iter_t *iter;
|
||||
d->intro_keys = strmap_new();
|
||||
for (iter = strmap_iter_init(service->intro_keys); !strmap_iter_done(iter);
|
||||
iter = strmap_iter_next(service->intro_keys, iter)) {
|
||||
const char *key;
|
||||
void *val;
|
||||
crypto_pk_env_t *k;
|
||||
strmap_iter_get(iter, &key, &val);
|
||||
k = val;
|
||||
strmap_set(d->intro_keys, key, crypto_pk_dup_key(k));
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < n; ++i) {
|
||||
const char *name = smartlist_get(service->intro_nodes, i);
|
||||
router = router_get_by_nickname(name, 1);
|
||||
if (!router) {
|
||||
log_info(LD_REND,"Router '%s' not found for intro point %d. Skipping.",
|
||||
safe_str(name), i);
|
||||
for (i = 0; i < smartlist_len(service->intro_nodes); ++i) {
|
||||
rend_intro_point_t *intro_svc = smartlist_get(service->intro_nodes, i);
|
||||
rend_intro_point_t *intro_desc;
|
||||
circ = find_intro_circuit(intro_svc, service->pk_digest, d->version);
|
||||
if (!circ || circ->_base.purpose != CIRCUIT_PURPOSE_S_INTRO)
|
||||
continue;
|
||||
}
|
||||
circ = find_intro_circuit(router, service->pk_digest);
|
||||
if (circ && circ->_base.purpose == CIRCUIT_PURPOSE_S_INTRO) {
|
||||
/* We have an entirely established intro circuit. */
|
||||
d->intro_points[d->n_intro_points] = tor_strdup(name);
|
||||
d->intro_point_extend_info[d->n_intro_points] =
|
||||
extend_info_from_router(router);
|
||||
d->n_intro_points++;
|
||||
}
|
||||
|
||||
/* We have an entirely established intro circuit. */
|
||||
intro_desc = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
intro_desc->extend_info = extend_info_dup(intro_svc->extend_info);
|
||||
if (intro_svc->intro_key)
|
||||
intro_desc->intro_key = crypto_pk_dup_key(intro_svc->intro_key);
|
||||
smartlist_add(d->intro_nodes, intro_desc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,35 +756,32 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc)
|
||||
*/
|
||||
static int
|
||||
rend_service_launch_establish_intro(rend_service_t *service,
|
||||
const char *nickname)
|
||||
rend_intro_point_t *intro)
|
||||
{
|
||||
origin_circuit_t *launched;
|
||||
|
||||
log_info(LD_REND,
|
||||
"Launching circuit to introduction point %s for service %s",
|
||||
escaped_safe_str(nickname), service->service_id);
|
||||
escaped_safe_str(intro->extend_info->nickname),
|
||||
service->service_id);
|
||||
|
||||
rep_hist_note_used_internal(time(NULL), 1, 0);
|
||||
|
||||
++service->n_intro_circuits_launched;
|
||||
launched = circuit_launch_by_nickname(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, 0,
|
||||
nickname, 1, 0, 1);
|
||||
launched = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO,
|
||||
0, intro->extend_info, 1, 0, 1);
|
||||
if (!launched) {
|
||||
log_info(LD_REND,
|
||||
"Can't launch circuit to establish introduction at %s.",
|
||||
escaped_safe_str(nickname));
|
||||
escaped_safe_str(intro->extend_info->nickname));
|
||||
return -1;
|
||||
}
|
||||
strlcpy(launched->rend_query, service->service_id,
|
||||
sizeof(launched->rend_query));
|
||||
memcpy(launched->rend_pk_digest, service->pk_digest, DIGEST_LEN);
|
||||
launched->rend_desc_version = service->descriptor_version;
|
||||
if (service->descriptor_version == 2) {
|
||||
launched->intro_key = crypto_new_pk_env();
|
||||
tor_assert(!crypto_pk_generate_key(launched->intro_key));
|
||||
strmap_set(service->intro_keys, nickname,
|
||||
crypto_pk_dup_key(launched->intro_key));
|
||||
}
|
||||
if (service->descriptor_version == 2)
|
||||
launched->intro_key = crypto_pk_dup_key(intro->intro_key);
|
||||
if (launched->_base.state == CIRCUIT_STATE_OPEN)
|
||||
rend_service_intro_has_opened(launched);
|
||||
return 0;
|
||||
@ -1024,19 +986,22 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
|
||||
*/
|
||||
|
||||
/** Return the (possibly non-open) introduction circuit ending at
|
||||
* <b>router</b> for the service whose public key is <b>pk_digest</b>. Return
|
||||
* <b>intro</b> for the service whose public key is <b>pk_digest</b> and
|
||||
* which publishes descriptor of version <b>desc_version</b>. Return
|
||||
* NULL if no such service is found.
|
||||
*/
|
||||
static origin_circuit_t *
|
||||
find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
||||
find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
|
||||
int desc_version)
|
||||
{
|
||||
origin_circuit_t *circ = NULL;
|
||||
|
||||
tor_assert(router);
|
||||
tor_assert(intro);
|
||||
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
|
||||
CIRCUIT_PURPOSE_S_INTRO))) {
|
||||
if (!strcasecmp(circ->build_state->chosen_exit->nickname,
|
||||
router->nickname)) {
|
||||
if (!strcasecmp(circ->build_state->chosen_exit->identity_digest,
|
||||
intro->extend_info->identity_digest) &&
|
||||
circ->rend_desc_version == desc_version) {
|
||||
return circ;
|
||||
}
|
||||
}
|
||||
@ -1044,8 +1009,9 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
||||
circ = NULL;
|
||||
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
|
||||
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
|
||||
if (!strcasecmp(circ->build_state->chosen_exit->nickname,
|
||||
router->nickname)) {
|
||||
if (!strcasecmp(circ->build_state->chosen_exit->identity_digest,
|
||||
intro->extend_info->identity_digest) &&
|
||||
circ->rend_desc_version == desc_version) {
|
||||
return circ;
|
||||
}
|
||||
}
|
||||
@ -1168,7 +1134,7 @@ rend_services_introduce(void)
|
||||
int i,j,r;
|
||||
routerinfo_t *router;
|
||||
rend_service_t *service;
|
||||
char *intro;
|
||||
rend_intro_point_t *intro;
|
||||
int changed, prev_intro_nodes;
|
||||
smartlist_t *intro_routers, *exclude_routers;
|
||||
time_t now;
|
||||
@ -1198,12 +1164,12 @@ rend_services_introduce(void)
|
||||
service. */
|
||||
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
|
||||
intro = smartlist_get(service->intro_nodes, j);
|
||||
router = router_get_by_nickname(intro, 0);
|
||||
if (!router || !find_intro_circuit(router,service->pk_digest)) {
|
||||
router = router_get_by_digest(intro->extend_info->identity_digest);
|
||||
if (!router || !find_intro_circuit(intro, service->pk_digest,
|
||||
service->descriptor_version)) {
|
||||
log_info(LD_REND,"Giving up on %s as intro point for %s.",
|
||||
intro, service->service_id);
|
||||
tor_free(intro);
|
||||
/* XXXXX020 we could also remove the intro key here. */
|
||||
intro->extend_info->nickname, service->service_id);
|
||||
rend_intro_point_free(intro);
|
||||
smartlist_del(service->intro_nodes,j--);
|
||||
changed = 1;
|
||||
service->desc_is_dirty = now;
|
||||
@ -1228,7 +1194,6 @@ rend_services_introduce(void)
|
||||
smartlist_add_all(exclude_routers, intro_routers);
|
||||
/* The directory is now here. Pick three ORs as intro points. */
|
||||
for (j=prev_intro_nodes; j < NUM_INTRO_POINTS; ++j) {
|
||||
char *hex_digest;
|
||||
router = router_choose_random_node(service->intro_prefer_nodes,
|
||||
service->intro_exclude_nodes, exclude_routers, 1, 0, 0,
|
||||
get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION,
|
||||
@ -1240,14 +1205,15 @@ rend_services_introduce(void)
|
||||
break;
|
||||
}
|
||||
changed = 1;
|
||||
hex_digest = tor_malloc_zero(HEX_DIGEST_LEN+2);
|
||||
hex_digest[0] = '$';
|
||||
base16_encode(hex_digest+1, HEX_DIGEST_LEN+1,
|
||||
router->cache_info.identity_digest,
|
||||
DIGEST_LEN);
|
||||
smartlist_add(intro_routers, router);
|
||||
smartlist_add(exclude_routers, router);
|
||||
smartlist_add(service->intro_nodes, hex_digest);
|
||||
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
intro->extend_info = extend_info_from_router(router);
|
||||
if (service->descriptor_version == 2) {
|
||||
intro->intro_key = crypto_new_pk_env();
|
||||
tor_assert(!crypto_pk_generate_key(intro->intro_key));
|
||||
}
|
||||
smartlist_add(service->intro_nodes, intro);
|
||||
log_info(LD_REND, "Picked router %s as an intro point for %s.",
|
||||
router->nickname, service->service_id);
|
||||
}
|
||||
@ -1265,7 +1231,7 @@ rend_services_introduce(void)
|
||||
r = rend_service_launch_establish_intro(service, intro);
|
||||
if (r<0) {
|
||||
log_warn(LD_REND, "Error launching circuit to node %s for service %s.",
|
||||
intro, service->service_id);
|
||||
intro->extend_info->nickname, service->service_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1315,10 +1281,9 @@ void
|
||||
rend_service_dump_stats(int severity)
|
||||
{
|
||||
int i,j;
|
||||
routerinfo_t *router;
|
||||
rend_service_t *service;
|
||||
const char *nickname, *safe_name;
|
||||
char nn_buf[MAX_VERBOSE_NICKNAME_LEN];
|
||||
rend_intro_point_t *intro;
|
||||
const char *safe_name;
|
||||
origin_circuit_t *circ;
|
||||
|
||||
for (i=0; i < smartlist_len(rend_service_list); ++i) {
|
||||
@ -1326,20 +1291,11 @@ rend_service_dump_stats(int severity)
|
||||
log(severity, LD_GENERAL, "Service configured in \"%s\":",
|
||||
service->directory);
|
||||
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
|
||||
nickname = smartlist_get(service->intro_nodes, j);
|
||||
router = router_get_by_nickname(nickname,1);
|
||||
if (router) {
|
||||
router_get_verbose_nickname(nn_buf, router);
|
||||
nickname = nn_buf;
|
||||
}
|
||||
safe_name = safe_str(nickname);
|
||||
intro = smartlist_get(service->intro_nodes, j);
|
||||
safe_name = safe_str(intro->extend_info->nickname);
|
||||
|
||||
if (!router) {
|
||||
log(severity, LD_GENERAL,
|
||||
" Intro point %d at %s: unrecognized router", j, safe_name);
|
||||
continue;
|
||||
}
|
||||
circ = find_intro_circuit(router, service->pk_digest);
|
||||
circ = find_intro_circuit(intro, service->pk_digest,
|
||||
service->descriptor_version);
|
||||
if (!circ) {
|
||||
log(severity, LD_GENERAL, " Intro point %d at %s: no circuit",
|
||||
j, safe_name);
|
||||
|
@ -862,8 +862,8 @@ check_signature_token(const char *digest,
|
||||
tor_free(signed_digest);
|
||||
return -1;
|
||||
}
|
||||
log_debug(LD_DIR,"Signed %s hash starts %s", doctype,
|
||||
hex_str(signed_digest,4));
|
||||
// log_debug(LD_DIR,"Signed %s hash starts %s", doctype,
|
||||
// hex_str(signed_digest,4));
|
||||
if (memcmp(digest, signed_digest, DIGEST_LEN)) {
|
||||
log_warn(LD_DIR, "Error reading %s: signature does not match.", doctype);
|
||||
tor_free(signed_digest);
|
||||
@ -3384,14 +3384,15 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
{
|
||||
char *ipos_decrypted = NULL;
|
||||
const char **current_ipo;
|
||||
smartlist_t *intropoints;
|
||||
smartlist_t *tokens;
|
||||
int i;
|
||||
directory_token_t *tok;
|
||||
rend_intro_point_t *intro;
|
||||
extend_info_t *info;
|
||||
struct in_addr ip;
|
||||
int result;
|
||||
tor_assert(parsed);
|
||||
/** Function may only be invoked once. */
|
||||
tor_assert(!parsed->intro_nodes);
|
||||
tor_assert(intro_points_encrypted);
|
||||
tor_assert(intro_points_encrypted_size > 0);
|
||||
/* Decrypt introduction points, if required. */
|
||||
@ -3413,15 +3414,9 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
intro_points_encrypted_size = unenclen;
|
||||
}
|
||||
/* Consider one intro point after the other. */
|
||||
current_ipo = &intro_points_encrypted;
|
||||
intropoints = smartlist_create();
|
||||
current_ipo = (const char **)&intro_points_encrypted;
|
||||
tokens = smartlist_create();
|
||||
if (parsed->intro_keys) {
|
||||
log_warn(LD_BUG, "Parsing list of introduction points for the same "
|
||||
"hidden service, twice.");
|
||||
} else {
|
||||
parsed->intro_keys = strmap_new();
|
||||
}
|
||||
parsed->intro_nodes = smartlist_create();
|
||||
while (!strcmpstart(*current_ipo, "introduction-point ")) {
|
||||
/* Determine end of string. */
|
||||
const char *eos = strstr(*current_ipo, "\nintroduction-point ");
|
||||
@ -3444,8 +3439,9 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
log_warn(LD_REND, "Impossibly short introduction point.");
|
||||
goto err;
|
||||
}
|
||||
/* Allocate new extend info. */
|
||||
info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
/* Allocate new intro point and extend info. */
|
||||
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
info = intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
/* Parse identifier. */
|
||||
tok = find_first_by_keyword(tokens, R_IPO_IDENTIFIER);
|
||||
tor_assert(tok);
|
||||
@ -3453,7 +3449,7 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
tok->args[0], REND_INTRO_POINT_ID_LEN_BASE32) < 0) {
|
||||
log_warn(LD_REND, "Identity digest contains illegal characters: %s",
|
||||
tok->args[0]);
|
||||
tor_free(info);
|
||||
rend_intro_point_free(intro);
|
||||
goto err;
|
||||
}
|
||||
/* Write identifier to nickname. */
|
||||
@ -3464,7 +3460,7 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
tok = find_first_by_keyword(tokens, R_IPO_IP_ADDRESS);
|
||||
if (tor_inet_aton(tok->args[0], &ip) == 0) {
|
||||
log_warn(LD_REND, "Could not parse IP address.");
|
||||
tor_free(info);
|
||||
rend_intro_point_free(intro);
|
||||
goto err;
|
||||
}
|
||||
info->addr = ntohl(ip.s_addr);
|
||||
@ -3477,7 +3473,7 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
if (!info->port) {
|
||||
log_warn(LD_REND, "Introduction point onion port is out of range: %d",
|
||||
info->port);
|
||||
tor_free(info);
|
||||
rend_intro_point_free(intro);
|
||||
goto err;
|
||||
}
|
||||
/* Parse onion key. */
|
||||
@ -3486,30 +3482,12 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
tok->key = NULL; /* Prevent free */
|
||||
/* Parse service key. */
|
||||
tok = find_first_by_keyword(tokens, R_IPO_SERVICE_KEY);
|
||||
strmap_set(parsed->intro_keys, info->nickname, tok->key);
|
||||
intro->intro_key = tok->key;
|
||||
tok->key = NULL; /* Prevent free */
|
||||
/* Add extend info to list of introduction points. */
|
||||
smartlist_add(intropoints, info);
|
||||
/* XXX if intropoints has items on it, but we goto err the next
|
||||
* time through the loop, we don't free the items in the 'err'
|
||||
* section below. -RD */
|
||||
smartlist_add(parsed->intro_nodes, intro);
|
||||
}
|
||||
/* Write extend infos to descriptor. */
|
||||
/* XXXX020 what if intro_points (&tc) are already set? */
|
||||
/* This function is not intended to be invoced multiple times for
|
||||
* the same descriptor. Should this be asserted? -KL */
|
||||
/* Yes. -NM */
|
||||
parsed->n_intro_points = smartlist_len(intropoints);
|
||||
parsed->intro_point_extend_info =
|
||||
tor_malloc_zero(sizeof(extend_info_t *) * parsed->n_intro_points);
|
||||
parsed->intro_points =
|
||||
tor_malloc_zero(sizeof(char *) * parsed->n_intro_points);
|
||||
i = 0;
|
||||
SMARTLIST_FOREACH(intropoints, extend_info_t *, ipo, {
|
||||
parsed->intro_points[i] = tor_strdup(ipo->nickname);
|
||||
parsed->intro_point_extend_info[i++] = ipo;
|
||||
});
|
||||
result = parsed->n_intro_points;
|
||||
result = smartlist_len(parsed->intro_nodes);
|
||||
goto done;
|
||||
|
||||
err:
|
||||
@ -3520,8 +3498,6 @@ rend_decrypt_introduction_points(rend_service_descriptor_t *parsed,
|
||||
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
|
||||
smartlist_free(tokens);
|
||||
|
||||
smartlist_free(intropoints);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2984,6 +2984,7 @@ test_rend_fns(void)
|
||||
size_t len;
|
||||
crypto_pk_env_t *pk1, *pk2;
|
||||
time_t now;
|
||||
int i;
|
||||
pk1 = pk_generate(0);
|
||||
pk2 = pk_generate(1);
|
||||
|
||||
@ -2992,12 +2993,17 @@ test_rend_fns(void)
|
||||
d1->pk = crypto_pk_dup_key(pk1);
|
||||
now = time(NULL);
|
||||
d1->timestamp = now;
|
||||
d1->n_intro_points = 3;
|
||||
d1->version = 0;
|
||||
d1->intro_points = tor_malloc(sizeof(char*)*3);
|
||||
d1->intro_points[0] = tor_strdup("tom");
|
||||
d1->intro_points[1] = tor_strdup("crow");
|
||||
d1->intro_points[2] = tor_strdup("joel");
|
||||
d1->intro_nodes = smartlist_create();
|
||||
for (i = 0; i < 3; i++) {
|
||||
rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
crypto_rand(intro->extend_info->identity_digest, DIGEST_LEN);
|
||||
intro->extend_info->nickname[0] = '$';
|
||||
base16_encode(intro->extend_info->nickname+1, HEX_DIGEST_LEN+1,
|
||||
intro->extend_info->identity_digest, DIGEST_LEN);
|
||||
smartlist_add(d1->intro_nodes, intro);
|
||||
}
|
||||
test_assert(! rend_encode_service_descriptor(d1, pk1, &encoded, &len));
|
||||
d2 = rend_parse_service_descriptor(encoded, len);
|
||||
test_assert(d2);
|
||||
@ -3006,11 +3012,13 @@ test_rend_fns(void)
|
||||
test_eq(d2->timestamp, now);
|
||||
test_eq(d2->version, 0);
|
||||
test_eq(d2->protocols, 1<<2);
|
||||
test_eq(d2->n_intro_points, 3);
|
||||
test_streq(d2->intro_points[0], "tom");
|
||||
test_streq(d2->intro_points[1], "crow");
|
||||
test_streq(d2->intro_points[2], "joel");
|
||||
test_eq(NULL, d2->intro_point_extend_info);
|
||||
test_eq(smartlist_len(d2->intro_nodes), 3);
|
||||
for (i = 0; i < 3; i++) {
|
||||
rend_intro_point_t *intro1 = smartlist_get(d1->intro_nodes, i);
|
||||
rend_intro_point_t *intro2 = smartlist_get(d2->intro_nodes, i);
|
||||
test_streq(intro1->extend_info->nickname,
|
||||
intro2->extend_info->nickname);
|
||||
}
|
||||
|
||||
rend_service_descriptor_free(d1);
|
||||
rend_service_descriptor_free(d2);
|
||||
@ -3304,28 +3312,26 @@ test_rend_fns_v2(void)
|
||||
service_id, REND_SERVICE_ID_LEN);
|
||||
now = time(NULL);
|
||||
generated->timestamp = now;
|
||||
generated->n_intro_points = 3;
|
||||
generated->version = 2;
|
||||
generated->protocols = 42;
|
||||
generated->intro_point_extend_info =
|
||||
tor_malloc_zero(sizeof(extend_info_t *) * generated->n_intro_points);
|
||||
generated->intro_points =
|
||||
tor_malloc_zero(sizeof(char *) * generated->n_intro_points);
|
||||
generated->intro_keys = strmap_new();
|
||||
for (i = 0; i < generated->n_intro_points; i++) {
|
||||
extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
generated->intro_nodes = smartlist_create();
|
||||
for (i = 0; i < 3; i++) {
|
||||
rend_intro_point_t *intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
||||
crypto_pk_env_t *okey = pk_generate(2 + i);
|
||||
info->onion_key = crypto_pk_dup_key(okey);
|
||||
crypto_pk_get_digest(info->onion_key, info->identity_digest);
|
||||
intro->extend_info = tor_malloc_zero(sizeof(extend_info_t));
|
||||
intro->extend_info->onion_key = crypto_pk_dup_key(okey);
|
||||
crypto_pk_get_digest(intro->extend_info->onion_key,
|
||||
intro->extend_info->identity_digest);
|
||||
//crypto_rand(info->identity_digest, DIGEST_LEN); /* Would this work? */
|
||||
info->nickname[0] = '$';
|
||||
base16_encode(info->nickname + 1, sizeof(info->nickname) - 1,
|
||||
info->identity_digest, DIGEST_LEN);
|
||||
info->addr = crypto_rand_int(65536); /* Does not cover all IP addresses. */
|
||||
info->port = crypto_rand_int(65536);
|
||||
generated->intro_points[i] = tor_strdup(info->nickname);
|
||||
generated->intro_point_extend_info[i] = info;
|
||||
strmap_set(generated->intro_keys, info->nickname, crypto_pk_dup_key(pk2));
|
||||
intro->extend_info->nickname[0] = '$';
|
||||
base16_encode(intro->extend_info->nickname + 1,
|
||||
sizeof(intro->extend_info->nickname) - 1,
|
||||
intro->extend_info->identity_digest, DIGEST_LEN);
|
||||
intro->extend_info->addr = crypto_rand_int(65536); /* Does not cover all
|
||||
* IP addresses. */
|
||||
intro->extend_info->port = crypto_rand_int(65536);
|
||||
intro->intro_key = pk2;
|
||||
smartlist_add(generated->intro_nodes, intro);
|
||||
}
|
||||
test_assert(rend_encode_v2_descriptors(descs, generated, now,
|
||||
NULL, 0) > 0);
|
||||
@ -3350,15 +3356,16 @@ test_rend_fns_v2(void)
|
||||
test_eq(parsed->timestamp, now);
|
||||
test_eq(parsed->version, 2);
|
||||
test_eq(parsed->protocols, 42);
|
||||
test_eq(parsed->n_intro_points, 3);
|
||||
for (i = 0; i < parsed->n_intro_points; i++) {
|
||||
extend_info_t *par_info = parsed->intro_point_extend_info[i];
|
||||
extend_info_t *gen_info = generated->intro_point_extend_info[i];
|
||||
test_eq(smartlist_len(parsed->intro_nodes), 3);
|
||||
for (i = 0; i < smartlist_len(parsed->intro_nodes); i++) {
|
||||
rend_intro_point_t *par_intro = smartlist_get(parsed->intro_nodes, i),
|
||||
*gen_intro = smartlist_get(generated->intro_nodes, i);
|
||||
extend_info_t *par_info = par_intro->extend_info;
|
||||
extend_info_t *gen_info = gen_intro->extend_info;
|
||||
test_assert(!crypto_pk_cmp_keys(gen_info->onion_key, par_info->onion_key));
|
||||
test_memeq(gen_info->identity_digest, par_info->identity_digest,
|
||||
DIGEST_LEN);
|
||||
test_streq(gen_info->nickname, par_info->nickname);
|
||||
test_streq(generated->intro_points[i], parsed->intro_points[i]);
|
||||
test_eq(gen_info->addr, par_info->addr);
|
||||
test_eq(gen_info->port, par_info->port);
|
||||
}
|
||||
@ -3367,7 +3374,6 @@ test_rend_fns_v2(void)
|
||||
rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
|
||||
smartlist_free(descs);
|
||||
rend_service_descriptor_free(parsed);
|
||||
rend_service_descriptor_free(generated);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user