[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r13040: Add a reverse mapping from SSL to tor_tls_t*: we need this i (in tor/trunk: . src/common src/or)



Author: nickm
Date: 2008-01-05 22:16:11 -0500 (Sat, 05 Jan 2008)
New Revision: 13040

Modified:
   tor/trunk/
   tor/trunk/src/common/tortls.c
   tor/trunk/src/or/connection_or.c
Log:
 r17473@catbus:  nickm | 2008-01-05 22:15:05 -0500
 Add a reverse mapping from SSL to tor_tls_t*: we need this in order to do a couple of things the sensible way from inside callbacks.  Also, add a couple of missing cases in connection_or.c



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r17473] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/common/tortls.c
===================================================================
--- tor/trunk/src/common/tortls.c	2008-01-06 03:16:08 UTC (rev 13039)
+++ tor/trunk/src/common/tortls.c	2008-01-06 03:16:11 UTC (rev 13040)
@@ -39,6 +39,7 @@
 #include "util.h"
 #include "log.h"
 #include "container.h"
+#include "ht.h"
 #include <string.h>
 
 // #define V2_HANDSHAKE_SERVER
@@ -64,6 +65,7 @@
  * accessed from within tortls.c.
  */
 struct tor_tls_t {
+  HT_ENTRY(tor_tls_t) node;
   tor_tls_context_t *context; /**DOCDOC */
   SSL *ssl; /**< An OpenSSL SSL object. */
   int socket; /**< The underlying file descriptor for this TLS connection. */
@@ -83,6 +85,45 @@
   void *callback_arg;
 };
 
+/** Helper: compare tor_tls_t objects by its SSL. */
+static INLINE int
+tor_tls_entries_eq(const tor_tls_t *a, const tor_tls_t *b)
+{
+  return a->ssl == b->ssl;
+}
+
+/** Helper: return a hash value for a tor_tls_t by its SSL. */
+static INLINE unsigned int
+tor_tls_entry_hash(const tor_tls_t *a)
+{
+#if SIZEOF_INT == SIZEOF_VOID_P
+  return ((unsigned int)a->ssl);
+#else
+  return (unsigned int) ((((uint64_t)a->ssl)>>2) & UINT_MAX);
+#endif
+}
+
+/** Map from SSL* pointers to tor_tls_t objects using those pointers.
+ */
+static HT_HEAD(tlsmap, tor_tls_t) tlsmap_root = HT_INITIALIZER();
+
+HT_PROTOTYPE(tlsmap, tor_tls_t, node, tor_tls_entry_hash,
+             tor_tls_entries_eq)
+HT_GENERATE(tlsmap, tor_tls_t, node, tor_tls_entry_hash,
+            tor_tls_entries_eq, 0.6, malloc, realloc, free)
+
+/** Helper: given a SSL* pointer, return the tor_tls_t object using that
+ * pointer. */
+static INLINE tor_tls_t *
+tor_tls_get_by_ssl(SSL *ssl)
+{
+  tor_tls_t search, *result;
+  memset(&search, 0, sizeof(search));
+  search.ssl = ssl;
+  result = HT_FIND(tlsmap, &tlsmap_root, &search);
+  return result;
+}
+
 static void tor_tls_context_decref(tor_tls_context_t *ctx);
 static void tor_tls_context_incref(tor_tls_context_t *ctx);
 static X509* tor_tls_create_certificate(crypto_pk_env_t *rsa,
@@ -404,8 +445,13 @@
    SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA ":"           \
    TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA ":"     \
    TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA ":"   \
-   SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA ":"     \
+   /*SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA ":"*/ \
    SSL3_TXT_RSA_DES_192_CBC3_SHA)
+/* SSL3_TXT_RSA_FIPS_WITH_3DES_EDE_CBC_SHA is commented out because it doesn't
+ * really exist; if I understand correctly, it's a bit of silliness that
+ * netscape did on its own before any standard for what they wanted was
+ * formally approved.  Nonetheless, Firefox still uses it, so we need to
+ * fake it at some point soon. XXXX020 -NM */
 #else
 /* Ug. We don't have as many ciphers with openssl 0.9.7 as we'd like.  Fix
  * this list into something that sucks less. */
@@ -622,6 +668,7 @@
     return;
 
   if (tor_tls_client_is_using_v2_ciphers(ssl)) {
+    tor_tls_t *tls;
     /* Yes, we're casting away the const from ssl.  This is very naughty of us.
      * Let's hope openssl doesn't notice! */
 
@@ -629,6 +676,13 @@
     SSL_set_mode((SSL*) ssl, SSL_MODE_NO_AUTO_CHAIN);
     /* Don't send a hello request. */
     SSL_set_verify((SSL*) ssl, SSL_VERIFY_NONE, NULL);
+
+    tls = tor_tls_get_by_ssl((SSL*)ssl);
+    if (tls) {
+      tls->wasV2Handshake = 1;
+    } else {
+      log_warn(LD_BUG, "Couldn't look up the tls for an SSL*. How odd!");
+    }
   }
 }
 #endif
@@ -666,6 +720,7 @@
     tor_free(result);
     return NULL;
   }
+  HT_INSERT(tlsmap, &tlsmap_root, result);
   SSL_set_bio(result->ssl, bio, bio);
   tor_tls_context_incref(global_tls_context);
   result->context = global_tls_context;
@@ -707,7 +762,12 @@
 void
 tor_tls_free(tor_tls_t *tls)
 {
+  tor_tls_t *removed;
   tor_assert(tls && tls->ssl);
+  removed = HT_REMOVE(tlsmap, &tlsmap_root, tls);
+  if (!removed) {
+    log_warn(LD_BUG, "Freeing a TLS that was not in the ssl->tls map.");
+  }
   SSL_free(tls->ssl);
   tls->ssl = NULL;
   tls->negotiated_callback = NULL;
@@ -820,9 +880,12 @@
 #ifdef V2_HANDSHAKE_SERVER
       if (tor_tls_client_is_using_v2_ciphers(tls->ssl)) {
         /* This check is redundant, but back when we did it in the callback,
-         * we didn't have access to the tor_tls_t struct.  We could make some
-         * kind of static map linking SSLs to tor_tls_ts, but that way lies
-         * sadness. */
+         * we might have not been able to look up the tor_tls_t if the code
+         * was buggy.  Fixing that. */
+        if (!tls->wasV2Handshake) {
+          log_warn(LD_BUG, "For some reason, wasV2Handshake didn't"
+                   " get set. Fixing that.");
+        }
         tls->wasV2Handshake = 1;
       } else {
         tls->wasV2Handshake = 0;
@@ -836,8 +899,10 @@
       int n_certs = sk_X509_num(chain);
       if (n_certs > 1 || (n_certs == 1 && cert != sk_X509_value(chain, 0)))
         tls->wasV2Handshake = 0;
-      else
+      else {
+        log_notice(LD_NET, "I think I got a v2 handshake!");
         tls->wasV2Handshake = 1;
+      }
 #endif
       SSL_set_cipher_list(tls->ssl, SERVER_CIPHER_LIST);
     }

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2008-01-06 03:16:08 UTC (rev 13039)
+++ tor/trunk/src/or/connection_or.c	2008-01-06 03:16:11 UTC (rev 13040)
@@ -261,6 +261,7 @@
     case OR_CONN_STATE_PROXY_READING:
       return connection_or_read_proxy_response(conn);
     case OR_CONN_STATE_OPEN:
+    case OR_CONN_STATE_OR_HANDSHAKING:
       return connection_or_process_cells_from_inbuf(conn);
     default:
       return 0; /* don't do anything */
@@ -315,6 +316,7 @@
       connection_stop_writing(TO_CONN(conn));
       break;
     case OR_CONN_STATE_OPEN:
+    case OR_CONN_STATE_OR_HANDSHAKING:
       connection_stop_writing(TO_CONN(conn));
       break;
     default: