mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- Fix to print detailed errors when an SSL IO routine fails via
SSL_get_error.
This commit is contained in:
parent
44c3d4d2dc
commit
35d0a8a843
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
104
util/net_help.c
104
util/net_help.c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user