|
@@ -42,8 +42,6 @@ typedef struct rend_service_t {
|
|
/* Fields specified in config file */
|
|
/* Fields specified in config file */
|
|
char *directory; /**< where in the filesystem it stores it */
|
|
char *directory; /**< where in the filesystem it stores it */
|
|
smartlist_t *ports; /**< List of rend_service_port_config_t */
|
|
smartlist_t *ports; /**< List of rend_service_port_config_t */
|
|
- int descriptor_version; /**< Rendezvous descriptor version that will be
|
|
|
|
- * published. */
|
|
|
|
rend_auth_type_t auth_type; /**< Client authorization type or 0 if no client
|
|
rend_auth_type_t auth_type; /**< Client authorization type or 0 if no client
|
|
* authorization is performed. */
|
|
* authorization is performed. */
|
|
smartlist_t *clients; /**< List of rend_authorized_client_t's of
|
|
smartlist_t *clients; /**< List of rend_authorized_client_t's of
|
|
@@ -156,36 +154,6 @@ rend_add_service(rend_service_t *service)
|
|
|
|
|
|
service->intro_nodes = smartlist_create();
|
|
service->intro_nodes = smartlist_create();
|
|
|
|
|
|
- /* If the service is configured to publish unversioned (v0) and versioned
|
|
|
|
- * descriptors (v2 or higher), split it up into two separate services
|
|
|
|
- * (unless it is configured to perform client authorization). */
|
|
|
|
- if (service->descriptor_version == -1) {
|
|
|
|
- if (service->auth_type == REND_NO_AUTH) {
|
|
|
|
- rend_service_t *v0_service = tor_malloc_zero(sizeof(rend_service_t));
|
|
|
|
- v0_service->directory = tor_strdup(service->directory);
|
|
|
|
- v0_service->ports = smartlist_create();
|
|
|
|
- SMARTLIST_FOREACH(service->ports, rend_service_port_config_t *, p, {
|
|
|
|
- rend_service_port_config_t *copy =
|
|
|
|
- tor_malloc_zero(sizeof(rend_service_port_config_t));
|
|
|
|
- memcpy(copy, p, sizeof(rend_service_port_config_t));
|
|
|
|
- smartlist_add(v0_service->ports, copy);
|
|
|
|
- });
|
|
|
|
- v0_service->intro_period_started = service->intro_period_started;
|
|
|
|
- v0_service->descriptor_version = 0; /* Unversioned descriptor. */
|
|
|
|
- v0_service->auth_type = REND_NO_AUTH;
|
|
|
|
- rend_add_service(v0_service);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- service->descriptor_version = 2; /* Versioned descriptor. */
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (service->auth_type != REND_NO_AUTH && !service->descriptor_version) {
|
|
|
|
- log_warn(LD_CONFIG, "Hidden service with client authorization and "
|
|
|
|
- "version 0 descriptors configured; ignoring.");
|
|
|
|
- rend_service_free(service);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (service->auth_type != REND_NO_AUTH &&
|
|
if (service->auth_type != REND_NO_AUTH &&
|
|
smartlist_len(service->clients) == 0) {
|
|
smartlist_len(service->clients) == 0) {
|
|
log_warn(LD_CONFIG, "Hidden service with client authorization but no "
|
|
log_warn(LD_CONFIG, "Hidden service with client authorization but no "
|
|
@@ -307,7 +275,6 @@ rend_config_services(or_options_t *options, int validate_only)
|
|
service->directory = tor_strdup(line->value);
|
|
service->directory = tor_strdup(line->value);
|
|
service->ports = smartlist_create();
|
|
service->ports = smartlist_create();
|
|
service->intro_period_started = time(NULL);
|
|
service->intro_period_started = time(NULL);
|
|
- service->descriptor_version = -1; /**< All descriptor versions. */
|
|
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
if (!service) {
|
|
if (!service) {
|
|
@@ -433,35 +400,13 @@ rend_config_services(or_options_t *options, int validate_only)
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- smartlist_t *versions;
|
|
|
|
- char *version_str;
|
|
|
|
- int i, version, ver_ok=1, versions_bitmask = 0;
|
|
|
|
tor_assert(!strcasecmp(line->key, "HiddenServiceVersion"));
|
|
tor_assert(!strcasecmp(line->key, "HiddenServiceVersion"));
|
|
- versions = smartlist_create();
|
|
|
|
- smartlist_split_string(versions, line->value, ",",
|
|
|
|
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
|
|
|
- for (i = 0; i < smartlist_len(versions); i++) {
|
|
|
|
- version_str = smartlist_get(versions, i);
|
|
|
|
- if (strlen(version_str) != 1 || strspn(version_str, "02") != 1) {
|
|
|
|
- log_warn(LD_CONFIG,
|
|
|
|
- "HiddenServiceVersion can only be 0 and/or 2.");
|
|
|
|
- SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
|
|
|
|
- smartlist_free(versions);
|
|
|
|
- rend_service_free(service);
|
|
|
|
- return -1;
|
|
|
|
- }
|
|
|
|
- version = (int)tor_parse_long(version_str, 10, 0, INT_MAX, &ver_ok,
|
|
|
|
- NULL);
|
|
|
|
- if (!ver_ok)
|
|
|
|
- continue;
|
|
|
|
- versions_bitmask |= 1 << version;
|
|
|
|
|
|
+ if (strcmp(line->value, "2")) {
|
|
|
|
+ log_warn(LD_CONFIG,
|
|
|
|
+ "The only supported HiddenServiceVersion is 2.");
|
|
|
|
+ rend_service_free(service);
|
|
|
|
+ return -1;
|
|
}
|
|
}
|
|
- /* If exactly one version is set, change descriptor_version to that
|
|
|
|
- * value; otherwise leave it at -1. */
|
|
|
|
- if (versions_bitmask == 1 << 0) service->descriptor_version = 0;
|
|
|
|
- if (versions_bitmask == 1 << 2) service->descriptor_version = 2;
|
|
|
|
- SMARTLIST_FOREACH(versions, char *, cp, tor_free(cp));
|
|
|
|
- smartlist_free(versions);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (service) {
|
|
if (service) {
|
|
@@ -483,8 +428,7 @@ rend_config_services(or_options_t *options, int validate_only)
|
|
* probably ok? */
|
|
* probably ok? */
|
|
SMARTLIST_FOREACH(rend_service_list, rend_service_t *, new, {
|
|
SMARTLIST_FOREACH(rend_service_list, rend_service_t *, new, {
|
|
SMARTLIST_FOREACH(old_service_list, rend_service_t *, old, {
|
|
SMARTLIST_FOREACH(old_service_list, rend_service_t *, old, {
|
|
- if (!strcmp(old->directory, new->directory) &&
|
|
|
|
- old->descriptor_version == new->descriptor_version) {
|
|
|
|
|
|
+ if (!strcmp(old->directory, new->directory)) {
|
|
smartlist_add_all(new->intro_nodes, old->intro_nodes);
|
|
smartlist_add_all(new->intro_nodes, old->intro_nodes);
|
|
smartlist_clear(old->intro_nodes);
|
|
smartlist_clear(old->intro_nodes);
|
|
smartlist_add(surviving_services, old);
|
|
smartlist_add(surviving_services, old);
|
|
@@ -507,8 +451,7 @@ rend_config_services(or_options_t *options, int validate_only)
|
|
tor_assert(oc->rend_data);
|
|
tor_assert(oc->rend_data);
|
|
SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
|
|
SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
|
|
if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest,
|
|
if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest,
|
|
- DIGEST_LEN) &&
|
|
|
|
- ptr->descriptor_version == oc->rend_data->rend_desc_version) {
|
|
|
|
|
|
+ DIGEST_LEN)) {
|
|
keep_it = 1;
|
|
keep_it = 1;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -548,7 +491,6 @@ rend_service_update_descriptor(rend_service_t *service)
|
|
d = service->desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
|
|
d = service->desc = tor_malloc_zero(sizeof(rend_service_descriptor_t));
|
|
d->pk = crypto_pk_dup_key(service->private_key);
|
|
d->pk = crypto_pk_dup_key(service->private_key);
|
|
d->timestamp = time(NULL);
|
|
d->timestamp = time(NULL);
|
|
- d->version = service->descriptor_version;
|
|
|
|
d->intro_nodes = smartlist_create();
|
|
d->intro_nodes = smartlist_create();
|
|
/* Support intro protocols 2 and 3. */
|
|
/* Support intro protocols 2 and 3. */
|
|
d->protocols = (1 << 2) + (1 << 3);
|
|
d->protocols = (1 << 2) + (1 << 3);
|
|
@@ -798,16 +740,18 @@ rend_service_load_keys(void)
|
|
}
|
|
}
|
|
|
|
|
|
/** Return the service whose public key has a digest of <b>digest</b> and
|
|
/** Return the service whose public key has a digest of <b>digest</b> and
|
|
- * which publishes the given descriptor <b>version</b>. Return NULL if no
|
|
|
|
- * such service exists.
|
|
|
|
|
|
+ * which publishes the given descriptor <b>version</b>. (There is no other
|
|
|
|
+ * version than 2, so version is ignored.) Return NULL if no such service
|
|
|
|
+ * exists.
|
|
*/
|
|
*/
|
|
static rend_service_t *
|
|
static rend_service_t *
|
|
rend_service_get_by_pk_digest_and_version(const char* digest,
|
|
rend_service_get_by_pk_digest_and_version(const char* digest,
|
|
uint8_t version)
|
|
uint8_t version)
|
|
{
|
|
{
|
|
|
|
+ (void) version;
|
|
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
|
|
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
|
|
- if (!memcmp(s->pk_digest,digest,DIGEST_LEN) &&
|
|
|
|
- s->descriptor_version == version) return s);
|
|
|
|
|
|
+ if (!memcmp(s->pk_digest,digest,DIGEST_LEN))
|
|
|
|
+ return s);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -953,12 +897,8 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
- /* if descriptor version is 2, use intro key instead of service key. */
|
|
|
|
- if (circuit->rend_data->rend_desc_version == 0) {
|
|
|
|
- intro_key = service->private_key;
|
|
|
|
- } else {
|
|
|
|
- intro_key = circuit->intro_key;
|
|
|
|
- }
|
|
|
|
|
|
+ /* use intro key instead of service key. */
|
|
|
|
+ intro_key = circuit->intro_key;
|
|
|
|
|
|
/* first DIGEST_LEN bytes of request is intro or service pk digest */
|
|
/* first DIGEST_LEN bytes of request is intro or service pk digest */
|
|
crypto_pk_get_digest(intro_key, intro_key_digest);
|
|
crypto_pk_get_digest(intro_key, intro_key_digest);
|
|
@@ -1201,7 +1141,6 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
|
|
memcpy(launched->rend_data->rend_cookie, r_cookie, REND_COOKIE_LEN);
|
|
memcpy(launched->rend_data->rend_cookie, r_cookie, REND_COOKIE_LEN);
|
|
strlcpy(launched->rend_data->onion_address, service->service_id,
|
|
strlcpy(launched->rend_data->onion_address, service->service_id,
|
|
sizeof(launched->rend_data->onion_address));
|
|
sizeof(launched->rend_data->onion_address));
|
|
- launched->rend_data->rend_desc_version = service->descriptor_version;
|
|
|
|
launched->build_state->pending_final_cpath = cpath =
|
|
launched->build_state->pending_final_cpath = cpath =
|
|
tor_malloc_zero(sizeof(crypt_path_t));
|
|
tor_malloc_zero(sizeof(crypt_path_t));
|
|
cpath->magic = CRYPT_PATH_MAGIC;
|
|
cpath->magic = CRYPT_PATH_MAGIC;
|
|
@@ -1323,9 +1262,7 @@ rend_service_launch_establish_intro(rend_service_t *service,
|
|
strlcpy(launched->rend_data->onion_address, service->service_id,
|
|
strlcpy(launched->rend_data->onion_address, service->service_id,
|
|
sizeof(launched->rend_data->onion_address));
|
|
sizeof(launched->rend_data->onion_address));
|
|
memcpy(launched->rend_data->rend_pk_digest, service->pk_digest, DIGEST_LEN);
|
|
memcpy(launched->rend_data->rend_pk_digest, service->pk_digest, DIGEST_LEN);
|
|
- launched->rend_data->rend_desc_version = service->descriptor_version;
|
|
|
|
- if (service->descriptor_version == 2)
|
|
|
|
- launched->intro_key = crypto_pk_dup_key(intro->intro_key);
|
|
|
|
|
|
+ launched->intro_key = crypto_pk_dup_key(intro->intro_key);
|
|
if (launched->_base.state == CIRCUIT_STATE_OPEN)
|
|
if (launched->_base.state == CIRCUIT_STATE_OPEN)
|
|
rend_service_intro_has_opened(launched);
|
|
rend_service_intro_has_opened(launched);
|
|
return 0;
|
|
return 0;
|
|
@@ -1401,13 +1338,8 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
|
|
"Established circuit %d as introduction point for service %s",
|
|
"Established circuit %d as introduction point for service %s",
|
|
circuit->_base.n_circ_id, serviceid);
|
|
circuit->_base.n_circ_id, serviceid);
|
|
|
|
|
|
- /* If the introduction point will not be used in an unversioned
|
|
|
|
- * descriptor, use the intro key instead of the service key in
|
|
|
|
- * ESTABLISH_INTRO. */
|
|
|
|
- if (service->descriptor_version == 0)
|
|
|
|
- intro_key = service->private_key;
|
|
|
|
- else
|
|
|
|
- intro_key = circuit->intro_key;
|
|
|
|
|
|
+ /* Use the intro key instead of the service key in ESTABLISH_INTRO. */
|
|
|
|
+ intro_key = circuit->intro_key;
|
|
/* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
|
|
/* Build the payload for a RELAY_ESTABLISH_INTRO cell. */
|
|
r = crypto_pk_asn1_encode(intro_key, buf+2,
|
|
r = crypto_pk_asn1_encode(intro_key, buf+2,
|
|
RELAY_PAYLOAD_SIZE-2);
|
|
RELAY_PAYLOAD_SIZE-2);
|
|
@@ -1695,9 +1627,8 @@ directory_post_to_hs_dir(rend_service_descriptor_t *renddesc,
|
|
smartlist_free(successful_uploads);
|
|
smartlist_free(successful_uploads);
|
|
}
|
|
}
|
|
|
|
|
|
-/** Encode and sign up-to-date v0 and/or v2 service descriptors for
|
|
|
|
- * <b>service</b>, and upload it/them to all the dirservers/to the
|
|
|
|
- * responsible hidden service directories.
|
|
|
|
|
|
+/** Encode and sign an up-to-date service descriptor for <b>service</b>,
|
|
|
|
+ * and upload it/them to the responsible hidden service directories.
|
|
*/
|
|
*/
|
|
static void
|
|
static void
|
|
upload_service_descriptor(rend_service_t *service)
|
|
upload_service_descriptor(rend_service_t *service)
|
|
@@ -1709,35 +1640,8 @@ upload_service_descriptor(rend_service_t *service)
|
|
|
|
|
|
rendpostperiod = get_options()->RendPostPeriod;
|
|
rendpostperiod = get_options()->RendPostPeriod;
|
|
|
|
|
|
- /* Upload unversioned (v0) descriptor? */
|
|
|
|
- if (service->descriptor_version == 0 &&
|
|
|
|
- get_options()->PublishHidServDescriptors) {
|
|
|
|
- char *desc;
|
|
|
|
- size_t desc_len;
|
|
|
|
- /* Encode the descriptor. */
|
|
|
|
- if (rend_encode_service_descriptor(service->desc,
|
|
|
|
- service->private_key,
|
|
|
|
- &desc, &desc_len)<0) {
|
|
|
|
- log_warn(LD_BUG, "Internal error: couldn't encode service descriptor; "
|
|
|
|
- "not uploading.");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Post it to the dirservers */
|
|
|
|
- rend_get_service_id(service->desc->pk, serviceid);
|
|
|
|
- log_info(LD_REND, "Sending publish request for hidden service %s",
|
|
|
|
- serviceid);
|
|
|
|
- directory_post_to_dirservers(DIR_PURPOSE_UPLOAD_RENDDESC,
|
|
|
|
- ROUTER_PURPOSE_GENERAL,
|
|
|
|
- HIDSERV_AUTHORITY, desc, desc_len, 0);
|
|
|
|
- tor_free(desc);
|
|
|
|
- service->next_upload_time = now + rendpostperiod;
|
|
|
|
- uploaded = 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* Upload v2 descriptor? */
|
|
|
|
- if (service->descriptor_version == 2 &&
|
|
|
|
- get_options()->PublishHidServDescriptors) {
|
|
|
|
|
|
+ /* Upload descriptor? */
|
|
|
|
+ if (get_options()->PublishHidServDescriptors) {
|
|
networkstatus_t *c = networkstatus_get_latest_consensus();
|
|
networkstatus_t *c = networkstatus_get_latest_consensus();
|
|
if (c && smartlist_len(c->routerstatus_list) > 0) {
|
|
if (c && smartlist_len(c->routerstatus_list) > 0) {
|
|
int seconds_valid, i, j, num_descs;
|
|
int seconds_valid, i, j, num_descs;
|
|
@@ -1876,8 +1780,7 @@ rend_services_introduce(void)
|
|
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
|
|
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
|
|
intro = smartlist_get(service->intro_nodes, j);
|
|
intro = smartlist_get(service->intro_nodes, j);
|
|
router = router_get_by_digest(intro->extend_info->identity_digest);
|
|
router = router_get_by_digest(intro->extend_info->identity_digest);
|
|
- if (!router || !find_intro_circuit(intro, service->pk_digest,
|
|
|
|
- service->descriptor_version)) {
|
|
|
|
|
|
+ if (!router || !find_intro_circuit(intro, service->pk_digest, -1)) {
|
|
log_info(LD_REND,"Giving up on %s as intro point for %s.",
|
|
log_info(LD_REND,"Giving up on %s as intro point for %s.",
|
|
intro->extend_info->nickname, service->service_id);
|
|
intro->extend_info->nickname, service->service_id);
|
|
if (service->desc) {
|
|
if (service->desc) {
|
|
@@ -1941,10 +1844,8 @@ rend_services_introduce(void)
|
|
smartlist_add(intro_routers, router);
|
|
smartlist_add(intro_routers, router);
|
|
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
|
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
|
|
intro->extend_info = extend_info_from_router(router);
|
|
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));
|
|
|
|
- }
|
|
|
|
|
|
+ intro->intro_key = crypto_new_pk_env();
|
|
|
|
+ tor_assert(!crypto_pk_generate_key(intro->intro_key));
|
|
smartlist_add(service->intro_nodes, intro);
|
|
smartlist_add(service->intro_nodes, intro);
|
|
log_info(LD_REND, "Picked router %s as an intro point for %s.",
|
|
log_info(LD_REND, "Picked router %s as an intro point for %s.",
|
|
router->nickname, service->service_id);
|
|
router->nickname, service->service_id);
|
|
@@ -2037,8 +1938,7 @@ rend_consider_descriptor_republication(void)
|
|
|
|
|
|
for (i=0; i < smartlist_len(rend_service_list); ++i) {
|
|
for (i=0; i < smartlist_len(rend_service_list); ++i) {
|
|
service = smartlist_get(rend_service_list, i);
|
|
service = smartlist_get(rend_service_list, i);
|
|
- if (service->descriptor_version && service->desc &&
|
|
|
|
- !service->desc->all_uploads_performed) {
|
|
|
|
|
|
+ if (service->desc && !service->desc->all_uploads_performed) {
|
|
/* If we failed in uploading a descriptor last time, try again *without*
|
|
/* If we failed in uploading a descriptor last time, try again *without*
|
|
* updating the descriptor's contents. */
|
|
* updating the descriptor's contents. */
|
|
upload_service_descriptor(service);
|
|
upload_service_descriptor(service);
|
|
@@ -2066,8 +1966,7 @@ rend_service_dump_stats(int severity)
|
|
intro = smartlist_get(service->intro_nodes, j);
|
|
intro = smartlist_get(service->intro_nodes, j);
|
|
safe_name = safe_str(intro->extend_info->nickname);
|
|
safe_name = safe_str(intro->extend_info->nickname);
|
|
|
|
|
|
- circ = find_intro_circuit(intro, service->pk_digest,
|
|
|
|
- service->descriptor_version);
|
|
|
|
|
|
+ circ = find_intro_circuit(intro, service->pk_digest, -1);
|
|
if (!circ) {
|
|
if (!circ) {
|
|
log(severity, LD_GENERAL, " Intro point %d at %s: no circuit",
|
|
log(severity, LD_GENERAL, " Intro point %d at %s: no circuit",
|
|
j, safe_name);
|
|
j, safe_name);
|