You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by cl...@apache.org on 2022/05/12 14:12:37 UTC
[qpid-proton] branch main updated: PROTON-1870: openssl layer: flush TLS error alert to peer for better error reporting
This is an automated email from the ASF dual-hosted git repository.
cliffjansen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
The following commit(s) were added to refs/heads/main by this push:
new dfebbe8c PROTON-1870: openssl layer: flush TLS error alert to peer for better error reporting
dfebbe8c is described below
commit dfebbe8c10666fecb65f74c99199fc7e013997ef
Author: Clifford Jansen <cl...@apache.org>
AuthorDate: Thu May 12 07:11:45 2022 -0700
PROTON-1870: openssl layer: flush TLS error alert to peer for better error reporting
---
c/src/ssl/openssl.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/c/src/ssl/openssl.c b/c/src/ssl/openssl.c
index b4b75645..2681d2d6 100644
--- a/c/src/ssl/openssl.c
+++ b/c/src/ssl/openssl.c
@@ -114,6 +114,7 @@ struct pni_ssl_t {
bool ssl_closed; // shutdown complete, or SSL error
bool read_blocked; // SSL blocked until more network data is read
bool write_blocked; // SSL blocked until data is written to network
+ int err_reason;
char *subject;
X509 *peer_certificate;
@@ -193,14 +194,30 @@ static void ssl_log_clear_data(pn_transport_t *transport, const char *data, size
}
// unrecoverable SSL failure occurred, notify transport and generate error code.
-static int ssl_failed(pn_transport_t *transport)
+static int ssl_failed(pn_transport_t *transport, int reason)
{
pni_ssl_t *ssl = transport->ssl;
- SSL_set_shutdown(ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
- ssl->ssl_closed = true;
+ bool first_fail = true;
+ if (ssl->err_reason != 0)
+ first_fail = false; // No need for second transport error event.
+ else
+ ssl->err_reason = reason;
+
ssl->app_input_closed = ssl->app_output_closed = PN_EOS;
// fake a shutdown so the i/o processing code will close properly
SSL_set_shutdown(ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
+
+ if (first_fail && reason == SSL_ERROR_SSL) {
+ // Protocol error. Toss input and pending app output but best efforts for SSL generated output (i.e. error alerts)
+ ssl->out_count = 0; // Discard. No more writing into SSL engine allowed.
+ } else {
+ // SSL_ERROR_SYS or unknown error. SSL engine state unknown. Stop IO in all directions immediately.
+ ssl->ssl_closed = true;
+ }
+ // transport->io_layers[layer] is updated in handle_error_ssl
+ if (!first_fail)
+ return PN_EOS;
+
// try to grab the first SSL error to add to the failure log
char buf[256] = "Unknown error";
unsigned long ssl_err = ERR_get_error();
@@ -208,6 +225,7 @@ static int ssl_failed(pn_transport_t *transport)
ERR_error_string_n( ssl_err, buf, sizeof(buf) );
}
ssl_log_flush(transport, PN_LEVEL_ERROR); // spit out any remaining errors to the log file
+ // Following call invokes hanlde_error_ssl which sets transport->io_layers[layer]
pn_do_error(transport, "amqp:connection:framing-error", "SSL Failure: %s", buf);
return PN_EOS;
}
@@ -1059,7 +1077,7 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
break;
default:
// unexpected error
- return (ssize_t)ssl_failed(transport);
+ return (ssize_t)ssl_failed(transport, reason);
}
} else {
if (BIO_should_write( ssl->bio_ssl )) {
@@ -1152,7 +1170,12 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer,
static void handle_error_ssl(pn_transport_t *transport, unsigned int layer)
{
- transport->io_layers[layer] = &ssl_closed_layer;
+ // External errors do not affect SSL operation and graceful shutdown.
+ if (transport->ssl->err_reason == SSL_ERROR_SSL) {
+ transport->io_layers[layer] = &ssl_input_closed_layer;
+ } else {
+ transport->io_layers[layer] = &ssl_closed_layer;
+ }
}
static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer, char *buffer, size_t max_len)
@@ -1209,7 +1232,7 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer
break;
default:
// unexpected error
- return (ssize_t)ssl_failed(transport);
+ return (ssize_t)ssl_failed(transport, reason);
}
} else {
if (BIO_should_read( ssl->bio_ssl )) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org