1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 12:41:29 +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-*-
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
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.

View File

@@ -628,6 +628,9 @@ 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);
@@ -637,11 +640,28 @@ int read_socket(int recv_fd)
int n;
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)
logdebug("Closing connection.\n");
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);
@@ -659,9 +679,10 @@ int read_socket(int recv_fd)
return n;
}
Write(STDOUT_FILENO, buf, n);
nbytes += n;
else if (n > 0) {
Write(STDOUT_FILENO, buf, n);
nbytes += n;
}
} while (pending);
return nbytes;