From 74c2bff781e12635daead9149c1000367feddfae Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Wed, 12 Feb 2014 14:36:08 +0100 Subject: Remove remaining v0 hidden service descriptor code. Fixes the rest of #10841 after #10881 already removed some hidden service authority code. --- changes/bug10841 | 6 +++ src/or/directory.c | 95 +++++---------------------------- src/or/or.h | 15 ++---- src/or/rendclient.c | 3 +- src/or/rendcommon.c | 149 ++-------------------------------------------------- src/or/rendcommon.h | 4 -- 6 files changed, 25 insertions(+), 247 deletions(-) create mode 100644 changes/bug10841 diff --git a/changes/bug10841 b/changes/bug10841 new file mode 100644 index 000000000..5b065a8b2 --- /dev/null +++ b/changes/bug10841 @@ -0,0 +1,6 @@ + o Removed code + - Remove all code for hidden service authorities to accept and serve + version 0 descriptors and left-over code for hidden services and + hidden service clients to upload and fetch version 0 descriptors. + Version 0 descriptors are not in use anymore since 0.2.2.1-alpha. + Fixes the rest of bug 10841. diff --git a/src/or/directory.c b/src/or/directory.c index c102512c2..6924bec91 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -170,12 +170,8 @@ dir_conn_purpose_to_string(int purpose) { switch (purpose) { - case DIR_PURPOSE_FETCH_RENDDESC: - return "hidden-service descriptor fetch"; case DIR_PURPOSE_UPLOAD_DIR: return "server descriptor upload"; - case DIR_PURPOSE_UPLOAD_RENDDESC: - return "hidden-service descriptor upload"; case DIR_PURPOSE_UPLOAD_VOTE: return "server vote upload"; case DIR_PURPOSE_UPLOAD_SIGNATURES: @@ -247,13 +243,13 @@ directories_have_accepted_server_descriptor(void) /** Start a connection to every suitable directory authority, using * connection purpose dir_purpose and uploading payload * (of length payload_len). The dir_purpose should be one of - * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'. + * 'DIR_PURPOSE_UPLOAD_{DIR|VOTE|SIGNATURES}'. * * router_purpose describes the type of descriptor we're * publishing, if we're publishing a descriptor -- e.g. general or bridge. * * type specifies what sort of dir authorities (V1, V3, - * HIDSERV, BRIDGE, etc) we should upload to. + * BRIDGE, etc) we should upload to. * * If extrainfo_len is nonzero, the first payload_len bytes of * payload hold a router descriptor, and the next extrainfo_len @@ -410,9 +406,6 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, type = (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_DIRINFO : V3_DIRINFO); break; - case DIR_PURPOSE_FETCH_RENDDESC: - type = HIDSERV_DIRINFO; - break; case DIR_PURPOSE_FETCH_STATUS_VOTE: case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES: case DIR_PURPOSE_FETCH_CERTIFICATE: @@ -452,7 +445,7 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, } } - if (!options->FetchServerDescriptors && type != HIDSERV_DIRINFO) + if (!options->FetchServerDescriptors) return; if (!get_via_tor) { @@ -523,11 +516,7 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose, } } else { /* get_via_tor */ /* Never use fascistfirewall; we're going via Tor. */ - if (dir_purpose == DIR_PURPOSE_FETCH_RENDDESC) { - /* only ask hidserv authorities, any of them will do */ - pds_flags |= PDS_IGNORE_FASCISTFIREWALL|PDS_ALLOW_SELF; - rs = router_pick_trusteddirserver(HIDSERV_DIRINFO, pds_flags); - } else { + if (1) { /* anybody with a non-zero dirport will do. Disregard firewalls. */ pds_flags |= PDS_IGNORE_FASCISTFIREWALL; rs = router_pick_directory_server(type, pds_flags); @@ -649,7 +638,7 @@ directory_initiate_command_routerstatus_rend(const routerstatus_t *status, * upload or download a server or rendezvous * descriptor. dir_purpose determines what * kind of directory connection we're launching, and must be one of - * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC|RENDDESC_V2}. router_purpose + * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC_V2}. router_purpose * specifies the descriptor purposes we have in mind (currently only * used for FETCH_DIR). * @@ -900,9 +889,7 @@ directory_initiate_command(const char *address, const tor_addr_t *_addr, static int is_sensitive_dir_purpose(uint8_t dir_purpose) { - return ((dir_purpose == DIR_PURPOSE_FETCH_RENDDESC) || - (dir_purpose == DIR_PURPOSE_HAS_FETCHED_RENDDESC) || - (dir_purpose == DIR_PURPOSE_UPLOAD_RENDDESC) || + return ((dir_purpose == DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2) || (dir_purpose == DIR_PURPOSE_UPLOAD_RENDDESC_V2) || (dir_purpose == DIR_PURPOSE_FETCH_RENDDESC_V2)); } @@ -1267,12 +1254,6 @@ directory_send_command(dir_connection_t *conn, httpcommand = "GET"; tor_asprintf(&url, "/tor/rendezvous2/%s", resource); break; - case DIR_PURPOSE_UPLOAD_RENDDESC: - tor_assert(!resource); - tor_assert(payload); - httpcommand = "POST"; - url = tor_strdup("/tor/rendezvous/publish"); - break; case DIR_PURPOSE_UPLOAD_RENDDESC_V2: tor_assert(!resource); tor_assert(payload); @@ -1532,20 +1513,18 @@ body_is_plausible(const char *body, size_t len, int purpose) if (purpose == DIR_PURPOSE_FETCH_MICRODESC) { return (!strcmpstart(body,"onion-key")); } - if (purpose != DIR_PURPOSE_FETCH_RENDDESC) { + if (1) { if (!strcmpstart(body,"router") || !strcmpstart(body,"signed-directory") || !strcmpstart(body,"network-status") || !strcmpstart(body,"running-routers")) - return 1; + return 1; for (i=0;i<32;++i) { if (!TOR_ISPRINT(body[i]) && !TOR_ISSPACE(body[i])) return 0; } - return 1; - } else { - return 1; } + return 1; } /** Called when we've just fetched a bunch of router descriptors in @@ -2104,46 +2083,6 @@ connection_dir_client_reached_eof(dir_connection_t *conn) * dirservers down just because they don't like us. */ } - if (conn->base_.purpose == DIR_PURPOSE_FETCH_RENDDESC) { - tor_assert(conn->rend_data); - log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d " - "(%s))", - (int)body_len, status_code, escaped(reason)); - switch (status_code) { - case 200: - if (rend_cache_store(body, body_len, 0, - conn->rend_data->onion_address) < -1) { - log_warn(LD_REND,"Failed to parse rendezvous descriptor."); - /* Any pending rendezvous attempts will notice when - * connection_about_to_close_connection() - * cleans this dir conn up. */ - /* We could retry. But since v0 descriptors are going out of - * style, it isn't worth the hassle. We'll do better in v2. */ - } else { - /* Success, or at least there's a v2 descriptor already - * present. Notify pending connections about this. */ - conn->base_.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC; - rend_client_desc_trynow(conn->rend_data->onion_address); - } - break; - case 404: - /* Not there. Pending connections will be notified when - * connection_about_to_close_connection() cleans this conn up. */ - break; - case 400: - log_warn(LD_REND, - "http status 400 (%s). Dirserver didn't like our " - "rendezvous query?", escaped(reason)); - break; - default: - log_warn(LD_REND,"http status %d (%s) response unexpected while " - "fetching hidden service descriptor (server '%s:%d').", - status_code, escaped(reason), conn->base_.address, - conn->base_.port); - break; - } - } - if (conn->base_.purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) { #define SEND_HS_DESC_FAILED_EVENT() ( \ control_event_hs_descriptor_failed(conn->rend_data, \ @@ -2162,20 +2101,13 @@ connection_dir_client_reached_eof(dir_connection_t *conn) * cleans this dir conn up. */ SEND_HS_DESC_FAILED_EVENT(); break; - case -1: - /* We already have a v0 descriptor here. Ignoring this one - * and _not_ performing another request. */ - log_info(LD_REND, "Successfully fetched v2 rendezvous " - "descriptor, but we already have a v0 descriptor."); - conn->base_.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC; - break; default: /* success. notify pending connections about this. */ log_info(LD_REND, "Successfully fetched v2 rendezvous " "descriptor."); control_event_hs_descriptor_received(conn->rend_data, conn->identity_digest); - conn->base_.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC; + conn->base_.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2; rend_client_desc_trynow(conn->rend_data->onion_address); break; } @@ -2206,8 +2138,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn) } } - if (conn->base_.purpose == DIR_PURPOSE_UPLOAD_RENDDESC || - conn->base_.purpose == DIR_PURPOSE_UPLOAD_RENDDESC_V2) { + if (conn->base_.purpose == DIR_PURPOSE_UPLOAD_RENDDESC_V2) { log_info(LD_REND,"Uploaded rendezvous descriptor (status %d " "(%s))", status_code, escaped(reason)); @@ -2311,7 +2242,7 @@ connection_dir_about_to_close(dir_connection_t *dir_conn) } /* If we were trying to fetch a v2 rend desc and did not succeed, * retry as needed. (If a fetch is successful, the connection state - * is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC to mark that + * is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2 to mark that * refetching is unnecessary.) */ if (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2 && dir_conn->rend_data && @@ -2452,9 +2383,7 @@ note_client_request(int purpose, int compressed, size_t bytes) case DIR_PURPOSE_UPLOAD_DIR: kind = "dl/ul-dir"; break; case DIR_PURPOSE_UPLOAD_VOTE: kind = "dl/ul-vote"; break; case DIR_PURPOSE_UPLOAD_SIGNATURES: kind = "dl/ul-sig"; break; - case DIR_PURPOSE_FETCH_RENDDESC: kind = "dl/rend"; break; case DIR_PURPOSE_FETCH_RENDDESC_V2: kind = "dl/rend2"; break; - case DIR_PURPOSE_UPLOAD_RENDDESC: kind = "dl/ul-rend"; break; case DIR_PURPOSE_UPLOAD_RENDDESC_V2: kind = "dl/ul-rend2"; break; } if (kind) { diff --git a/src/or/or.h b/src/or/or.h index cc4e5ed9d..c47ae23ed 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -400,13 +400,10 @@ typedef enum { #define CONTROL_CONN_STATE_NEEDAUTH 2 #define CONTROL_CONN_STATE_MAX_ 2 -#define DIR_PURPOSE_MIN_ 3 -/** A connection to a directory server: download a rendezvous - * descriptor. */ -#define DIR_PURPOSE_FETCH_RENDDESC 3 -/** A connection to a directory server: set after a rendezvous +#define DIR_PURPOSE_MIN_ 4 +/** A connection to a directory server: set after a v2 rendezvous * descriptor is downloaded. */ -#define DIR_PURPOSE_HAS_FETCHED_RENDDESC 4 +#define DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2 4 /** A connection to a directory server: download one or more server * descriptors. */ #define DIR_PURPOSE_FETCH_SERVERDESC 6 @@ -415,9 +412,6 @@ typedef enum { #define DIR_PURPOSE_FETCH_EXTRAINFO 7 /** A connection to a directory server: upload a server descriptor. */ #define DIR_PURPOSE_UPLOAD_DIR 8 -/** A connection to a directory server: upload a rendezvous - * descriptor. */ -#define DIR_PURPOSE_UPLOAD_RENDDESC 9 /** A connection to a directory server: upload a v3 networkstatus vote. */ #define DIR_PURPOSE_UPLOAD_VOTE 10 /** A connection to a directory server: upload a v3 consensus signature */ @@ -451,7 +445,6 @@ typedef enum { * directory server. */ #define DIR_PURPOSE_IS_UPLOAD(p) \ ((p)==DIR_PURPOSE_UPLOAD_DIR || \ - (p)==DIR_PURPOSE_UPLOAD_RENDDESC || \ (p)==DIR_PURPOSE_UPLOAD_VOTE || \ (p)==DIR_PURPOSE_UPLOAD_SIGNATURES) @@ -2599,8 +2592,6 @@ typedef enum { V1_DIRINFO = 1 << 0, /** Serves/signs v3 directory information: votes, consensuses, certs */ V3_DIRINFO = 1 << 2, - /** Serves hidden service descriptors. */ - HIDSERV_DIRINFO = 1 << 3, /** Serves bridge descriptors. */ BRIDGE_DIRINFO = 1 << 4, /** Serves extrainfo documents. */ diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 2327a547c..24d720c91 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -796,8 +796,7 @@ rend_client_cancel_descriptor_fetches(void) SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) { if (conn->type == CONN_TYPE_DIR && - (conn->purpose == DIR_PURPOSE_FETCH_RENDDESC || - conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2)) { + conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) { /* It's a rendezvous descriptor fetch in progress -- cancel it * by marking the connection for close. * diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index d1b49411c..384d028ae 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -843,7 +843,7 @@ void rend_cache_purge(void) { if (rend_cache) { - log_info(LD_REND, "Purging client/v0-HS-authority HS descriptor cache"); + log_info(LD_REND, "Purging HS descriptor cache"); strmap_free(rend_cache, rend_cache_entry_free_); } rend_cache = strmap_new(); @@ -954,27 +954,6 @@ rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e) return 1; } -/** query is a base32'ed service id. If it's malformed, return -1. - * Else look it up. - * - If it is found, point *desc to it, and write its length into - * *desc_len, and return 1. - * - If it is not found, return 0. - * Note: calls to rend_cache_clean or rend_cache_store may invalidate - * *desc. - */ -int -rend_cache_lookup_desc(const char *query, int version, const char **desc, - size_t *desc_len) -{ - rend_cache_entry_t *e; - int r; - r = rend_cache_lookup_entry(query,version,&e); - if (r <= 0) return r; - *desc = e->desc; - *desc_len = e->len; - return 1; -} - /** Lookup the v2 service descriptor with base32-encoded desc_id and * copy the pointer to it to *desc. Return 1 on success, 0 on * well-formed-but-not-found, and -1 on failure. @@ -1006,118 +985,6 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc) * descriptor */ #define MAX_INTRO_POINTS 10 -/** Parse *desc, calculate its service id, and store it in the cache. - * If we have a newer v0 descriptor with the same ID, ignore this one. - * If we have an older descriptor with the same ID, replace it. - * If we are acting as client due to the published flag and have any v2 - * descriptor with the same ID, reject this one in order to not get - * confused with having both versions for the same service. - * - * Return -2 if it's malformed or otherwise rejected; return -1 if we - * already have a v2 descriptor here; return 0 if it's the same or older - * than one we've already got; return 1 if it's novel. - * - * The published flag tells us if we store the descriptor - * in our role as directory (1) or if we cache it as client (0). - * - * If service_id is non-NULL and the descriptor is not for that - * service ID, reject it. service_id must be specified if and - * only if published is 0 (we fetched this descriptor). - */ -int -rend_cache_store(const char *desc, size_t desc_len, int published, - const char *service_id) -{ - rend_cache_entry_t *e; - rend_service_descriptor_t *parsed; - char query[REND_SERVICE_ID_LEN_BASE32+1]; - char key[REND_SERVICE_ID_LEN_BASE32+2]; /* 0\0 */ - time_t now; - tor_assert(rend_cache); - parsed = rend_parse_service_descriptor(desc,desc_len); - if (!parsed) { - log_warn(LD_PROTOCOL,"Couldn't parse service descriptor."); - return -2; - } - if (rend_get_service_id(parsed->pk, query)<0) { - log_warn(LD_BUG,"Couldn't compute service ID."); - rend_service_descriptor_free(parsed); - return -2; - } - if ((service_id != NULL) && strcmp(query, service_id)) { - log_warn(LD_REND, "Received service descriptor for service ID %s; " - "expected descriptor for service ID %s.", - query, safe_str(service_id)); - rend_service_descriptor_free(parsed); - return -2; - } - now = time(NULL); - if (parsed->timestamp < now-REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) { - log_fn(LOG_PROTOCOL_WARN, LD_REND, - "Service descriptor %s is too old.", - safe_str_client(query)); - rend_service_descriptor_free(parsed); - return -2; - } - if (parsed->timestamp > now+REND_CACHE_MAX_SKEW) { - log_fn(LOG_PROTOCOL_WARN, LD_REND, - "Service descriptor %s is too far in the future.", - safe_str_client(query)); - rend_service_descriptor_free(parsed); - return -2; - } - /* Do we have a v2 descriptor and fetched this descriptor as a client? */ - tor_snprintf(key, sizeof(key), "2%s", query); - if (!published && strmap_get_lc(rend_cache, key)) { - log_info(LD_REND, "We already have a v2 descriptor for service %s.", - safe_str_client(query)); - rend_service_descriptor_free(parsed); - return -1; - } - if (parsed->intro_nodes && - smartlist_len(parsed->intro_nodes) > MAX_INTRO_POINTS) { - log_warn(LD_REND, "Found too many introduction points on a hidden " - "service descriptor for %s. This is probably a (misguided) " - "attempt to improve reliability, but it could also be an " - "attempt to do a guard enumeration attack. Rejecting.", - safe_str_client(query)); - rend_service_descriptor_free(parsed); - return -2; - } - tor_snprintf(key, sizeof(key), "0%s", query); - e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key); - if (e && e->parsed->timestamp > parsed->timestamp) { - log_info(LD_REND,"We already have a newer service descriptor %s with the " - "same ID and version.", - safe_str_client(query)); - rend_service_descriptor_free(parsed); - return 0; - } - if (e && e->len == desc_len && tor_memeq(desc,e->desc,desc_len)) { - log_info(LD_REND,"We already have this service descriptor %s.", - safe_str_client(query)); - e->received = time(NULL); - rend_service_descriptor_free(parsed); - return 0; - } - if (!e) { - e = tor_malloc_zero(sizeof(rend_cache_entry_t)); - strmap_set_lc(rend_cache, key, e); - } else { - rend_service_descriptor_free(e->parsed); - tor_free(e->desc); - } - e->received = time(NULL); - e->parsed = parsed; - e->len = desc_len; - e->desc = tor_malloc(desc_len); - memcpy(e->desc, desc, desc_len); - - log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.", - safe_str_client(query), (int)desc_len); - return 1; -} - /** Parse the v2 service descriptor(s) in desc and store it/them to the * local rend cache. Don't attempt to decrypt the included list of introduction * points (as we don't have a descriptor cookie for it). @@ -1239,12 +1106,10 @@ rend_cache_store_v2_desc_as_dir(const char *desc) * * If we have a newer v2 descriptor with the same ID, ignore this one. * If we have an older descriptor with the same ID, replace it. - * If we have any v0 descriptor with the same ID, reject this one in order - * to not get confused with having both versions for the same service. * If the descriptor's service ID does not match * rend_query-\>onion_address, reject it. - * Return -2 if it's malformed or otherwise rejected; return -1 if we - * already have a v0 descriptor here; return 0 if it's the same or older + * Return -2 if it's malformed or otherwise rejected; + * return 0 if it's the same or older * than one we've already got; return 1 if it's novel. */ int @@ -1360,14 +1225,6 @@ rend_cache_store_v2_desc_as_client(const char *desc, retval = -2; goto err; } - /* Do we have a v0 descriptor? */ - tor_snprintf(key, sizeof(key), "0%s", service_id); - if (strmap_get_lc(rend_cache, key)) { - log_info(LD_REND, "We already have a v0 descriptor for service ID %s.", - safe_str_client(service_id)); - retval = -1; - goto err; - } /* Do we already have a newer descriptor? */ tor_snprintf(key, sizeof(key), "2%s", service_id); e = (rend_cache_entry_t*) strmap_get_lc(rend_cache, key); diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index f476593d2..b5f49c66e 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -39,13 +39,9 @@ void rend_cache_clean_v2_descs_as_dir(time_t now); void rend_cache_purge(void); void rend_cache_free_all(void); int rend_valid_service_id(const char *query); -int rend_cache_lookup_desc(const char *query, int version, const char **desc, - size_t *desc_len); int rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **entry_out); int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc); -int rend_cache_store(const char *desc, size_t desc_len, int published, - const char *service_id); int rend_cache_store_v2_desc_as_client(const char *desc, const rend_data_t *rend_query); int rend_cache_store_v2_desc_as_dir(const char *desc); -- cgit v1.2.3 From c024ff86719c24958433974a86e982ddc5a982d4 Mon Sep 17 00:00:00 2001 From: Karsten Loesing Date: Fri, 14 Feb 2014 17:54:16 +0100 Subject: Remove another unused v0 hidserv function. Noted by Nick on #10841. --- src/or/rendcommon.c | 73 ----------------------------------------------------- src/or/rendcommon.h | 2 -- 2 files changed, 75 deletions(-) diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 384d028ae..490529509 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -672,79 +672,6 @@ rend_encode_v2_descriptors(smartlist_t *descs_out, return seconds_valid; } -/** Parse a service descriptor at str (len bytes). On - * success, return a newly alloced service_descriptor_t. On failure, - * return NULL. - */ -rend_service_descriptor_t * -rend_parse_service_descriptor(const char *str, size_t len) -{ - rend_service_descriptor_t *result = NULL; - 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; - end = str+len; - if (end-cp<2) goto truncated; - result->version = 0; - if (end-cp < 2) goto truncated; - asn1len = ntohs(get_uint16(cp)); - cp += 2; - if ((size_t)(end-cp) < asn1len) goto truncated; - result->pk = crypto_pk_asn1_decode(cp, asn1len); - if (!result->pk) goto truncated; - cp += asn1len; - if (end-cp < 4) goto truncated; - result->timestamp = (time_t) ntohl(get_uint32(cp)); - cp += 4; - result->protocols = 1<<2; /* always use intro format 2 */ - if (end-cp < 2) goto truncated; - n_intro_points = ntohs(get_uint16(cp)); - cp += 2; - - result->intro_nodes = smartlist_new(); - for (i=0;iextend_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); - if ((size_t)(end-cp) < keylen) goto truncated; - if ((size_t)(end-cp) > keylen) { - log_warn(LD_PROTOCOL, - "Signature is %d bytes too long on service descriptor.", - (int)((size_t)(end-cp) - keylen)); - goto error; - } - note_crypto_pk_op(REND_CLIENT); - if (crypto_pk_public_checksig_digest(result->pk, - (char*)str,cp-str, /* data */ - (char*)cp,end-cp /* signature*/ - )<0) { - log_warn(LD_PROTOCOL, "Bad signature on service descriptor."); - goto error; - } - - return result; - truncated: - log_warn(LD_PROTOCOL, "Truncated service descriptor."); - error: - rend_service_descriptor_free(result); - return NULL; -} - /** Sets out to the first 10 bytes of the digest of pk, * base32 encoded. NUL-terminates out. (We use this string to * identify services in directory requests and .onion URLs.) diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index b5f49c66e..a955cfa32 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -26,8 +26,6 @@ void rend_process_relay_cell(circuit_t *circ, const crypt_path_t *layer_hint, const uint8_t *payload); void rend_service_descriptor_free(rend_service_descriptor_t *desc); -rend_service_descriptor_t *rend_parse_service_descriptor(const char *str, - size_t len); int rend_get_service_id(crypto_pk_t *pk, char *out); void rend_encoded_v2_service_descriptor_free( rend_encoded_v2_service_descriptor_t *desc); -- cgit v1.2.3 From ac5ae794bd58aafcf0dddfaa09abd2184b11bbde Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 14 Feb 2014 23:23:53 -0500 Subject: tristate->enum in rendcommon functions When we have more than two return values, we should really be using an enum rather than "-2 means this, -1 means that, 0 means this, and 1 or more means a number." --- src/or/directory.c | 9 ++++++--- src/or/rendcommon.c | 42 +++++++++++++++++------------------------- src/or/rendcommon.h | 12 ++++++++++-- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/or/directory.c b/src/or/directory.c index 6924bec91..739885c76 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -2094,13 +2094,15 @@ connection_dir_client_reached_eof(dir_connection_t *conn) switch (status_code) { case 200: switch (rend_cache_store_v2_desc_as_client(body, conn->rend_data)) { - case -2: + case RCS_BADDESC: + case RCS_NOTDIR: /* Impossible */ log_warn(LD_REND,"Fetching v2 rendezvous descriptor failed. " "Retrying at another directory."); /* We'll retry when connection_about_to_close_connection() * cleans this dir conn up. */ SEND_HS_DESC_FAILED_EVENT(); break; + case RCS_OKAY: default: /* success. notify pending connections about this. */ log_info(LD_REND, "Successfully fetched v2 rendezvous " @@ -3241,19 +3243,20 @@ directory_handle_command_post(dir_connection_t *conn, const char *headers, connection_dir_is_encrypted(conn) && !strcmpstart(url,"/tor/rendezvous2/publish")) { switch (rend_cache_store_v2_desc_as_dir(body)) { - case -2: + case RCS_NOTDIR: log_info(LD_REND, "Rejected v2 rend descriptor (length %d) from %s " "since we're not currently a hidden service directory.", (int)body_len, conn->base_.address); write_http_status_line(conn, 503, "Currently not acting as v2 " "hidden service directory"); break; - case -1: + case RCS_BADDESC: log_warn(LD_REND, "Rejected v2 rend descriptor (length %d) from %s.", (int)body_len, conn->base_.address); write_http_status_line(conn, 400, "Invalid v2 service descriptor rejected"); break; + case RCS_OKAY: default: write_http_status_line(conn, 200, "Service descriptor (v2) stored"); log_info(LD_REND, "Handled v2 rendezvous descriptor post: accepted"); diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 490529509..a664b5d50 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -918,12 +918,10 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc) * * If we have a newer descriptor with the same ID, ignore this one. * If we have an older descriptor with the same ID, replace it. - * Return -2 if we are not acting as hidden service directory; - * return -1 if the descriptor(s) were not parsable; return 0 if all - * descriptors are the same or older than those we've already got; - * return a positive number for the number of novel stored descriptors. + * + * Return an appropriate rend_cache_store_status_t. */ -int +rend_cache_store_status_t rend_cache_store_v2_desc_as_dir(const char *desc) { rend_service_descriptor_t *parsed; @@ -943,7 +941,7 @@ rend_cache_store_v2_desc_as_dir(const char *desc) /* Cannot store descs, because we are (currently) not acting as * hidden service directory. */ log_info(LD_REND, "Cannot store descs: Not acting as hs dir"); - return -2; + return RCS_NOTDIR; } while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content, &intro_size, &encoded_size, @@ -1019,11 +1017,11 @@ rend_cache_store_v2_desc_as_dir(const char *desc) } if (!number_parsed) { log_info(LD_REND, "Could not parse any descriptor."); - return -1; + return RCS_BADDESC; } log_info(LD_REND, "Parsed %d and added %d descriptor%s.", number_parsed, number_stored, number_stored != 1 ? "s" : ""); - return number_stored; + return RCS_OKAY; } /** Parse the v2 service descriptor in desc, decrypt the included list @@ -1035,11 +1033,10 @@ rend_cache_store_v2_desc_as_dir(const char *desc) * If we have an older descriptor with the same ID, replace it. * If the descriptor's service ID does not match * rend_query-\>onion_address, reject it. - * Return -2 if it's malformed or otherwise rejected; - * return 0 if it's the same or older - * than one we've already got; return 1 if it's novel. + * + * Return an appropriate rend_cache_store_status_t. */ -int +rend_cache_store_status_t rend_cache_store_v2_desc_as_client(const char *desc, const rend_data_t *rend_query) { @@ -1068,7 +1065,7 @@ rend_cache_store_v2_desc_as_client(const char *desc, char key[REND_SERVICE_ID_LEN_BASE32+2]; char service_id[REND_SERVICE_ID_LEN_BASE32+1]; rend_cache_entry_t *e; - int retval; + rend_cache_store_status_t retval = RCS_BADDESC; tor_assert(rend_cache); tor_assert(desc); /* Parse the descriptor. */ @@ -1076,20 +1073,17 @@ rend_cache_store_v2_desc_as_client(const char *desc, &intro_size, &encoded_size, &next_desc, desc) < 0) { log_warn(LD_REND, "Could not parse descriptor."); - retval = -2; goto err; } /* Compute service ID from public key. */ if (rend_get_service_id(parsed->pk, service_id)<0) { log_warn(LD_REND, "Couldn't compute service ID."); - retval = -2; goto err; } if (strcmp(rend_query->onion_address, service_id)) { log_warn(LD_REND, "Received service descriptor for service ID %s; " "expected descriptor for service ID %s.", service_id, safe_str(rend_query->onion_address)); - retval = -2; goto err; } /* Decode/decrypt introduction points. */ @@ -1121,7 +1115,6 @@ rend_cache_store_v2_desc_as_client(const char *desc, log_warn(LD_REND, "Failed to parse introduction points. Either the " "service has published a corrupt descriptor or you have " "provided invalid authorization data."); - retval = -2; goto err; } else if (n_intro_points > MAX_INTRO_POINTS) { log_warn(LD_REND, "Found too many introduction points on a hidden " @@ -1129,7 +1122,7 @@ rend_cache_store_v2_desc_as_client(const char *desc, "attempt to improve reliability, but it could also be an " "attempt to do a guard enumeration attack. Rejecting.", safe_str_client(rend_query->onion_address)); - retval = -2; + goto err; } } else { @@ -1142,14 +1135,12 @@ rend_cache_store_v2_desc_as_client(const char *desc, if (parsed->timestamp < now - REND_CACHE_MAX_AGE-REND_CACHE_MAX_SKEW) { log_warn(LD_REND, "Service descriptor with service ID %s is too old.", safe_str_client(service_id)); - retval = -2; goto err; } /* Is descriptor too far in the future? */ if (parsed->timestamp > now + REND_CACHE_MAX_SKEW) { log_warn(LD_REND, "Service descriptor with service ID %s is too far in " "the future.", safe_str_client(service_id)); - retval = -2; goto err; } /* Do we already have a newer descriptor? */ @@ -1159,16 +1150,14 @@ rend_cache_store_v2_desc_as_client(const char *desc, log_info(LD_REND, "We already have a newer service descriptor for " "service ID %s with the same desc ID and version.", safe_str_client(service_id)); - retval = 0; - goto err; + goto okay; } /* Do we already have this descriptor? */ if (e && !strcmp(desc, e->desc)) { log_info(LD_REND,"We already have this service descriptor %s.", safe_str_client(service_id)); e->received = time(NULL); - retval = 0; - goto err; + goto okay; } if (!e) { e = tor_malloc_zero(sizeof(rend_cache_entry_t)); @@ -1184,7 +1173,10 @@ rend_cache_store_v2_desc_as_client(const char *desc, e->len = encoded_size; log_debug(LD_REND,"Successfully stored rend desc '%s', len %d.", safe_str_client(service_id), (int)encoded_size); - return 1; + return RCS_OKAY; + + okay: + retval = RCS_OKAY; err: rend_service_descriptor_free(parsed); diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index a955cfa32..07a47accf 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -40,9 +40,17 @@ int rend_valid_service_id(const char *query); int rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **entry_out); int rend_cache_lookup_v2_desc_as_dir(const char *query, const char **desc); -int rend_cache_store_v2_desc_as_client(const char *desc, +/** Return value from rend_cache_store_v2_desc_as_{dir,client}. */ +typedef enum { + RCS_NOTDIR = -2, /**< We're not a directory */ + RCS_BADDESC = -1, /**< This descriptor is no good. */ + RCS_OKAY = 0 /**< All worked as expected */ +} rend_cache_store_status_t; + +rend_cache_store_status_t rend_cache_store_v2_desc_as_dir(const char *desc); +rend_cache_store_status_t rend_cache_store_v2_desc_as_client(const char *desc, const rend_data_t *rend_query); -int rend_cache_store_v2_desc_as_dir(const char *desc); + int rend_encode_v2_descriptors(smartlist_t *descs_out, rend_service_descriptor_t *desc, time_t now, uint8_t period, rend_auth_type_t auth_type, -- cgit v1.2.3