- Fix to print detailed errors when an SSL IO routine fails via

SSL_get_error.
This commit is contained in:
W.C.A. Wijngaards 2023-10-19 11:17:32 +02:00
parent 44c3d4d2dc
commit 35d0a8a843
9 changed files with 165 additions and 31 deletions

View File

@ -523,12 +523,13 @@ ssl_print_text(RES* res, const char* text)
if(res->ssl) {
ERR_clear_error();
if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) {
if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
int r2;
if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN) {
verbose(VERB_QUERY, "warning, in SSL_write, peer "
"closed connection");
return 0;
}
log_crypto_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", r2);
return 0;
}
} else {
@ -579,11 +580,12 @@ ssl_read_line(RES* res, char* buf, size_t max)
if(res->ssl) {
ERR_clear_error();
if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) {
if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) {
int r2;
if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN) {
buf[len] = 0;
return 1;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", r2);
return 0;
}
} else {
@ -3222,9 +3224,10 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
if(res->ssl) {
ERR_clear_error();
if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) {
if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN)
int r2;
if((r2=SSL_get_error(res->ssl, r)) == SSL_ERROR_ZERO_RETURN)
return;
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", r2);
return;
}
} else {
@ -3291,7 +3294,7 @@ remote_handshake_later(struct daemon_remote* rc, struct rc_state* s,
log_err("remote control connection closed prematurely");
log_addr(VERB_OPS, "failed connection from",
&s->c->repinfo.remote_addr, s->c->repinfo.remote_addrlen);
log_crypto_err("remote control failed ssl");
log_crypto_err_io("remote control failed ssl", r2);
clean_point(rc, s);
}
return 0;

View File

@ -788,7 +788,7 @@ static int dtio_write_ssl(struct dt_io_thread* dtio, uint8_t* buf,
}
return -1;
}
log_crypto_err("dnstap io, could not SSL_write");
log_crypto_err_io("dnstap io, could not SSL_write", want);
return -1;
}
return r;
@ -1029,7 +1029,7 @@ static int ssl_read_bytes(struct dt_io_thread* dtio, void* buf, size_t len)
"other side");
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
verbose(VERB_DETAIL, "dnstap io: output closed by the "
"other side");
return 0;
@ -1431,8 +1431,8 @@ static int dtio_ssl_handshake(struct dt_io_thread* dtio,
} else {
unsigned long err = ERR_get_error();
if(!squelch_err_ssl_handshake(err)) {
log_crypto_err_code("dnstap io, ssl handshake failed",
err);
log_crypto_err_io_code("dnstap io, ssl handshake failed",
want, err);
verbose(VERB_OPS, "dnstap io, ssl handshake failed "
"from %s", dtio->ip_str);
}

View File

@ -708,7 +708,7 @@ static ssize_t ssl_read_bytes(struct tap_data* data, void* buf, size_t len)
(data->id?data->id:""));
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
if(verbosity) log_info("dnstap client stream closed from %s",
(data->id?data->id:""));
return 0;
@ -760,10 +760,11 @@ static int reply_with_accept(struct tap_data* data)
fd_set_block(data->fd);
if(data->ssl) {
if((r=SSL_write(data->ssl, acceptframe, len)) <= 0) {
if(SSL_get_error(data->ssl, r) == SSL_ERROR_ZERO_RETURN)
int r2;
if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
log_err("SSL_write, peer closed connection");
else
log_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", r2);
fd_set_nonblock(data->fd);
free(acceptframe);
return 0;
@ -805,10 +806,11 @@ static int reply_with_finish(struct tap_data* data)
if(data->ssl) {
int r;
if((r=SSL_write(data->ssl, finishframe, len)) <= 0) {
if(SSL_get_error(data->ssl, r) == SSL_ERROR_ZERO_RETURN)
int r2;
if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
log_err("SSL_write, peer closed connection");
else
log_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", r2);
fd_set_nonblock(data->fd);
free(finishframe);
return 0;

View File

@ -1,3 +1,7 @@
19 October 2023: Wouter
- Fix to print detailed errors when an SSL IO routine fails via
SSL_get_error.
18 October 2023: George
- Mailing list patches from Daniel Gröber for DNS64 fallback to plain
AAAA when no A record exists for synthesis, and minor DNS64 code

View File

@ -286,7 +286,7 @@ static ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session),
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_EOF;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
return NGHTTP2_ERR_EOF;
}
return r;
@ -317,7 +317,7 @@ static ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session),
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", want);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;
@ -526,7 +526,7 @@ run(struct http2_session* h2_session, int port, int no_tls, int count, char** q)
r = SSL_get_error(ssl, r);
if(r != SSL_ERROR_WANT_READ &&
r != SSL_ERROR_WANT_WRITE) {
log_crypto_err("could not ssl_handshake");
log_crypto_err_io("could not ssl_handshake", r);
exit(1);
}
}

View File

@ -466,7 +466,7 @@ send_em(const char* svr, const char* pp2_client, int udp, int usessl,
r = SSL_get_error(ssl, r);
if(r != SSL_ERROR_WANT_READ &&
r != SSL_ERROR_WANT_WRITE) {
log_crypto_err("could not ssl_handshake");
log_crypto_err_io("could not ssl_handshake", r);
exit(1);
}
}

View File

@ -952,6 +952,110 @@ void log_crypto_err_code(const char* str, unsigned long err)
#endif /* HAVE_SSL */
}
/** Print crypt erro with SSL_get_error want code and err_get_error code */
static void log_crypto_err_io_code_arg(const char* str, int r,
unsigned long err, int err_present)
{
#ifdef HAVE_SSL
int print_errno = 0, print_crypto_err = 0;
const char* inf = NULL;
switch(r) {
case SSL_ERROR_NONE:
inf = "no error";
break;
case SSL_ERROR_ZERO_RETURN:
inf = "channel closed";
break;
case SSL_ERROR_WANT_READ:
inf = "want read";
break;
case SSL_ERROR_WANT_WRITE:
inf = "want write";
break;
case SSL_ERROR_WANT_CONNECT:
inf = "want connect";
break;
case SSL_ERROR_WANT_ACCEPT:
inf = "want accept";
break;
case SSL_ERROR_WANT_X509_LOOKUP:
inf = "want X509 lookup";
break;
case SSL_ERROR_WANT_ASYNC:
inf = "want async";
break;
case SSL_ERROR_WANT_ASYNC_JOB:
inf = "want async job";
break;
case SSL_ERROR_WANT_CLIENT_HELLO_CB:
inf = "want client hello cb";
break;
case SSL_ERROR_SYSCALL:
print_errno = 1;
inf = "syscall";
break;
case SSL_ERROR_SSL:
print_crypto_err = 1;
inf = "SSL, usually protocol, error";
break;
default:
inf = "unknown SSL_get_error result code";
print_errno = 1;
print_crypto_err = 1;
}
if(print_crypto_err) {
if(print_errno) {
char buf[1024];
snprintf(buf, sizeof(buf), "%s with errno %s",
str, strerror(errno));
if(err_present)
log_crypto_err_code(buf, err);
else log_crypto_err(buf);
} else {
if(err_present)
log_crypto_err_code(str, err);
else log_crypto_err(str);
}
} else {
if(print_errno) {
if(errno == 0)
log_err("str: syscall error with errno %s",
strerror(errno));
else log_err("str: %s", strerror(errno));
} else {
log_err("str: %s", inf);
}
}
#else
(void)str;
(void)r;
(void)err;
(void)err_present;
#endif /* HAVE_SSL */
}
void log_crypto_err_io(const char* str, int r)
{
#ifdef HAVE_SSL
log_crypto_err_io_code_arg(str, r, 0, 0);
#else
(void)str;
(void)r;
#endif /* HAVE_SSL */
}
void log_crypto_err_io_code(const char* str, int r, unsigned long err)
{
#ifdef HAVE_SSL
log_crypto_err_io_code_arg(str, r, err, 1);
#else
(void)str;
(void)r;
(void)err;
#endif /* HAVE_SSL */
}
#ifdef HAVE_SSL
/** log certificate details */
void

View File

@ -429,6 +429,24 @@ void log_crypto_err(const char* str);
*/
void log_crypto_err_code(const char* str, unsigned long err);
/**
* Log an error from libcrypto that came from SSL_write and so on, with
* a value from SSL_get_error, calls log_err. If that fails it logs with
* log_crypto_err.
* @param str: what failed
* @param r: output of SSL_get_error on the I/O operation result.
*/
void log_crypto_err_io(const char* str, int r);
/**
* Log an error from libcrypt that came from an I/O routine with the
* errcode from ERR_get_error. Calls log_err() and log_crypto_err_code.
* @param str: what failed
* @param r: output of SSL_get_error on the I/O operation result.
* @param err: error code from ERR_get_error
*/
void log_crypto_err_io_code(const char* str, int r, unsigned long err);
/**
* Log certificate details verbosity, string, of X509 cert
* @param level: verbosity level

View File

@ -1666,7 +1666,8 @@ ssl_handshake(struct comm_point* c)
} else {
unsigned long err = ERR_get_error();
if(!squelch_err_ssl_handshake(err)) {
log_crypto_err_code("ssl handshake failed", err);
log_crypto_err_io_code("ssl handshake failed",
want, err);
log_addr(VERB_OPS, "ssl handshake failed",
&c->repinfo.remote_addr,
c->repinfo.remote_addrlen);
@ -1816,7 +1817,8 @@ ssl_handle_read(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read",
want);
return 0;
}
c->tcp_byte_count += r;
@ -1883,7 +1885,8 @@ ssl_handle_read(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read",
want);
return 0;
}
c->tcp_byte_count += r;
@ -1943,7 +1946,7 @@ ssl_handle_read(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
return 0;
}
c->tcp_byte_count += r;
@ -1993,7 +1996,7 @@ ssl_handle_read(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
return 0;
}
sldns_buffer_skip(c->buffer, (ssize_t)r);
@ -2084,7 +2087,7 @@ ssl_handle_write(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", want);
return 0;
}
if(c->tcp_write_and_read) {
@ -2136,7 +2139,7 @@ ssl_handle_write(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", want);
return 0;
}
if(c->tcp_write_and_read) {
@ -2930,7 +2933,7 @@ ssl_http_read_more(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
return 0;
}
verbose(VERB_ALGO, "ssl http read more skip to %d + %d",
@ -3381,7 +3384,7 @@ ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf,
strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_read");
log_crypto_err_io("could not SSL_read", want);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;
@ -3636,7 +3639,7 @@ ssl_http_write_more(struct comm_point* c)
strerror(errno));
return 0;
}
log_crypto_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", want);
return 0;
}
sldns_buffer_skip(c->buffer, (ssize_t)r);
@ -3709,7 +3712,7 @@ ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session), const uint8_t* buf,
strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_write");
log_crypto_err_io("could not SSL_write", want);
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;