summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbeck <>2015-09-11 21:07:01 +0000
committerbeck <>2015-09-11 21:07:01 +0000
commit37a2330d0f355087b739ffe7d0a69f1f0d87055d (patch)
tree388c48fe01cb6fc8e34d78f32f9557bce52e0311
parent150d9a597eaa22312d0f25f7714b9d3cbfb1ce2d (diff)
downloadopenbsd-37a2330d0f355087b739ffe7d0a69f1f0d87055d.tar.gz
openbsd-37a2330d0f355087b739ffe7d0a69f1f0d87055d.tar.bz2
openbsd-37a2330d0f355087b739ffe7d0a69f1f0d87055d.zip
Add TLS suppport to nc. Provides a useful little test and script tool.
ok jsing@ bluhm@
-rw-r--r--src/usr.bin/nc/Makefile4
-rw-r--r--src/usr.bin/nc/nc.151
-rw-r--r--src/usr.bin/nc/netcat.c336
3 files changed, 346 insertions, 45 deletions
diff --git a/src/usr.bin/nc/Makefile b/src/usr.bin/nc/Makefile
index 150f8295bd..5f20c40cf7 100644
--- a/src/usr.bin/nc/Makefile
+++ b/src/usr.bin/nc/Makefile
@@ -1,6 +1,8 @@
1# $OpenBSD: Makefile,v 1.6 2001/09/02 18:45:41 jakob Exp $ 1# $OpenBSD: Makefile,v 1.7 2015/09/11 21:07:01 beck Exp $
2 2
3PROG= nc 3PROG= nc
4SRCS= netcat.c atomicio.c socks.c 4SRCS= netcat.c atomicio.c socks.c
5LDADD+= -ltls -lssl -lcrypto
6DPADD+= ${LIBTLS} ${LIBSSL} ${LIBCRYPTO}
5 7
6.include <bsd.prog.mk> 8.include <bsd.prog.mk>
diff --git a/src/usr.bin/nc/nc.1 b/src/usr.bin/nc/nc.1
index d83cb5ca8d..8cb96e8734 100644
--- a/src/usr.bin/nc/nc.1
+++ b/src/usr.bin/nc/nc.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: nc.1,v 1.68 2015/03/26 10:35:04 tobias Exp $ 1.\" $OpenBSD: nc.1,v 1.69 2015/09/11 21:07:01 beck Exp $
2.\" 2.\"
3.\" Copyright (c) 1996 David Sacerdote 3.\" Copyright (c) 1996 David Sacerdote
4.\" All rights reserved. 4.\" All rights reserved.
@@ -25,7 +25,7 @@
25.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27.\" 27.\"
28.Dd $Mdocdate: March 26 2015 $ 28.Dd $Mdocdate: September 11 2015 $
29.Dt NC 1 29.Dt NC 1
30.Os 30.Os
31.Sh NAME 31.Sh NAME
@@ -41,7 +41,7 @@
41.Op Fl P Ar proxy_username 41.Op Fl P Ar proxy_username
42.Op Fl p Ar source_port 42.Op Fl p Ar source_port
43.Op Fl s Ar source 43.Op Fl s Ar source
44.Op Fl T Ar toskeyword 44.Op Fl T Ar keyword
45.Op Fl V Ar rtable 45.Op Fl V Ar rtable
46.Op Fl w Ar timeout 46.Op Fl w Ar timeout
47.Op Fl X Ar proxy_protocol 47.Op Fl X Ar proxy_protocol
@@ -98,10 +98,18 @@ to use IPv4 addresses only.
98Forces 98Forces
99.Nm 99.Nm
100to use IPv6 addresses only. 100to use IPv6 addresses only.
101.It Fl C Ar certificate_filename
102Specifies the filename from which the public key part of the TLS
103certificate is loaded, in PEM format. May only be used with TLS.
104.It Fl c
105If using a TCP socket to connect or listen, use TLS. Illegal if not using TCP sockets.
101.It Fl D 106.It Fl D
102Enable debugging on the socket. 107Enable debugging on the socket.
103.It Fl d 108.It Fl d
104Do not attempt to read from stdin. 109Do not attempt to read from stdin.
110.It Fl e Ar name
111specify the name that must be present in the peer certificate when using TLS.
112Illegal if not using TLS.
105.It Fl F 113.It Fl F
106Pass the first connected socket using 114Pass the first connected socket using
107.Xr sendmsg 2 115.Xr sendmsg 2
@@ -117,6 +125,11 @@ using the
117.Xr ssh_config 5 125.Xr ssh_config 5
118.Cm ProxyUseFdpass 126.Cm ProxyUseFdpass
119option). 127option).
128.It Fl H Ar hash_string
129Specifies the required hash string of the peer certificate when using TLS.
130The string format required is that used by
131.Xr tls_peer_cert_hash 3 .
132Illegal if not using TLS, and may not be used with -T noverify.
120.It Fl h 133.It Fl h
121Prints out 134Prints out
122.Nm 135.Nm
@@ -126,6 +139,9 @@ Specifies the size of the TCP receive buffer.
126.It Fl i Ar interval 139.It Fl i Ar interval
127Specifies a delay time interval between lines of text sent and received. 140Specifies a delay time interval between lines of text sent and received.
128Also causes a delay time between connections to multiple ports. 141Also causes a delay time between connections to multiple ports.
142.It Fl K Ar key_filename
143Specifies the filename from which the private key
144is loaded in PEM format. May only be used with TLS.
129.It Fl k 145.It Fl k
130Forces 146Forces
131.Nm 147.Nm
@@ -172,6 +188,11 @@ should use, subject to privilege restrictions and availability.
172It is an error to use this option in conjunction with the 188It is an error to use this option in conjunction with the
173.Fl l 189.Fl l
174option. 190option.
191.It Fl R Ar CA_filename
192Specifies the filename from which the root CA bundle for Certificate
193verification is loaded in pem format. Illegal if not using TLS.
194Default value is
195.Pa /etc/ssl/cert.pem .
175.It Fl r 196.It Fl r
176Specifies that source and/or destination ports should be chosen randomly 197Specifies that source and/or destination ports should be chosen randomly
177instead of sequentially within a range or in the order that the system 198instead of sequentially within a range or in the order that the system
@@ -187,9 +208,22 @@ to create and use so that datagrams can be received.
187It is an error to use this option in conjunction with the 208It is an error to use this option in conjunction with the
188.Fl l 209.Fl l
189option. 210option.
190.It Fl T Ar toskeyword 211.It Fl T Ar keyword
191Change IPv4 TOS value. 212Change IPv4 TOS value or TLS options.
192.Ar toskeyword 213For TLS options
214.Ar keyword
215may be one of
216.Ar tlslegacy ,
217which allows legacy TLS protocols,
218.Ar noverify ,
219which disables certificate verification
220.Ar noname ,
221which disables certificate name checking, or
222.Ar clientcert,
223which requires a client certificate on incoming connections .
224It is illegal to specify TLS options if not using TLS.
225For IPv4 TOS value
226.Ar keyword
193may be one of 227may be one of
194.Ar critical , 228.Ar critical ,
195.Ar inetcontrol , 229.Ar inetcontrol ,
@@ -429,6 +463,11 @@ the source port, with a timeout of 5 seconds:
429.Pp 463.Pp
430.Dl $ nc -p 31337 -w 5 host.example.com 42 464.Dl $ nc -p 31337 -w 5 host.example.com 42
431.Pp 465.Pp
466Open a TCP connection to port 443 of www.google.ca, and negotiate
467TLS. Check for a different name in the certificate for validation.
468.Pp
469.Dl $ nc -v -c -e adsf.au.doubleclick.net www.google.ca 443
470.Pp
432Open a UDP connection to port 53 of host.example.com: 471Open a UDP connection to port 53 of host.example.com:
433.Pp 472.Pp
434.Dl $ nc -u host.example.com 53 473.Dl $ nc -u host.example.com 53
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c
index ce613cd75d..3909f70817 100644
--- a/src/usr.bin/nc/netcat.c
+++ b/src/usr.bin/nc/netcat.c
@@ -1,6 +1,7 @@
1/* $OpenBSD: netcat.c,v 1.132 2015/09/08 17:28:47 bluhm Exp $ */ 1/* $OpenBSD: netcat.c,v 1.133 2015/09/11 21:07:01 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> 3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
4 * Copyright (c) 2015 Bob Beck. All rights reserved.
4 * 5 *
5 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
@@ -54,6 +55,7 @@
54#include <stdlib.h> 55#include <stdlib.h>
55#include <string.h> 56#include <string.h>
56#include <unistd.h> 57#include <unistd.h>
58#include <tls.h>
57#include "atomicio.h" 59#include "atomicio.h"
58 60
59#ifndef SUN_LEN 61#ifndef SUN_LEN
@@ -70,6 +72,12 @@
70#define POLL_NETIN 2 72#define POLL_NETIN 2
71#define POLL_STDOUT 3 73#define POLL_STDOUT 3
72#define BUFSIZE 16384 74#define BUFSIZE 16384
75#define DEFAULT_CA_FILE "/etc/ssl/cert.pem"
76
77#define TLS_LEGACY (1 << 1)
78#define TLS_NOVERIFY (1 << 2)
79#define TLS_NONAME (1 << 3)
80#define TLS_CCERT (1 << 4)
73 81
74/* Command Line Options */ 82/* Command Line Options */
75int dflag; /* detached, no stdin */ 83int dflag; /* detached, no stdin */
@@ -95,6 +103,16 @@ int Sflag; /* TCP MD5 signature option */
95int Tflag = -1; /* IP Type of Service */ 103int Tflag = -1; /* IP Type of Service */
96int rtableid = -1; 104int rtableid = -1;
97 105
106int usetls; /* use TLS */
107char *Cflag; /* Public cert file */
108char *Kflag; /* Private key file */
109char *Rflag = DEFAULT_CA_FILE; /* Root CA file */
110int tls_cachanged; /* Using non-default CA file */
111int TLSopt; /* TLS options */
112char *tls_expectname; /* required name in peer cert */
113char *tls_peerhash; /* hash of peer cert */
114char *tls_expecthash; /* required hash of peer cert */
115
98int timeout = -1; 116int timeout = -1;
99int family = AF_UNSPEC; 117int family = AF_UNSPEC;
100char *portlist[PORT_MAX+1]; 118char *portlist[PORT_MAX+1];
@@ -104,7 +122,7 @@ void atelnet(int, unsigned char *, unsigned int);
104void build_ports(char *); 122void build_ports(char *);
105void help(void); 123void help(void);
106int local_listen(char *, char *, struct addrinfo); 124int local_listen(char *, char *, struct addrinfo);
107void readwrite(int); 125void readwrite(int, struct tls *);
108void fdpass(int nfd) __attribute__((noreturn)); 126void fdpass(int nfd) __attribute__((noreturn));
109int remote_connect(const char *, const char *, struct addrinfo); 127int remote_connect(const char *, const char *, struct addrinfo);
110int timeout_connect(int, const struct sockaddr *, socklen_t); 128int timeout_connect(int, const struct sockaddr *, socklen_t);
@@ -116,10 +134,14 @@ int unix_connect(char *);
116int unix_listen(char *); 134int unix_listen(char *);
117void set_common_sockopts(int, int); 135void set_common_sockopts(int, int);
118int map_tos(char *, int *); 136int map_tos(char *, int *);
137int map_tls(char *, int *);
119void report_connect(const struct sockaddr *, socklen_t); 138void report_connect(const struct sockaddr *, socklen_t);
139void report_tls(struct tls * tls_ctx, char * host, char *tls_expectname);
120void usage(int); 140void usage(int);
121ssize_t drainbuf(int, unsigned char *, size_t *); 141ssize_t drainbuf(int, unsigned char *, size_t *, struct tls *);
122ssize_t fillbuf(int, unsigned char *, size_t *); 142ssize_t fillbuf(int, unsigned char *, size_t *, struct tls *);
143void tls_setup_client(struct tls *, int, char *);
144struct tls * tls_setup_server(struct tls *, int, char *);
123 145
124int 146int
125main(int argc, char *argv[]) 147main(int argc, char *argv[])
@@ -134,6 +156,8 @@ main(int argc, char *argv[])
134 const char *errstr, *proxyhost = "", *proxyport = NULL; 156 const char *errstr, *proxyhost = "", *proxyport = NULL;
135 struct addrinfo proxyhints; 157 struct addrinfo proxyhints;
136 char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; 158 char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
159 struct tls_config *tls_cfg = NULL;
160 struct tls *tls_ctx = NULL;
137 161
138 ret = 1; 162 ret = 1;
139 s = 0; 163 s = 0;
@@ -145,7 +169,7 @@ main(int argc, char *argv[])
145 signal(SIGPIPE, SIG_IGN); 169 signal(SIGPIPE, SIG_IGN);
146 170
147 while ((ch = getopt(argc, argv, 171 while ((ch = getopt(argc, argv,
148 "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { 172 "46C:cDde:FH:hI:i:K:klNnO:P:p:R:rSs:T:tUuV:vw:X:x:z")) != -1) {
149 switch (ch) { 173 switch (ch) {
150 case '4': 174 case '4':
151 family = AF_INET; 175 family = AF_INET;
@@ -166,12 +190,24 @@ main(int argc, char *argv[])
166 else 190 else
167 errx(1, "unsupported proxy protocol"); 191 errx(1, "unsupported proxy protocol");
168 break; 192 break;
193 case 'C':
194 Cflag = optarg;
195 break;
196 case 'c':
197 usetls = 1;
198 break;
169 case 'd': 199 case 'd':
170 dflag = 1; 200 dflag = 1;
171 break; 201 break;
202 case 'e':
203 tls_expectname = optarg;
204 break;
172 case 'F': 205 case 'F':
173 Fflag = 1; 206 Fflag = 1;
174 break; 207 break;
208 case 'H':
209 tls_expecthash = optarg;
210 break;
175 case 'h': 211 case 'h':
176 help(); 212 help();
177 break; 213 break;
@@ -180,6 +216,9 @@ main(int argc, char *argv[])
180 if (errstr) 216 if (errstr)
181 errx(1, "interval %s: %s", errstr, optarg); 217 errx(1, "interval %s: %s", errstr, optarg);
182 break; 218 break;
219 case 'K':
220 Kflag = optarg;
221 break;
183 case 'k': 222 case 'k':
184 kflag = 1; 223 kflag = 1;
185 break; 224 break;
@@ -198,6 +237,10 @@ main(int argc, char *argv[])
198 case 'p': 237 case 'p':
199 pflag = optarg; 238 pflag = optarg;
200 break; 239 break;
240 case 'R':
241 tls_cachanged = 1;
242 Rflag = optarg;
243 break;
201 case 'r': 244 case 'r':
202 rflag = 1; 245 rflag = 1;
203 break; 246 break;
@@ -256,6 +299,8 @@ main(int argc, char *argv[])
256 errno = 0; 299 errno = 0;
257 if (map_tos(optarg, &Tflag)) 300 if (map_tos(optarg, &Tflag))
258 break; 301 break;
302 if (map_tls(optarg, &TLSopt))
303 break;
259 if (strlen(optarg) > 1 && optarg[0] == '0' && 304 if (strlen(optarg) > 1 && optarg[0] == '0' &&
260 optarg[1] == 'x') 305 optarg[1] == 'x')
261 Tflag = (int)strtol(optarg, NULL, 16); 306 Tflag = (int)strtol(optarg, NULL, 16);
@@ -263,7 +308,7 @@ main(int argc, char *argv[])
263 Tflag = (int)strtonum(optarg, 0, 255, 308 Tflag = (int)strtonum(optarg, 0, 255,
264 &errstr); 309 &errstr);
265 if (Tflag < 0 || Tflag > 255 || errstr || errno) 310 if (Tflag < 0 || Tflag > 255 || errstr || errno)
266 errx(1, "illegal tos value %s", optarg); 311 errx(1, "illegal tos/tls value %s", optarg);
267 break; 312 break;
268 default: 313 default:
269 usage(1); 314 usage(1);
@@ -295,6 +340,22 @@ main(int argc, char *argv[])
295 errx(1, "cannot use -z and -l"); 340 errx(1, "cannot use -z and -l");
296 if (!lflag && kflag) 341 if (!lflag && kflag)
297 errx(1, "must use -l with -k"); 342 errx(1, "must use -l with -k");
343 if (uflag && usetls)
344 errx(1, "cannot use -c and -u");
345 if ((family == AF_UNIX) && usetls)
346 errx(1, "cannot use -c and -U");
347 if (TLSopt && !usetls)
348 errx(1, "you must specify -c to use TLS options");
349 if (Cflag && !usetls)
350 errx(1, "you must specify -c to use -C");
351 if (Kflag && !usetls)
352 errx(1, "you must specify -c to use -K");
353 if (tls_cachanged && !usetls)
354 errx(1, "you must specify -c to use -R");
355 if (tls_expecthash && !usetls)
356 errx(1, "you must specify -c to use -H");
357 if (tls_expectname && !usetls)
358 errx(1, "you must specify -c to use -e");
298 359
299 /* Get name of temporary socket for unix datagram client */ 360 /* Get name of temporary socket for unix datagram client */
300 if ((family == AF_UNIX) && uflag && !lflag) { 361 if ((family == AF_UNIX) && uflag && !lflag) {
@@ -347,7 +408,34 @@ main(int argc, char *argv[])
347 proxyhints.ai_flags |= AI_NUMERICHOST; 408 proxyhints.ai_flags |= AI_NUMERICHOST;
348 } 409 }
349 410
411 if (usetls) {
412 if (tls_init() == -1)
413 errx(1, "unable to initialize TLS");
414 if ((tls_cfg = tls_config_new()) == NULL)
415 errx(1, "unable to allocate TLS config");
416 if (Cflag && (tls_config_set_cert_file(tls_cfg, Cflag) == -1))
417 errx(1, "unable to set TLS certificate file %s", Cflag);
418 if (Kflag && (tls_config_set_key_file(tls_cfg, Kflag) == -1))
419 errx(1, "unable to set TLS key file %s", Kflag);
420 if (Rflag && (tls_config_set_ca_file(tls_cfg, Rflag) == -1))
421 errx(1, "unable to set root CA file %s", Rflag);
422 if (TLSopt & TLS_LEGACY) {
423 tls_config_set_protocols(tls_cfg, TLS_PROTOCOLS_ALL);
424 tls_config_set_ciphers(tls_cfg, "legacy");
425 }
426 if (!lflag && (TLSopt & TLS_CCERT))
427 errx(1, "clientcert is only valid with -l");
428 if (TLSopt & TLS_NONAME)
429 tls_config_insecure_noverifyname(tls_cfg);
430 if (TLSopt & TLS_NOVERIFY) {
431 if (tls_expecthash != NULL)
432 errx(1, "-H and -T noverify may not be used"
433 "together");
434 tls_config_insecure_noverifycert(tls_cfg);
435 }
436 }
350 if (lflag) { 437 if (lflag) {
438 struct tls *tls_cctx = NULL;
351 int connfd; 439 int connfd;
352 ret = 0; 440 ret = 0;
353 441
@@ -358,6 +446,14 @@ main(int argc, char *argv[])
358 s = unix_listen(host); 446 s = unix_listen(host);
359 } 447 }
360 448
449 if (usetls) {
450 tls_config_verify_client_optional(tls_cfg);
451 if ((tls_ctx = tls_server()) == NULL)
452 errx(1, "tls server creation failed");
453 if (tls_configure(tls_ctx, tls_cfg) == -1)
454 errx(1, "tls configuration failed (%s)",
455 tls_error(tls_ctx));
456 }
361 /* Allow only one connection at a time, but stay alive. */ 457 /* Allow only one connection at a time, but stay alive. */
362 for (;;) { 458 for (;;) {
363 if (family != AF_UNIX) 459 if (family != AF_UNIX)
@@ -369,7 +465,7 @@ main(int argc, char *argv[])
369 * receive datagrams from multiple socket pairs. 465 * receive datagrams from multiple socket pairs.
370 */ 466 */
371 if (uflag && kflag) 467 if (uflag && kflag)
372 readwrite(s); 468 readwrite(s, NULL);
373 /* 469 /*
374 * For UDP and not -k, we will use recvfrom() initially 470 * For UDP and not -k, we will use recvfrom() initially
375 * to wait for a caller, then use the regular functions 471 * to wait for a caller, then use the regular functions
@@ -394,7 +490,7 @@ main(int argc, char *argv[])
394 if (vflag) 490 if (vflag)
395 report_connect((struct sockaddr *)&z, len); 491 report_connect((struct sockaddr *)&z, len);
396 492
397 readwrite(s); 493 readwrite(s, NULL);
398 } else { 494 } else {
399 len = sizeof(cliaddr); 495 len = sizeof(cliaddr);
400 connfd = accept4(s, (struct sockaddr *)&cliaddr, 496 connfd = accept4(s, (struct sockaddr *)&cliaddr,
@@ -405,11 +501,23 @@ main(int argc, char *argv[])
405 } 501 }
406 if (vflag) 502 if (vflag)
407 report_connect((struct sockaddr *)&cliaddr, len); 503 report_connect((struct sockaddr *)&cliaddr, len);
408 504 if ((usetls) &&
409 readwrite(connfd); 505 (tls_cctx = tls_setup_server(tls_ctx, connfd,
506 host)))
507 readwrite(connfd, tls_cctx);
508 if (!usetls)
509 readwrite(connfd, NULL);
510 if (tls_cctx) {
511 int i;
512 do {
513 i = tls_close(tls_cctx);
514 } while (i == TLS_WANT_POLLIN ||
515 i == TLS_WANT_POLLOUT);
516 tls_free(tls_cctx);
517 tls_cctx = NULL;
518 }
410 close(connfd); 519 close(connfd);
411 } 520 }
412
413 if (family != AF_UNIX) 521 if (family != AF_UNIX)
414 close(s); 522 close(s);
415 else if (uflag) { 523 else if (uflag) {
@@ -424,7 +532,7 @@ main(int argc, char *argv[])
424 ret = 0; 532 ret = 0;
425 533
426 if ((s = unix_connect(host)) > 0 && !zflag) { 534 if ((s = unix_connect(host)) > 0 && !zflag) {
427 readwrite(s); 535 readwrite(s, NULL);
428 close(s); 536 close(s);
429 } else 537 } else
430 ret = 1; 538 ret = 1;
@@ -444,6 +552,13 @@ main(int argc, char *argv[])
444 if (s) 552 if (s)
445 close(s); 553 close(s);
446 554
555 if (usetls) {
556 if ((tls_ctx = tls_client()) == NULL)
557 errx(1, "tls client creation failed");
558 if (tls_configure(tls_ctx, tls_cfg) == -1)
559 errx(1, "tls configuration failed (%s)",
560 tls_error(tls_ctx));
561 }
447 if (xflag) 562 if (xflag)
448 s = socks_connect(host, portlist[i], hints, 563 s = socks_connect(host, portlist[i], hints,
449 proxyhost, proxyport, proxyhints, socksv, 564 proxyhost, proxyport, proxyhints, socksv,
@@ -481,14 +596,30 @@ main(int argc, char *argv[])
481 } 596 }
482 if (Fflag) 597 if (Fflag)
483 fdpass(s); 598 fdpass(s);
484 else if (!zflag) 599 else {
485 readwrite(s); 600 if (usetls)
601 tls_setup_client(tls_ctx, s, host);
602 if (!zflag)
603 readwrite(s, tls_ctx);
604 if (tls_ctx) {
605 int j;
606 do {
607 j = tls_close(tls_ctx);
608 } while (j == TLS_WANT_POLLIN ||
609 j == TLS_WANT_POLLOUT);
610 tls_free(tls_ctx);
611 tls_ctx = NULL;
612 }
613 }
486 } 614 }
487 } 615 }
488 616
489 if (s) 617 if (s)
490 close(s); 618 close(s);
491 619
620 free(tls_peerhash);
621 tls_config_free(tls_cfg);
622
492 exit(ret); 623 exit(ret);
493} 624}
494 625
@@ -524,6 +655,67 @@ unix_bind(char *path)
524 return (s); 655 return (s);
525} 656}
526 657
658void
659tls_setup_client(struct tls *tls_ctx, int s, char *host)
660
661{
662 int i;
663 if (tls_connect_socket(tls_ctx, s,
664 tls_expectname ? tls_expectname : host) == -1) {
665 errx(1, "tls connection failed (%s)",
666 tls_error(tls_ctx));
667 }
668 do {
669 if ((i = tls_handshake(tls_ctx)) == -1)
670 errx(1, "tls handshake failed (%s)",
671 tls_error(tls_ctx));
672 } while (i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT);
673 if (tls_peer_cert_hash(tls_ctx, &tls_peerhash) == -1)
674 errx(1, "hash of peer certificate failed");
675 if (vflag)
676 report_tls(tls_ctx, host, tls_expectname);
677 if (tls_expecthash && tls_peerhash &&
678 strcmp(tls_expecthash, tls_peerhash) != 0)
679 errx(1, "peer certificate is not %s", tls_expecthash);
680}
681struct tls *
682tls_setup_server(struct tls *tls_ctx, int connfd, char *host)
683{
684 struct tls *tls_cctx;
685 if (tls_accept_socket(tls_ctx, &tls_cctx,
686 connfd) == -1) {
687 warnx("tls accept failed (%s)",
688 tls_error(tls_ctx));
689 tls_cctx = NULL;
690 } else {
691 int i;
692 do {
693 if ((i = tls_handshake(tls_cctx)) == -1)
694 warnx("tls handshake failed (%s)",
695 tls_error(tls_cctx));
696 } while(i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT);
697 }
698 if (tls_cctx) {
699 int gotcert = tls_peer_cert_provided(tls_cctx);
700 if (gotcert && tls_peer_cert_hash(tls_cctx, &tls_peerhash) == -1)
701 warn("hash of peer certificate failed");
702 if (vflag && gotcert)
703 report_tls(tls_cctx, host, tls_expectname);
704 if ((TLSopt & TLS_CCERT) && !gotcert)
705 warnx("No client certificate provided");
706 else if (gotcert && tls_peerhash && tls_expecthash &&
707 strcmp(tls_expecthash, tls_peerhash) != 0)
708 warnx("peer certificate is not %s", tls_expecthash);
709 else if (gotcert && tls_expectname &&
710 (! tls_peer_cert_contains_name(tls_cctx, tls_expectname)))
711 warnx("name (%s) not found in client cert",
712 tls_expectname);
713 else {
714 return tls_cctx;
715 }
716 }
717 return NULL;
718}
527/* 719/*
528 * unix_connect() 720 * unix_connect()
529 * Returns a socket connected to a local unix socket. Returns -1 on failure. 721 * Returns a socket connected to a local unix socket. Returns -1 on failure.
@@ -731,7 +923,7 @@ local_listen(char *host, char *port, struct addrinfo hints)
731 * Loop that polls on the network file descriptor and stdin. 923 * Loop that polls on the network file descriptor and stdin.
732 */ 924 */
733void 925void
734readwrite(int net_fd) 926readwrite(int net_fd, struct tls *tls_ctx)
735{ 927{
736 struct pollfd pfd[4]; 928 struct pollfd pfd[4];
737 int stdin_fd = STDIN_FILENO; 929 int stdin_fd = STDIN_FILENO;
@@ -839,9 +1031,12 @@ readwrite(int net_fd)
839 /* try to read from stdin */ 1031 /* try to read from stdin */
840 if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) { 1032 if (pfd[POLL_STDIN].revents & POLLIN && stdinbufpos < BUFSIZE) {
841 ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf, 1033 ret = fillbuf(pfd[POLL_STDIN].fd, stdinbuf,
842 &stdinbufpos); 1034 &stdinbufpos, NULL);
843 /* error or eof on stdin - remove from pfd */ 1035 if (ret == TLS_WANT_POLLIN)
844 if (ret == 0 || ret == -1) 1036 pfd[POLL_STDIN].events = POLLIN;
1037 else if (ret == TLS_WANT_POLLOUT)
1038 pfd[POLL_STDIN].events = POLLOUT;
1039 else if (ret == 0 || ret == -1)
845 pfd[POLL_STDIN].fd = -1; 1040 pfd[POLL_STDIN].fd = -1;
846 /* read something - poll net out */ 1041 /* read something - poll net out */
847 if (stdinbufpos > 0) 1042 if (stdinbufpos > 0)
@@ -853,8 +1048,12 @@ readwrite(int net_fd)
853 /* try to write to network */ 1048 /* try to write to network */
854 if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) { 1049 if (pfd[POLL_NETOUT].revents & POLLOUT && stdinbufpos > 0) {
855 ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf, 1050 ret = drainbuf(pfd[POLL_NETOUT].fd, stdinbuf,
856 &stdinbufpos); 1051 &stdinbufpos, tls_ctx);
857 if (ret == -1) 1052 if (ret == TLS_WANT_POLLIN)
1053 pfd[POLL_NETOUT].events = POLLIN;
1054 else if (ret == TLS_WANT_POLLOUT)
1055 pfd[POLL_NETOUT].events = POLLOUT;
1056 else if (ret == -1)
858 pfd[POLL_NETOUT].fd = -1; 1057 pfd[POLL_NETOUT].fd = -1;
859 /* buffer empty - remove self from polling */ 1058 /* buffer empty - remove self from polling */
860 if (stdinbufpos == 0) 1059 if (stdinbufpos == 0)
@@ -866,8 +1065,12 @@ readwrite(int net_fd)
866 /* try to read from network */ 1065 /* try to read from network */
867 if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) { 1066 if (pfd[POLL_NETIN].revents & POLLIN && netinbufpos < BUFSIZE) {
868 ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf, 1067 ret = fillbuf(pfd[POLL_NETIN].fd, netinbuf,
869 &netinbufpos); 1068 &netinbufpos, tls_ctx);
870 if (ret == -1) 1069 if (ret == TLS_WANT_POLLIN)
1070 pfd[POLL_NETIN].events = POLLIN;
1071 else if (ret == TLS_WANT_POLLOUT)
1072 pfd[POLL_NETIN].events = POLLOUT;
1073 else if (ret == -1)
871 pfd[POLL_NETIN].fd = -1; 1074 pfd[POLL_NETIN].fd = -1;
872 /* eof on net in - remove from pfd */ 1075 /* eof on net in - remove from pfd */
873 if (ret == 0) { 1076 if (ret == 0) {
@@ -888,8 +1091,12 @@ readwrite(int net_fd)
888 /* try to write to stdout */ 1091 /* try to write to stdout */
889 if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) { 1092 if (pfd[POLL_STDOUT].revents & POLLOUT && netinbufpos > 0) {
890 ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf, 1093 ret = drainbuf(pfd[POLL_STDOUT].fd, netinbuf,
891 &netinbufpos); 1094 &netinbufpos, NULL);
892 if (ret == -1) 1095 if (ret == TLS_WANT_POLLIN)
1096 pfd[POLL_STDOUT].events = POLLIN;
1097 else if (ret == TLS_WANT_POLLOUT)
1098 pfd[POLL_STDOUT].events = POLLOUT;
1099 else if (ret == -1)
893 pfd[POLL_STDOUT].fd = -1; 1100 pfd[POLL_STDOUT].fd = -1;
894 /* buffer empty - remove self from polling */ 1101 /* buffer empty - remove self from polling */
895 if (netinbufpos == 0) 1102 if (netinbufpos == 0)
@@ -913,15 +1120,19 @@ readwrite(int net_fd)
913} 1120}
914 1121
915ssize_t 1122ssize_t
916drainbuf(int fd, unsigned char *buf, size_t *bufpos) 1123drainbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
917{ 1124{
918 ssize_t n; 1125 ssize_t n;
919 ssize_t adjust; 1126 ssize_t adjust;
920 1127
921 n = write(fd, buf, *bufpos); 1128 if (tls)
922 /* don't treat EAGAIN, EINTR as error */ 1129 n = tls_write(tls, buf, *bufpos);
923 if (n == -1 && (errno == EAGAIN || errno == EINTR)) 1130 else {
924 n = -2; 1131 n = write(fd, buf, *bufpos);
1132 /* don't treat EAGAIN, EINTR as error */
1133 if (n == -1 && (errno == EAGAIN || errno == EINTR))
1134 n = TLS_WANT_POLLOUT;
1135 }
925 if (n <= 0) 1136 if (n <= 0)
926 return n; 1137 return n;
927 /* adjust buffer */ 1138 /* adjust buffer */
@@ -934,15 +1145,19 @@ drainbuf(int fd, unsigned char *buf, size_t *bufpos)
934 1145
935 1146
936ssize_t 1147ssize_t
937fillbuf(int fd, unsigned char *buf, size_t *bufpos) 1148fillbuf(int fd, unsigned char *buf, size_t *bufpos, struct tls *tls)
938{ 1149{
939 size_t num = BUFSIZE - *bufpos; 1150 size_t num = BUFSIZE - *bufpos;
940 ssize_t n; 1151 ssize_t n;
941 1152
942 n = read(fd, buf + *bufpos, num); 1153 if (tls)
943 /* don't treat EAGAIN, EINTR as error */ 1154 n = tls_read(tls, buf + *bufpos, num);
944 if (n == -1 && (errno == EAGAIN || errno == EINTR)) 1155 else {
945 n = -2; 1156 n = read(fd, buf + *bufpos, num);
1157 /* don't treat EAGAIN, EINTR as error */
1158 if (n == -1 && (errno == EAGAIN || errno == EINTR))
1159 n = TLS_WANT_POLLIN;
1160 }
946 if (n <= 0) 1161 if (n <= 0)
947 return n; 1162 return n;
948 *bufpos += n; 1163 *bufpos += n;
@@ -1209,6 +1424,49 @@ map_tos(char *s, int *val)
1209 return (0); 1424 return (0);
1210} 1425}
1211 1426
1427int
1428map_tls(char *s, int *val)
1429{
1430 const struct tlskeywords {
1431 const char *keyword;
1432 int val;
1433 } *t, tlskeywords[] = {
1434 { "tlslegacy", TLS_LEGACY },
1435 { "noverify", TLS_NOVERIFY },
1436 { "noname", TLS_NONAME },
1437 { "clientcert", TLS_CCERT},
1438 { NULL, -1 },
1439 };
1440
1441 for (t = tlskeywords; t->keyword != NULL; t++) {
1442 if (strcmp(s, t->keyword) == 0) {
1443 *val |= t->val;
1444 return (1);
1445 }
1446 }
1447 return (0);
1448}
1449
1450void
1451report_tls(struct tls * tls_ctx, char * host, char *tls_expectname)
1452{
1453 char *subject = NULL, *issuer = NULL;
1454 if (tls_peer_cert_subject(tls_ctx, &subject) == -1)
1455 errx(1, "unable to get certificate subject");
1456 if (tls_peer_cert_issuer(tls_ctx, &issuer) == -1)
1457 errx(1, "unable to get certificate issuer");
1458 fprintf(stderr, "TLS handshake completed with %s\n", host);
1459 fprintf(stderr, "Peer name %s\n",
1460 tls_expectname ? tls_expectname : host);
1461 if (subject)
1462 fprintf(stderr, "Subject: %s\n", subject);
1463 if (issuer)
1464 fprintf(stderr, "Issuer: %s\n", issuer);
1465 if (tls_peerhash)
1466 fprintf(stderr, "Cert Hash: %s\n", tls_peerhash);
1467 free(subject);
1468 free(issuer);
1469}
1212void 1470void
1213report_connect(const struct sockaddr *sa, socklen_t salen) 1471report_connect(const struct sockaddr *sa, socklen_t salen)
1214{ 1472{
@@ -1276,10 +1534,12 @@ void
1276usage(int ret) 1534usage(int ret)
1277{ 1535{
1278 fprintf(stderr, 1536 fprintf(stderr,
1279 "usage: nc [-46DdFhklNnrStUuvz] [-I length] [-i interval] [-O length]\n" 1537 "usage: nc [-46cDdFhklNnrStUuvz] [-C certfile] [-e name] \n"
1280 "\t [-P proxy_username] [-p source_port] [-s source] [-T toskeyword]\n" 1538 "\t [-I length] [-i interval] [-H hash] [-K keyfile] [-O length]\n"
1281 "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" 1539 "\t [-P proxy_username] [-p source_port] [-R cafile] [-s source]\n"
1282 "\t [-x proxy_address[:port]] [destination] [port]\n"); 1540 "\t [-T tls|toskeyword] [-V rtable] [-w timeout]\n"
1541 "\t [-X proxy_protocol] [-x proxy_address[:port]]\n"
1542 "\t [destination] [port]\n");
1283 if (ret) 1543 if (ret)
1284 exit(1); 1544 exit(1);
1285} 1545}