Browse Source

check for funny business from the remote peer

svn:r445
Roger Dingledine 22 years ago
parent
commit
fa1bfaa349
2 changed files with 44 additions and 7 deletions
  1. 41 7
      src/or/connection.c
  2. 3 0
      src/or/or.h

+ 41 - 7
src/or/connection.c

@@ -319,18 +319,52 @@ static int connection_tls_finish_handshake(connection_t *conn) {
       if (!router) {
       if (!router) {
         log_fn(LOG_INFO,"Unrecognized public key from peer. Closing.");
         log_fn(LOG_INFO,"Unrecognized public key from peer. Closing.");
         crypto_free_pk_env(pk);
         crypto_free_pk_env(pk);
+        return -1;
+      }
+      if(conn->pkey) { /* I initiated this connection. */
+        if(crypto_pk_cmp_keys(conn->pkey, pk)) {
+          log_fn(LOG_INFO,"We connected to '%s' but he gave us a different key. Closing.", router->nickname);
+          crypto_free_pk_env(pk);
+          return -1;
+        }
+        log_fn(LOG_DEBUG,"The router's pk matches the one we meant to connect to. Good.");
+        crypto_free_pk_env(pk);
+      } else {
+        if(connection_exact_get_by_addr_port(router->addr,router->or_port)) {
+          log_fn(LOG_INFO,"That router is already connected. Dropping.");
+          return -1;
+        }
+        conn->pkey = pk;
+        conn->bandwidth = router->bandwidth;
+        conn->addr = router->addr, conn->port = router->or_port;
+        conn->address = strdup(router->address);
       }
       }
-      conn->bandwidth = router->bandwidth;
-      conn->addr = router->addr, conn->port = router->or_port;
-      conn->pkey = pk;
-      if(conn->address)
-        free(conn->address);
-      conn->address = strdup(router->address);
     } else { /* it's an OP */
     } else { /* it's an OP */
       conn->bandwidth = DEFAULT_BANDWIDTH_OP;
       conn->bandwidth = DEFAULT_BANDWIDTH_OP;
     }
     }
   } else { /* I'm a client */
   } else { /* I'm a client */
-    /* XXX Clients should also verify certificates. */
+    if(!tor_tls_peer_has_cert(conn->tls)) { /* it's a client too?! */
+      log_fn(LOG_INFO,"Neither peer sent a cert! Closing.");
+      return -1;
+    }
+    pk = tor_tls_verify(conn->tls);
+    if(!pk) {
+      log_fn(LOG_INFO,"Other side has a cert but it's bad. Closing.");
+      return -1;
+    }
+    router = router_get_by_pk(pk);
+    if (!router) {
+      log_fn(LOG_INFO,"Unrecognized public key from peer. Closing.");
+      crypto_free_pk_env(pk);
+      return -1;
+    }
+    if(crypto_pk_cmp_keys(conn->pkey, pk)) {
+      log_fn(LOG_INFO,"We connected to '%s' but he gave us a different key. Closing.", router->nickname);
+      crypto_free_pk_env(pk);
+      return -1;
+    }
+    log_fn(LOG_DEBUG,"The router's pk matches the one we meant to connect to. Good.");
+    crypto_free_pk_env(pk);
     conn->bandwidth = DEFAULT_BANDWIDTH_OP;
     conn->bandwidth = DEFAULT_BANDWIDTH_OP;
     circuit_n_conn_open(conn); /* send the pending create */
     circuit_n_conn_open(conn); /* send the pending create */
   }
   }

+ 3 - 0
src/or/or.h

@@ -7,6 +7,8 @@
 
 
 #include "orconfig.h"
 #include "orconfig.h"
 
 
+#define USE_TLS
+
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <limits.h>
@@ -351,6 +353,7 @@ struct exit_policy_t {
 /* config stuff we know about the other ORs in the network */
 /* config stuff we know about the other ORs in the network */
 typedef struct {
 typedef struct {
   char *address;
   char *address;
+  char *nickname;
  
  
   uint32_t addr; /* all host order */
   uint32_t addr; /* all host order */
   uint16_t or_port;
   uint16_t or_port;