[or-cvs] tls infrastructure now in place, give or take

Roger Dingledine arma at seul.org
Mon Sep 8 10:59:02 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	connection.c connection_ap.c connection_or.c directory.c 
	main.c or.h 
Log Message:
tls infrastructure now in place, give or take


Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -d -r1.81 -r1.82
--- connection.c	7 Sep 2003 10:24:40 -0000	1.81
+++ connection.c	8 Sep 2003 10:59:00 -0000	1.82
@@ -68,6 +68,7 @@
 
 /********* END VARIABLES ************/
 
+static int connection_init_accepted_conn(connection_t *conn);
 
 /**************************************************************/
 
@@ -183,7 +184,7 @@
     return -1;
   }
 
-  log_fn(LOG_DEBUG,"Listening on port %u.",ntohs(bindaddr->sin_port));
+  log_fn(LOG_DEBUG,"%s listening on port %u.",conn_type_to_string[type], ntohs(bindaddr->sin_port));
 
   conn->state = LISTENER_STATE_READY;
   connection_start_reading(conn);
@@ -191,7 +192,7 @@
   return 0;
 }
 
-int connection_handle_listener_read(connection_t *conn, int new_type, int new_state) {
+int connection_handle_listener_read(connection_t *conn, int new_type) {
 
   int news; /* the new socket */
   connection_t *newconn;
@@ -237,12 +238,73 @@
     return 0; /* no need to tear down the parent */
   }
 
-  log(LOG_DEBUG,"connection_handle_listener_read(): socket %d entered state %d.",newconn->s, new_state);
-  newconn->state = new_state;
-  connection_start_reading(newconn);
+  if(connection_init_accepted_conn(newconn) < 0) {
+    connection_free(newconn);
+    return 0;
+  }
+  return 0;
+}
+
+static int connection_init_accepted_conn(connection_t *conn) {
+
+  connection_start_reading(conn);
+
+  switch(conn->type) {
+    case CONN_TYPE_OR:
+#ifdef USE_TLS
+      if(connection_tls_start_handshake(conn) < 0)
+        return -1;
+#else
+      conn->state = OR_CONN_STATE_SERVER_AUTH_WAIT;
+#endif
+      break;
+    case CONN_TYPE_AP:
+      conn->state = AP_CONN_STATE_SOCKS_WAIT;
+      break;
+    case CONN_TYPE_DIR:
+      conn->state = DIR_CONN_STATE_COMMAND_WAIT;
+      break;
+  }
+  return 0;
+}
+
+#ifdef USE_TLS
+int connection_tls_start_handshake(connection_t *conn) {
+  conn->state = OR_CONN_STATE_HANDSHAKING;
+  conn->tls = tor_tls_new(conn->s, options.OnionRouter);
+  if(!conn->tls) {
+    log_fn(LOG_ERR,"tor_tls_new failed. Closing.");
+    return -1;
+  }
+  connection_start_reading(conn);
+  if(connection_tls_continue_handshake(conn) < 0)
+    return -1;
+  return 0;
+}
 
+int connection_tls_continue_handshake(connection_t *conn) {
+  switch(tor_tls_handshake(conn->tls)) {
+    case TOR_TLS_ERROR:
+    case TOR_TLS_CLOSE:
+      log_fn(LOG_DEBUG,"tls error. breaking.");
+      return -1;
+    case TOR_TLS_DONE:
+      conn->state = OR_CONN_STATE_OPEN;
+      directory_set_dirty();
+      connection_watch_events(conn, POLLIN);
+      if(!options.OnionRouter)
+        circuit_n_conn_open(conn); /* send the pending create */
+      log_fn(LOG_DEBUG,"tls handshake done, now open.");
+      return 0;
+    case TOR_TLS_WANTWRITE:
+      connection_start_writing(conn);
+      return 0;
+    case TOR_TLS_WANTREAD: /* handshaking conns are *always* reading */
+      return 0;
+  }
   return 0;
 }
+#endif
 
 /* start all connections that should be up but aren't */
 int retry_all_connections(uint16_t or_listenport, uint16_t ap_listenport, uint16_t dir_listenport) {
@@ -259,14 +321,14 @@
   if(or_listenport) {
     bindaddr.sin_port = htons(or_listenport);
     if(!connection_get_by_type(CONN_TYPE_OR_LISTENER)) {
-      connection_or_create_listener(&bindaddr);
+      connection_create_listener(&bindaddr, CONN_TYPE_OR_LISTENER);
     }
   }
 
   if(dir_listenport) {
     bindaddr.sin_port = htons(dir_listenport);
     if(!connection_get_by_type(CONN_TYPE_DIR_LISTENER)) {
-      connection_dir_create_listener(&bindaddr);
+      connection_create_listener(&bindaddr, CONN_TYPE_DIR_LISTENER);
     }
   }
  
@@ -274,7 +336,7 @@
     bindaddr.sin_port = htons(ap_listenport);
     bindaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* the AP listens only on localhost! */
     if(!connection_get_by_type(CONN_TYPE_AP_LISTENER)) {
-      connection_ap_create_listener(&bindaddr);
+      connection_create_listener(&bindaddr, CONN_TYPE_AP_LISTENER);
     }
   }
 
@@ -289,31 +351,30 @@
 
   switch(conn->type) {
     case CONN_TYPE_OR_LISTENER:
-      return connection_or_handle_listener_read(conn);
+      return connection_handle_listener_read(conn, CONN_TYPE_OR);
     case CONN_TYPE_AP_LISTENER:
-      return connection_ap_handle_listener_read(conn);
+      return connection_handle_listener_read(conn, CONN_TYPE_AP);
     case CONN_TYPE_DIR_LISTENER:
-      return connection_dir_handle_listener_read(conn);
-    default:
+      return connection_handle_listener_read(conn, CONN_TYPE_DIR);
+  }
 
-      if(connection_read_to_buf(conn) < 0) {
-        if(conn->type == CONN_TYPE_DIR && conn->state == DIR_CONN_STATE_CONNECTING) {
-           /* it's a directory server and connecting failed: forget about this router */
-           /* XXX I suspect pollerr may make Windows not get to this point. :( */
-           router_forget_router(conn->addr,conn->port); 
-             /* FIXME i don't think router_forget_router works. */
-        }
-        return -1;
-      }
-      if(connection_process_inbuf(conn) < 0) {
-        //log_fn(LOG_DEBUG,"connection_process_inbuf returned %d.",retval);
-        return -1;
-      }
-      if(!connection_state_is_open(conn) && conn->receiver_bucket == 0) {
-        log_fn(LOG_DEBUG,"receiver bucket reached 0 before handshake finished. Closing.");
-        return -1;
-      }
-  } /* end switch */
+  if(connection_read_to_buf(conn) < 0) {
+    if(conn->type == CONN_TYPE_DIR && conn->state == DIR_CONN_STATE_CONNECTING) {
+       /* it's a directory server and connecting failed: forget about this router */
+       /* XXX I suspect pollerr may make Windows not get to this point. :( */
+       router_forget_router(conn->addr,conn->port); 
+         /* FIXME i don't think router_forget_router works. */
+    }
+    return -1;
+  }
+  if(connection_process_inbuf(conn) < 0) {
+    //log_fn(LOG_DEBUG,"connection_process_inbuf returned %d.",retval);
+    return -1;
+  }
+  if(!connection_state_is_open(conn) && conn->receiver_bucket == 0) {
+    log_fn(LOG_DEBUG,"receiver bucket reached 0 before handshake finished. Closing.");
+    return -1;
+  }
   return 0;
 }
 
@@ -344,26 +405,22 @@
 
 #ifdef USE_TLS
   if(connection_speaks_cells(conn) && conn->state != OR_CONN_STATE_CONNECTING) {
-    if(conn->state == OR_CONN_STATE_HANDSHAKING) {
-      result = tor_tls_handshake(conn->tls)
-      if(result == TOR_TLS_DONE) {
-        conn->state = OR_CONN_STATE_OPEN;
-        log_fn(LOG_DEBUG,"tls handshake done, now open.");
-      }
-    } else { /* open, or closing */
-      result = read_to_buf_tls(conn->tls, at_most, &conn->inbuf,
-                                    &conn->inbuflen, &conn->inbuf_datalen);
-    }
+    if(conn->state == OR_CONN_STATE_HANDSHAKING)
+      return connection_tls_continue_handshake(conn);
+
+    /* else open, or closing */
+    result = read_to_buf_tls(conn->tls, at_most, &conn->inbuf,
+                             &conn->inbuflen, &conn->inbuf_datalen);
 
     switch(result) {
       case TOR_TLS_ERROR:
       case TOR_TLS_CLOSE:
         log_fn(LOG_DEBUG,"tls error. breaking.");
         return -1; /* XXX deal with close better */
-      case TOR_TLS_WANT_WRITE:
+      case TOR_TLS_WANTWRITE:
         connection_start_writing(conn);
         return 0;
-      case TOR_TLS_WANT_READ: /* we're already reading */
+      case TOR_TLS_WANTREAD: /* we're already reading */
       case TOR_TLS_DONE: /* no data read, so nothing to process */
         return 0;
     }
@@ -413,7 +470,6 @@
 /* return -1 if you want to break the conn, else return 0 */
 int connection_handle_write(connection_t *conn) {
   struct timeval now;
-  int result;
 
   if(connection_is_listener(conn)) {
     log_fn(LOG_DEBUG,"Got a listener socket. Can't happen!");
@@ -425,26 +481,20 @@
 
 #ifdef USE_TLS
   if(connection_speaks_cells(conn) && conn->state != OR_CONN_STATE_CONNECTING) {
-    if(conn->state == OR_CONN_STATE_HANDSHAKING) {
-      result = tor_tls_handshake(conn->tls)
-      if(result == TOR_TLS_DONE) {
-        conn->state = OR_CONN_STATE_OPEN;
-        log_fn(LOG_DEBUG,"tls handshake done, now open.");
-      }
-    } else { /* open, or closing */
-      result = flush_buf_tls(conn->tls, &conn->outbuf, &conn->outbuflen,
-                             &conn->outbuf_flushlen, &conn->outbuf_datalen);
-    }
+    if(conn->state == OR_CONN_STATE_HANDSHAKING)
+      return connection_tls_continue_handshake(conn);
 
-    switch(result) {
+    /* else open, or closing */
+    switch(flush_buf_tls(conn->tls, &conn->outbuf, &conn->outbuflen,
+                         &conn->outbuf_flushlen, &conn->outbuf_datalen)) {
       case TOR_TLS_ERROR:
       case TOR_TLS_CLOSE:
         log_fn(LOG_DEBUG,"tls error. breaking.");
         return -1; /* XXX deal with close better */
-      case TOR_TLS_WANT_WRITE:
+      case TOR_TLS_WANTWRITE:
         /* we're already writing */
         return 0;
-      case TOR_TLS_WANT_READ:
+      case TOR_TLS_WANTREAD:
         /* Make sure to avoid a loop if the receive buckets are empty. */
         if(!connection_is_reading(conn)) {
           connection_stop_writing(conn);
@@ -766,7 +816,9 @@
   /* check if there's a whole cell there.
    * if yes, pull it off, decrypt it if we're not doing TLS, and process it.
    */
+#ifndef USE_TLS
   char networkcell[CELL_NETWORK_SIZE];
+#endif
   char buf[CELL_NETWORK_SIZE];
 //  int x;
   cell_t cell;

Index: connection_ap.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_ap.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- connection_ap.c	25 Jun 2003 00:31:41 -0000	1.46
+++ connection_ap.c	8 Sep 2003 10:59:00 -0000	1.47
@@ -159,16 +159,6 @@
   return connection_flush_buf(conn); /* try to flush it, in case we're about to close the conn */
 }
 
-int connection_ap_create_listener(struct sockaddr_in *bindaddr) {
-  log_fn(LOG_DEBUG,"starting");
-  return connection_create_listener(bindaddr, CONN_TYPE_AP_LISTENER);
-}
-
-int connection_ap_handle_listener_read(connection_t *conn) {
-  log(LOG_NOTICE,"AP: Received a connection request. Waiting for socksinfo.");
-  return connection_handle_listener_read(conn, CONN_TYPE_AP, AP_CONN_STATE_SOCKS_WAIT);
-} 
-
 /*
   Local Variables:
   mode:c

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_or.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- connection_or.c	7 Sep 2003 10:24:40 -0000	1.42
+++ connection_or.c	8 Sep 2003 10:59:00 -0000	1.43
@@ -17,8 +17,8 @@
 static int or_handshake_server_process_nonce(connection_t *conn);
 
 static void conn_or_init_crypto(connection_t *conn);
-#endif
 static void connection_or_set_open(connection_t *conn);
+#endif
 
 /*
  *
@@ -85,7 +85,8 @@
           conn->address,conn->port);
 
 #ifdef USE_TLS
-      call TLS new, and start the TLS handshake
+      if(connection_tls_start_handshake(conn) < 0)
+        return -1;
 #else
       if(options.OnionRouter)
         return or_handshake_client_send_auth(conn);
@@ -182,7 +183,11 @@
       connection_watch_events(conn, POLLIN | POLLOUT | POLLERR); 
       /* writable indicates finish, readable indicates broken link,
          error indicates broken link on windows */
+#ifdef USE_TLS
+      conn->state = OR_CONN_STATE_CONNECTING;
+#else
       conn->state = OR_CONN_STATE_CLIENT_CONNECTING;
+#endif
       return conn;
     }
   }
@@ -198,9 +203,14 @@
   log(LOG_DEBUG,"connection_or_connect() : Connection to router %s:%u established.",
       router->address, router->or_port);
 
+#ifdef USE_TLS
+  if(connection_tls_start_handshake(conn) >= 0)
+    return conn;
+#else
   if((options.OnionRouter && or_handshake_client_send_auth(conn) >= 0) ||
      (!options.OnionRouter && or_handshake_op_send_keys(conn) >= 0))
     return conn; /* success! */
+#endif
 
   /* failure */
   connection_remove(conn);
@@ -210,17 +220,7 @@
 
 /* ********************************** */
 
-int connection_or_create_listener(struct sockaddr_in *bindaddr) {
-  log(LOG_DEBUG,"connection_create_or_listener starting");
-  return connection_create_listener(bindaddr, CONN_TYPE_OR_LISTENER);
-}
-
-int connection_or_handle_listener_read(connection_t *conn) {
-  log(LOG_NOTICE,"OR: Received a connection request. Attempting to authenticate.");
-  return connection_handle_listener_read(conn, CONN_TYPE_OR, OR_CONN_STATE_SERVER_AUTH_WAIT);
-}
-
-/* ***************** */
+#ifndef USE_TLS
 /* Helper functions to implement handshaking */
 
 #define FLAGS_LEN 2
@@ -237,7 +237,7 @@
 
   assert(conn && conn->type == CONN_TYPE_OR);
 
-  conn->bandwidth = DEFAULT_BANDWIDTH_OP;
+  conn->bandwidth = DEFAULT_BANDWIDTH_OP; /* XXX USE_TLS */
 
   /* generate random keys */
   if(crypto_cipher_generate_key(conn->f_crypto) ||
@@ -520,7 +520,7 @@
     crypto_cipher_set_key(conn->b_crypto,buf+14);
     crypto_cipher_set_key(conn->f_crypto,buf+30);
 
-    conn->bandwidth = router->bandwidth;
+    conn->bandwidth = router->bandwidth; /* XXX USE_TLS and below */
 
     /* copy all relevant info to conn */
     conn->addr = router->addr, conn->port = router->or_port;
@@ -665,7 +665,6 @@
   connection_watch_events(conn, POLLIN);
 }
 
-#ifndef USE_TLS
 static void 
 conn_or_init_crypto(connection_t *conn) {
   //int x;

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- directory.c	14 Aug 2003 17:13:51 -0000	1.22
+++ directory.c	8 Sep 2003 10:59:00 -0000	1.23
@@ -290,16 +290,6 @@
   return 0;
 }
 
-int connection_dir_create_listener(struct sockaddr_in *bindaddr) {
-  log_fn(LOG_DEBUG,"starting");
-  return connection_create_listener(bindaddr, CONN_TYPE_DIR_LISTENER);
-}
-
-int connection_dir_handle_listener_read(connection_t *conn) {
-  log(LOG_INFO,"Dir: Received a connection request. Waiting for command.");
-  return connection_handle_listener_read(conn, CONN_TYPE_DIR, DIR_CONN_STATE_COMMAND_WAIT);
-} 
-
 /*
   Local Variables:
   mode:c

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- main.c	8 Sep 2003 06:26:37 -0000	1.89
+++ main.c	8 Sep 2003 10:59:00 -0000	1.90
@@ -462,7 +462,7 @@
       }
     }
 
-    if(tor_tls_context_new(certfile, get_privatekey(), 1) < 0) {
+    if(tor_tls_context_new(options.CertFile, get_privatekey(), 1) < 0) {
       log_fn(LOG_ERR,"Error creating tls context.");
       return -1;
     }

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -d -r1.116 -r1.117
--- or.h	8 Sep 2003 06:26:38 -0000	1.116
+++ or.h	8 Sep 2003 10:59:00 -0000	1.117
@@ -131,7 +131,7 @@
 #define CPUWORKER_TASK_ONION CPUWORKER_STATE_BUSY_ONION
 #define CPUWORKER_TASK_HANDSHAKE CPUWORKER_STATE_BUSY_HANDSHAKE
 
-#ifndef TOR_TLS
+#ifndef USE_TLS
 /* how to read these states:
  * foo_CONN_STATE_bar_baz:
  * "I am acting as a bar, currently in stage baz of talking with a foo."
@@ -303,7 +303,7 @@
   crypto_pk_env_t *pkey; /* public RSA key for the other side */
 
 /* Used only by OR connections: */
-#ifdef TOR_TLS
+#ifdef USE_TLS
   tor_tls *tls;
 #else
   /* link encryption */
@@ -578,7 +578,10 @@
 
 int connection_create_listener(struct sockaddr_in *bindaddr, int type);
 
-int connection_handle_listener_read(connection_t *conn, int new_type, int new_state);
+int connection_handle_listener_read(connection_t *conn, int new_type);
+
+int connection_tls_start_handshake(connection_t *conn);
+int connection_tls_continue_handshake(connection_t *conn);
 
 /* start all connections that should be up but aren't */
 int retry_all_connections(uint16_t or_listenport, uint16_t ap_listenport, uint16_t dir_listenport);
@@ -631,10 +634,6 @@
 
 int ap_handshake_socks_reply(connection_t *conn, char result);
 
-int connection_ap_create_listener(struct sockaddr_in *bindaddr);
-
-int connection_ap_handle_listener_read(connection_t *conn);
-
 /********************************* connection_edge.c ***************************/
 
 int connection_edge_process_inbuf(connection_t *conn);
@@ -649,18 +648,6 @@
 
 int connection_exit_connect(connection_t *conn);
 
-/********************************* connection_op.c ***************************/
-
-int op_handshake_process_keys(connection_t *conn);
-
-int connection_op_process_inbuf(connection_t *conn);
-
-int connection_op_finished_flushing(connection_t *conn);
-
-int connection_op_create_listener(struct sockaddr_in *bindaddr);
-
-int connection_op_handle_listener_read(connection_t *conn);
-
 /********************************* connection_or.c ***************************/
 
 int connection_or_process_inbuf(connection_t *conn);
@@ -668,9 +655,6 @@
 
 connection_t *connection_or_connect(routerinfo_t *router);
 
-int connection_or_create_listener(struct sockaddr_in *bindaddr);
-int connection_or_handle_listener_read(connection_t *conn);
-
 /********************************* cpuworker.c *****************************/
 
 void cpu_init(void);
@@ -690,8 +674,6 @@
 int directory_handle_command(connection_t *conn);
 int directory_handle_reading(connection_t *conn);
 int connection_dir_finished_flushing(connection_t *conn);
-int connection_dir_create_listener(struct sockaddr_in *bindaddr);
-int connection_dir_handle_listener_read(connection_t *conn);
 
 /********************************* dns.c ***************************/
 



More information about the tor-commits mailing list