aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-06-02 20:00:57 +0000
committerNick Mathewson <nickm@torproject.org>2004-06-02 20:00:57 +0000
commit65e26bae3d8cbee189135ed09918e1560f3cf3e6 (patch)
tree5d082e4642c8ebd57f9c80be473964e46ba98f18
parent43c404ca681259427a367a9da15fed5de19c086c (diff)
downloadtor-65e26bae3d8cbee189135ed09918e1560f3cf3e6.tar.gz
tor-65e26bae3d8cbee189135ed09918e1560f3cf3e6.zip
Check directory signatures based on name of signer, not on whom we got the directory from.
svn:r1940
-rw-r--r--src/or/directory.c2
-rw-r--r--src/or/or.h2
-rw-r--r--src/or/routerlist.c10
-rw-r--r--src/or/routerparse.c21
4 files changed, 28 insertions, 7 deletions
diff --git a/src/or/directory.c b/src/or/directory.c
index 2890736f1f..3119a3fb7b 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -336,7 +336,7 @@ int connection_dir_process_inbuf(connection_t *conn) {
connection_mark_for_close(conn);
return -1;
}
- if(router_load_routerlist_from_directory(body, conn->identity_pkey) < 0){
+ if(router_load_routerlist_from_directory(body, NULL) < 0){
log_fn(LOG_INFO,"...but parsing failed. Ignoring.");
} else {
log_fn(LOG_INFO,"updated routers.");
diff --git a/src/or/or.h b/src/or/or.h
index 7548bf4e2c..7eee5a789b 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -578,6 +578,8 @@ typedef struct {
* published?
*/
time_t published_on;
+ /** Which router is claimed to have signed it? */
+ char *signing_router;
} routerlist_t;
/** Holds accounting information for a single step in the layered encryption
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index b2cc910fc1..e221ec4a43 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -212,7 +212,8 @@ routerinfo_t *router_get_by_nickname(char *nickname)
routerinfo_t *router;
tor_assert(nickname);
- tor_assert(routerlist);
+ if (!routerlist)
+ return NULL;
for(i=0;i<smartlist_len(routerlist->routers);i++) {
router = smartlist_get(routerlist->routers, i);
@@ -446,9 +447,10 @@ int router_load_routerlist_from_string(const char *s, int trusted)
}
/** Add to the current routerlist each router stored in the
- * signed directory <b>s</b>. If pkey is provided, make sure that <b>s</b> is
- * signed with pkey. */
-int router_load_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey)
+ * signed directory <b>s</b>. If pkey is provided, check the signature against
+ * pkey; else check against the pkey of the signing directory server. */
+int router_load_routerlist_from_directory(const char *s,
+ crypto_pk_env_t *pkey)
{
routerlist_t *new_list = NULL;
check_software_version_against_directory(s, options.IgnoreVersion);
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index c239a613e2..1304975015 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -366,10 +366,27 @@ router_parse_routerlist_from_directory(const char *str,
}
if (smartlist_len(tokens) != 1 ||
- ((directory_token_t*)smartlist_get(tokens,0))->tp != K_DIRECTORY_SIGNATURE){
+ (!(tok=smartlist_get(tokens,0))) || /* always succeeds */
+ (tok->tp != K_DIRECTORY_SIGNATURE)) {
log_fn(LOG_WARN,"Expected a single directory signature"); goto err;
}
- tok = smartlist_get(tokens,0);
+ if (tok->n_args == 1) {
+ routerinfo_t *r = router_get_by_nickname(tok->args[0]);
+ log_fn(LOG_DEBUG, "Got directory signed by %s", tok->args[0]);
+ if (r && r->is_trusted_dir) {
+ pkey = r->identity_pkey;
+ } else if (!r && pkey) {
+ /* pkey provided for debugging purposes. */
+ } else if (!r) {
+ log_fn(LOG_WARN, "Directory was signed by unrecognized server %s",
+ tok->args[0]);
+ goto err;
+ } else if (r && !r->is_trusted_dir) {
+ log_fn(LOG_WARN, "Directory was signed by non-trusted server %s",
+ tok->args[0]);
+ goto err;
+ }
+ }
if (strcmp(tok->object_type, "SIGNATURE") || tok->object_size != 128) {
log_fn(LOG_WARN, "Bad object type or length on directory signature");
goto err;