summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2017-11-28 16:59:10 +0000
committerjsing <>2017-11-28 16:59:10 +0000
commita2923d77ad66abdec14564d2310edca22c7a6024 (patch)
treea710970e7d644316b9b6165dc353680df486a153
parentde5ca2b5f99a16f432ca4cc02b4ac5d82c930283 (diff)
downloadopenbsd-a2923d77ad66abdec14564d2310edca22c7a6024.tar.gz
openbsd-a2923d77ad66abdec14564d2310edca22c7a6024.tar.bz2
openbsd-a2923d77ad66abdec14564d2310edca22c7a6024.zip
Allow TLS ciphers and protocols to be specified for nc(1).
Replace the "tlscompat" and "tlsall" options with "cipher" and "protocol" options that are key/value pairs. This allows the user to specify ciphers and protocols in a form that are accepted by tls_config_set_ciphers() and tls_config_set_protocols() respectively. ok beck@ (also ok jmc@ for a previous revision of the man page).
-rw-r--r--src/usr.bin/nc/nc.126
-rw-r--r--src/usr.bin/nc/netcat.c80
2 files changed, 65 insertions, 41 deletions
diff --git a/src/usr.bin/nc/nc.1 b/src/usr.bin/nc/nc.1
index bb3a8f7cf5..e10d385a14 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.87 2017/07/15 18:11:47 jmc Exp $ 1.\" $OpenBSD: nc.1,v 1.88 2017/11/28 16:59:10 jsing 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: July 15 2017 $ 28.Dd $Mdocdate: November 28 2017 $
29.Dt NC 1 29.Dt NC 1
30.Os 30.Os
31.Sh NAME 31.Sh NAME
@@ -233,10 +233,6 @@ Change IPv4 TOS value or TLS options.
233For TLS options 233For TLS options
234.Ar keyword 234.Ar keyword
235may be one of: 235may be one of:
236.Ar tlsall ,
237which allows the use of all supported TLS protocols and ciphers;
238.Ar tlscompat ,
239which allows the use of all supported TLS protocols and "compat" ciphers;
240.Ar noverify , 236.Ar noverify ,
241which disables certificate verification; 237which disables certificate verification;
242.Ar noname , 238.Ar noname ,
@@ -246,6 +242,15 @@ which requires a client certificate on incoming connections; or
246.Ar muststaple , 242.Ar muststaple ,
247which requires the peer to provide a valid stapled OCSP response 243which requires the peer to provide a valid stapled OCSP response
248with the handshake. 244with the handshake.
245The following TLS options specify a value in the form of a key=value pair:
246.Ar ciphers ,
247which allows the supported TLS ciphers to be specified (see
248.Xr tls_config_set_ciphers 3
249for further details);
250.Ar protocols ,
251which allows the supported TLS protocols to be specified (see
252.Xr tls_config_parse_protocols 3
253for further details).
249It is illegal to specify TLS options if not using TLS. 254It is illegal to specify TLS options if not using TLS.
250.Pp 255.Pp
251For IPv4 TOS value 256For IPv4 TOS value
@@ -497,10 +502,15 @@ the source port, with a timeout of 5 seconds:
497.Pp 502.Pp
498.Dl $ nc -p 31337 -w 5 host.example.com 42 503.Dl $ nc -p 31337 -w 5 host.example.com 42
499.Pp 504.Pp
505Open a TCP connection to port 443 of www.example.com, and negotiate TLS with
506any supported TLS protocol version and "compat" ciphers:
507.Pp
508.Dl $ nc -cv -T protocols=all -T ciphers=compat www.example.com 443
509.Pp
500Open a TCP connection to port 443 of www.google.ca, and negotiate TLS. 510Open a TCP connection to port 443 of www.google.ca, and negotiate TLS.
501Check for a different name in the certificate for validation. 511Check for a different name in the certificate for validation:
502.Pp 512.Pp
503.Dl $ nc -v -c -e adsf.au.doubleclick.net www.google.ca 443 513.Dl $ nc -cv -e adsf.au.doubleclick.net www.google.ca 443
504.Pp 514.Pp
505Open a UDP connection to port 53 of host.example.com: 515Open a UDP connection to port 53 of host.example.com:
506.Pp 516.Pp
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c
index f8bd8fa498..867927de69 100644
--- a/src/usr.bin/nc/netcat.c
+++ b/src/usr.bin/nc/netcat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: netcat.c,v 1.188 2017/10/24 17:49:35 bluhm Exp $ */ 1/* $OpenBSD: netcat.c,v 1.189 2017/11/28 16:59:10 jsing 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 * Copyright (c) 2015 Bob Beck. All rights reserved.
@@ -68,12 +68,10 @@
68#define BUFSIZE 16384 68#define BUFSIZE 16384
69#define DEFAULT_CA_FILE "/etc/ssl/cert.pem" 69#define DEFAULT_CA_FILE "/etc/ssl/cert.pem"
70 70
71#define TLS_ALL (1 << 1) 71#define TLS_NOVERIFY (1 << 1)
72#define TLS_NOVERIFY (1 << 2) 72#define TLS_NONAME (1 << 2)
73#define TLS_NONAME (1 << 3) 73#define TLS_CCERT (1 << 3)
74#define TLS_CCERT (1 << 4) 74#define TLS_MUSTSTAPLE (1 << 4)
75#define TLS_MUSTSTAPLE (1 << 5)
76#define TLS_COMPAT (1 << 6)
77 75
78/* Command Line Options */ 76/* Command Line Options */
79int dflag; /* detached, no stdin */ 77int dflag; /* detached, no stdin */
@@ -108,6 +106,8 @@ int tls_cachanged; /* Using non-default CA file */
108int TLSopt; /* TLS options */ 106int TLSopt; /* TLS options */
109char *tls_expectname; /* required name in peer cert */ 107char *tls_expectname; /* required name in peer cert */
110char *tls_expecthash; /* required hash of peer cert */ 108char *tls_expecthash; /* required hash of peer cert */
109char *tls_ciphers; /* TLS ciphers */
110char *tls_protocols; /* TLS protocols */
111FILE *Zflag; /* file to save peer cert */ 111FILE *Zflag; /* file to save peer cert */
112 112
113int recvcount, recvlimit; 113int recvcount, recvlimit;
@@ -135,8 +135,8 @@ int unix_bind(char *, int);
135int unix_connect(char *); 135int unix_connect(char *);
136int unix_listen(char *); 136int unix_listen(char *);
137void set_common_sockopts(int, int); 137void set_common_sockopts(int, int);
138int map_tos(char *, int *); 138int process_tos_opt(char *, int *);
139int map_tls(char *, int *); 139int process_tls_opt(char *, int *);
140void save_peer_cert(struct tls *_tls_ctx, FILE *_fp); 140void save_peer_cert(struct tls *_tls_ctx, FILE *_fp);
141void report_connect(const struct sockaddr *, socklen_t, char *); 141void report_connect(const struct sockaddr *, socklen_t, char *);
142void report_tls(struct tls *tls_ctx, char * host); 142void report_tls(struct tls *tls_ctx, char * host);
@@ -161,6 +161,7 @@ main(int argc, char *argv[])
161 char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; 161 char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
162 struct tls_config *tls_cfg = NULL; 162 struct tls_config *tls_cfg = NULL;
163 struct tls *tls_ctx = NULL; 163 struct tls *tls_ctx = NULL;
164 uint32_t protocols;
164 165
165 ret = 1; 166 ret = 1;
166 socksv = 5; 167 socksv = 5;
@@ -324,9 +325,9 @@ main(int argc, char *argv[])
324 case 'T': 325 case 'T':
325 errstr = NULL; 326 errstr = NULL;
326 errno = 0; 327 errno = 0;
327 if (map_tos(optarg, &Tflag)) 328 if (process_tls_opt(optarg, &TLSopt))
328 break; 329 break;
329 if (map_tls(optarg, &TLSopt)) 330 if (process_tos_opt(optarg, &Tflag))
330 break; 331 break;
331 if (strlen(optarg) > 1 && optarg[0] == '0' && 332 if (strlen(optarg) > 1 && optarg[0] == '0' &&
332 optarg[1] == 'x') 333 optarg[1] == 'x')
@@ -402,8 +403,6 @@ main(int argc, char *argv[])
402 errx(1, "cannot use -c and -F"); 403 errx(1, "cannot use -c and -F");
403 if (TLSopt && !usetls) 404 if (TLSopt && !usetls)
404 errx(1, "you must specify -c to use TLS options"); 405 errx(1, "you must specify -c to use TLS options");
405 if ((TLSopt & (TLS_ALL|TLS_COMPAT)) == (TLS_ALL|TLS_COMPAT))
406 errx(1, "cannot use -T tlsall and -T tlscompat");
407 if (Cflag && !usetls) 406 if (Cflag && !usetls)
408 errx(1, "you must specify -c to use -C"); 407 errx(1, "you must specify -c to use -C");
409 if (Kflag && !usetls) 408 if (Kflag && !usetls)
@@ -497,14 +496,12 @@ main(int argc, char *argv[])
497 errx(1, "%s", tls_config_error(tls_cfg)); 496 errx(1, "%s", tls_config_error(tls_cfg));
498 if (oflag && tls_config_set_ocsp_staple_file(tls_cfg, oflag) == -1) 497 if (oflag && tls_config_set_ocsp_staple_file(tls_cfg, oflag) == -1)
499 errx(1, "%s", tls_config_error(tls_cfg)); 498 errx(1, "%s", tls_config_error(tls_cfg));
500 if (TLSopt & (TLS_ALL|TLS_COMPAT)) { 499 if (tls_config_parse_protocols(&protocols, tls_protocols) == -1)
501 if (tls_config_set_protocols(tls_cfg, 500 errx(1, "invalid TLS protocols `%s'", tls_protocols);
502 TLS_PROTOCOLS_ALL) != 0) 501 if (tls_config_set_protocols(tls_cfg, protocols) == -1)
503 errx(1, "%s", tls_config_error(tls_cfg)); 502 errx(1, "%s", tls_config_error(tls_cfg));
504 if (tls_config_set_ciphers(tls_cfg, 503 if (tls_config_set_ciphers(tls_cfg, tls_ciphers) == -1)
505 (TLSopt & TLS_ALL) ? "all" : "compat") != 0) 504 errx(1, "%s", tls_config_error(tls_cfg));
506 errx(1, "%s", tls_config_error(tls_cfg));
507 }
508 if (!lflag && (TLSopt & TLS_CCERT)) 505 if (!lflag && (TLSopt & TLS_CCERT))
509 errx(1, "clientcert is only valid with -l"); 506 errx(1, "clientcert is only valid with -l");
510 if (TLSopt & TLS_NONAME) 507 if (TLSopt & TLS_NONAME)
@@ -1509,7 +1506,7 @@ set_common_sockopts(int s, int af)
1509} 1506}
1510 1507
1511int 1508int
1512map_tos(char *s, int *val) 1509process_tos_opt(char *s, int *val)
1513{ 1510{
1514 /* DiffServ Codepoints and other TOS mappings */ 1511 /* DiffServ Codepoints and other TOS mappings */
1515 const struct toskeywords { 1512 const struct toskeywords {
@@ -1557,24 +1554,41 @@ map_tos(char *s, int *val)
1557} 1554}
1558 1555
1559int 1556int
1560map_tls(char *s, int *val) 1557process_tls_opt(char *s, int *flags)
1561{ 1558{
1559 size_t len;
1560 char *v;
1561
1562 const struct tlskeywords { 1562 const struct tlskeywords {
1563 const char *keyword; 1563 const char *keyword;
1564 int val; 1564 int flag;
1565 char **value;
1565 } *t, tlskeywords[] = { 1566 } *t, tlskeywords[] = {
1566 { "tlsall", TLS_ALL }, 1567 { "ciphers", -1, &tls_ciphers },
1567 { "noverify", TLS_NOVERIFY }, 1568 { "clientcert", TLS_CCERT, NULL },
1568 { "noname", TLS_NONAME }, 1569 { "muststaple", TLS_MUSTSTAPLE, NULL },
1569 { "clientcert", TLS_CCERT}, 1570 { "noverify", TLS_NOVERIFY, NULL },
1570 { "muststaple", TLS_MUSTSTAPLE}, 1571 { "noname", TLS_NONAME, NULL },
1571 { "tlscompat", TLS_COMPAT }, 1572 { "protocols", -1, &tls_protocols },
1572 { NULL, -1 }, 1573 { NULL, -1, NULL },
1573 }; 1574 };
1574 1575
1576 len = strlen(s);
1577 if ((v = strchr(s, '=')) != NULL) {
1578 len = v - s;
1579 v++;
1580 }
1581
1575 for (t = tlskeywords; t->keyword != NULL; t++) { 1582 for (t = tlskeywords; t->keyword != NULL; t++) {
1576 if (strcmp(s, t->keyword) == 0) { 1583 if (strlen(t->keyword) == len &&
1577 *val |= t->val; 1584 strncmp(s, t->keyword, len) == 0) {
1585 if (t->value != NULL) {
1586 if (v == NULL)
1587 errx(1, "invalid tls value `%s'", s);
1588 *t->value = v;
1589 } else {
1590 *flags |= t->flag;
1591 }
1578 return 1; 1592 return 1;
1579 } 1593 }
1580 } 1594 }