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 <er...@monkey.org>
  * Copyright (c) 2015 Bob Beck.  All rights reserved.
@@ -53,25 +53,27 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
-#include <unistd.h>
 #include <tls.h>
+#include <unistd.h>
+
 #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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to