mirror of
https://github.com/nmap/nmap.git
synced 2025-12-20 14:39:02 +00:00
Add DTLS and ALPN support to Ncat. Closes #446
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o [Ncat][GH#446] Added Datagram TLS (DTLS) support to Ncat in connect (client)
|
||||||
|
mode with --udp --ssl. Also added Application Layer Protocol Negotiation
|
||||||
|
(ALPN) support with the --ssl-alpn option. [denandz, Daniel Miller]
|
||||||
|
|
||||||
o Updated the default ciphers list for Ncat and the secure ciphers list for
|
o Updated the default ciphers list for Ncat and the secure ciphers list for
|
||||||
Nsock to use "!aNULL:!eNULL" instead of "!ADH". With the addition of ECDH
|
Nsock to use "!aNULL:!eNULL" instead of "!ADH". With the addition of ECDH
|
||||||
ciphersuites, anonymous ECDH suites were being allowed. [Daniel Miller]
|
ciphersuites, anonymous ECDH suites were being allowed. [Daniel Miller]
|
||||||
|
|||||||
@@ -314,6 +314,8 @@
|
|||||||
particularly handy for talking to SSL enabled HTTP servers, etc.</para>
|
particularly handy for talking to SSL enabled HTTP servers, etc.</para>
|
||||||
<para>In server mode, this option listens for incoming SSL connections,
|
<para>In server mode, this option listens for incoming SSL connections,
|
||||||
rather than plain untunneled traffic.</para>
|
rather than plain untunneled traffic.</para>
|
||||||
|
<para>In UDP connect mode, this option enables Datagram TLS (DTLS).
|
||||||
|
This is not supported in server mode.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@@ -395,6 +397,20 @@
|
|||||||
<literal>ALL:!aNULL:!eNULL:!LOW:!EXP:!MD5:@STRENGTH</literal></para>
|
<literal>ALL:!aNULL:!eNULL:!LOW:!EXP:!MD5:@STRENGTH</literal></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<option>--ssl-alpn <replaceable>ALPN list</replaceable></option> (Specify ALPN protocol list)
|
||||||
|
<indexterm><primary><option>--ssl-alpn</option> (Ncat option)</primary></indexterm>
|
||||||
|
</term>
|
||||||
|
<listitem>
|
||||||
|
<para>This option allows you to specify a comma-separated list of
|
||||||
|
protocols to send via the Application-Layer Protocol Negotiation
|
||||||
|
(ALPN) TLS extension. Not supported by all versions of OpenSSL.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|||||||
@@ -308,8 +308,8 @@ Content-Type: text/html; charset=UTF-8
|
|||||||
with only one client, and the
|
with only one client, and the
|
||||||
<option>--keep-open</option><indexterm><primary><option>--keep-open</option> (Ncat option)</primary><secondary>not supported with UDP</secondary></indexterm>
|
<option>--keep-open</option><indexterm><primary><option>--keep-open</option> (Ncat option)</primary><secondary>not supported with UDP</secondary></indexterm>
|
||||||
option doesn't work, the reason for this being that UDP has no notion
|
option doesn't work, the reason for this being that UDP has no notion
|
||||||
of a connection. UDP may not be combined with
|
of a connection. UDP may be secured by a form of SSL called Datagram TLS (DTLS)<indexterm><primary>DTLS</primary><secondary>Datagram TLS</secondary></indexterm>.
|
||||||
SSL.<indexterm><primary>SSL</primary><secondary>not supported with UDP</secondary></indexterm>
|
This is currently only supported in connect (client) mode.<indexterm><primary>SSL</primary><secondary>not supported with UDP in server mode</secondary></indexterm>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|||||||
@@ -256,6 +256,30 @@ static void set_ssl_ctx_options(SSL_CTX *ctx)
|
|||||||
if (!SSL_CTX_set_cipher_list(ctx, o.sslciphers))
|
if (!SSL_CTX_set_cipher_list(ctx, o.sslciphers))
|
||||||
bye("Unable to set OpenSSL cipher list: %s", ERR_error_string(ERR_get_error(), NULL));
|
bye("Unable to set OpenSSL cipher list: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ALPN_SUPPORT
|
||||||
|
|
||||||
|
if (o.sslalpn) {
|
||||||
|
size_t alpn_len;
|
||||||
|
unsigned char *alpn = next_protos_parse(&alpn_len, o.sslalpn);
|
||||||
|
|
||||||
|
if (alpn == NULL)
|
||||||
|
bye("Could not parse ALPN string");
|
||||||
|
|
||||||
|
if (o.debug)
|
||||||
|
logdebug("Using ALPN String %s\n", o.sslalpn);
|
||||||
|
|
||||||
|
/* SSL_CTX_set_alpn_protos returns 0 on success */
|
||||||
|
if (SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len) != 0){
|
||||||
|
free(alpn);
|
||||||
|
bye("SSL_CTX_set_alpn_protos: %s.", ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(alpn);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -878,6 +902,51 @@ static int do_proxy_socks5(void)
|
|||||||
return(sd);
|
return(sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
bye("Failed to set hostname on iod.");
|
||||||
|
|
||||||
|
switch (srcaddr.storage.ss_family) {
|
||||||
|
case AF_UNSPEC:
|
||||||
|
break;
|
||||||
|
case AF_INET:
|
||||||
|
nsock_iod_set_localaddr(nsi, &srcaddr.storage,
|
||||||
|
sizeof(srcaddr.in));
|
||||||
|
break;
|
||||||
|
#ifdef AF_INET6
|
||||||
|
case AF_INET6:
|
||||||
|
nsock_iod_set_localaddr(nsi, &srcaddr.storage,
|
||||||
|
sizeof(srcaddr.in6));
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if HAVE_SYS_UN_H
|
||||||
|
case AF_UNIX:
|
||||||
|
nsock_iod_set_localaddr(nsi, &srcaddr.storage,
|
||||||
|
SUN_LEN((struct sockaddr_un *)&srcaddr.storage));
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
nsock_iod_set_localaddr(nsi, &srcaddr.storage,
|
||||||
|
sizeof(srcaddr.storage));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.numsrcrtes) {
|
||||||
|
unsigned char *ipopts = NULL;
|
||||||
|
size_t ipoptslen = 0;
|
||||||
|
|
||||||
|
if (o.af != AF_INET)
|
||||||
|
bye("Sorry, -g can only currently be used with IPv4.");
|
||||||
|
ipopts = buildsrcrte(targetaddrs->addr.in.sin_addr, o.srcrtes, o.numsrcrtes, o.srcrteptr, &ipoptslen);
|
||||||
|
|
||||||
|
nsock_iod_set_ipoptions(nsi, ipopts, ipoptslen);
|
||||||
|
free(ipopts); /* Nsock has its own copy */
|
||||||
|
}
|
||||||
|
return nsi;
|
||||||
|
}
|
||||||
|
|
||||||
int ncat_connect(void)
|
int ncat_connect(void)
|
||||||
{
|
{
|
||||||
@@ -908,18 +977,15 @@ int ncat_connect(void)
|
|||||||
nsock_pool_set_broadcast(mypool, 1);
|
nsock_pool_set_broadcast(mypool, 1);
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
set_ssl_ctx_options((SSL_CTX *) nsock_pool_ssl_init(mypool, 0));
|
#ifdef HAVE_DTLS_CLIENT_METHOD
|
||||||
|
if(o.proto == IPPROTO_UDP)
|
||||||
|
set_ssl_ctx_options((SSL_CTX *) nsock_pool_dtls_init(mypool, 0));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
set_ssl_ctx_options((SSL_CTX *) nsock_pool_ssl_init(mypool, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!o.proxytype) {
|
if (!o.proxytype) {
|
||||||
/* A non-proxy connection. Create an iod for a new socket. */
|
|
||||||
cs.sock_nsi = nsock_iod_new(mypool, NULL);
|
|
||||||
if (cs.sock_nsi == NULL)
|
|
||||||
bye("Failed to create nsock_iod.");
|
|
||||||
|
|
||||||
if (nsock_iod_set_hostname(cs.sock_nsi, o.target) == -1)
|
|
||||||
bye("Failed to set hostname on iod.");
|
|
||||||
|
|
||||||
#if HAVE_SYS_UN_H
|
#if HAVE_SYS_UN_H
|
||||||
/* For DGRAM UNIX socket we have to use source socket */
|
/* For DGRAM UNIX socket we have to use source socket */
|
||||||
if (o.af == AF_UNIX && o.proto == IPPROTO_UDP)
|
if (o.af == AF_UNIX && o.proto == IPPROTO_UDP)
|
||||||
@@ -945,50 +1011,13 @@ int ncat_connect(void)
|
|||||||
strncpy(srcaddr.un.sun_path, tmp_name, sizeof(srcaddr.un.sun_path));
|
strncpy(srcaddr.un.sun_path, tmp_name, sizeof(srcaddr.un.sun_path));
|
||||||
free (tmp_name);
|
free (tmp_name);
|
||||||
}
|
}
|
||||||
nsock_iod_set_localaddr(cs.sock_nsi, &srcaddr.storage,
|
|
||||||
SUN_LEN((struct sockaddr_un *)&srcaddr.storage));
|
|
||||||
|
|
||||||
if (o.verbose)
|
if (o.verbose)
|
||||||
loguser("[%s] used as source DGRAM Unix domain socket.\n", srcaddr.un.sun_path);
|
loguser("[%s] used as source DGRAM Unix domain socket.\n", srcaddr.un.sun_path);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
switch (srcaddr.storage.ss_family) {
|
/* A non-proxy connection. Create an iod for a new socket. */
|
||||||
case AF_UNSPEC:
|
cs.sock_nsi = new_iod(mypool);
|
||||||
break;
|
|
||||||
case AF_INET:
|
|
||||||
nsock_iod_set_localaddr(cs.sock_nsi, &srcaddr.storage,
|
|
||||||
sizeof(srcaddr.in));
|
|
||||||
break;
|
|
||||||
#ifdef AF_INET6
|
|
||||||
case AF_INET6:
|
|
||||||
nsock_iod_set_localaddr(cs.sock_nsi, &srcaddr.storage,
|
|
||||||
sizeof(srcaddr.in6));
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if HAVE_SYS_UN_H
|
|
||||||
case AF_UNIX:
|
|
||||||
nsock_iod_set_localaddr(cs.sock_nsi, &srcaddr.storage,
|
|
||||||
SUN_LEN((struct sockaddr_un *)&srcaddr.storage));
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
nsock_iod_set_localaddr(cs.sock_nsi, &srcaddr.storage,
|
|
||||||
sizeof(srcaddr.storage));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.numsrcrtes) {
|
|
||||||
unsigned char *ipopts = NULL;
|
|
||||||
size_t ipoptslen = 0;
|
|
||||||
|
|
||||||
if (o.af != AF_INET)
|
|
||||||
bye("Sorry, -g can only currently be used with IPv4.");
|
|
||||||
ipopts = buildsrcrte(targetaddrs->addr.in.sin_addr, o.srcrtes, o.numsrcrtes, o.srcrteptr, &ipoptslen);
|
|
||||||
|
|
||||||
nsock_iod_set_ipoptions(cs.sock_nsi, ipopts, ipoptslen);
|
|
||||||
free(ipopts); /* Nsock has its own copy */
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SYS_UN_H
|
#if HAVE_SYS_UN_H
|
||||||
if (o.af == AF_UNIX) {
|
if (o.af == AF_UNIX) {
|
||||||
@@ -1068,35 +1097,27 @@ int ncat_connect(void)
|
|||||||
|
|
||||||
static void try_nsock_connect(nsock_pool nsp, struct sockaddr_list *conn_addr)
|
static void try_nsock_connect(nsock_pool nsp, struct sockaddr_list *conn_addr)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
if (o.ssl) {
|
||||||
|
nsock_connect_ssl(nsp, cs.sock_nsi, connect_handler,
|
||||||
|
o.conntimeout, (void *)conn_addr->next,
|
||||||
|
&conn_addr->addr.sockaddr, conn_addr->addrlen,
|
||||||
|
o.proto, inet_port(&conn_addr->addr),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if (o.proto == IPPROTO_UDP) {
|
if (o.proto == IPPROTO_UDP) {
|
||||||
nsock_connect_udp(nsp, cs.sock_nsi, connect_handler, (void *)conn_addr->next,
|
nsock_connect_udp(nsp, cs.sock_nsi, connect_handler, (void *)conn_addr->next,
|
||||||
&conn_addr->addr.sockaddr, conn_addr->addrlen,
|
&conn_addr->addr.sockaddr, conn_addr->addrlen,
|
||||||
inet_port(&conn_addr->addr));
|
inet_port(&conn_addr->addr));
|
||||||
}
|
}
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
else if (o.proto == IPPROTO_SCTP && o.ssl) {
|
|
||||||
nsock_connect_ssl(nsp, cs.sock_nsi, connect_handler,
|
|
||||||
o.conntimeout, (void *)conn_addr->next,
|
|
||||||
&conn_addr->addr.sockaddr, conn_addr->addrlen,
|
|
||||||
IPPROTO_SCTP, inet_port(&conn_addr->addr),
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (o.proto == IPPROTO_SCTP) {
|
else if (o.proto == IPPROTO_SCTP) {
|
||||||
nsock_connect_sctp(nsp, cs.sock_nsi, connect_handler,
|
nsock_connect_sctp(nsp, cs.sock_nsi, connect_handler,
|
||||||
o.conntimeout, (void *)conn_addr->next,
|
o.conntimeout, (void *)conn_addr->next,
|
||||||
&conn_addr->addr.sockaddr, conn_addr->addrlen,
|
&conn_addr->addr.sockaddr, conn_addr->addrlen,
|
||||||
inet_port(&conn_addr->addr));
|
inet_port(&conn_addr->addr));
|
||||||
}
|
}
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
else if (o.ssl) {
|
|
||||||
nsock_connect_ssl(nsp, cs.sock_nsi, connect_handler,
|
|
||||||
o.conntimeout, (void *)conn_addr->next,
|
|
||||||
&conn_addr->addr.sockaddr, conn_addr->addrlen,
|
|
||||||
IPPROTO_TCP, inet_port(&conn_addr->addr),
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
nsock_connect_tcp(nsp, cs.sock_nsi, connect_handler,
|
nsock_connect_tcp(nsp, cs.sock_nsi, connect_handler,
|
||||||
o.conntimeout, (void *)conn_addr->next,
|
o.conntimeout, (void *)conn_addr->next,
|
||||||
@@ -1132,6 +1153,13 @@ static void connect_handler(nsock_pool nsp, nsock_event evt, void *data)
|
|||||||
loguser("Connection to %s failed: %s.\n", inet_socktop(&peer), socket_strerror(errcode));
|
loguser("Connection to %s failed: %s.\n", inet_socktop(&peer), socket_strerror(errcode));
|
||||||
loguser("Trying next address...\n");
|
loguser("Trying next address...\n");
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
/* If it's an SSL reconnect, clear out any old session info */
|
||||||
|
if (nsock_iod_check_ssl(cs.sock_nsi)) {
|
||||||
|
nsock_iod_delete(cs.sock_nsi, NSOCK_PENDING_NOTIFY);
|
||||||
|
cs.sock_nsi = new_iod(nsp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
try_nsock_connect(nsp, next_addr);
|
try_nsock_connect(nsp, next_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ void options_init(void)
|
|||||||
o.sslverify = 0;
|
o.sslverify = 0;
|
||||||
o.ssltrustfile = NULL;
|
o.ssltrustfile = NULL;
|
||||||
o.sslciphers = NULL;
|
o.sslciphers = NULL;
|
||||||
|
o.sslalpn = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ struct options {
|
|||||||
int sslverify;
|
int sslverify;
|
||||||
char *ssltrustfile;
|
char *ssltrustfile;
|
||||||
char *sslciphers;
|
char *sslciphers;
|
||||||
|
char *sslalpn;
|
||||||
int zerobyte;
|
int zerobyte;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -264,6 +264,8 @@ static int ncat_listen_stream(int proto)
|
|||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
if (o.ssl)
|
if (o.ssl)
|
||||||
|
if (o.sslalpn)
|
||||||
|
bye("ALPN is not supported in listen mode\n");
|
||||||
setup_ssl_listen();
|
setup_ssl_listen();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -712,6 +714,11 @@ static int ncat_listen_dgram(int proto)
|
|||||||
struct timeval *tvp = NULL;
|
struct timeval *tvp = NULL;
|
||||||
unsigned int num_sockets;
|
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++) {
|
for (i = 0; i < NUM_LISTEN_ADDRS; i++) {
|
||||||
sockfd[i].fd = -1;
|
sockfd[i].fd = -1;
|
||||||
sockfd[i].addr.storage.ss_family = AF_UNSPEC;
|
sockfd[i].addr.storage.ss_family = AF_UNSPEC;
|
||||||
|
|||||||
@@ -320,12 +320,14 @@ int main(int argc, char *argv[])
|
|||||||
{"ssl-verify", no_argument, NULL, 0},
|
{"ssl-verify", no_argument, NULL, 0},
|
||||||
{"ssl-trustfile", required_argument, NULL, 0},
|
{"ssl-trustfile", required_argument, NULL, 0},
|
||||||
{"ssl-ciphers", required_argument, NULL, 0},
|
{"ssl-ciphers", required_argument, NULL, 0},
|
||||||
|
{"ssl-alpn", required_argument, NULL, 0},
|
||||||
#else
|
#else
|
||||||
{"ssl-cert", optional_argument, NULL, 0},
|
{"ssl-cert", optional_argument, NULL, 0},
|
||||||
{"ssl-key", optional_argument, NULL, 0},
|
{"ssl-key", optional_argument, NULL, 0},
|
||||||
{"ssl-verify", no_argument, NULL, 0},
|
{"ssl-verify", no_argument, NULL, 0},
|
||||||
{"ssl-trustfile", optional_argument, NULL, 0},
|
{"ssl-trustfile", optional_argument, NULL, 0},
|
||||||
{"ssl-ciphers", optional_argument, NULL, 0},
|
{"ssl-ciphers", optional_argument, NULL, 0},
|
||||||
|
{"ssl-alpn", optional_argument, NULL, 0},
|
||||||
#endif
|
#endif
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
@@ -536,7 +538,16 @@ int main(int argc, char *argv[])
|
|||||||
} else if (strcmp(long_options[option_index].name, "ssl-ciphers") == 0) {
|
} else if (strcmp(long_options[option_index].name, "ssl-ciphers") == 0) {
|
||||||
o.ssl = 1;
|
o.ssl = 1;
|
||||||
o.sslciphers = Strdup(optarg);
|
o.sslciphers = Strdup(optarg);
|
||||||
|
#ifdef HAVE_ALPN_SUPPORT
|
||||||
|
} else if (strcmp(long_options[option_index].name, "ssl-alpn") == 0) {
|
||||||
|
o.ssl = 1;
|
||||||
|
o.sslalpn = Strdup(optarg);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
} else if (strcmp(long_options[option_index].name, "ssl-alpn") == 0) {
|
||||||
|
bye("OpenSSL does not have ALPN support compiled in. The --ssl-alpn option cannot be chosen.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
else if (strcmp(long_options[option_index].name, "ssl-cert") == 0) {
|
else if (strcmp(long_options[option_index].name, "ssl-cert") == 0) {
|
||||||
bye("OpenSSL isn't compiled in. The --ssl-cert option cannot be chosen.");
|
bye("OpenSSL isn't compiled in. The --ssl-cert option cannot be chosen.");
|
||||||
@@ -548,6 +559,8 @@ int main(int argc, char *argv[])
|
|||||||
bye("OpenSSL isn't compiled in. The --ssl-trustfile option cannot be chosen.");
|
bye("OpenSSL isn't compiled in. The --ssl-trustfile option cannot be chosen.");
|
||||||
} else if (strcmp(long_options[option_index].name, "ssl-ciphers") == 0) {
|
} else if (strcmp(long_options[option_index].name, "ssl-ciphers") == 0) {
|
||||||
bye("OpenSSL isn't compiled in. The --ssl-ciphers option cannot be chosen.");
|
bye("OpenSSL isn't compiled in. The --ssl-ciphers 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.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LUA
|
#ifdef HAVE_LUA
|
||||||
@@ -637,6 +650,7 @@ int main(int argc, char *argv[])
|
|||||||
" --ssl-verify Verify trust and domain name of certificates\n"
|
" --ssl-verify Verify trust and domain name of certificates\n"
|
||||||
" --ssl-trustfile PEM file containing trusted SSL certificates\n"
|
" --ssl-trustfile PEM file containing trusted SSL certificates\n"
|
||||||
" --ssl-ciphers Cipherlist containing SSL ciphers to use\n"
|
" --ssl-ciphers Cipherlist containing SSL ciphers to use\n"
|
||||||
|
" --ssl-alpn ALPN protocol list to use.\n"
|
||||||
#endif
|
#endif
|
||||||
" --version Display Ncat's version information and exit\n"
|
" --version Display Ncat's version information and exit\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -903,9 +917,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (o.proto == IPPROTO_UDP) {
|
if (o.proto == IPPROTO_UDP) {
|
||||||
/* Don't allow a false sense of security if someone tries SSL over UDP. */
|
|
||||||
|
#ifndef HAVE_DTLS_CLIENT_METHOD
|
||||||
if (o.ssl)
|
if (o.ssl)
|
||||||
bye("UDP mode does not support SSL.");
|
bye("OpenSSL does not have DTLS support compiled in.");
|
||||||
|
#endif
|
||||||
if (o.keepopen && o.cmdexec == NULL)
|
if (o.keepopen && o.cmdexec == NULL)
|
||||||
bye("UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec.");
|
bye("UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec.");
|
||||||
if (o.broker)
|
if (o.broker)
|
||||||
|
|||||||
36
ncat/util.c
36
ncat/util.c
@@ -750,3 +750,39 @@ int fix_line_endings(char *src, int *len, char **dst, int *state)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* next_protos_parse parses a comma separated list of strings into a string
|
||||||
|
* in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
|
||||||
|
* outlen: (output) set to the length of the resulting buffer on success.
|
||||||
|
* err: NULL on failure
|
||||||
|
* in: a NULL terminated string like "abc,def,ghi"
|
||||||
|
*
|
||||||
|
* returns: a malloc'd buffer or NULL on failure.
|
||||||
|
*/
|
||||||
|
unsigned char *next_protos_parse(size_t *outlen, const char *in)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
unsigned char *out;
|
||||||
|
size_t i, start = 0;
|
||||||
|
|
||||||
|
len = strlen(in);
|
||||||
|
if (len >= 65535)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
out = safe_malloc(strlen(in) + 1);
|
||||||
|
for (i = 0; i <= len; ++i) {
|
||||||
|
if (i == len || in[i] == ',') {
|
||||||
|
if (i - start > 255) {
|
||||||
|
free(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
out[start] = i - start;
|
||||||
|
start = i + 1;
|
||||||
|
} else
|
||||||
|
out[i + 1] = in[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
*outlen = len + 1;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|||||||
@@ -230,4 +230,6 @@ struct fdinfo *get_fdinfo(const fd_list_t *, int);
|
|||||||
|
|
||||||
int fix_line_endings(char *src, int *len, char **dst, int *state);
|
int fix_line_endings(char *src, int *len, char **dst, int *state);
|
||||||
|
|
||||||
|
unsigned char *next_protos_parse(size_t *outlen, const char *in);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -248,6 +248,13 @@ void nsock_pool_set_device(nsock_pool nsp, const char *device);
|
|||||||
#define NSOCK_SSL_MAX_SPEED (1 << 0)
|
#define NSOCK_SSL_MAX_SPEED (1 << 0)
|
||||||
nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags);
|
nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags);
|
||||||
|
|
||||||
|
/* Initializes an Nsock pool to create a DTLS connect. This sets and internal
|
||||||
|
* SSL_CTX, which is like a template that sets options for all connections that
|
||||||
|
* are made from it. Returns the SSL_CTX so tyou can set your own options.
|
||||||
|
*
|
||||||
|
* Functionally similar to nsock_pool_ssl_init, just for the DTLS */
|
||||||
|
nsock_ssl_ctx nsock_pool_dtls_init(nsock_pool ms_pool, int flags);
|
||||||
|
|
||||||
/* Enforce use of a given IO engine.
|
/* Enforce use of a given IO engine.
|
||||||
* The engine parameter is a zero-terminated string that will be
|
* The engine parameter is a zero-terminated string that will be
|
||||||
* strup()'ed by the library. No validity check is performed by this function,
|
* strup()'ed by the library. No validity check is performed by this function,
|
||||||
|
|||||||
@@ -82,6 +82,8 @@
|
|||||||
|
|
||||||
#undef HAVE_OPENSSL
|
#undef HAVE_OPENSSL
|
||||||
#undef HAVE_SSL_SET_TLSEXT_HOST_NAME
|
#undef HAVE_SSL_SET_TLSEXT_HOST_NAME
|
||||||
|
#undef HAVE_DTLS_CLIENT_METHOD
|
||||||
|
#undef HAVE_ALPN_SUPPORT
|
||||||
|
|
||||||
#undef HAVE_EPOLL
|
#undef HAVE_EPOLL
|
||||||
#undef HAVE_POLL
|
#undef HAVE_POLL
|
||||||
|
|||||||
60
nsock/src/configure
vendored
60
nsock/src/configure
vendored
@@ -664,6 +664,7 @@ infodir
|
|||||||
docdir
|
docdir
|
||||||
oldincludedir
|
oldincludedir
|
||||||
includedir
|
includedir
|
||||||
|
runstatedir
|
||||||
localstatedir
|
localstatedir
|
||||||
sharedstatedir
|
sharedstatedir
|
||||||
sysconfdir
|
sysconfdir
|
||||||
@@ -738,6 +739,7 @@ datadir='${datarootdir}'
|
|||||||
sysconfdir='${prefix}/etc'
|
sysconfdir='${prefix}/etc'
|
||||||
sharedstatedir='${prefix}/com'
|
sharedstatedir='${prefix}/com'
|
||||||
localstatedir='${prefix}/var'
|
localstatedir='${prefix}/var'
|
||||||
|
runstatedir='${localstatedir}/run'
|
||||||
includedir='${prefix}/include'
|
includedir='${prefix}/include'
|
||||||
oldincludedir='/usr/include'
|
oldincludedir='/usr/include'
|
||||||
docdir='${datarootdir}/doc/${PACKAGE}'
|
docdir='${datarootdir}/doc/${PACKAGE}'
|
||||||
@@ -990,6 +992,15 @@ do
|
|||||||
| -silent | --silent | --silen | --sile | --sil)
|
| -silent | --silent | --silen | --sile | --sil)
|
||||||
silent=yes ;;
|
silent=yes ;;
|
||||||
|
|
||||||
|
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||||
|
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||||
|
| --run | --ru | --r)
|
||||||
|
ac_prev=runstatedir ;;
|
||||||
|
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||||
|
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||||
|
| --run=* | --ru=* | --r=*)
|
||||||
|
runstatedir=$ac_optarg ;;
|
||||||
|
|
||||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||||
ac_prev=sbindir ;;
|
ac_prev=sbindir ;;
|
||||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||||
@@ -1127,7 +1138,7 @@ fi
|
|||||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||||
libdir localedir mandir
|
libdir localedir mandir runstatedir
|
||||||
do
|
do
|
||||||
eval ac_val=\$$ac_var
|
eval ac_val=\$$ac_var
|
||||||
# Remove trailing slashes.
|
# Remove trailing slashes.
|
||||||
@@ -1280,6 +1291,7 @@ Fine tuning of the installation directories:
|
|||||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||||
|
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||||
--includedir=DIR C header files [PREFIX/include]
|
--includedir=DIR C header files [PREFIX/include]
|
||||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||||
@@ -4908,6 +4920,52 @@ if ac_fn_c_try_link "$LINENO"; then :
|
|||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
$as_echo "yes" >&6; }; $as_echo "#define HAVE_SSL_SET_TLSEXT_HOST_NAME 1" >>confdefs.h
|
$as_echo "yes" >&6; }; $as_echo "#define HAVE_SSL_SET_TLSEXT_HOST_NAME 1" >>confdefs.h
|
||||||
|
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTLS_client_method" >&5
|
||||||
|
$as_echo_n "checking for DTLS_client_method... " >&6; }
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
DTLS_client_method()
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"; then :
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }; $as_echo "#define HAVE_DTLS_CLIENT_METHOD 1" >>confdefs.h
|
||||||
|
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_set_alpn_protos" >&5
|
||||||
|
$as_echo_n "checking for SSL_set_alpn_protos... " >&6; }
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
SSL_set_alpn_protos(NULL, NULL, 0)
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"; then :
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }; $as_echo "#define HAVE_ALPN_SUPPORT 1" >>confdefs.h
|
||||||
|
|
||||||
else
|
else
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
$as_echo "no" >&6; }
|
$as_echo "no" >&6; }
|
||||||
|
|||||||
@@ -263,6 +263,14 @@ if test "$use_openssl" = "yes"; then
|
|||||||
AC_TRY_LINK([#include <openssl/ssl.h>], [SSL_set_tlsext_host_name(NULL, NULL)],
|
AC_TRY_LINK([#include <openssl/ssl.h>], [SSL_set_tlsext_host_name(NULL, NULL)],
|
||||||
[AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_SSL_SET_TLSEXT_HOST_NAME)],
|
[AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_SSL_SET_TLSEXT_HOST_NAME)],
|
||||||
[AC_MSG_RESULT([no])])
|
[AC_MSG_RESULT([no])])
|
||||||
|
AC_MSG_CHECKING([for DTLS_client_method])
|
||||||
|
AC_TRY_LINK([#include <openssl/ssl.h>], [DTLS_client_method()],
|
||||||
|
[AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_DTLS_CLIENT_METHOD)],
|
||||||
|
[AC_MSG_RESULT([no])])
|
||||||
|
AC_MSG_CHECKING([for SSL_set_alpn_protos])
|
||||||
|
AC_TRY_LINK([#include <openssl/ssl.h>], [SSL_set_alpn_protos(NULL, NULL, 0)],
|
||||||
|
[AC_MSG_RESULT([yes]); AC_DEFINE(HAVE_ALPN_SUPPORT)],
|
||||||
|
[AC_MSG_RESULT([no])])
|
||||||
LIBS="$LIBS_TMP"
|
LIBS="$LIBS_TMP"
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -184,8 +184,8 @@ int nsock_setup_udp(nsock_pool nsp, nsock_iod ms_iod, int af) {
|
|||||||
return nsi->sd;
|
return nsi->sd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This does the actual logistics of requesting a TCP connection. It is shared
|
/* This does the actual logistics of requesting a connection. It is shared
|
||||||
* by nsock_connect_tcp and nsock_connect_ssl */
|
* by nsock_connect_tcp and nsock_connect_ssl, among others */
|
||||||
void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int proto, struct sockaddr_storage *ss, size_t sslen,
|
void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int proto, struct sockaddr_storage *ss, size_t sslen,
|
||||||
unsigned short port) {
|
unsigned short port) {
|
||||||
|
|
||||||
@@ -256,7 +256,7 @@ void nsock_connect_internal(struct npool *ms, struct nevent *nse, int type, int
|
|||||||
if (ms->engine->io_operations->iod_connect(ms, iod->sd, (struct sockaddr *)ss, sslen) == -1) {
|
if (ms->engine->io_operations->iod_connect(ms, iod->sd, (struct sockaddr *)ss, sslen) == -1) {
|
||||||
int err = socket_errno();
|
int err = socket_errno();
|
||||||
|
|
||||||
if (proto == IPPROTO_UDP || (err != EINPROGRESS && err != EAGAIN)) {
|
if ((proto == IPPROTO_UDP) || (err != EINPROGRESS && err != EAGAIN)) {
|
||||||
nse->event_done = 1;
|
nse->event_done = 1;
|
||||||
nse->status = NSE_STATUS_ERROR;
|
nse->status = NSE_STATUS_ERROR;
|
||||||
nse->errnum = err;
|
nse->errnum = err;
|
||||||
@@ -376,7 +376,7 @@ nsock_event_id nsock_connect_sctp(nsock_pool nsp, nsock_iod ms_iod, nsock_ev_han
|
|||||||
return nse->id;
|
return nse->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Request an SSL over TCP/SCTP connection to another system (by IP address).
|
/* Request an SSL over TCP/SCTP/UDP connection to another system (by IP address).
|
||||||
* The in_addr is normal network byte order, but the port number should be given
|
* The in_addr is normal network byte order, but the port number should be given
|
||||||
* in HOST BYTE ORDER. This function will call back only after it has made the
|
* in HOST BYTE ORDER. This function will call back only after it has made the
|
||||||
* connection AND done the initial SSL negotiation. From that point on, you use
|
* connection AND done the initial SSL negotiation. From that point on, you use
|
||||||
@@ -397,7 +397,12 @@ nsock_event_id nsock_connect_ssl(nsock_pool nsp, nsock_iod nsiod, nsock_ev_handl
|
|||||||
struct nevent *nse;
|
struct nevent *nse;
|
||||||
|
|
||||||
if (!ms->sslctx)
|
if (!ms->sslctx)
|
||||||
nsock_pool_ssl_init(ms, 0);
|
{
|
||||||
|
if (proto == IPPROTO_UDP)
|
||||||
|
nsock_pool_dtls_init(ms, 0);
|
||||||
|
else
|
||||||
|
nsock_pool_ssl_init(ms, 0);
|
||||||
|
}
|
||||||
|
|
||||||
assert(nsi->state == NSIOD_STATE_INITIAL || nsi->state == NSIOD_STATE_UNKNOWN);
|
assert(nsi->state == NSIOD_STATE_INITIAL || nsi->state == NSIOD_STATE_UNKNOWN);
|
||||||
|
|
||||||
@@ -405,14 +410,22 @@ nsock_event_id nsock_connect_ssl(nsock_pool nsp, nsock_iod nsiod, nsock_ev_handl
|
|||||||
assert(nse);
|
assert(nse);
|
||||||
|
|
||||||
/* Set our SSL_SESSION so we can benefit from session-id reuse. */
|
/* Set our SSL_SESSION so we can benefit from session-id reuse. */
|
||||||
nsi_set_ssl_session(nsi, (SSL_SESSION *)ssl_session);
|
/* but not with DTLS; save space in ClientHello message */
|
||||||
|
if (proto != IPPROTO_UDP)
|
||||||
|
nsi_set_ssl_session(nsi, (SSL_SESSION *)ssl_session);
|
||||||
|
|
||||||
nsock_log_info("SSL connection requested to %s:%hu/%s (IOD #%li) EID %li",
|
if (proto == IPPROTO_UDP)
|
||||||
|
nsock_log_info("DTLS connection requested to %s:%hu/udp (IOD #%li) EID %li",
|
||||||
|
|
||||||
|
inet_ntop_ez(ss, sslen), port, nsi->id, nse->id);
|
||||||
|
else
|
||||||
|
nsock_log_info("SSL connection requested to %s:%hu/%s (IOD #%li) EID %li",
|
||||||
inet_ntop_ez(ss, sslen), port, (proto == IPPROTO_TCP ? "tcp" : "sctp"),
|
inet_ntop_ez(ss, sslen), port, (proto == IPPROTO_TCP ? "tcp" : "sctp"),
|
||||||
nsi->id, nse->id);
|
nsi->id, nse->id);
|
||||||
|
|
||||||
/* Do the actual connect() */
|
/* Do the actual connect() */
|
||||||
nsock_connect_internal(ms, nse, SOCK_STREAM, proto, ss, sslen, port);
|
nsock_connect_internal(ms, nse, (proto == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM), proto, ss, sslen, port);
|
||||||
|
|
||||||
nsock_pool_add_event(ms, nse);
|
nsock_pool_add_event(ms, nse);
|
||||||
|
|
||||||
return nse->id;
|
return nse->id;
|
||||||
|
|||||||
@@ -377,7 +377,9 @@ void handle_connect_result(struct npool *ms, struct nevent *nse, enum nse_status
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_SSL_SET_TLSEXT_HOST_NAME
|
#if HAVE_SSL_SET_TLSEXT_HOST_NAME
|
||||||
if (iod->hostname != NULL) {
|
/* Avoid sending SNI extension with DTLS because many servers don't allow
|
||||||
|
* fragmented ClientHello messages. */
|
||||||
|
if (iod->hostname != NULL && iod->lastproto != IPPROTO_UDP) {
|
||||||
if (SSL_set_tlsext_host_name(iod->ssl, iod->hostname) != 1)
|
if (SSL_set_tlsext_host_name(iod->ssl, iod->hostname) != 1)
|
||||||
fatal("SSL_set_tlsext_host_name failed: %s", ERR_error_string(ERR_get_error(), NULL));
|
fatal("SSL_set_tlsext_host_name failed: %s", ERR_error_string(ERR_get_error(), NULL));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,7 @@
|
|||||||
|
|
||||||
extern struct timeval nsock_tod;
|
extern struct timeval nsock_tod;
|
||||||
|
|
||||||
/* Create an SSL_CTX and do initialization that is common to all init modes. */
|
static SSL_CTX *ssl_init_helper(const SSL_METHOD *method) {
|
||||||
static SSL_CTX *ssl_init_common() {
|
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
|
||||||
@@ -89,7 +88,7 @@ static SSL_CTX *ssl_init_common() {
|
|||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
ctx = SSL_CTX_new(method);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
fatal("OpenSSL failed to create a new SSL_CTX: %s",
|
fatal("OpenSSL failed to create a new SSL_CTX: %s",
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
@@ -105,18 +104,19 @@ static SSL_CTX *ssl_init_common() {
|
|||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create an SSL_CTX and do initialization that is common to all init modes. */
|
||||||
|
static SSL_CTX *ssl_init_common() {
|
||||||
|
return ssl_init_helper(SSLv23_client_method());
|
||||||
|
}
|
||||||
|
|
||||||
/* Initializes an Nsock pool to create SSL connections. This sets an internal
|
/* Initializes an Nsock pool to create SSL connections. This sets an internal
|
||||||
* SSL_CTX, which is like a template that sets options for all connections that
|
* SSL_CTX, which is like a template that sets options for all connections that
|
||||||
* are made from it. The connections made from this context will use only secure
|
* are made from it. The connections made from this context will use only secure
|
||||||
* ciphers but no server certificate verification is done. Returns the SSL_CTX
|
* ciphers but no server certificate verification is done. Returns the SSL_CTX
|
||||||
* so you can set your own options. */
|
* so you can set your own options. */
|
||||||
nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags) {
|
static nsock_ssl_ctx nsock_pool_ssl_init_helper(struct npool *ms, int flags) {
|
||||||
struct npool *ms = (struct npool *)ms_pool;
|
|
||||||
char rndbuf[128];
|
char rndbuf[128];
|
||||||
|
|
||||||
if (ms->sslctx == NULL)
|
|
||||||
ms->sslctx = ssl_init_common();
|
|
||||||
|
|
||||||
/* Get_random_bytes may or may not provide high-quality randomness. Add it to
|
/* Get_random_bytes may or may not provide high-quality randomness. Add it to
|
||||||
* the entropy pool without increasing the entropy estimate (third argument of
|
* the entropy pool without increasing the entropy estimate (third argument of
|
||||||
* RAND_add is 0). We rely on OpenSSL's entropy gathering, called implicitly
|
* RAND_add is 0). We rely on OpenSSL's entropy gathering, called implicitly
|
||||||
@@ -146,6 +146,49 @@ nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags) {
|
|||||||
return ms->sslctx;
|
return ms->sslctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags) {
|
||||||
|
struct npool *ms = (struct npool *)ms_pool;
|
||||||
|
|
||||||
|
if (ms->sslctx == NULL)
|
||||||
|
ms->sslctx = ssl_init_common();
|
||||||
|
return nsock_pool_ssl_init_helper(ms, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DTLS_CLIENT_METHOD
|
||||||
|
|
||||||
|
/* Create an SSL_CTX and do initialisation, creating a DTLS client */
|
||||||
|
static SSL_CTX *dtls_init_common() {
|
||||||
|
return ssl_init_helper(DTLS_client_method());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initializes an Nsock pool to create DTLS connections. Very much similar to
|
||||||
|
* nsock_pool_ssl_init, just with DTLS. */
|
||||||
|
nsock_ssl_ctx nsock_pool_dtls_init(nsock_pool ms_pool, int flags) {
|
||||||
|
SSL_CTX *dtls_ctx = NULL;
|
||||||
|
struct npool *ms = (struct npool *)ms_pool;
|
||||||
|
|
||||||
|
if (ms->sslctx == NULL)
|
||||||
|
ms->sslctx = dtls_init_common();
|
||||||
|
dtls_ctx = (SSL_CTX *) nsock_pool_ssl_init_helper(ms, flags);
|
||||||
|
|
||||||
|
/* Don't add padding or the ClientHello will fragment and not connect properly. */
|
||||||
|
SSL_CTX_clear_options(dtls_ctx, SSL_OP_TLSEXT_PADDING);
|
||||||
|
|
||||||
|
if (!SSL_CTX_set_cipher_list(dtls_ctx, "DEFAULT"))
|
||||||
|
fatal("Unable to set OpenSSL cipher list: %s",
|
||||||
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
|
||||||
|
return dtls_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* OpenSSL Version does not support DTLS */
|
||||||
|
|
||||||
|
nsock_ssl_ctx nsock_pool_dtls_init(nsock_pool ms_pool, int flags) {
|
||||||
|
fatal("%s called with no OpenSSL DTLS support", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check server certificate verification, after a connection is established. We
|
/* Check server certificate verification, after a connection is established. We
|
||||||
* check first that a certificate was even offered, then call
|
* check first that a certificate was even offered, then call
|
||||||
* SSL_get_verify_result to get the overall status of verification. (Just
|
* SSL_get_verify_result to get the overall status of verification. (Just
|
||||||
@@ -180,6 +223,10 @@ nsock_ssl_ctx nsock_pool_ssl_init(nsock_pool ms_pool, int flags) {
|
|||||||
fatal("%s called with no OpenSSL support", __func__);
|
fatal("%s called with no OpenSSL support", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsock_ssl_ctx nsock_pool_dtls_init(nsock_pool ms_pool, int flags) {
|
||||||
|
fatal("%s called with no OpenSSL support", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
int nsi_ssl_post_connect_verify(const nsock_iod nsockiod) {
|
int nsi_ssl_post_connect_verify(const nsock_iod nsockiod) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user