diff options
author | jsing <> | 2017-11-28 16:59:10 +0000 |
---|---|---|
committer | jsing <> | 2017-11-28 16:59:10 +0000 |
commit | a2923d77ad66abdec14564d2310edca22c7a6024 (patch) | |
tree | a710970e7d644316b9b6165dc353680df486a153 | |
parent | de5ca2b5f99a16f432ca4cc02b4ac5d82c930283 (diff) | |
download | openbsd-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.1 | 26 | ||||
-rw-r--r-- | src/usr.bin/nc/netcat.c | 80 |
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. | |||
233 | For TLS options | 233 | For TLS options |
234 | .Ar keyword | 234 | .Ar keyword |
235 | may be one of: | 235 | may be one of: |
236 | .Ar tlsall , | ||
237 | which allows the use of all supported TLS protocols and ciphers; | ||
238 | .Ar tlscompat , | ||
239 | which allows the use of all supported TLS protocols and "compat" ciphers; | ||
240 | .Ar noverify , | 236 | .Ar noverify , |
241 | which disables certificate verification; | 237 | which 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 , |
247 | which requires the peer to provide a valid stapled OCSP response | 243 | which requires the peer to provide a valid stapled OCSP response |
248 | with the handshake. | 244 | with the handshake. |
245 | The following TLS options specify a value in the form of a key=value pair: | ||
246 | .Ar ciphers , | ||
247 | which allows the supported TLS ciphers to be specified (see | ||
248 | .Xr tls_config_set_ciphers 3 | ||
249 | for further details); | ||
250 | .Ar protocols , | ||
251 | which allows the supported TLS protocols to be specified (see | ||
252 | .Xr tls_config_parse_protocols 3 | ||
253 | for further details). | ||
249 | It is illegal to specify TLS options if not using TLS. | 254 | It is illegal to specify TLS options if not using TLS. |
250 | .Pp | 255 | .Pp |
251 | For IPv4 TOS value | 256 | For 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 |
505 | Open a TCP connection to port 443 of www.example.com, and negotiate TLS with | ||
506 | any 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 | ||
500 | Open a TCP connection to port 443 of www.google.ca, and negotiate TLS. | 510 | Open a TCP connection to port 443 of www.google.ca, and negotiate TLS. |
501 | Check for a different name in the certificate for validation. | 511 | Check 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 |
505 | Open a UDP connection to port 53 of host.example.com: | 515 | Open 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 */ |
79 | int dflag; /* detached, no stdin */ | 77 | int dflag; /* detached, no stdin */ |
@@ -108,6 +106,8 @@ int tls_cachanged; /* Using non-default CA file */ | |||
108 | int TLSopt; /* TLS options */ | 106 | int TLSopt; /* TLS options */ |
109 | char *tls_expectname; /* required name in peer cert */ | 107 | char *tls_expectname; /* required name in peer cert */ |
110 | char *tls_expecthash; /* required hash of peer cert */ | 108 | char *tls_expecthash; /* required hash of peer cert */ |
109 | char *tls_ciphers; /* TLS ciphers */ | ||
110 | char *tls_protocols; /* TLS protocols */ | ||
111 | FILE *Zflag; /* file to save peer cert */ | 111 | FILE *Zflag; /* file to save peer cert */ |
112 | 112 | ||
113 | int recvcount, recvlimit; | 113 | int recvcount, recvlimit; |
@@ -135,8 +135,8 @@ int unix_bind(char *, int); | |||
135 | int unix_connect(char *); | 135 | int unix_connect(char *); |
136 | int unix_listen(char *); | 136 | int unix_listen(char *); |
137 | void set_common_sockopts(int, int); | 137 | void set_common_sockopts(int, int); |
138 | int map_tos(char *, int *); | 138 | int process_tos_opt(char *, int *); |
139 | int map_tls(char *, int *); | 139 | int process_tls_opt(char *, int *); |
140 | void save_peer_cert(struct tls *_tls_ctx, FILE *_fp); | 140 | void save_peer_cert(struct tls *_tls_ctx, FILE *_fp); |
141 | void report_connect(const struct sockaddr *, socklen_t, char *); | 141 | void report_connect(const struct sockaddr *, socklen_t, char *); |
142 | void report_tls(struct tls *tls_ctx, char * host); | 142 | void 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 | ||
1511 | int | 1508 | int |
1512 | map_tos(char *s, int *val) | 1509 | process_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 | ||
1559 | int | 1556 | int |
1560 | map_tls(char *s, int *val) | 1557 | process_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 | } |