Mercurial > dropbear
comparison cli-tcpfwd.c @ 64:efb5e0b335cf
TCP forwarding works.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 12 Aug 2004 13:48:42 +0000 |
parents | dcc43965928f |
children | 38c3146aa23d |
comparison
equal
deleted
inserted
replaced
63:dcc43965928f | 64:efb5e0b335cf |
---|---|
1 #include "includes.h" | 1 #include "includes.h" |
2 #include "options.h" | 2 #include "options.h" |
3 #include "tcp-accept.h" | 3 #include "dbutil.h" |
4 #include "tcp-connect.h" | 4 #include "tcpfwd.h" |
5 #include "channel.h" | 5 #include "channel.h" |
6 #include "runopts.h" | |
7 #include "session.h" | |
8 #include "ssh.h" | |
6 | 9 |
10 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, | |
11 unsigned int remoteport); | |
12 static int newtcpforwarded(struct Channel * channel); | |
13 | |
14 const struct ChanType cli_chan_tcpremote = { | |
15 1, /* sepfds */ | |
16 "forwarded-tcpip", | |
17 newtcpforwarded, | |
18 NULL, | |
19 NULL, | |
20 NULL | |
21 }; | |
7 static const struct ChanType cli_chan_tcplocal = { | 22 static const struct ChanType cli_chan_tcplocal = { |
8 1, /* sepfds */ | 23 1, /* sepfds */ |
9 "direct-tcpip", | 24 "direct-tcpip", |
25 NULL, | |
10 NULL, | 26 NULL, |
11 NULL, | 27 NULL, |
12 NULL | 28 NULL |
13 }; | 29 }; |
14 | 30 |
15 void setup_localtcp() { | 31 void setup_localtcp() { |
16 | 32 |
17 qv | 33 int ret; |
34 | |
35 if (cli_opts.localfwds == NULL) { | |
36 TRACE(("cli_opts.localfwds == NULL")); | |
37 } | |
38 | |
39 while (cli_opts.localfwds != NULL) { | |
40 ret = cli_localtcp(cli_opts.localfwds->listenport, | |
41 cli_opts.localfwds->connectaddr, | |
42 cli_opts.localfwds->connectport); | |
43 if (ret == DROPBEAR_FAILURE) { | |
44 dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d", | |
45 cli_opts.localfwds->listenport, | |
46 cli_opts.localfwds->connectaddr, | |
47 cli_opts.localfwds->connectport); | |
48 } | |
49 | |
50 cli_opts.localfwds = cli_opts.localfwds->next; | |
51 } | |
18 | 52 |
19 } | 53 } |
20 | 54 |
21 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, | 55 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, |
22 unsigned int remoteport) { | 56 unsigned int remoteport) { |
23 | 57 |
24 struct TCPListener* tcpinfo = NULL; | 58 struct TCPListener* tcpinfo = NULL; |
59 int ret; | |
60 | |
61 TRACE(("enter cli_localtcp: %d %s %d", listenport, remoteaddr, | |
62 remoteport)); | |
25 | 63 |
26 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener*)); | 64 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener*)); |
27 tcpinfo->sendaddr = remoteaddr; | 65 tcpinfo->sendaddr = remoteaddr; |
28 tcpinfo->sendport = remoteport; | 66 tcpinfo->sendport = remoteport; |
29 tcpinfo->listenport = listenport; | 67 tcpinfo->listenport = listenport; |
32 ret = listen_tcpfwd(tcpinfo); | 70 ret = listen_tcpfwd(tcpinfo); |
33 | 71 |
34 if (ret == DROPBEAR_FAILURE) { | 72 if (ret == DROPBEAR_FAILURE) { |
35 m_free(tcpinfo); | 73 m_free(tcpinfo); |
36 } | 74 } |
75 TRACE(("leave cli_localtcp: %d", ret)); | |
37 return ret; | 76 return ret; |
38 } | 77 } |
78 | |
79 static void send_msg_global_request_remotetcp(int port) { | |
80 | |
81 TRACE(("enter send_msg_global_request_remotetcp")); | |
82 | |
83 CHECKCLEARTOWRITE(); | |
84 buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); | |
85 buf_putstring(ses.writepayload, "tcpip-forward", 13); | |
86 buf_putbyte(ses.writepayload, 0); | |
87 buf_putstring(ses.writepayload, "0.0.0.0", 7); /* TODO: IPv6? */ | |
88 buf_putint(ses.writepayload, port); | |
89 | |
90 encrypt_packet(); | |
91 | |
92 TRACE(("leave send_msg_global_request_remotetcp")); | |
93 } | |
94 | |
95 void setup_remotetcp() { | |
96 | |
97 struct TCPFwdList * iter = NULL; | |
98 | |
99 if (cli_opts.remotefwds == NULL) { | |
100 TRACE(("cli_opts.remotefwds == NULL")); | |
101 } | |
102 | |
103 iter = cli_opts.remotefwds; | |
104 | |
105 while (iter != NULL) { | |
106 send_msg_global_request_remotetcp(iter->listenport); | |
107 iter = iter->next; | |
108 } | |
109 } | |
110 | |
111 static int newtcpforwarded(struct Channel * channel) { | |
112 | |
113 unsigned int origport; | |
114 struct TCPFwdList * iter = NULL; | |
115 char portstring[NI_MAXSERV]; | |
116 int sock; | |
117 int ret = DROPBEAR_FAILURE; | |
118 | |
119 /* We don't care what address they connected to */ | |
120 buf_eatstring(ses.payload); | |
121 | |
122 origport = buf_getint(ses.payload); | |
123 | |
124 /* Find which port corresponds */ | |
125 iter = cli_opts.remotefwds; | |
126 | |
127 while (iter != NULL) { | |
128 if (origport == iter->listenport) { | |
129 break; | |
130 } | |
131 iter = iter->next; | |
132 } | |
133 | |
134 if (iter == NULL) { | |
135 /* We didn't request forwarding on that port */ | |
136 dropbear_log(LOG_INFO, "Server send unrequested port, from port %d", | |
137 origport); | |
138 goto out; | |
139 } | |
140 | |
141 snprintf(portstring, sizeof(portstring), "%d", iter->connectport); | |
142 sock = connect_remote(iter->connectaddr, portstring, 1, NULL); | |
143 if (sock < 0) { | |
144 TRACE(("leave newtcpdirect: sock failed")); | |
145 goto out; | |
146 } | |
147 | |
148 ses.maxfd = MAX(ses.maxfd, sock); | |
149 | |
150 /* Note that infd is actually the "outgoing" direction on the | |
151 * tcp connection, vice versa for outfd. | |
152 * We don't set outfd, that will get set after the connection's | |
153 * progress succeeds */ | |
154 channel->infd = sock; | |
155 channel->initconn = 1; | |
156 | |
157 ret = DROPBEAR_SUCCESS; | |
158 | |
159 out: | |
160 TRACE(("leave newtcpdirect: ret %d", ret)); | |
161 return ret; | |
162 } |