1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 20:51:30 +00:00

Fix Ncat SSL server. Closes #773 and potentially #197

This commit is contained in:
dmiller
2017-03-19 02:26:12 +00:00
parent 4629f6d836
commit ac8b866d73
2 changed files with 30 additions and 5 deletions

View File

@@ -1,5 +1,9 @@
# Nmap Changelog ($Id$); -*-text-*- # Nmap Changelog ($Id$); -*-text-*-
o [Ncat][GH#773] Ncat in server mode properly handles TLS renegotiations and
other situations where SSL_read returns a non-fatal error. This was causing
SSL-over-TCP connections to be dropped. [Daniel Miller]
o [Ncat][GH#157] Ncat will now continue trying to connect to each resolved o [Ncat][GH#157] Ncat will now continue trying to connect to each resolved
address for a hostname before declaring the connection refused, allowing it address for a hostname before declaring the connection refused, allowing it
to fallback from IPv6 to IPv4 or to connect to names that use DNS failover. to fallback from IPv6 to IPv4 or to connect to names that use DNS failover.

View File

@@ -628,6 +628,9 @@ int read_socket(int recv_fd)
char buf[DEFAULT_TCP_BUF_LEN]; char buf[DEFAULT_TCP_BUF_LEN];
struct fdinfo *fdn; struct fdinfo *fdn;
int nbytes, pending; int nbytes, pending;
#ifdef HAVE_OPENSSL
int err = SSL_ERROR_NONE;
#endif
fdn = get_fdinfo(&client_fdlist, recv_fd); fdn = get_fdinfo(&client_fdlist, recv_fd);
ncat_assert(fdn != NULL); ncat_assert(fdn != NULL);
@@ -637,11 +640,28 @@ int read_socket(int recv_fd)
int n; int n;
n = ncat_recv(fdn, buf, sizeof(buf), &pending); n = ncat_recv(fdn, buf, sizeof(buf), &pending);
if (n <= 0) { #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 (o.debug) if (o.debug)
logdebug("Closing connection.\n"); logdebug("Closing fd %d.\n", recv_fd);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl) { 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) if (nbytes == 0)
SSL_shutdown(fdn->ssl); SSL_shutdown(fdn->ssl);
SSL_free(fdn->ssl); SSL_free(fdn->ssl);
@@ -659,9 +679,10 @@ int read_socket(int recv_fd)
return n; return n;
} }
else if (n > 0) {
Write(STDOUT_FILENO, buf, n); Write(STDOUT_FILENO, buf, n);
nbytes += n; nbytes += n;
}
} while (pending); } while (pending);
return nbytes; return nbytes;