Remove remaining v0 hidden service descriptor code.

Fixes the rest of #10841 after #10881 already removed some hidden service
authority code.
This commit is contained in:
Karsten Loesing 2014-02-12 14:36:08 +01:00
parent 1ccc282122
commit 74c2bff781
6 changed files with 25 additions and 247 deletions

6
changes/bug10841 Normal file
View file

@ -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.

View file

@ -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 <b>dir_purpose</b> and uploading <b>payload</b>
* (of length <b>payload_len</b>). The dir_purpose should be one of
* 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
* 'DIR_PURPOSE_UPLOAD_{DIR|VOTE|SIGNATURES}'.
*
* <b>router_purpose</b> describes the type of descriptor we're
* publishing, if we're publishing a descriptor -- e.g. general or bridge.
*
* <b>type</b> specifies what sort of dir authorities (V1, V3,
* HIDSERV, BRIDGE, etc) we should upload to.
* BRIDGE, etc) we should upload to.
*
* If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
* <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
@ -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. <b>dir_purpose</b> determines what
* kind of directory connection we're launching, and must be one of
* DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC|RENDDESC_V2}. <b>router_purpose</b>
* DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC_V2}. <b>router_purpose</b>
* 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) {

View file

@ -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. */

View file

@ -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.
*

View file

@ -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;
}
/** <b>query</b> 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 <b>desc_id</b> and
* copy the pointer to it to *<b>desc</b>. 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 <b>service_id</b> is non-NULL and the descriptor is not for that
* service ID, reject it. <b>service_id</b> must be specified if and
* only if <b>published</b> 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<query>\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 <b>desc</b> 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
* <b>rend_query</b>-\>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);

View file

@ -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);