diff --git a/CHANGELOG b/CHANGELOG
index 1d04218b3..a03987345 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,12 @@
#Nmap Changelog ($Id$); -*-text-*-
+o [Ncat] Ncat in listen mode with --udp --ssl will use DTLS to secure incoming
+ connections. [Daniel Miller]
+
+o [Ncat][GH#1223] Ncat can now accept "connections" from multiple UDP hosts in
+ listen mode with the --keep-open option. This also enables --broker and
+ --chat via UDP. [Daniel Miller]
+
o [GH#2507] Updates to the Japanese manpage translation by Taichi Kotake.
o [NSE][GH#548] New script tftp-version requests a nonexistent file from a TFTP
diff --git a/ncat/docs/ncat.xml b/ncat/docs/ncat.xml
index 2d7e80161..d20284344 100644
--- a/ncat/docs/ncat.xml
+++ b/ncat/docs/ncat.xml
@@ -327,8 +327,8 @@
particularly handy for talking to SSL enabled HTTP servers, etc.
In server mode, this option listens for incoming SSL connections,
rather than plain untunneled traffic.
- In UDP connect mode, this option enables Datagram TLS (DTLS).
- This is not supported in server mode.
+ In UDP mode, this option enables Datagram TLS (DTLS).
+
diff --git a/ncat/docs/ncatguide.xml b/ncat/docs/ncatguide.xml
index 198b81180..d9677205d 100644
--- a/ncat/docs/ncatguide.xml
+++ b/ncat/docs/ncatguide.xml
@@ -131,9 +131,7 @@ the tool? Many of these examples suppose a Unix environment. -->
to the connection limit. With (or
for short), the server receives everything sent by
any of its clients, and anything the server sends is sent to all of
- them. A UDP server will communicate with only one client (the first
- one to send it data), because in UDP there is no list of
- connected clients.
+ them.
@@ -304,12 +302,9 @@ Content-Type: text/html; charset=UTF-8
the User Datagram Protocol, is an unreliable protocol often used by
applications that can't afford the overhead of TCP. Use the
(Ncat option)
- option to make Ncat use UDP. In listen mode, Ncat will communicate
- with only one client, and the
- (Ncat option)not supported with UDP
- option doesn't work, the reason for this being that UDP has no notion
- of a connection. UDP may be secured by a form of SSL called Datagram TLS (DTLS)DTLSDatagram TLS.
- This is currently only supported in connect (client) mode.SSLnot supported with UDP in server mode
+ option to make Ncat use UDP.
+ UDP may be secured using the option, which enables
+ Datagram TLS (DTLS)DTLSDatagram TLS.
@@ -646,8 +641,8 @@ print("Hello, world!")
combined with
,with
Ncat will accept multiple connections, forking off a new handler for
- each. This works even in UDP mode; the usual limit of only one client
- doesn't apply. The server will keep running until you press
+ each.
+ The server will keep running until you press
ctrlC or
otherwise terminate it externally. In this way Ncat can work much like
inetd.inetd
@@ -1779,20 +1774,17 @@ host1$ ncat --send-only host2 < log.txtUDP discard server
-ncat -l 9 --keep-open --udp --sh-exec "cat > /dev/null"
+ncat --udp -l --keep-open 9 --recv-only > /dev/null
- With the TCP server we used so the server
- could handle multiple simultaneous connections, not just one. For the
- UDP server we had to use to allow multiple
- concurrent connections. Recall from that
- a UDP server can handle only one client but with
- and this limitation
- does not apply.
+ Ncat in UDP mode uses all the same options as TCP. The caveat here is that
+ connections can't be closed, only timed out, so you will eventually run out
+ of sockets if you do not use a timeout. Currently, none of the timeout
+ options do the appropriate thing in this instance.
diff --git a/ncat/ncat_listen.c b/ncat/ncat_listen.c
index be84b45d7..4493bf15e 100644
--- a/ncat/ncat_listen.c
+++ b/ncat/ncat_listen.c
@@ -117,7 +117,7 @@ static int listen_socket[NUM_LISTEN_ADDRS];
static int stdin_eof = 0;
static int crlf_state = 0;
-static void handle_connection(int socket_accept);
+static void handle_connection(int socket_accept, int type, fd_set *listen_fds);
static int read_stdin(void);
static int read_socket(int recv_fd);
static void post_handle_connection(struct fdinfo sinfo);
@@ -165,14 +165,51 @@ static void sigchld_handler(int signum)
}
#endif
-static int ncat_listen_stream(int proto)
+int new_listen_socket(int type, int proto, const union sockaddr_u *addr, fd_set *listen_fds)
+{
+ struct fdinfo fdi;
+ fdi.fd = do_listen(type, proto, addr);
+ if (fdi.fd < 0) {
+ return -1;
+ }
+ fdi.remoteaddr = *addr; /* actually our local addr, but whatevs */
+
+ /* Make our listening socket non-blocking because there are timing issues
+ * which could cause us to block on accept() even though select() says it's
+ * readable. See UNPv1 2nd ed, p422 for more.
+ */
+ unblock_socket(fdi.fd);
+
+ /* setup select sets and max fd */
+ checked_fd_set(fdi.fd, &master_readfds);
+ add_fdinfo(&client_fdlist, &fdi);
+
+ checked_fd_set(fdi.fd, listen_fds);
+
+ return fdi.fd;
+}
+
+int ncat_listen()
{
int rc, i, fds_ready;
fd_set listen_fds;
struct timeval tv;
struct timeval *tvp = NULL;
unsigned int num_sockets;
+ int proto = o.proto;
+ int type = o.proto == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+ if (o.httpserver)
+ return ncat_http_server();
+
+#if HAVE_SYS_UN_H
+ if (o.af == AF_UNIX)
+ proto = 0;
+#endif
+#if HAVE_LINUX_VM_SOCKETS_H
+ if (o.af == AF_VSOCK)
+ proto = 0;
+#endif
/* clear out structs */
FD_ZERO(&master_readfds);
FD_ZERO(&master_writefds);
@@ -199,7 +236,7 @@ static int ncat_listen_stream(int proto)
{
if (o.sslalpn)
bye("ALPN is not supported in listen mode\n");
- setup_ssl_listen();
+ setup_ssl_listen(type == SOCK_STREAM ? SSLv23_server_method() : DTLS_server_method());
}
#endif
@@ -230,25 +267,12 @@ static int ncat_listen_stream(int proto)
num_sockets = 0;
for (i = 0; i < num_listenaddrs; i++) {
/* setup the main listening socket */
- listen_socket[num_sockets] = do_listen(SOCK_STREAM, proto, &listenaddrs[i]);
+ listen_socket[num_sockets] = new_listen_socket(type, proto, &listenaddrs[i], &listen_fds);
if (listen_socket[num_sockets] == -1) {
if (o.debug > 0)
logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno()));
continue;
}
-
- /* Make our listening socket non-blocking because there are timing issues
- * which could cause us to block on accept() even though select() says it's
- * readable. See UNPv1 2nd ed, p422 for more.
- */
- unblock_socket(listen_socket[num_sockets]);
-
- /* setup select sets and max fd */
- checked_fd_set(listen_socket[num_sockets], &master_readfds);
- add_fd(&client_fdlist, listen_socket[num_sockets]);
-
- checked_fd_set(listen_socket[num_sockets], &listen_fds);
-
num_sockets++;
}
if (num_sockets == 0) {
@@ -341,7 +365,7 @@ static int ncat_listen_stream(int proto)
#endif
if (checked_fd_isset(cfd, &listen_fds)) {
/* we have a new connection request */
- handle_connection(cfd);
+ handle_connection(cfd, type, &listen_fds);
} else if (cfd == STDIN_FILENO) {
if (o.broker) {
read_and_broadcast(cfd);
@@ -354,7 +378,7 @@ static int ncat_listen_stream(int proto)
receiving anything, we can quit here. */
return 0;
}
- if (!o.noshutdown) shutdown_sockets(SHUT_WR);
+ if (!o.noshutdown && type == SOCK_STREAM) shutdown_sockets(SHUT_WR);
}
if (rc < 0)
return 1;
@@ -380,7 +404,7 @@ static int ncat_listen_stream(int proto)
/* Accept a connection on a listening socket. Allow or deny the connection.
Fork a command if o.cmdexec is set. Otherwise, add the new socket to the
watch set. */
-static void handle_connection(int socket_accept)
+static void handle_connection(int socket_accept, int type, fd_set *listen_fds)
{
union sockaddr_u remoteaddr;
socklen_t ss_len;
@@ -393,7 +417,39 @@ static void handle_connection(int socket_accept)
ss_len = sizeof(remoteaddr.storage);
errno = 0;
- s.fd = accept(socket_accept, &remoteaddr.sockaddr, &ss_len);
+ if (type == SOCK_STREAM) {
+ s.fd = accept(socket_accept, &remoteaddr.sockaddr, &ss_len);
+ }
+ else {
+ char buf[4] = {0};
+ int nbytes = recvfrom(socket_accept, buf, sizeof(buf), MSG_PEEK,
+ &remoteaddr.sockaddr, &ss_len);
+ if (nbytes < 0) {
+ loguser("%s.\n", socket_strerror(socket_errno()));
+ return;
+ }
+ /*
+ * We're using connected udp. This has the down side of only
+ * being able to handle one udp client at a time
+ */
+ Connect(socket_accept, &remoteaddr.sockaddr, ss_len);
+ s.fd = socket_accept;
+ // Remove this socket from listening and put a new one up.
+ for (int i = 0; i < num_listenaddrs; i++) {
+ if (listen_socket[i] == socket_accept) {
+ struct fdinfo *lfdi = get_fdinfo(&client_fdlist, socket_accept);
+ union sockaddr_u localaddr = lfdi->remoteaddr;
+ checked_fd_clr(socket_accept, &master_readfds);
+ checked_fd_clr(socket_accept, listen_fds);
+ rm_fd(&client_fdlist, socket_accept);
+ listen_socket[i] = new_listen_socket(type, (o.af == AF_INET || o.af == AF_INET6) ? o.proto : 0, &localaddr, listen_fds);
+ if (listen_socket[i] < 0) {
+ bye("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno()));
+ return;
+ }
+ }
+ }
+ }
if (s.fd < 0) {
if (o.debug)
@@ -406,12 +462,12 @@ static void handle_connection(int socket_accept)
if (o.verbose) {
#if HAVE_SYS_UN_H
if (remoteaddr.sockaddr.sa_family == AF_UNIX)
- loguser("Connection from a client on Unix domain socket.\n");
+ loguser("Connection from %s.\n", remoteaddr.un.sun_path);
else
#endif
#ifdef HAVE_LINUX_VM_SOCKETS_H
if (remoteaddr.sockaddr.sa_family == AF_VSOCK)
- loguser("Connection from a client on vsock socket.\n");
+ loguser("Connection from %u.\n", remoteaddr.vm.svm_cid);
else
#endif
if (o.chat)
@@ -616,350 +672,6 @@ int read_socket(int recv_fd)
return nbytes;
}
-/* This is sufficiently different from the TCP code (wrt SSL, etc) that it
- * resides in its own simpler function
- */
-static int ncat_listen_dgram(int proto)
-{
- struct {
- int fd;
- union sockaddr_u addr;
- } sockfd[NUM_LISTEN_ADDRS];
- int i, fdn = -1;
- int fdmax, nbytes, n, fds_ready;
- char buf[DEFAULT_UDP_BUF_LEN] = { 0 };
- char *tempbuf = NULL;
- fd_set read_fds;
- union sockaddr_u remotess;
- socklen_t sslen = sizeof(remotess.storage);
- struct timeval tv;
- struct timeval *tvp = NULL;
- unsigned int num_sockets;
-
-#ifdef HAVE_OPENSSL
- if(o.ssl)
- bye("DTLS is not supported in listen mode\n");
-#endif
-
- for (i = 0; i < NUM_LISTEN_ADDRS; i++) {
- sockfd[i].fd = -1;
- sockfd[i].addr.storage.ss_family = AF_UNSPEC;
- }
-
- FD_ZERO(&read_fds);
-
- /* Initialize remotess struct so recvfrom() doesn't hit the fan.. */
- zmem(&remotess.storage, sizeof(remotess.storage));
- remotess.storage.ss_family = o.af;
-
-#ifdef WIN32
- set_pseudo_sigchld_handler(decrease_conn_count);
-#else
- /* Reap on SIGCHLD */
- Signal(SIGCHLD, sigchld_handler);
- /* Ignore the SIGPIPE that occurs when a client disconnects suddenly and we
- send data to it before noticing. */
- Signal(SIGPIPE, SIG_IGN);
-#endif
-
-/* Not sure if this problem exists on Windows, but fcntl and /dev/null don't */
-#ifndef WIN32
- /* Check whether stdin is closed. Because we treat this fd specially, we
- * can't risk it being reopened for an incoming connection, so we'll hold
- * it open instead. */
- if (fcntl(STDIN_FILENO, F_GETFD) == -1 && errno == EBADF) {
- logdebug("stdin is closed, attempting to reserve STDIN_FILENO\n");
- i = open("/dev/null", O_RDONLY);
- if (i >= 0 && i != STDIN_FILENO) {
- /* Oh well, we tried */
- logdebug("Couldn't reserve STDIN_FILENO\n");
- close(i);
- }
- }
-#endif
-
- /* set for selecting udp listening sockets */
- fd_set listen_fds;
- fd_list_t listen_fdlist;
- FD_ZERO(&listen_fds);
- init_fdlist(&listen_fdlist, num_listenaddrs);
-
- num_sockets = 0;
- for (i = 0; i < num_listenaddrs; i++) {
- /* create the UDP listen sockets */
- sockfd[num_sockets].fd = do_listen(SOCK_DGRAM, proto, &listenaddrs[i]);
- if (sockfd[num_sockets].fd == -1) {
- if (o.debug > 0)
- logdebug("do_listen(\"%s\"): %s\n", inet_ntop_ez(&listenaddrs[i].storage, sizeof(listenaddrs[i].storage)), socket_strerror(socket_errno()));
- continue;
- }
- checked_fd_set(sockfd[num_sockets].fd, &listen_fds);
- add_fd(&listen_fdlist, sockfd[num_sockets].fd);
- sockfd[num_sockets].addr = listenaddrs[i];
- num_sockets++;
- }
- if (num_sockets == 0) {
- if (num_listenaddrs == 1)
- bye("Unable to open listening socket on %s: %s", inet_ntop_ez(&listenaddrs[0].storage, sizeof(listenaddrs[0].storage)), socket_strerror(socket_errno()));
- else
- bye("Unable to open any listening sockets.");
- }
-
- if (o.idletimeout > 0)
- tvp = &tv;
-
- while (1) {
- int i, j, conn_count, socket_n;
-
- if (fdn != -1) {
- /*remove socket descriptor which is burnt */
- checked_fd_clr(sockfd[fdn].fd, &listen_fds);
- rm_fd(&listen_fdlist, sockfd[fdn].fd);
-
- /* Rebuild the udp socket which got burnt */
- sockfd[fdn].fd = do_listen(SOCK_DGRAM, proto, &sockfd[fdn].addr);
- if (sockfd[fdn].fd == -1)
- bye("do_listen: %s", socket_strerror(socket_errno()));
- checked_fd_set(sockfd[fdn].fd, &listen_fds);
- add_fd(&listen_fdlist, sockfd[fdn].fd);
-
- }
- fdn = -1;
- socket_n = -1;
- fd_set fds;
- FD_ZERO(&fds);
- while (1) {
- /*
- * We just select to get a list of sockets which we can talk to
- */
- if (o.debug > 1)
- logdebug("selecting, fdmax %d\n", listen_fdlist.fdmax);
- fds = listen_fds;
-
- if (o.idletimeout > 0)
- ms_to_timeval(tvp, o.idletimeout);
-
- /* The idle timer should only be running when there are active connections */
- if (get_conn_count())
- fds_ready = fselect(listen_fdlist.fdmax + 1, &fds, NULL, NULL, tvp);
- else
- fds_ready = fselect(listen_fdlist.fdmax + 1, &fds, NULL, NULL, NULL);
-
- if (o.debug > 1)
- logdebug("select returned %d fds ready\n", fds_ready);
-
- if (fds_ready == 0)
- bye("Idle timeout expired (%d ms).", o.idletimeout);
-
- /*
- * Figure out which listening socket got a connection. This loop should
- * really call a function for each ready socket instead of breaking on
- * the first one.
- */
- for (i = 0; i <= listen_fdlist.fdmax && fds_ready > 0; i++) {
- /* Loop through descriptors until there is something ready */
- if (!checked_fd_isset(i, &fds))
- continue;
-
- /* Check each listening socket */
- for (j = 0; j < num_sockets; j++) {
- if (i == sockfd[j].fd) {
- if (o.debug > 1)
- logdebug("Valid descriptor %d \n", i);
- fdn = j;
- socket_n = i;
- break;
- }
- }
-
- /* if we found a valid socket break */
- if (fdn != -1) {
- fds_ready--;
- break;
- }
- }
-
- /* Make sure someone connected */
- if (fdn == -1)
- continue;
-
- /*
- * We just peek so we can get the client connection details without
- * removing anything from the queue. Sigh.
- */
- nbytes = recvfrom(socket_n, buf, sizeof(buf), MSG_PEEK,
- &remotess.sockaddr, &sslen);
- if (nbytes < 0) {
- loguser("%s.\n", socket_strerror(socket_errno()));
- close(socket_n);
- return 1;
- }
-
- /* Check conditions that might cause us to deny the connection. */
- conn_count = get_conn_count();
- if (conn_count >= o.conn_limit) {
- if (o.verbose)
- loguser("New connection denied: connection limit reached (%d)\n", conn_count);
- } else if (!allow_access(&remotess)) {
- if (o.verbose)
- loguser("New connection denied: not allowed\n");
- } else {
- /* Good to go. */
- break;
- }
-
- /* Dump the current datagram */
- nbytes = recv(socket_n, buf, sizeof(buf), 0);
- if (nbytes < 0) {
- loguser("%s.\n", socket_strerror(socket_errno()));
- close(socket_n);
- return 1;
- }
- ncat_log_recv(buf, nbytes);
- }
-
- if (o.verbose) {
-#if HAVE_SYS_UN_H
- if (remotess.sockaddr.sa_family == AF_UNIX)
- loguser("Connection from %s.\n", remotess.un.sun_path);
- else
-#endif
-#ifdef HAVE_LINUX_VM_SOCKETS_H
- if (remotess.sockaddr.sa_family == AF_VSOCK)
- loguser("Connection from %u.\n", remotess.vm.svm_cid);
- else
-#endif
- loguser("Connection from %s.\n", inet_socktop(&remotess));
- }
-
- conn_inc++;
-
- /*
- * We're using connected udp. This has the down side of only
- * being able to handle one udp client at a time
- */
- Connect(socket_n, &remotess.sockaddr, sslen);
-
- /* clean slate for buf */
- zmem(buf, sizeof(buf));
-
- /* are we executing a command? then do it */
- if (o.cmdexec) {
- struct fdinfo info = { 0 };
-
- info.fd = socket_n;
- info.remoteaddr = remotess;
- if (o.keepopen)
- netrun(&info, o.cmdexec);
- else
- netexec(&info, o.cmdexec);
- continue;
- }
-
- checked_fd_set(socket_n, &read_fds);
- checked_fd_set(STDIN_FILENO, &read_fds);
- fdmax = socket_n;
-
- /* stdin -> socket and socket -> stdout */
- while (1) {
- fd_set fds;
-
- fds = read_fds;
-
- if (o.debug > 1)
- logdebug("udp select'ing\n");
-
- if (o.idletimeout > 0)
- ms_to_timeval(tvp, o.idletimeout);
-
- fds_ready = fselect(fdmax + 1, &fds, NULL, NULL, tvp);
-
- if (fds_ready == 0)
- bye("Idle timeout expired (%d ms).", o.idletimeout);
-
- if (checked_fd_isset(STDIN_FILENO, &fds)) {
- nbytes = Read(STDIN_FILENO, buf, sizeof(buf));
- if (nbytes <= 0) {
- if (nbytes < 0 && o.verbose) {
- logdebug("Error reading from stdin: %s\n", strerror(errno));
- } else if (nbytes == 0 && o.debug) {
- logdebug("EOF on stdin\n");
- }
- checked_fd_clr(STDIN_FILENO, &read_fds);
- if (nbytes < 0)
- return 1;
- continue;
- }
- if (o.crlf)
- fix_line_endings((char *) buf, &nbytes, &tempbuf, &crlf_state);
- if (!o.recvonly) {
- if (tempbuf != NULL)
- n = send(socket_n, tempbuf, nbytes, 0);
- else
- n = send(socket_n, buf, nbytes, 0);
- if (n < nbytes) {
- loguser("%s.\n", socket_strerror(socket_errno()));
- close(socket_n);
- return 1;
- }
- ncat_log_send(buf, nbytes);
- }
- if (tempbuf != NULL) {
- free(tempbuf);
- tempbuf = NULL;
- }
- }
- if (checked_fd_isset(socket_n, &fds)) {
- nbytes = recv(socket_n, buf, sizeof(buf), 0);
- if (nbytes < 0) {
- loguser("%s.\n", socket_strerror(socket_errno()));
- close(socket_n);
- return 1;
- }
- ncat_log_recv(buf, nbytes);
- if (!o.sendonly)
- Write(STDOUT_FILENO, buf, nbytes);
- }
-
- zmem(buf, sizeof(buf));
- }
- }
-
- return 0;
-}
-
-int ncat_listen()
-{
-#if HAVE_SYS_UN_H
- if (o.af == AF_UNIX)
- if (o.proto == IPPROTO_UDP)
- return ncat_listen_dgram(0);
- else
- return ncat_listen_stream(0);
- else
-#endif
-#if HAVE_LINUX_VM_SOCKETS_H
- if (o.af == AF_VSOCK) {
- if (o.proto == IPPROTO_UDP)
- return ncat_listen_dgram(0);
- else
- return ncat_listen_stream(0);
- } else
-#endif
- if (o.httpserver)
- return ncat_http_server();
- else if (o.proto == IPPROTO_UDP)
- return ncat_listen_dgram(o.proto);
- else if (o.proto == IPPROTO_SCTP)
- return ncat_listen_stream(o.proto);
- else if (o.proto == IPPROTO_TCP)
- return ncat_listen_stream(o.proto);
- else
- bye("Unknown o.proto %d\n", o.proto);
-
- /* unreached */
- return 1;
-}
//---------------
/* Read from recv_fd and broadcast whatever is read to all other descriptors in
diff --git a/ncat/ncat_main.c b/ncat/ncat_main.c
index e1923ed2f..ce36ea236 100644
--- a/ncat/ncat_main.c
+++ b/ncat/ncat_main.c
@@ -984,13 +984,6 @@ int main(int argc, char *argv[])
if (o.ssl)
bye("OpenSSL does not have DTLS support compiled in.");
#endif
- if (o.keepopen && o.cmdexec == NULL)
- bye("UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec.");
- if (o.broker)
- bye("UDP mode does not support connection brokering.\n\
-If this feature is important to you, write dev@nmap.org with a\n\
-description of how you intend to use it, as an aid to deciding how UDP\n\
-connection brokering should work.");
}
/* Do whatever is necessary to receive \n for line endings on input from
diff --git a/ncat/ncat_proxy.c b/ncat/ncat_proxy.c
index 86ec8e407..7f4f477d0 100644
--- a/ncat/ncat_proxy.c
+++ b/ncat/ncat_proxy.c
@@ -140,7 +140,7 @@ int ncat_http_server(void)
#ifdef HAVE_OPENSSL
if (o.ssl)
- setup_ssl_listen();
+ setup_ssl_listen(SSLv23_server_method());
#endif
/* Clear the socket list */
for (i = 0; i < NUM_LISTEN_ADDRS; i++)
diff --git a/ncat/ncat_ssl.c b/ncat/ncat_ssl.c
index f98df66ac..0c3cad512 100644
--- a/ncat/ncat_ssl.c
+++ b/ncat/ncat_ssl.c
@@ -105,10 +105,8 @@ enum {
};
#define CERTIFICATE_COMMENT "Automatically generated by Ncat. See https://nmap.org/ncat/."
-SSL_CTX *setup_ssl_listen(void)
+SSL_CTX *setup_ssl_listen(const SSL_METHOD *method)
{
- const SSL_METHOD *method;
-
if (sslctx)
goto done;
@@ -138,8 +136,8 @@ SSL_CTX *setup_ssl_listen(void)
if (!RAND_status())
bye("Failed to seed OpenSSL PRNG (RAND_status returned false).");
- if (!(method = SSLv23_server_method()))
- bye("SSLv23_server_method(): %s.", ERR_error_string(ERR_get_error(), NULL));
+ if (!method)
+ bye("Invalid SSL method: %s.", ERR_error_string(ERR_get_error(), NULL));
if (!(sslctx = SSL_CTX_new(method)))
bye("SSL_CTX_new(): %s.", ERR_error_string(ERR_get_error(), NULL));
diff --git a/ncat/ncat_ssl.h b/ncat/ncat_ssl.h
index 458736e27..9e3dc707b 100644
--- a/ncat/ncat_ssl.h
+++ b/ncat/ncat_ssl.h
@@ -84,7 +84,7 @@ enum {
NCAT_SSL_HANDSHAKE_FAILED = 3
};
-extern SSL_CTX *setup_ssl_listen(void);
+extern SSL_CTX *setup_ssl_listen(const SSL_METHOD *method);
extern SSL *new_ssl(int fd);