diff options
author | Daniel Fiala <daniel@openssl.org> | 2022-05-10 08:46:37 +0000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2022-05-19 12:37:35 +0200 |
commit | e04ba889594d84a8805f3d0caeadf0527470e508 (patch) | |
tree | 824c7abc930ef3de0b4f52be4aef5fa5eaf5963d | |
parent | 6ef91d8153e04a2302bff11b29caf7e888b62fe8 (diff) |
s_serve: Report an error if init-connection fails without an attempt to read.
Fixes: openssl#18047.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18283)
-rw-r--r-- | apps/s_server.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/apps/s_server.c b/apps/s_server.c index 64d53e68d0..478b01620d 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -2236,6 +2236,30 @@ static void print_stats(BIO *bio, SSL_CTX *ssl_ctx) SSL_CTX_sess_get_cache_size(ssl_ctx)); } +static long int count_reads_callback(BIO *bio, int cmd, const char *argp, + int argi, long int argl, long int ret) +{ + unsigned int *p_counter = (unsigned int *)BIO_get_callback_arg(bio); + + switch (cmd) { + case BIO_CB_READ: /* No break here */ + case BIO_CB_GETS: + if (p_counter != NULL) + ++*p_counter; + break; + default: + break; + } + + if (s_debug) { + BIO_set_callback_arg(bio, (char *)bio_s_out); + ret = bio_dump_callback(bio, cmd, argp, argi, argl, ret); + BIO_set_callback_arg(bio, (char *)p_counter); + } + + return ret; +} + static int sv_body(int s, int stype, int prot, unsigned char *context) { char *buf = NULL; @@ -2353,10 +2377,7 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) SSL_set_accept_state(con); /* SSL_set_fd(con,s); */ - if (s_debug) { - BIO_set_callback(SSL_get_rbio(con), bio_dump_callback); - BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out); - } + BIO_set_callback(SSL_get_rbio(con), count_reads_callback); if (s_msg) { #ifndef OPENSSL_NO_SSL_TRACE if (s_msg == 2) @@ -2648,7 +2669,25 @@ static int sv_body(int s, int stype, int prot, unsigned char *context) */ if ((!async || !SSL_waiting_for_async(con)) && !SSL_is_init_finished(con)) { + /* + * Count number of reads during init_ssl_connection. + * It helps us to distinguish configuration errors from errors + * caused by a client. + */ + unsigned int read_counter = 0; + + BIO_set_callback_arg(SSL_get_rbio(con), (char *)&read_counter); i = init_ssl_connection(con); + BIO_set_callback_arg(SSL_get_rbio(con), NULL); + + /* + * If initialization fails without reads, then + * there was a fatal error in configuration. + */ + if (i <= 0 && read_counter == 0) { + ret = -1; + goto err; + } if (i < 0) { ret = 0; |