mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Merge branch 'nss_27451'
This commit is contained in:
commit
e43ae24e7d
@ -638,8 +638,19 @@ connection_free_minimal(connection_t *conn)
|
|||||||
|
|
||||||
if (connection_speaks_cells(conn)) {
|
if (connection_speaks_cells(conn)) {
|
||||||
or_connection_t *or_conn = TO_OR_CONN(conn);
|
or_connection_t *or_conn = TO_OR_CONN(conn);
|
||||||
tor_tls_free(or_conn->tls);
|
if (or_conn->tls) {
|
||||||
or_conn->tls = NULL;
|
if (! SOCKET_OK(conn->s)) {
|
||||||
|
/* The socket has been closed by somebody else; we must tell the
|
||||||
|
* TLS object not to close it. */
|
||||||
|
tor_tls_release_socket(or_conn->tls);
|
||||||
|
} else {
|
||||||
|
/* The tor_tls_free() call below will close the socket; we must tell
|
||||||
|
* the code below not to close it a second time. */
|
||||||
|
conn->s = TOR_INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
tor_tls_free(or_conn->tls);
|
||||||
|
or_conn->tls = NULL;
|
||||||
|
}
|
||||||
or_handshake_state_free(or_conn->handshake_state);
|
or_handshake_state_free(or_conn->handshake_state);
|
||||||
or_conn->handshake_state = NULL;
|
or_conn->handshake_state = NULL;
|
||||||
tor_free(or_conn->nickname);
|
tor_free(or_conn->nickname);
|
||||||
|
@ -94,6 +94,7 @@ void tor_tls_set_renegotiate_callback(tor_tls_t *tls,
|
|||||||
void (*cb)(tor_tls_t *, void *arg),
|
void (*cb)(tor_tls_t *, void *arg),
|
||||||
void *arg);
|
void *arg);
|
||||||
int tor_tls_is_server(tor_tls_t *tls);
|
int tor_tls_is_server(tor_tls_t *tls);
|
||||||
|
void tor_tls_release_socket(tor_tls_t *tls);
|
||||||
void tor_tls_free_(tor_tls_t *tls);
|
void tor_tls_free_(tor_tls_t *tls);
|
||||||
#define tor_tls_free(tls) FREE_AND_NULL(tor_tls_t, tor_tls_free_, (tls))
|
#define tor_tls_free(tls) FREE_AND_NULL(tor_tls_t, tor_tls_free_, (tls))
|
||||||
int tor_tls_peer_has_cert(tor_tls_t *tls);
|
int tor_tls_peer_has_cert(tor_tls_t *tls);
|
||||||
|
@ -414,6 +414,43 @@ tor_tls_set_renegotiate_callback(tor_tls_t *tls,
|
|||||||
/* We don't support renegotiation-based TLS with NSS. */
|
/* We don't support renegotiation-based TLS with NSS. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the TLS library that the underlying socket for <b>tls</b> has been
|
||||||
|
* closed, and the library should not attempt to free that socket itself.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tor_tls_release_socket(tor_tls_t *tls)
|
||||||
|
{
|
||||||
|
if (! tls)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* NSS doesn't have the equivalent of BIO_NO_CLOSE. If you replace the
|
||||||
|
* fd with something that's invalid, it causes a memory leak in PR_Close.
|
||||||
|
*
|
||||||
|
* If there were a way to put the PRFileDesc into the CLOSED state, that
|
||||||
|
* would prevent it from closing its fd -- but there doesn't seem to be a
|
||||||
|
* supported way to do that either.
|
||||||
|
*
|
||||||
|
* So instead: we make a new sacrificial socket, and replace the original
|
||||||
|
* socket with that one. This seems to be the best we can do, until we
|
||||||
|
* redesign the mainloop code enough to make this function unnecessary.
|
||||||
|
*/
|
||||||
|
tor_socket_t sock =
|
||||||
|
tor_open_socket_nonblocking(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (!sock) {
|
||||||
|
log_warn(LD_NET, "Out of sockets when trying to shut down an NSS "
|
||||||
|
"connection");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRFileDesc *tcp = PR_GetIdentitiesLayer(tls->ssl, PR_NSPR_IO_LAYER);
|
||||||
|
if (BUG(! tcp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PR_ChangeFileDescNativeHandle(tcp, sock);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tor_tls_impl_free_(tor_tls_impl_t *tls)
|
tor_tls_impl_free_(tor_tls_impl_t *tls)
|
||||||
{
|
{
|
||||||
|
@ -1048,7 +1048,7 @@ tor_tls_new(tor_socket_t sock, int isServer)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
result->socket = sock;
|
result->socket = sock;
|
||||||
bio = BIO_new_socket(sock, BIO_NOCLOSE);
|
bio = BIO_new_socket(sock, BIO_CLOSE);
|
||||||
if (! bio) {
|
if (! bio) {
|
||||||
tls_log_errors(NULL, LOG_WARN, LD_NET, "opening BIO");
|
tls_log_errors(NULL, LOG_WARN, LD_NET, "opening BIO");
|
||||||
#ifdef SSL_set_tlsext_host_name
|
#ifdef SSL_set_tlsext_host_name
|
||||||
@ -1154,6 +1154,28 @@ tor_tls_assert_renegotiation_unblocked(tor_tls_t *tls)
|
|||||||
#endif /* defined(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) && ... */
|
#endif /* defined(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) && ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the TLS library that the underlying socket for <b>tls</b> has been
|
||||||
|
* closed, and the library should not attempt to free that socket itself.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tor_tls_release_socket(tor_tls_t *tls)
|
||||||
|
{
|
||||||
|
if (! tls)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BIO *rbio, *wbio;
|
||||||
|
rbio = SSL_get_rbio(tls->ssl);
|
||||||
|
wbio = SSL_get_wbio(tls->ssl);
|
||||||
|
|
||||||
|
if (rbio) {
|
||||||
|
BIO_set_close(rbio, BIO_NOCLOSE);
|
||||||
|
}
|
||||||
|
if (wbio && wbio != rbio) {
|
||||||
|
BIO_set_close(wbio, BIO_NOCLOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tor_tls_impl_free_(tor_tls_impl_t *ssl)
|
tor_tls_impl_free_(tor_tls_impl_t *ssl)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user