[tor-commits] [tor/release-0.4.4] Carry TLS error strings forward to controller when reporting them.

nickm at torproject.org nickm at torproject.org
Thu Jul 2 14:15:11 UTC 2020


commit 7b5f58a1c93f99ef3eaa840b4443ca0a4120a512
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Jun 26 11:18:38 2020 -0400

    Carry TLS error strings forward to controller when reporting them.
    
    Now instead of saying "DONE, DONE" or "MISC, MISC" or "TLS_ERROR,
    TLS_ERROR",  we can finally give a nice sensible "TLS_ERROR,
    wrong version number" which should help debug a great deal.
    
    Closes ticket 32622.
---
 src/core/or/connection_or.c  | 14 ++++++++++----
 src/lib/tls/tortls.h         |  1 +
 src/lib/tls/tortls_nss.c     | 13 +++++++++++++
 src/lib/tls/tortls_openssl.c | 20 ++++++++++++++++++++
 src/lib/tls/tortls_st.h      |  3 +++
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/core/or/connection_or.c b/src/core/or/connection_or.c
index 4cb83f45a..b88d1b6af 100644
--- a/src/core/or/connection_or.c
+++ b/src/core/or/connection_or.c
@@ -745,10 +745,16 @@ connection_or_about_to_close(or_connection_t *or_conn)
         int reason = tls_error_to_orconn_end_reason(or_conn->tls_error);
         connection_or_event_status(or_conn, OR_CONN_EVENT_FAILED,
                                    reason);
-        if (!authdir_mode_tests_reachability(options))
-          control_event_bootstrap_prob_or(
-                orconn_end_reason_to_control_string(reason),
-                reason, or_conn);
+        if (!authdir_mode_tests_reachability(options)) {
+          const char *warning = NULL;
+          if (reason == END_OR_CONN_REASON_TLS_ERROR && or_conn->tls) {
+            warning = tor_tls_get_last_error_msg(or_conn->tls);
+          }
+          if (warning == NULL) {
+            warning = orconn_end_reason_to_control_string(reason);
+          }
+          control_event_bootstrap_prob_or(warning, reason, or_conn);
+        }
       }
     }
   } else if (conn->hold_open_until_flushed) {
diff --git a/src/lib/tls/tortls.h b/src/lib/tls/tortls.h
index e8dbbf527..517cdc17d 100644
--- a/src/lib/tls/tortls.h
+++ b/src/lib/tls/tortls.h
@@ -81,6 +81,7 @@ void tor_tls_free_all(void);
 void tor_tls_init(void);
 void tls_log_errors(tor_tls_t *tls, int severity, int domain,
                     const char *doing);
+const char *tor_tls_get_last_error_msg(const tor_tls_t *tls);
 int tor_tls_context_init(unsigned flags,
                          crypto_pk_t *client_identity,
                          crypto_pk_t *server_identity,
diff --git a/src/lib/tls/tortls_nss.c b/src/lib/tls/tortls_nss.c
index 62e826211..a9ec731c0 100644
--- a/src/lib/tls/tortls_nss.c
+++ b/src/lib/tls/tortls_nss.c
@@ -369,6 +369,8 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain,
 
   (void)tls;
   PRErrorCode code = PORT_GetError();
+  if (tls)
+    tls->last_error = code;
 
   const char *addr = tls ? tls->address : NULL;
   const char *string = PORT_ErrorToString(code);
@@ -391,6 +393,17 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain,
            with, addr);
   }
 }
+const char *
+tor_tls_get_last_error_msg(const tor_tls_t *tls)
+{
+  IF_BUG_ONCE(!tls) {
+    return NULL;
+  }
+  if (tls->last_error == 0) {
+    return NULL;
+  }
+  return PORT_ErrorToString((PRErrorCode)tls->last_error);
+}
 
 tor_tls_t *
 tor_tls_new(tor_socket_t sock, int is_server)
diff --git a/src/lib/tls/tortls_openssl.c b/src/lib/tls/tortls_openssl.c
index 68d6e2aa5..226971414 100644
--- a/src/lib/tls/tortls_openssl.c
+++ b/src/lib/tls/tortls_openssl.c
@@ -245,10 +245,30 @@ tls_log_errors(tor_tls_t *tls, int severity, int domain, const char *doing)
   unsigned long err;
 
   while ((err = ERR_get_error()) != 0) {
+    if (tls)
+      tls->last_error = err;
     tor_tls_log_one_error(tls, err, severity, domain, doing);
   }
 }
 
+/**
+ * Return a string representing more detail about the last error received
+ * on TLS.
+ *
+ * May return null if no error was found.
+ **/
+const char *
+tor_tls_get_last_error_msg(const tor_tls_t *tls)
+{
+  IF_BUG_ONCE(!tls) {
+    return NULL;
+  }
+  if (tls->last_error == 0) {
+    return NULL;
+  }
+  return (const char*)ERR_reason_error_string(tls->last_error);
+}
+
 #define CATCH_SYSCALL 1
 #define CATCH_ZERO    2
 
diff --git a/src/lib/tls/tortls_st.h b/src/lib/tls/tortls_st.h
index 925896d49..34abe52ee 100644
--- a/src/lib/tls/tortls_st.h
+++ b/src/lib/tls/tortls_st.h
@@ -67,6 +67,8 @@ struct tor_tls_t {
    */
   unsigned long last_write_count;
   unsigned long last_read_count;
+  /** Most recent error value from ERR_get_error(). */
+  unsigned long last_error;
   /** If set, a callback to invoke whenever the client tries to renegotiate
    * the handshake. */
   void (*negotiated_callback)(tor_tls_t *tls, void *arg);
@@ -77,6 +79,7 @@ struct tor_tls_t {
   /** Last values retried from tor_get_prfiledesc_byte_counts(). */
   uint64_t last_write_count;
   uint64_t last_read_count;
+  long last_error;
 #endif
 };
 





More information about the tor-commits mailing list