Merge branch 'ticket32622_044_squashed' into maint-0.4.4

This commit is contained in:
Nick Mathewson 2020-07-02 10:14:55 -04:00
commit 18fa53fdf4
9 changed files with 62 additions and 6 deletions

5
changes/ticket32622 Normal file
View File

@ -0,0 +1,5 @@
o Minor features (bootstrap reporting):
- Report more detailed reasons for bootstrap failure when the failure
happens due to a TLS error. Previously we would just call these errors
"MISC" when they happened during read, and "DONE" when they
happened during any other TLS operation. Closes ticket 32622.

View File

@ -4205,6 +4205,7 @@ connection_handle_write_impl(connection_t *conn, int force)
switch (result) {
CASE_TOR_TLS_ERROR_ANY:
case TOR_TLS_CLOSE:
or_conn->tls_error = result;
log_info(LD_NET, result != TOR_TLS_CLOSE ?
"tls error. breaking.":"TLS connection closed on flush");
/* Don't flush; connection is dead. */

View File

@ -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) {
@ -1692,6 +1698,7 @@ connection_tls_continue_handshake(or_connection_t *conn)
switch (result) {
CASE_TOR_TLS_ERROR_ANY:
conn->tls_error = result;
log_info(LD_OR,"tls error [%s]. breaking connection.",
tor_tls_err_to_string(result));
return -1;
@ -1724,6 +1731,7 @@ connection_tls_continue_handshake(or_connection_t *conn)
log_debug(LD_OR,"wanted read");
return 0;
case TOR_TLS_CLOSE:
conn->tls_error = result;
log_info(LD_OR,"tls closed. breaking connection.");
return -1;
}

View File

@ -220,7 +220,8 @@ struct curve25519_public_key_t;
#define END_OR_CONN_REASON_IO_ERROR 7 /* read/write error */
#define END_OR_CONN_REASON_RESOURCE_LIMIT 8 /* sockets, buffers, etc */
#define END_OR_CONN_REASON_PT_MISSING 9 /* PT failed or not available */
#define END_OR_CONN_REASON_MISC 10
#define END_OR_CONN_REASON_TLS_ERROR 10 /* Problem in TLS protocol */
#define END_OR_CONN_REASON_MISC 11
/* Reasons why we (or a remote OR) might close a stream. See tor-spec.txt for
* documentation of these. The values must match. */

View File

@ -244,6 +244,8 @@ orconn_end_reason_to_control_string(int r)
return "IOERROR";
case END_OR_CONN_REASON_RESOURCE_LIMIT:
return "RESOURCELIMIT";
case END_OR_CONN_REASON_TLS_ERROR:
return "TLS_ERROR";
case END_OR_CONN_REASON_MISC:
return "MISC";
case END_OR_CONN_REASON_PT_MISSING:
@ -276,6 +278,8 @@ tls_error_to_orconn_end_reason(int e)
case TOR_TLS_CLOSE:
case TOR_TLS_DONE:
return END_OR_CONN_REASON_DONE;
case TOR_TLS_ERROR_MISC:
return END_OR_CONN_REASON_TLS_ERROR;
default:
return END_OR_CONN_REASON_MISC;
}

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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
};