summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm <>2013-08-20 16:22:09 +0000
committerdjm <>2013-08-20 16:22:09 +0000
commitd5f8f8e59eb9f2f497bd9efca4c92985f7a84b9d (patch)
tree08931a383a296601451d482c7f4e29eb41db7a0d
parentb71e62c5b2f158e276c970f1bd698819a2c49af3 (diff)
downloadopenbsd-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.121
-rw-r--r--src/usr.bin/nc/netcat.c74
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.
102Enable debugging on the socket. 102Enable debugging on the socket.
103.It Fl d 103.It Fl d
104Do not attempt to read from stdin. 104Do not attempt to read from stdin.
105.It Fl F
106Pass the first connected socket using
107.Xr sendmsg 2
108to stdout and exit.
109This is useful in conjunction with
110.Fl X
111to have
112.Nm
113perform connection setup with a proxy but then leave the rest of the
114connection to another program (e.g.
115.Xr ssh 1
116using the
117.Xr ssh_config 5
118.Cm ProxyUseFdPass
119option).
105.It Fl h 120.It Fl h
106Prints out 121Prints 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 */
68int dflag; /* detached, no stdin */ 69int dflag; /* detached, no stdin */
70int Fflag; /* fdpass sock to stdout */
69unsigned int iflag; /* Interval Flag */ 71unsigned int iflag; /* Interval Flag */
70int kflag; /* More than one connect */ 72int kflag; /* More than one connect */
71int lflag; /* Bind to local port */ 73int lflag; /* Bind to local port */
@@ -97,6 +99,7 @@ void build_ports(char *);
97void help(void); 99void help(void);
98int local_listen(char *, char *, struct addrinfo); 100int local_listen(char *, char *, struct addrinfo);
99void readwrite(int); 101void readwrite(int);
102void fdpass(int nfd) __attribute__((noreturn));
100int remote_connect(const char *, const char *, struct addrinfo); 103int remote_connect(const char *, const char *, struct addrinfo);
101int timeout_connect(int, const struct sockaddr *, socklen_t); 104int timeout_connect(int, const struct sockaddr *, socklen_t);
102int socks_connect(const char *, const char *, struct addrinfo, 105int 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 */
802void
803fdpass(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. */
791void 859void
792atelnet(int nfd, unsigned char *buf, unsigned int size) 860atelnet(int nfd, unsigned char *buf, unsigned int size)