diff --git a/CHANGELOG b/CHANGELOG index af97bb420..99daf1241 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ #Nmap Changelog ($Id$); -*-text-*- +o [Ncat][GH#2087][GH#1927][GH#1928][GH#1974] It is now possible to override + the value of TLS SNI via --ssl-servername [Hank Leininger, nnposter] + o [GH#2104] Fixed parsing of TCP options which would hang (infinite loop) if an option had an explicit length of 0. Affects Nmap 7.80 only. [Daniel Miller, Imed Mnif] diff --git a/ncat/docs/ncat.usage.txt b/ncat/docs/ncat.usage.txt index d00aab367..f45de3eef 100644 --- a/ncat/docs/ncat.usage.txt +++ b/ncat/docs/ncat.usage.txt @@ -50,7 +50,8 @@ Options taking a time assume seconds. Append 'ms' for milliseconds, --ssl-verify Verify trust and domain name of certificates --ssl-trustfile PEM file containing trusted SSL certificates --ssl-ciphers Cipherlist containing SSL ciphers to use - --ssl-alpn ALPN protocol list to use. + --ssl-servername Request distinct server name (SNI) + --ssl-alpn ALPN protocol list to use --version Display Ncat's version information and exit See the ncat(1) manpage for full options, descriptions and usage examples diff --git a/ncat/docs/ncat.xml b/ncat/docs/ncat.xml index cfc0137f5..e6fd64bb2 100644 --- a/ncat/docs/ncat.xml +++ b/ncat/docs/ncat.xml @@ -411,6 +411,21 @@ + + + (Request distinct server name) + (Ncat option) + + + In client mode, this option sets the TLS SNI (Server Name + Indication) extension, which tells the server the name of the + logical server Ncat is contacting. This is important when the + target server hosts multiple virtual servers at a single underlying + network address. If the option is not provided, the TLS SNI + extension will be populated with the target server hostname. + + + (Specify ALPN protocol list) diff --git a/ncat/ncat_connect.c b/ncat/ncat_connect.c index 4acb8ef8a..7a0848050 100644 --- a/ncat/ncat_connect.c +++ b/ncat/ncat_connect.c @@ -972,7 +972,7 @@ static nsock_iod new_iod(nsock_pool mypool) { nsock_iod nsi = nsock_iod_new(mypool, NULL); if (nsi == NULL) bye("Failed to create nsock_iod."); - if (nsock_iod_set_hostname(nsi, o.target) == -1) + if (nsock_iod_set_hostname(nsi, o.sslservername) == -1) bye("Failed to set hostname on iod."); switch (srcaddr.storage.ss_family) { @@ -1128,7 +1128,8 @@ int ncat_connect(void) /* Once the proxy negotiation is done, Nsock takes control of the socket. */ cs.sock_nsi = nsock_iod_new2(mypool, connect_socket, NULL); - nsock_iod_set_hostname(cs.sock_nsi, o.target); + if (nsock_iod_set_hostname(cs.sock_nsi, o.sslservername) == -1) + bye("Failed to set hostname on iod."); if (o.ssl) { nsock_reconnect_ssl(mypool, cs.sock_nsi, connect_handler, o.conntimeout, NULL, NULL); @@ -1267,7 +1268,7 @@ static void connect_handler(nsock_pool nsp, nsock_event evt, void *data) if (nsock_iod_check_ssl(cs.sock_nsi)) { /* Check the domain name. ssl_post_connect_check prints an error message if appropriate. */ - if (!ssl_post_connect_check((SSL *)nsock_iod_get_ssl(cs.sock_nsi), o.target)) + if (!ssl_post_connect_check((SSL *)nsock_iod_get_ssl(cs.sock_nsi), o.sslservername)) bye("Certificate verification error."); } #endif diff --git a/ncat/ncat_core.c b/ncat/ncat_core.c index 4c13bc539..450f62710 100644 --- a/ncat/ncat_core.c +++ b/ncat/ncat_core.c @@ -217,6 +217,7 @@ void options_init(void) o.sslverify = 0; o.ssltrustfile = NULL; o.sslciphers = NULL; + o.sslservername = NULL; o.sslalpn = NULL; #endif } diff --git a/ncat/ncat_core.h b/ncat/ncat_core.h index e421ed69f..ebf266f23 100644 --- a/ncat/ncat_core.h +++ b/ncat/ncat_core.h @@ -223,6 +223,7 @@ struct options { int sslverify; char *ssltrustfile; char *sslciphers; + char* sslservername; char *sslalpn; int zerobyte; }; diff --git a/ncat/ncat_main.c b/ncat/ncat_main.c index d1fff7e7e..f36db49a9 100644 --- a/ncat/ncat_main.c +++ b/ncat/ncat_main.c @@ -358,6 +358,7 @@ int main(int argc, char *argv[]) {"ssl-verify", no_argument, NULL, 0}, {"ssl-trustfile", required_argument, NULL, 0}, {"ssl-ciphers", required_argument, NULL, 0}, + {"ssl-servername", required_argument, NULL, 0}, {"ssl-alpn", required_argument, NULL, 0}, #else {"ssl-cert", optional_argument, NULL, 0}, @@ -573,6 +574,9 @@ int main(int argc, char *argv[]) } else if (strcmp(long_options[option_index].name, "ssl-ciphers") == 0) { o.ssl = 1; o.sslciphers = Strdup(optarg); + } else if (strcmp(long_options[option_index].name, "ssl-servername") == 0) { + o.ssl = 1; + o.sslservername = Strdup(optarg); #ifdef HAVE_ALPN_SUPPORT } else if (strcmp(long_options[option_index].name, "ssl-alpn") == 0) { o.ssl = 1; @@ -594,6 +598,8 @@ int main(int argc, char *argv[]) bye("OpenSSL isn't compiled in. The --ssl-trustfile option cannot be chosen."); } else if (strcmp(long_options[option_index].name, "ssl-ciphers") == 0) { bye("OpenSSL isn't compiled in. The --ssl-ciphers option cannot be chosen."); + } else if (strcmp(long_options[option_index].name, "ssl-servername") == 0) { + bye("OpenSSL isn't compiled in. The --ssl-servername option cannot be chosen."); } else if (strcmp(long_options[option_index].name, "ssl-alpn") == 0) { bye("OpenSSL isn't compiled in. The --ssl-alpn option cannot be chosen."); } @@ -695,7 +701,8 @@ int main(int argc, char *argv[]) " --ssl-verify Verify trust and domain name of certificates\n" " --ssl-trustfile PEM file containing trusted SSL certificates\n" " --ssl-ciphers Cipherlist containing SSL ciphers to use\n" -" --ssl-alpn ALPN protocol list to use.\n" +" --ssl-servername Request distinct server name (SNI)\n" +" --ssl-alpn ALPN protocol list to use\n" #endif " --version Display Ncat's version information and exit\n" "\n" @@ -943,6 +950,8 @@ int main(int argc, char *argv[]) && (rc = resolve_multi(o.target, 0, targetaddrs, o.af)) != 0) bye("Could not resolve hostname \"%s\": %s.", o.target, gai_strerror(rc)); + if (!o.sslservername) + o.sslservername = o.target; optind++; } else { if (!o.listen)