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 | |
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@
-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) |