diff options
| -rw-r--r-- | nc.1 | 26 | ||||
| -rw-r--r-- | netcat.c | 89 | 
2 files changed, 68 insertions, 47 deletions
| @@ -1,4 +1,4 @@ -.\"     $OpenBSD: nc.1,v 1.87 2017/07/15 18:11:47 jmc Exp $ +.\"     $OpenBSD: nc.1,v 1.88 2017/11/28 16:59:10 jsing Exp $  .\"  .\" Copyright (c) 1996 David Sacerdote  .\" All rights reserved. @@ -25,7 +25,7 @@  .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF  .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  .\" -.Dd $Mdocdate: July 15 2017 $ +.Dd $Mdocdate: November 28 2017 $  .Dt NC 1  .Os  .Sh NAME @@ -233,10 +233,6 @@ Change IPv4 TOS value or TLS options.  For TLS options  .Ar keyword  may be one of: -.Ar tlsall , -which allows the use of all supported TLS protocols and ciphers; -.Ar tlscompat , -which allows the use of all supported TLS protocols and "compat" ciphers;  .Ar noverify ,  which disables certificate verification;  .Ar noname , @@ -246,6 +242,15 @@ which requires a client certificate on incoming connections; or  .Ar muststaple ,  which requires the peer to provide a valid stapled OCSP response  with the handshake. +The following TLS options specify a value in the form of a key=value pair: +.Ar ciphers , +which allows the supported TLS ciphers to be specified (see +.Xr tls_config_set_ciphers 3 +for further details); +.Ar protocols , +which allows the supported TLS protocols to be specified (see +.Xr tls_config_parse_protocols 3 +for further details).  It is illegal to specify TLS options if not using TLS.  .Pp  For IPv4 TOS value @@ -497,10 +502,15 @@ the source port, with a timeout of 5 seconds:  .Pp  .Dl $ nc -p 31337 -w 5 host.example.com 42  .Pp +Open a TCP connection to port 443 of www.example.com, and negotiate TLS with +any supported TLS protocol version and "compat" ciphers: +.Pp +.Dl $ nc -cv -T protocols=all -T ciphers=compat www.example.com 443 +.Pp  Open a TCP connection to port 443 of www.google.ca, and negotiate TLS. -Check for a different name in the certificate for validation. +Check for a different name in the certificate for validation:  .Pp -.Dl $  nc -v -c -e adsf.au.doubleclick.net www.google.ca 443 +.Dl $ nc -cv -e adsf.au.doubleclick.net www.google.ca 443  .Pp  Open a UDP connection to port 53 of host.example.com:  .Pp diff --git a/netcat.c b/netcat.c index ce55972a7c2f4..fcc38897cd937 100644 --- a/netcat.c +++ b/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.187 2017/07/15 17:27:39 jsing Exp $ */ +/* $OpenBSD: netcat.c,v 1.190 2018/03/19 16:35:29 jsing Exp $ */  /*   * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>   * Copyright (c) 2015 Bob Beck.  All rights reserved. @@ -68,12 +68,10 @@  #define BUFSIZE		16384  #define DEFAULT_CA_FILE	"/etc/ssl/cert.pem" -#define TLS_ALL	(1 << 1) -#define TLS_NOVERIFY	(1 << 2) -#define TLS_NONAME	(1 << 3) -#define TLS_CCERT	(1 << 4) -#define TLS_MUSTSTAPLE	(1 << 5) -#define TLS_COMPAT	(1 << 6) +#define TLS_NOVERIFY	(1 << 1) +#define TLS_NONAME	(1 << 2) +#define TLS_CCERT	(1 << 3) +#define TLS_MUSTSTAPLE	(1 << 4)  /* Command Line Options */  int	dflag;					/* detached, no stdin */ @@ -108,6 +106,8 @@ int	tls_cachanged;				/* Using non-default CA file */  int     TLSopt;					/* TLS options */  char	*tls_expectname;			/* required name in peer cert */  char	*tls_expecthash;			/* required hash of peer cert */ +char	*tls_ciphers;				/* TLS ciphers */ +char	*tls_protocols;				/* TLS protocols */  FILE	*Zflag;					/* file to save peer cert */  int recvcount, recvlimit; @@ -135,8 +135,8 @@ int	unix_bind(char *, int);  int	unix_connect(char *);  int	unix_listen(char *);  void	set_common_sockopts(int, int); -int	map_tos(char *, int *); -int	map_tls(char *, int *); +int	process_tos_opt(char *, int *); +int	process_tls_opt(char *, int *);  void	save_peer_cert(struct tls *_tls_ctx, FILE *_fp);  void	report_connect(const struct sockaddr *, socklen_t, char *);  void	report_tls(struct tls *tls_ctx, char * host); @@ -161,6 +161,7 @@ main(int argc, char *argv[])  	char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];  	struct tls_config *tls_cfg = NULL;  	struct tls *tls_ctx = NULL; +	uint32_t protocols;  	ret = 1;  	socksv = 5; @@ -324,9 +325,9 @@ main(int argc, char *argv[])  		case 'T':  			errstr = NULL;  			errno = 0; -			if (map_tos(optarg, &Tflag)) +			if (process_tls_opt(optarg, &TLSopt))  				break; -			if (map_tls(optarg, &TLSopt)) +			if (process_tos_opt(optarg, &Tflag))  				break;  			if (strlen(optarg) > 1 && optarg[0] == '0' &&  			    optarg[1] == 'x') @@ -402,8 +403,6 @@ main(int argc, char *argv[])  		errx(1, "cannot use -c and -F");  	if (TLSopt && !usetls)  		errx(1, "you must specify -c to use TLS options"); -	if ((TLSopt & (TLS_ALL|TLS_COMPAT)) == (TLS_ALL|TLS_COMPAT)) -		errx(1, "cannot use -T tlsall and -T tlscompat");  	if (Cflag && !usetls)  		errx(1, "you must specify -c to use -C");  	if (Kflag && !usetls) @@ -485,8 +484,6 @@ main(int argc, char *argv[])  	}  	if (usetls) { -		if (tls_init() == -1) -			errx(1, "unable to initialize TLS");  		if ((tls_cfg = tls_config_new()) == NULL)  			errx(1, "unable to allocate TLS config");  		if (Rflag && tls_config_set_ca_file(tls_cfg, Rflag) == -1) @@ -497,14 +494,12 @@ main(int argc, char *argv[])  			errx(1, "%s", tls_config_error(tls_cfg));  		if (oflag && tls_config_set_ocsp_staple_file(tls_cfg, oflag) == -1)  			errx(1, "%s", tls_config_error(tls_cfg)); -		if (TLSopt & (TLS_ALL|TLS_COMPAT)) { -			if (tls_config_set_protocols(tls_cfg, -			    TLS_PROTOCOLS_ALL) != 0) -				errx(1, "%s", tls_config_error(tls_cfg)); -			if (tls_config_set_ciphers(tls_cfg, -			    (TLSopt & TLS_ALL) ? "all" : "compat") != 0) -				errx(1, "%s", tls_config_error(tls_cfg)); -		} +		if (tls_config_parse_protocols(&protocols, tls_protocols) == -1) +			errx(1, "invalid TLS protocols `%s'", tls_protocols); +		if (tls_config_set_protocols(tls_cfg, protocols) == -1) +			errx(1, "%s", tls_config_error(tls_cfg)); +		if (tls_config_set_ciphers(tls_cfg, tls_ciphers) == -1) +			errx(1, "%s", tls_config_error(tls_cfg));  		if (!lflag && (TLSopt & TLS_CCERT))  			errx(1, "clientcert is only valid with -l");  		if (TLSopt & TLS_NONAME) @@ -563,13 +558,12 @@ main(int argc, char *argv[])  				 * initially to wait for a caller, then use  				 * the regular functions to talk to the caller.  				 */ -				int rv, plen; -				char buf[16384]; +				int rv; +				char buf[2048];  				struct sockaddr_storage z;  				len = sizeof(z); -				plen = 2048; -				rv = recvfrom(s, buf, plen, MSG_PEEK, +				rv = recvfrom(s, buf, sizeof(buf), MSG_PEEK,  				    (struct sockaddr *)&z, &len);  				if (rv < 0)  					err(1, "recvfrom"); @@ -1510,7 +1504,7 @@ set_common_sockopts(int s, int af)  }  int -map_tos(char *s, int *val) +process_tos_opt(char *s, int *val)  {  	/* DiffServ Codepoints and other TOS mappings */  	const struct toskeywords { @@ -1558,24 +1552,41 @@ map_tos(char *s, int *val)  }  int -map_tls(char *s, int *val) +process_tls_opt(char *s, int *flags)  { +	size_t len; +	char *v; +  	const struct tlskeywords {  		const char	*keyword; -		int		 val; +		int		 flag; +		char		**value;  	} *t, tlskeywords[] = { -		{ "tlsall",		TLS_ALL }, -		{ "noverify",		TLS_NOVERIFY }, -		{ "noname",		TLS_NONAME }, -		{ "clientcert",		TLS_CCERT}, -		{ "muststaple",		TLS_MUSTSTAPLE}, -		{ "tlscompat",		TLS_COMPAT }, -		{ NULL,			-1 }, +		{ "ciphers",		-1,			&tls_ciphers }, +		{ "clientcert",		TLS_CCERT,		NULL }, +		{ "muststaple",		TLS_MUSTSTAPLE,		NULL }, +		{ "noverify",		TLS_NOVERIFY,		NULL }, +		{ "noname",		TLS_NONAME,		NULL }, +		{ "protocols",		-1,			&tls_protocols }, +		{ NULL,			-1,			NULL },  	}; +	len = strlen(s); +	if ((v = strchr(s, '=')) != NULL) { +		len = v - s; +		v++; +	} +  	for (t = tlskeywords; t->keyword != NULL; t++) { -		if (strcmp(s, t->keyword) == 0) { -			*val |= t->val; +		if (strlen(t->keyword) == len && +		    strncmp(s, t->keyword, len) == 0) { +			if (t->value != NULL) { +				if (v == NULL) +					errx(1, "invalid tls value `%s'", s); +				*t->value = v; +			} else { +				*flags |= t->flag; +			}  			return 1;  		}  	} | 
