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 }