From e547ab293b291933128419682ad3dcb537e67df5 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Wed, 21 Jul 2004 02:25:14 +0000 Subject: [PATCH] make connection_tls_finish_handshake() more plausible. now we accept connections from unknown routers. svn:r2074 --- src/or/circuitbuild.c | 2 +- src/or/connection_edge.c | 2 +- src/or/connection_or.c | 39 +++++++++++++++++++-------------------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 980c4410cd..0efdd3c5c5 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -957,7 +957,7 @@ static routerinfo_t *choose_good_exit_server(uint8_t purpose, routerlist_t *dir) } /** Allocate a cpath_build_state_t, populate it based on - * purpose and exit_nickname (if specified), and + * purpose and exit_digest (if specified), and * return it. */ static cpath_build_state_t * diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index ab430d39a2..f2c9d05a73 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -941,7 +941,7 @@ int connection_ap_can_use_exit(connection_t *conn, routerinfo_t *exit) if (conn->socks_request->command == SOCKS_COMMAND_RESOLVE) { /* 0.0.7 servers and earlier don't support DNS resolution. There are no * ORs running code before 0.0.7, so we only worry about 0.0.7. Once all - * servers are running 0.0.8, remove this check. */ + * servers are running 0.0.8, remove this check. XXX */ return strncmp(exit->platform, "Tor 0.0.7", 9) ? 1 : 0; } addr = client_dns_lookup_entry(conn->socks_request->address); diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 860eaff4b7..6960afd996 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -245,6 +245,12 @@ int connection_tls_continue_handshake(connection_t *conn) { return 0; } +static int digest_is_nonzero(const char *id) { + char ZERO_DIGEST[DIGEST_LEN]; + memset(ZERO_DIGEST, 0, DIGEST_LEN); + return !memcmp(ZERO_DIGEST, id, DIGEST_LEN); +} + /** The tls handshake is finished. * * Make sure we are happy with the person we just handshaked with: @@ -270,6 +276,7 @@ connection_tls_finish_handshake(connection_t *conn) { char nickname[MAX_NICKNAME_LEN+1]; connection_t *c; crypto_pk_env_t *identity_rcvd=NULL; + char digest_rcvd[DIGEST_LEN]; conn->state = OR_CONN_STATE_OPEN; connection_watch_events(conn, POLLIN); @@ -291,32 +298,24 @@ connection_tls_finish_handshake(connection_t *conn) { } log_fn(LOG_DEBUG, "Other side (%s:%d) claims to be '%s'", conn->address, conn->port, nickname); - router = router_get_by_nickname(nickname); - /* XXX008 here we need to tolerate unknown routers, so ORs can - * connect to us even when we don't know they're verified. This - * should probably be a call to router_get_by_digest() now, since - * we can't trust the nickname some guy shows up with. */ - if (!router) { - log_fn(LOG_INFO, "Unrecognized router with nickname '%s' at %s:%d", - nickname, conn->address, conn->port); - return -1; - } - if(tor_tls_verify(conn->tls, &identity_rcvd)<0) { + + if(tor_tls_verify(conn->tls, &identity_rcvd) < 0) { log_fn(LOG_WARN,"Other side '%s' (%s:%d) has a cert but it's invalid. Closing.", nickname, conn->address, conn->port); return -1; } log_fn(LOG_DEBUG,"The router's cert is valid."); - if(crypto_pk_cmp_keys(identity_rcvd, router->identity_pkey) != 0) { - crypto_free_pk_env(identity_rcvd); + crypto_pk_get_digest(identity_rcvd, digest_rcvd); + crypto_free_pk_env(identity_rcvd); + + router = router_get_by_nickname(nickname); + if(router && /* we know this nickname; make sure it's the right guy */ + memcmp(digest_rcvd, router->identity_digest, DIGEST_LEN) != 0) { log_fn(LOG_WARN, "Identity key not as expected for %s", nickname); return -1; } - crypto_free_pk_env(identity_rcvd); - /* XXXX008 This isn't right; fix this one we launch by identity digest - * XXXX008 rather than by nickname */ - if (conn->nickname) { + if (digest_is_nonzero(conn->identity_digest)) { /* I initiated this connection. */ if (strcasecmp(conn->nickname, nickname)) { log_fn(options.DirPort ? LOG_WARN : LOG_INFO, @@ -325,11 +324,11 @@ connection_tls_finish_handshake(connection_t *conn) { return -1; } } else { - if((c=connection_get_by_identity_digest(router->identity_digest, CONN_TYPE_OR))) { - log_fn(LOG_INFO,"Router %s is already connected on fd %d. Dropping fd %d.", router->nickname, c->s, conn->s); + if((c=connection_get_by_identity_digest(digest_rcvd, CONN_TYPE_OR))) { + log_fn(LOG_INFO,"Router %s is already connected on fd %d. Dropping fd %d.", nickname, c->s, conn->s); return -1; } - connection_or_init_conn_from_router(conn,router); + connection_or_init_conn_from_address(conn,conn->addr,conn->port,digest_rcvd); } if (!server_mode()) { /* If I'm an OP... */