1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-20 13:19:01 +00:00

Do a 2nd SSL_read if necessary for renegotiation.

This fix was previously applied to ncat_listen's read_socket in r36652
(ac8b866) as a fix for #773. It didn't fully solve the problem, though,
since the fix should have been applied in ncat_core's fdinfo_recv, right
after the call to SSL_read. This commit moves the fix where it belongs,
which also simplifies the code.

Fixes #197 and #1049.
This commit is contained in:
dmiller
2018-03-11 03:50:53 +00:00
parent ea2e9e4499
commit 8582bb5efe
2 changed files with 19 additions and 23 deletions

View File

@@ -338,8 +338,24 @@ int fdinfo_close(struct fdinfo *fdn)
int fdinfo_recv(struct fdinfo *fdn, char *buf, size_t size)
{
#ifdef HAVE_OPENSSL
int n;
int err = SSL_ERROR_NONE;
if (o.ssl && fdn->ssl)
return SSL_read(fdn->ssl, buf, size);
{
do {
n = SSL_read(fdn->ssl, buf, size);
/* SSL_read returns <0 in some cases like renegotiation. In these
* cases, SSL_get_error gives SSL_ERROR_WANT_{READ,WRITE}, and we
* should try the SSL_read again. */
if (n < 0) {
err = SSL_get_error(fdn->ssl, n);
if (err != SSL_ERROR_WANT_READ || err != SSL_ERROR_WANT_WRITE) {
logdebug("SSL error on %d: %s\n", fdn->fd, ERR_error_string(err, NULL));
}
}
} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
return n;
}
#endif
return recv(fdn->fd, buf, size, 0);
}

View File

@@ -636,9 +636,6 @@ int read_socket(int recv_fd)
char buf[DEFAULT_TCP_BUF_LEN];
struct fdinfo *fdn;
int nbytes, pending;
#ifdef HAVE_OPENSSL
int err = SSL_ERROR_NONE;
#endif
fdn = get_fdinfo(&client_fdlist, recv_fd);
ncat_assert(fdn != NULL);
@@ -648,28 +645,11 @@ int read_socket(int recv_fd)
int n;
n = ncat_recv(fdn, buf, sizeof(buf), &pending);
#ifdef HAVE_OPENSSL
/* SSL_read returns <0 in some cases like renegotiation. In these
* cases, SSL_get_error gives SSL_ERROR_WANT_{READ,WRITE}, and we
* should try the SSL_read again. */
if (n < 0 && o.ssl && fdn->ssl) {
err = SSL_get_error(fdn->ssl, n);
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
pending = 1;
}
}
#endif
/* If return value is 0, it's a clean shutdown from the other side, SSL
* or plain. If <0, it's an error. If pending, the error may be
* recoverable with a second SSL_read, so don't shut down yet. */
if (n <= 0 && !pending) {
if (n <= 0) {
if (o.debug)
logdebug("Closing fd %d.\n", recv_fd);
#ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl) {
if (n < 0 && o.debug) {
logdebug("SSL error on %d: %s\n", recv_fd, ERR_error_string(err, NULL));;
}
if (nbytes == 0)
SSL_shutdown(fdn->ssl);
SSL_free(fdn->ssl);
@@ -687,7 +667,7 @@ int read_socket(int recv_fd)
return n;
}
else if (n > 0) {
else {
Write(STDOUT_FILENO, buf, n);
nbytes += n;
}