diff options
| author | djm <> | 2013-08-20 16:22:09 +0000 |
|---|---|---|
| committer | djm <> | 2013-08-20 16:22:09 +0000 |
| commit | d5f8f8e59eb9f2f497bd9efca4c92985f7a84b9d (patch) | |
| tree | 08931a383a296601451d482c7f4e29eb41db7a0d /src | |
| parent | b71e62c5b2f158e276c970f1bd698819a2c49af3 (diff) | |
| download | openbsd-d5f8f8e59eb9f2f497bd9efca4c92985f7a84b9d.tar.gz openbsd-d5f8f8e59eb9f2f497bd9efca4c92985f7a84b9d.tar.bz2 openbsd-d5f8f8e59eb9f2f497bd9efca4c92985f7a84b9d.zip | |
add -F flag to enabled fd-pass mode: establish connection and pass
connected socket to stdout. This is useful in proxy mode to establish
a connection for use by ssh in conjunction with its new ProxyUseFDPass
option; ok markus@
Diffstat (limited to 'src')
| -rw-r--r-- | src/usr.bin/nc/nc.1 | 21 | ||||
| -rw-r--r-- | src/usr.bin/nc/netcat.c | 74 |
2 files changed, 89 insertions, 6 deletions
diff --git a/src/usr.bin/nc/nc.1 b/src/usr.bin/nc/nc.1 index 4c2a055cc4..c7a5a2b6e4 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.63 2013/07/16 00:07:52 schwarze Exp $ | 1 | .\" $OpenBSD: nc.1,v 1.64 2013/08/20 16:22:09 djm 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 16 2013 $ | 28 | .Dd $Mdocdate: August 20 2013 $ |
| 29 | .Dt NC 1 | 29 | .Dt NC 1 |
| 30 | .Os | 30 | .Os |
| 31 | .Sh NAME | 31 | .Sh NAME |
| @@ -34,7 +34,7 @@ | |||
| 34 | .Sh SYNOPSIS | 34 | .Sh SYNOPSIS |
| 35 | .Nm nc | 35 | .Nm nc |
| 36 | .Bk -words | 36 | .Bk -words |
| 37 | .Op Fl 46DdhklNnrStUuvz | 37 | .Op Fl 46DdFhklNnrStUuvz |
| 38 | .Op Fl I Ar length | 38 | .Op Fl I Ar length |
| 39 | .Op Fl i Ar interval | 39 | .Op Fl i Ar interval |
| 40 | .Op Fl O Ar length | 40 | .Op Fl O Ar length |
| @@ -102,6 +102,21 @@ to use IPv6 addresses only. | |||
| 102 | Enable debugging on the socket. | 102 | Enable debugging on the socket. |
| 103 | .It Fl d | 103 | .It Fl d |
| 104 | Do not attempt to read from stdin. | 104 | Do not attempt to read from stdin. |
| 105 | .It Fl F | ||
| 106 | Pass the first connected socket using | ||
| 107 | .Xr sendmsg 2 | ||
| 108 | to stdout and exit. | ||
| 109 | This is useful in conjunction with | ||
| 110 | .Fl X | ||
| 111 | to have | ||
| 112 | .Nm | ||
| 113 | perform connection setup with a proxy but then leave the rest of the | ||
| 114 | connection to another program (e.g. | ||
| 115 | .Xr ssh 1 | ||
| 116 | using the | ||
| 117 | .Xr ssh_config 5 | ||
| 118 | .Cm ProxyUseFdPass | ||
| 119 | option). | ||
| 105 | .It Fl h | 120 | .It Fl h |
| 106 | Prints out | 121 | Prints out |
| 107 | .Nm | 122 | .Nm |
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c index 571de9a766..6997b321db 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.112 2013/04/29 00:28:23 okan Exp $ */ | 1 | /* $OpenBSD: netcat.c,v 1.113 2013/08/20 16:22:09 djm Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> | 3 | * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> |
| 4 | * | 4 | * |
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <sys/types.h> | 34 | #include <sys/types.h> |
| 35 | #include <sys/socket.h> | 35 | #include <sys/socket.h> |
| 36 | #include <sys/time.h> | 36 | #include <sys/time.h> |
| 37 | #include <sys/uio.h> | ||
| 37 | #include <sys/un.h> | 38 | #include <sys/un.h> |
| 38 | 39 | ||
| 39 | #include <netinet/in.h> | 40 | #include <netinet/in.h> |
| @@ -66,6 +67,7 @@ | |||
| 66 | 67 | ||
| 67 | /* Command Line Options */ | 68 | /* Command Line Options */ |
| 68 | int dflag; /* detached, no stdin */ | 69 | int dflag; /* detached, no stdin */ |
| 70 | int Fflag; /* fdpass sock to stdout */ | ||
| 69 | unsigned int iflag; /* Interval Flag */ | 71 | unsigned int iflag; /* Interval Flag */ |
| 70 | int kflag; /* More than one connect */ | 72 | int kflag; /* More than one connect */ |
| 71 | int lflag; /* Bind to local port */ | 73 | int lflag; /* Bind to local port */ |
| @@ -97,6 +99,7 @@ void build_ports(char *); | |||
| 97 | void help(void); | 99 | void help(void); |
| 98 | int local_listen(char *, char *, struct addrinfo); | 100 | int local_listen(char *, char *, struct addrinfo); |
| 99 | void readwrite(int); | 101 | void readwrite(int); |
| 102 | void fdpass(int nfd) __attribute__((noreturn)); | ||
| 100 | int remote_connect(const char *, const char *, struct addrinfo); | 103 | int remote_connect(const char *, const char *, struct addrinfo); |
| 101 | int timeout_connect(int, const struct sockaddr *, socklen_t); | 104 | int timeout_connect(int, const struct sockaddr *, socklen_t); |
| 102 | int socks_connect(const char *, const char *, struct addrinfo, | 105 | int socks_connect(const char *, const char *, struct addrinfo, |
| @@ -132,7 +135,7 @@ main(int argc, char *argv[]) | |||
| 132 | sv = NULL; | 135 | sv = NULL; |
| 133 | 136 | ||
| 134 | while ((ch = getopt(argc, argv, | 137 | while ((ch = getopt(argc, argv, |
| 135 | "46DdhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { | 138 | "46DdFhI:i:klNnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { |
| 136 | switch (ch) { | 139 | switch (ch) { |
| 137 | case '4': | 140 | case '4': |
| 138 | family = AF_INET; | 141 | family = AF_INET; |
| @@ -156,6 +159,9 @@ main(int argc, char *argv[]) | |||
| 156 | case 'd': | 159 | case 'd': |
| 157 | dflag = 1; | 160 | dflag = 1; |
| 158 | break; | 161 | break; |
| 162 | case 'F': | ||
| 163 | Fflag = 1; | ||
| 164 | break; | ||
| 159 | case 'h': | 165 | case 'h': |
| 160 | help(); | 166 | help(); |
| 161 | break; | 167 | break; |
| @@ -463,7 +469,9 @@ main(int argc, char *argv[]) | |||
| 463 | uflag ? "udp" : "tcp", | 469 | uflag ? "udp" : "tcp", |
| 464 | sv ? sv->s_name : "*"); | 470 | sv ? sv->s_name : "*"); |
| 465 | } | 471 | } |
| 466 | if (!zflag) | 472 | if (Fflag) |
| 473 | fdpass(s); | ||
| 474 | else if (!zflag) | ||
| 467 | readwrite(s); | 475 | readwrite(s); |
| 468 | } | 476 | } |
| 469 | } | 477 | } |
| @@ -787,6 +795,66 @@ readwrite(int nfd) | |||
| 787 | } | 795 | } |
| 788 | } | 796 | } |
| 789 | 797 | ||
| 798 | /* | ||
| 799 | * fdpass() | ||
| 800 | * Pass the connected file descriptor to stdout and exit. | ||
| 801 | */ | ||
| 802 | void | ||
| 803 | fdpass(int nfd) | ||
| 804 | { | ||
| 805 | struct msghdr mh; | ||
| 806 | union { | ||
| 807 | struct cmsghdr hdr; | ||
| 808 | char buf[CMSG_SPACE(sizeof(int))]; | ||
| 809 | } cmsgbuf; | ||
| 810 | struct cmsghdr *cmsg; | ||
| 811 | struct iovec iov; | ||
| 812 | char c = '\0'; | ||
| 813 | ssize_t r; | ||
| 814 | struct pollfd pfd; | ||
| 815 | |||
| 816 | /* Avoid obvious stupidity */ | ||
| 817 | if (isatty(STDOUT_FILENO)) | ||
| 818 | errx(1, "Cannot pass file descriptor to tty"); | ||
| 819 | |||
| 820 | bzero(&mh, sizeof(mh)); | ||
| 821 | bzero(&cmsgbuf, sizeof(cmsgbuf)); | ||
| 822 | bzero(&iov, sizeof(iov)); | ||
| 823 | bzero(&pfd, sizeof(pfd)); | ||
| 824 | |||
| 825 | mh.msg_control = (caddr_t)&cmsgbuf.buf; | ||
| 826 | mh.msg_controllen = sizeof(cmsgbuf.buf); | ||
| 827 | cmsg = CMSG_FIRSTHDR(&mh); | ||
| 828 | cmsg->cmsg_len = CMSG_LEN(sizeof(int)); | ||
| 829 | cmsg->cmsg_level = SOL_SOCKET; | ||
| 830 | cmsg->cmsg_type = SCM_RIGHTS; | ||
| 831 | *(int *)CMSG_DATA(cmsg) = nfd; | ||
| 832 | |||
| 833 | iov.iov_base = &c; | ||
| 834 | iov.iov_len = 1; | ||
| 835 | mh.msg_iov = &iov; | ||
| 836 | mh.msg_iovlen = 1; | ||
| 837 | |||
| 838 | bzero(&pfd, sizeof(pfd)); | ||
| 839 | pfd.fd = STDOUT_FILENO; | ||
| 840 | for (;;) { | ||
| 841 | r = sendmsg(STDOUT_FILENO, &mh, 0); | ||
| 842 | if (r == -1) { | ||
| 843 | if (errno == EAGAIN || errno == EINTR) { | ||
| 844 | pfd.events = POLLOUT; | ||
| 845 | if (poll(&pfd, 1, -1) == -1) | ||
| 846 | err(1, "poll"); | ||
| 847 | continue; | ||
| 848 | } | ||
| 849 | err(1, "sendmsg"); | ||
| 850 | } else if (r == -1) | ||
| 851 | errx(1, "sendmsg: unexpected return value %zd", r); | ||
| 852 | else | ||
| 853 | break; | ||
| 854 | } | ||
| 855 | exit(0); | ||
| 856 | } | ||
| 857 | |||
| 790 | /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ | 858 | /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ |
| 791 | void | 859 | void |
| 792 | atelnet(int nfd, unsigned char *buf, unsigned int size) | 860 | atelnet(int nfd, unsigned char *buf, unsigned int size) |
