Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ticket32622 044 #1955

Open
wants to merge 5 commits into
base: maint-0.4.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions changes/ticket32622
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions src/core/mainloop/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
18 changes: 13 additions & 5 deletions src/core/or/connection_or.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -1692,7 +1698,8 @@ connection_tls_continue_handshake(or_connection_t *conn)

switch (result) {
CASE_TOR_TLS_ERROR_ANY:
log_info(LD_OR,"tls error [%s]. breaking connection.",
conn->tls_error = result;
log_info(LD_OR,"tls error [%s]. breaking connection.",
tor_tls_err_to_string(result));
return -1;
case TOR_TLS_DONE:
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/or/or.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
4 changes: 4 additions & 0 deletions src/core/or/reasons.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions src/lib/tls/tortls.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
13 changes: 13 additions & 0 deletions src/lib/tls/tortls_nss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
20 changes: 20 additions & 0 deletions src/lib/tls/tortls_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 3 additions & 0 deletions src/lib/tls/tortls_st.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
};

Expand Down