summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2008-01-10 17:48:40 +0000
committerNick Mathewson <nickm@torproject.org>2008-01-10 17:48:40 +0000
commit04263648c422af07489a1c55c1972dc91207de46 (patch)
tree2dbb9676b37c025777da42277ed52c40020c4637
parent29b0f51a7387608dd79ff29ffc3f37b7c8543341 (diff)
downloadtor-04263648c422af07489a1c55c1972dc91207de46.tar.gz
tor-04263648c422af07489a1c55c1972dc91207de46.zip
r17554@catbus: nickm | 2008-01-10 12:48:29 -0500
Do not send bridge descriptors over unencrypted connections. svn:r13094
-rw-r--r--ChangeLog4
-rw-r--r--doc/TODO2
-rw-r--r--src/or/directory.c3
-rw-r--r--src/or/dirserv.c35
-rw-r--r--src/or/or.h5
-rw-r--r--src/or/routerlist.c1
-rw-r--r--src/or/routerparse.c7
7 files changed, 48 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index ac4152bdda..ab5d209988 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -54,6 +54,10 @@ Changes in version 0.2.0.16-alpha - 2008-01-??
- Actually implement the -s option to tor-gencert.
- Add a manual page for tor-gencert.
+ o Minor features (bridges):
+ - Bridge authorities no longer serve bridge descriptors over unencrypted
+ connections.
+
o Minor features (other):
- Add hidden services and DNSPorts to the list of things that make
Tor accept that it has running ports. Change starting Tor with
diff --git a/doc/TODO b/doc/TODO
index 6ea761ea55..96ea0771da 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -28,7 +28,7 @@ RK- make it easier to set up a private tor network on your own computer
- Make BEGIN_DIR mandatory for asking questions of bridge authorities?
(but only for bridge descriptors. not for ordinary cache stuff.)
o Implement connection_dir_is_encrypted().
- - set up a filter to not answer any bridge descriptors on a
+ o set up a filter to not answer any bridge descriptors on a
non-encrypted request
o write a tor-gencert man page
diff --git a/src/or/directory.c b/src/or/directory.c
index 19b401f6c2..bff5161c5c 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -2421,7 +2421,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
url += is_extra ? strlen("/tor/extra/") : strlen("/tor/server/");
conn->fingerprint_stack = smartlist_create();
res = dirserv_get_routerdesc_fingerprints(conn->fingerprint_stack, url,
- &msg);
+ &msg,
+ !connection_dir_is_encrypted(conn));
if (!strcmpstart(url, "fp/")) {
request_type = deflated?"/tor/server/fp.z":"/tor/server/fp";
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index a4e29c86cd..ab0d17d7a9 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -57,7 +57,9 @@ dirserv_get_status_impl(const char *fp, const char *nickname,
const char *platform, const char *contact,
const char **msg, int should_log);
static void clear_cached_dir(cached_dir_t *d);
-
+static signed_descriptor_t *get_signed_descriptor_by_fp(const char *fp,
+ int extrainfo,
+ time_t publish_cutoff);
static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg);
/************** Fingerprint handling code ************/
@@ -2571,8 +2573,9 @@ dirserv_get_networkstatus_v2(smartlist_t *result,
*/
int
dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
- const char **msg)
+ const char **msg, int for_unencrypted_conn)
{
+ int by_id = 1;
*msg = NULL;
if (!strcmp(key, "all")) {
@@ -2586,6 +2589,7 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
smartlist_add(fps_out,
tor_memdup(ri->cache_info.identity_digest, DIGEST_LEN));
} else if (!strcmpstart(key, "d/")) {
+ by_id = 0;
key += strlen("d/");
dir_split_resource_into_fingerprints(key, fps_out, NULL, 1, 1);
} else if (!strcmpstart(key, "fp/")) {
@@ -2596,6 +2600,19 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
return -1;
}
+ if (for_unencrypted_conn) {
+ /* Remove anything whose purpose isn't general. */
+ SMARTLIST_FOREACH(fps_out, char *, cp, {
+ signed_descriptor_t *sd =
+ by_id ? get_signed_descriptor_by_fp(cp,0,0) :
+ router_get_by_descriptor_digest(cp);
+ if (sd && !sd->send_unencrypted) {
+ tor_free(cp);
+ SMARTLIST_DEL_CURRENT(fps_out, cp);
+ }
+ });
+ }
+
if (!smartlist_len(fps_out)) {
*msg = "Servers unavailable";
return -1;
@@ -2618,12 +2635,12 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
* If -1 is returned *<b>msg</b> will be set to an appropriate error
* message.
*
- * (Despite its name, this function is also called from the controller, which
- * exposes a similar means to fetch descriptors.)
+ * XXXX020 rename this function. IT's only called from the controller.
+ * XXXX020 in fact, refactor this function, mergeing as much as possible.
*/
int
dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
- const char **msg)
+ const char **msg)
{
*msg = NULL;
@@ -2938,6 +2955,14 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
tor_free(fp);
if (!sd)
continue;
+ if (!connection_dir_is_encrypted(conn) && !sd->send_unencrypted) {
+ /* we did this check once before (so we could have an accurate size
+ * estimate and maybe send a 404 if somebody asked for only bridges on a
+ * connection), but we need to do it again in case a previously
+ * unknown bridge descriptor has shown up between then and now. */
+ continue;
+ }
+
body = signed_descriptor_get_body(sd);
if (conn->zlib_state) {
int last = ! smartlist_len(conn->fingerprint_stack);
diff --git a/src/or/or.h b/src/or/or.h
index 33c50c73bb..b96693260b 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1245,6 +1245,8 @@ typedef struct signed_descriptor_t {
/* If true, we got an extrainfo for this item, and the digest was right,
* but it was incompatible. */
unsigned int extrainfo_is_bogus : 1;
+ /* If true, we are willing to transmit this item unencrypted. */
+ unsigned int send_unencrypted : 1;
} signed_descriptor_t;
/** Information about another onion router in the network. */
@@ -3113,7 +3115,8 @@ void dirserv_get_networkstatus_v2(smartlist_t *result, const char *key);
void dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
const char *key);
int dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
- const char **msg);
+ const char **msg,
+ int for_unencrypted_conn);
int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
const char **msg);
void dirserv_orconn_tls_done(const char *address,
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index cada13fb43..e789322b33 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -4226,6 +4226,7 @@ routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
goto err; /* Bad signature, or no match. */
}
+ ei->cache_info.send_unencrypted = ri->cache_info.send_unencrypted;
tor_free(ei->pending_sig);
}
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index eb7949000b..19fbf9fa4c 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1172,6 +1172,8 @@ router_parse_entry_from_string(const char *s, const char *end,
} else {
router->purpose = ROUTER_PURPOSE_GENERAL;
}
+ router->cache_info.send_unencrypted =
+ (router->purpose == ROUTER_PURPOSE_GENERAL) ? 1 : 0;
if ((tok = find_first_by_keyword(tokens, K_UPTIME))) {
tor_assert(tok->n_args >= 1);
@@ -1326,7 +1328,7 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
smartlist_t *tokens = NULL;
directory_token_t *tok;
crypto_pk_env_t *key = NULL;
- routerinfo_t *router;
+ routerinfo_t *router = NULL;
if (!end) {
end = s + strlen(s);
@@ -1405,6 +1407,9 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
if (check_signature_token(digest, tok, key, 0, "extra-info") < 0)
goto err;
+ if (router)
+ extrainfo->cache_info.send_unencrypted =
+ router->cache_info.send_unencrypted;
} else {
extrainfo->pending_sig = tor_memdup(tok->object_body,
tok->object_size);