From owner-svn-src-vendor@freebsd.org Fri May 10 17:29:32 2019 Return-Path: Delivered-To: svn-src-vendor@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 41C5115A8473; Fri, 10 May 2019 17:29:32 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id DF0E382D17; Fri, 10 May 2019 17:29:31 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 00FC476AC; Fri, 10 May 2019 17:29:31 +0000 (UTC) (envelope-from des@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x4AHTUBS009471; Fri, 10 May 2019 17:29:30 GMT (envelope-from des@FreeBSD.org) Received: (from des@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4AHTUKC009469; Fri, 10 May 2019 17:29:30 GMT (envelope-from des@FreeBSD.org) Message-Id: <201905101729.x4AHTUKC009469@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: des set sender to des@FreeBSD.org using -f From: =?UTF-8?Q?Dag-Erling_Sm=c3=b8rgrav?= Date: Fri, 10 May 2019 17:29:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r347450 - vendor/netcat/dist X-SVN-Group: vendor X-SVN-Commit-Author: des X-SVN-Commit-Paths: vendor/netcat/dist X-SVN-Commit-Revision: 347450 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: DF0E382D17 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.995,0]; NEURAL_HAM_SHORT(-0.98)[-0.979,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US]; NEURAL_HAM_LONG(-1.00)[-1.000,0] X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 May 2019 17:29:32 -0000 Author: des Date: Fri May 10 17:29:30 2019 New Revision: 347450 URL: https://svnweb.freebsd.org/changeset/base/347450 Log: Import netcat from OpenBSD 6.2. Modified: vendor/netcat/dist/nc.1 vendor/netcat/dist/netcat.c Modified: vendor/netcat/dist/nc.1 ============================================================================== --- vendor/netcat/dist/nc.1 Fri May 10 17:29:22 2019 (r347449) +++ vendor/netcat/dist/nc.1 Fri May 10 17:29:30 2019 (r347450) @@ -1,4 +1,4 @@ -.\" $OpenBSD: nc.1,v 1.82 2017/02/09 20:15:59 jca Exp $ +.\" $OpenBSD: nc.1,v 1.87 2017/07/15 18:11:47 jmc 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: February 9 2017 $ +.Dd $Mdocdate: July 15 2017 $ .Dt NC 1 .Os .Sh NAME @@ -50,9 +50,11 @@ .Op Fl s Ar source .Op Fl T Ar keyword .Op Fl V Ar rtable +.Op Fl W Ar recvlimit .Op Fl w Ar timeout .Op Fl X Ar proxy_protocol .Op Fl x Ar proxy_address Ns Op : Ns Ar port +.Op Fl Z Ar peercertfile .Op Ar destination .Op Ar port .Sh DESCRIPTION @@ -230,10 +232,12 @@ option. 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 noverify ; +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 , which disables certificate name checking; @@ -287,6 +291,10 @@ Set the routing table to be used. Have .Nm give more verbose output. +.It Fl W Ar recvlimit +Terminate after receiving +.Ar recvlimit +packets from the network. .It Fl w Ar timeout Connections which cannot be established or are idle timeout after .Ar timeout @@ -330,6 +338,10 @@ for SOCKS, 3128 for HTTPS). An IPv6 address can be specified unambiguously by enclosing .Ar proxy_address in square brackets. +.It Fl Z Ar peercertfile +Specifies the filename in which the peer supplied certificates will be saved +in PEM format. +May only be used with TLS. .It Fl z Specifies that .Nm Modified: vendor/netcat/dist/netcat.c ============================================================================== --- vendor/netcat/dist/netcat.c Fri May 10 17:29:22 2019 (r347449) +++ vendor/netcat/dist/netcat.c Fri May 10 17:29:30 2019 (r347450) @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.178 2017/03/09 13:58:00 bluhm Exp $ */ +/* $OpenBSD: netcat.c,v 1.187 2017/07/15 17:27:39 jsing Exp $ */ /* * Copyright (c) 2001 Eric Jackson * Copyright (c) 2015 Bob Beck. All rights reserved. @@ -53,25 +53,27 @@ #include #include #include -#include #include +#include + #include "atomicio.h" #define PORT_MAX 65535 #define UNIX_DG_TMP_SOCKET_SIZE 19 -#define POLL_STDIN 0 -#define POLL_NETOUT 1 -#define POLL_NETIN 2 -#define POLL_STDOUT 3 -#define BUFSIZE 16384 -#define DEFAULT_CA_FILE "/etc/ssl/cert.pem" +#define POLL_STDIN 0 +#define POLL_NETOUT 1 +#define POLL_NETIN 2 +#define POLL_STDOUT 3 +#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) /* Command Line Options */ int dflag; /* detached, no stdin */ @@ -106,7 +108,9 @@ 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 */ +FILE *Zflag; /* file to save peer cert */ +int recvcount, recvlimit; int timeout = -1; int family = AF_UNSPEC; char *portlist[PORT_MAX+1]; @@ -115,8 +119,9 @@ int ttl = -1; int minttl = -1; void atelnet(int, unsigned char *, unsigned int); +int strtoport(char *portstr, int udp); void build_ports(char *); -void help(void); +void help(void) __attribute__((noreturn)); int local_listen(char *, char *, struct addrinfo); void readwrite(int, struct tls *); void fdpass(int nfd) __attribute__((noreturn)); @@ -132,8 +137,9 @@ int unix_listen(char *); void set_common_sockopts(int, int); int map_tos(char *, int *); int map_tls(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, char *tls_expectname); +void report_tls(struct tls *tls_ctx, char * host); void usage(int); ssize_t drainbuf(int, unsigned char *, size_t *, struct tls *); ssize_t fillbuf(int, unsigned char *, size_t *, struct tls *); @@ -149,7 +155,7 @@ main(int argc, char *argv[]) struct servent *sv; socklen_t len; struct sockaddr_storage cliaddr; - char *proxy, *proxyport = NULL; + char *proxy = NULL, *proxyport = NULL; const char *errstr; struct addrinfo proxyhints; char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; @@ -165,7 +171,8 @@ main(int argc, char *argv[]) signal(SIGPIPE, SIG_IGN); while ((ch = getopt(argc, argv, - "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vw:X:x:z")) != -1) { + "46C:cDde:FH:hI:i:K:klM:m:NnO:o:P:p:R:rSs:T:tUuV:vW:w:X:x:Z:z")) + != -1) { switch (ch) { case '4': family = AF_INET; @@ -268,6 +275,11 @@ main(int argc, char *argv[]) case 'v': vflag = 1; break; + case 'W': + recvlimit = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr) + errx(1, "receive limit %s: %s", errstr, optarg); + break; case 'w': timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); if (errstr) @@ -279,6 +291,12 @@ main(int argc, char *argv[]) if ((proxy = strdup(optarg)) == NULL) err(1, NULL); break; + case 'Z': + if (strcmp(optarg, "-") == 0) + Zflag = stderr; + else if ((Zflag = fopen(optarg, "w")) == NULL) + err(1, "can't open %s", optarg); + break; case 'z': zflag = 1; break; @@ -333,12 +351,15 @@ main(int argc, char *argv[]) if (family == AF_UNIX) { if (pledge("stdio rpath wpath cpath tmppath unix", NULL) == -1) err(1, "pledge"); - } else if (Fflag) { - if (Pflag) { - if (pledge("stdio inet dns sendfd tty", NULL) == -1) - err(1, "pledge"); - } else if (pledge("stdio inet dns sendfd", NULL) == -1) + } else if (Fflag && Pflag) { + if (pledge("stdio inet dns sendfd tty", NULL) == -1) err(1, "pledge"); + } else if (Fflag) { + if (pledge("stdio inet dns sendfd", NULL) == -1) + err(1, "pledge"); + } else if (Pflag && usetls) { + if (pledge("stdio rpath inet dns tty", NULL) == -1) + err(1, "pledge"); } else if (Pflag) { if (pledge("stdio inet dns tty", NULL) == -1) err(1, "pledge"); @@ -353,7 +374,7 @@ main(int argc, char *argv[]) host = argv[0]; uport = NULL; } else if (argv[0] && !argv[1]) { - if (!lflag) + if (!lflag) usage(1); uport = argv[0]; host = NULL; @@ -381,10 +402,14 @@ 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) errx(1, "you must specify -c to use -K"); + if (Zflag && !usetls) + errx(1, "you must specify -c to use -Z"); if (oflag && !Cflag) errx(1, "you must specify -C to use -o"); if (tls_cachanged && !usetls) @@ -460,12 +485,6 @@ main(int argc, char *argv[]) } if (usetls) { - if (Pflag) { - if (pledge("stdio inet dns tty rpath", NULL) == -1) - err(1, "pledge"); - } else if (pledge("stdio inet dns rpath", NULL) == -1) - err(1, "pledge"); - if (tls_init() == -1) errx(1, "unable to initialize TLS"); if ((tls_cfg = tls_config_new()) == NULL) @@ -478,11 +497,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) { + 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, "all") != 0) + if (tls_config_set_ciphers(tls_cfg, + (TLSopt & TLS_ALL) ? "all" : "compat") != 0) errx(1, "%s", tls_config_error(tls_cfg)); } if (!lflag && (TLSopt & TLS_CCERT)) @@ -491,7 +511,7 @@ main(int argc, char *argv[]) tls_config_insecure_noverifyname(tls_cfg); if (TLSopt & TLS_NOVERIFY) { if (tls_expecthash != NULL) - errx(1, "-H and -T noverify may not be used" + errx(1, "-H and -T noverify may not be used " "together"); tls_config_insecure_noverifycert(tls_cfg); } @@ -530,18 +550,19 @@ main(int argc, char *argv[]) s = local_listen(host, uport, hints); if (s < 0) err(1, NULL); - /* - * For UDP and -k, don't connect the socket, let it - * receive datagrams from multiple socket pairs. - */ - if (uflag && kflag) + if (uflag && kflag) { + /* + * For UDP and -k, don't connect the socket, + * let it receive datagrams from multiple + * socket pairs. + */ readwrite(s, NULL); - /* - * For UDP and not -k, we will use recvfrom() initially - * to wait for a caller, then use the regular functions - * to talk to the caller. - */ - else if (uflag && !kflag) { + } else if (uflag && !kflag) { + /* + * For UDP and not -k, we will use recvfrom() + * initially to wait for a caller, then use + * the regular functions to talk to the caller. + */ int rv, plen; char buf[16384]; struct sockaddr_storage z; @@ -606,7 +627,7 @@ main(int argc, char *argv[]) if (uflag) unlink(unix_dg_tmp_socket); - exit(ret); + return ret; } else { int i = 0; @@ -682,7 +703,7 @@ main(int argc, char *argv[]) tls_config_free(tls_cfg); - exit(ret); + return ret; } /* @@ -698,7 +719,7 @@ unix_bind(char *path, int flags) /* Create unix domain socket. */ if ((s = socket(AF_UNIX, flags | (uflag ? SOCK_DGRAM : SOCK_STREAM), 0)) < 0) - return (-1); + return -1; memset(&s_un, 0, sizeof(struct sockaddr_un)); s_un.sun_family = AF_UNIX; @@ -707,16 +728,17 @@ unix_bind(char *path, int flags) sizeof(s_un.sun_path)) { close(s); errno = ENAMETOOLONG; - return (-1); + return -1; } if (bind(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) { save_errno = errno; close(s); errno = save_errno; - return (-1); + return -1; } - return (s); + + return s; } int @@ -743,7 +765,7 @@ timeout_tls(int s, struct tls *tls_ctx, int (*func)(st err(1, "poll failed"); } - return (ret); + return ret; } void @@ -762,10 +784,15 @@ tls_setup_client(struct tls *tls_ctx, int s, char *hos errx(1, "tls handshake failed (%s)", errstr); } if (vflag) - report_tls(tls_ctx, host, tls_expectname); + report_tls(tls_ctx, host); if (tls_expecthash && tls_peer_cert_hash(tls_ctx) && strcmp(tls_expecthash, tls_peer_cert_hash(tls_ctx)) != 0) errx(1, "peer certificate is not %s", tls_expecthash); + if (Zflag) { + save_peer_cert(tls_ctx, Zflag); + if (Zflag != stderr && (fclose(Zflag) != 0)) + err(1, "fclose failed saving peer cert"); + } } struct tls * @@ -784,7 +811,7 @@ tls_setup_server(struct tls *tls_ctx, int connfd, char int gotcert = tls_peer_cert_provided(tls_cctx); if (vflag && gotcert) - report_tls(tls_cctx, host, tls_expectname); + report_tls(tls_cctx, host); if ((TLSopt & TLS_CCERT) && !gotcert) warnx("No client certificate provided"); else if (gotcert && tls_peer_cert_hash(tls_ctx) && tls_expecthash && @@ -813,10 +840,10 @@ unix_connect(char *path) if (uflag) { if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) < 0) - return (-1); + return -1; } else { if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) - return (-1); + return -1; } memset(&s_un, 0, sizeof(struct sockaddr_un)); @@ -826,15 +853,15 @@ unix_connect(char *path) sizeof(s_un.sun_path)) { close(s); errno = ENAMETOOLONG; - return (-1); + return -1; } if (connect(s, (struct sockaddr *)&s_un, sizeof(s_un)) < 0) { save_errno = errno; close(s); errno = save_errno; - return (-1); + return -1; } - return (s); + return s; } @@ -847,13 +874,13 @@ unix_listen(char *path) { int s; if ((s = unix_bind(path, 0)) < 0) - return (-1); + return -1; if (listen(s, 5) < 0) { close(s); - return (-1); + return -1; } - return (s); + return s; } /* @@ -912,7 +939,7 @@ remote_connect(const char *host, const char *port, str freeaddrinfo(res0); - return (s); + return s; } int @@ -940,7 +967,7 @@ timeout_connect(int s, const struct sockaddr *name, so err(1, "poll failed"); } - return (ret); + return ret; } /* @@ -996,7 +1023,7 @@ local_listen(char *host, char *port, struct addrinfo h freeaddrinfo(res0); - return (s); + return s; } /* @@ -1150,6 +1177,12 @@ readwrite(int net_fd, struct tls *tls_ctx) shutdown(pfd[POLL_NETIN].fd, SHUT_RD); pfd[POLL_NETIN].fd = -1; } + if (recvlimit > 0 && ++recvcount >= recvlimit) { + if (pfd[POLL_NETIN].fd != -1) + shutdown(pfd[POLL_NETIN].fd, SHUT_RD); + pfd[POLL_NETIN].fd = -1; + pfd[POLL_STDIN].fd = -1; + } /* read something - poll stdout */ if (netinbufpos > 0) pfd[POLL_STDOUT].events = POLLOUT; @@ -1417,7 +1450,7 @@ udptest(int s) else ret = -1; } - return (ret); + return ret; } void @@ -1517,11 +1550,11 @@ map_tos(char *s, int *val) for (t = toskeywords; t->keyword != NULL; t++) { if (strcmp(s, t->keyword) == 0) { *val = t->val; - return (1); + return 1; } } - return (0); + return 0; } int @@ -1536,21 +1569,36 @@ map_tls(char *s, int *val) { "noname", TLS_NONAME }, { "clientcert", TLS_CCERT}, { "muststaple", TLS_MUSTSTAPLE}, + { "tlscompat", TLS_COMPAT }, { NULL, -1 }, }; for (t = tlskeywords; t->keyword != NULL; t++) { if (strcmp(s, t->keyword) == 0) { *val |= t->val; - return (1); + return 1; } } - return (0); + return 0; } void -report_tls(struct tls * tls_ctx, char * host, char *tls_expectname) +save_peer_cert(struct tls *tls_ctx, FILE *fp) { + const char *pem; + size_t plen; + + if ((pem = tls_peer_cert_chain_pem(tls_ctx, &plen)) == NULL) + errx(1, "Can't get peer certificate"); + if (fprintf(fp, "%.*s", (int)plen, pem) < 0) + err(1, "unable to save peer cert"); + if (fflush(fp) != 0) + err(1, "unable to flush peer cert"); +} + +void +report_tls(struct tls * tls_ctx, char * host) +{ time_t t; const char *ocsp_url; @@ -1675,9 +1723,11 @@ help(void) \t-u UDP mode\n\ \t-V rtable Specify alternate routing table\n\ \t-v Verbose\n\ + \t-W recvlimit Terminate after receiving a number of packets\n\ \t-w timeout Timeout for connects and final net reads\n\ \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ \t-x addr[:port]\tSpecify proxy address and port\n\ + \t-Z Peer certificate file\n\ \t-z Zero-I/O mode [used for scanning]\n\ Port numbers can be individual or ranges: lo-hi [inclusive]\n"); exit(1); @@ -1692,9 +1742,11 @@ usage(int ret) "\t [-i interval] [-K keyfile] [-M ttl] [-m minttl] [-O length]\n" "\t [-o staplefile] [-P proxy_username] [-p source_port] " "[-R CAfile]\n" - "\t [-s source] [-T keyword] [-V rtable] [-w timeout] " - "[-X proxy_protocol]\n" - "\t [-x proxy_address[:port]] [destination] [port]\n"); + "\t [-s source] [-T keyword] [-V rtable] [-W recvlimit] " + "[-w timeout]\n" + "\t [-X proxy_protocol] [-x proxy_address[:port]] " + "[-Z peercertfile]\n" + "\t [destination] [port]\n"); if (ret) exit(1); }