Prechádzať zdrojové kódy

Detect renegotiation when it actually happens.

The renegotiation callback was called only when the first Application
Data arrived, instead of when the renegotiation took place.

This happened because SSL_read() returns -1 and sets the error to
SSL_ERROR_WANT_READ when a renegotiation happens instead of reading
data [0].

I also added a commented out aggressive assert that I won't enable yet
because I don't feel I understand SSL_ERROR_WANT_READ enough.

[0]: Look at documentation of SSL_read(), SSL_get_error() and
     SSL_CTX_set_mode() (SSL_MODE_AUTO_RETRY section).
George Kadianakis 14 rokov pred
rodič
commit
4fd79f9def
1 zmenil súbory, kde vykonal 19 pridanie a 10 odobranie
  1. 19 10
      src/common/tortls.c

+ 19 - 10
src/common/tortls.c

@@ -1606,19 +1606,28 @@ tor_tls_read(tor_tls_t *tls, char *cp, size_t len)
   tor_assert(tls->state == TOR_TLS_ST_OPEN);
   tor_assert(len<INT_MAX);
   r = SSL_read(tls->ssl, cp, (int)len);
-  if (r > 0) {
+  if (r > 0) /* return the number of characters read */
+    return r;
+
+  /* If we got here, SSL_read() did not go as expected. */
+
+  err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_DEBUG, LD_NET);
+
 #ifdef V2_HANDSHAKE_SERVER
-    if (tls->got_renegotiate) {
-      /* Renegotiation happened! */
-      log_info(LD_NET, "Got a TLS renegotiation from %s", ADDR(tls));
-      if (tls->negotiated_callback)
-        tls->negotiated_callback(tls, tls->callback_arg);
-      tls->got_renegotiate = 0;
-    }
-#endif
+  if (tls->got_renegotiate) {
+    tor_assert(tls->server_handshake_count == 2);
+    /* XXX tor_assert(err == TOR_TLS_WANTREAD); */
+
+    /* Renegotiation happened! */
+    log_info(LD_NET, "Got a TLS renegotiation from %s", ADDR(tls));
+    if (tls->negotiated_callback)
+      tls->negotiated_callback(tls, tls->callback_arg);
+    tls->got_renegotiate = 0;
+
     return r;
   }
-  err = tor_tls_get_error(tls, r, CATCH_ZERO, "reading", LOG_DEBUG, LD_NET);
+#endif
+
   if (err == _TOR_TLS_ZERORETURN || err == TOR_TLS_CLOSE) {
     log_debug(LD_NET,"read returned r=%d; TLS is closed",r);
     tls->state = TOR_TLS_ST_CLOSED;