comparison cli-tcpfwd.c @ 577:69e98c45db7c

- Progress for allowing specifying a listenaddr for tcp forwards
author Matt Johnston <matt@ucc.asn.au>
date Wed, 24 Feb 2010 16:13:15 +0000
parents 805e557fdff7
children 8c737cd7c1af
comparison
equal deleted inserted replaced
518:ce104c8b0be1 577:69e98c45db7c
43 NULL 43 NULL
44 }; 44 };
45 #endif 45 #endif
46 46
47 #ifdef ENABLE_CLI_LOCALTCPFWD 47 #ifdef ENABLE_CLI_LOCALTCPFWD
48 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, 48 static int cli_localtcp(const char* listenaddr,
49 unsigned int listenport,
50 const char* remoteaddr,
49 unsigned int remoteport); 51 unsigned int remoteport);
50 static const struct ChanType cli_chan_tcplocal = { 52 static const struct ChanType cli_chan_tcplocal = {
51 1, /* sepfds */ 53 1, /* sepfds */
52 "direct-tcpip", 54 "direct-tcpip",
53 NULL, 55 NULL,
67 if (cli_opts.localfwds == NULL) { 69 if (cli_opts.localfwds == NULL) {
68 TRACE(("cli_opts.localfwds == NULL")) 70 TRACE(("cli_opts.localfwds == NULL"))
69 } 71 }
70 72
71 while (cli_opts.localfwds != NULL) { 73 while (cli_opts.localfwds != NULL) {
72 ret = cli_localtcp(cli_opts.localfwds->listenport, 74 ret = cli_localtcp(
75 cli_opts.localfwds->listenaddr,
76 cli_opts.localfwds->listenport,
73 cli_opts.localfwds->connectaddr, 77 cli_opts.localfwds->connectaddr,
74 cli_opts.localfwds->connectport); 78 cli_opts.localfwds->connectport);
75 if (ret == DROPBEAR_FAILURE) { 79 if (ret == DROPBEAR_FAILURE) {
76 dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d", 80 dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
81 cli_opts.localfwds->listenaddr,
77 cli_opts.localfwds->listenport, 82 cli_opts.localfwds->listenport,
78 cli_opts.localfwds->connectaddr, 83 cli_opts.localfwds->connectaddr,
79 cli_opts.localfwds->connectport); 84 cli_opts.localfwds->connectport);
80 } 85 }
81 86
83 } 88 }
84 TRACE(("leave setup_localtcp")) 89 TRACE(("leave setup_localtcp"))
85 90
86 } 91 }
87 92
88 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, 93 static int cli_localtcp(const char* listenaddr,
94 unsigned int listenport,
95 const char* remoteaddr,
89 unsigned int remoteport) { 96 unsigned int remoteport) {
90 97
91 struct TCPListener* tcpinfo = NULL; 98 struct TCPListener* tcpinfo = NULL;
92 int ret; 99 int ret;
93 100
97 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener)); 104 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
98 105
99 tcpinfo->sendaddr = m_strdup(remoteaddr); 106 tcpinfo->sendaddr = m_strdup(remoteaddr);
100 tcpinfo->sendport = remoteport; 107 tcpinfo->sendport = remoteport;
101 108
102 if (opts.listen_fwd_all) { 109 if (listenaddr)
103 tcpinfo->listenaddr = m_strdup(""); 110 {
104 } else { 111 tcpinfo->listenaddr = m_strdup(listenaddr);
105 tcpinfo->listenaddr = m_strdup("localhost"); 112 }
113 else
114 {
115 if (opts.listen_fwd_all) {
116 tcpinfo->listenaddr = m_strdup("");
117 } else {
118 tcpinfo->listenaddr = m_strdup("localhost");
119 }
106 } 120 }
107 tcpinfo->listenport = listenport; 121 tcpinfo->listenport = listenport;
108 122
109 tcpinfo->chantype = &cli_chan_tcplocal; 123 tcpinfo->chantype = &cli_chan_tcplocal;
110 tcpinfo->tcp_type = direct; 124 tcpinfo->tcp_type = direct;
118 return ret; 132 return ret;
119 } 133 }
120 #endif /* ENABLE_CLI_LOCALTCPFWD */ 134 #endif /* ENABLE_CLI_LOCALTCPFWD */
121 135
122 #ifdef ENABLE_CLI_REMOTETCPFWD 136 #ifdef ENABLE_CLI_REMOTETCPFWD
123 static void send_msg_global_request_remotetcp(int port) { 137 static void send_msg_global_request_remotetcp(const char *addr, int port) {
124 138
125 char* listenspec = NULL; 139 char* listenspec = NULL;
126 TRACE(("enter send_msg_global_request_remotetcp")) 140 TRACE(("enter send_msg_global_request_remotetcp"))
127 141
128 CHECKCLEARTOWRITE(); 142 CHECKCLEARTOWRITE();
129 buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); 143 buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
130 buf_putstring(ses.writepayload, "tcpip-forward", 13); 144 buf_putstring(ses.writepayload, "tcpip-forward", 13);
131 buf_putbyte(ses.writepayload, 1); /* want_reply */ 145 buf_putbyte(ses.writepayload, 1); /* want_reply */
132 if (opts.listen_fwd_all) { 146 buf_putstring(ses.writepayload, addr, strlen(addr));
133 listenspec = "";
134 } else {
135 listenspec = "localhost";
136 }
137 /* TODO: IPv6? */;
138 buf_putstring(ses.writepayload, listenspec, strlen(listenspec));
139 buf_putint(ses.writepayload, port); 147 buf_putint(ses.writepayload, port);
140 148
141 encrypt_packet(); 149 encrypt_packet();
142 150
143 TRACE(("leave send_msg_global_request_remotetcp")) 151 TRACE(("leave send_msg_global_request_remotetcp"))
190 } 198 }
191 199
192 iter = cli_opts.remotefwds; 200 iter = cli_opts.remotefwds;
193 201
194 while (iter != NULL) { 202 while (iter != NULL) {
195 send_msg_global_request_remotetcp(iter->listenport); 203 if (!iter->listenaddr)
204 {
205 // we store the addresses so that we can compare them
206 // when the server sends them back
207 if (opts.listen_fwd_all) {
208 iter->listenaddr = m_strdup("");
209 } else {
210 iter->listenaddr = m_strdup("localhost");
211 }
212 }
213 send_msg_global_request_remotetcp(iter->listenaddr, iter->listenport);
196 iter = iter->next; 214 iter = iter->next;
197 } 215 }
198 TRACE(("leave setup_remotetcp")) 216 TRACE(("leave setup_remotetcp"))
199 } 217 }
200 218
201 static int newtcpforwarded(struct Channel * channel) { 219 static int newtcpforwarded(struct Channel * channel) {
202 220
221 char *origaddr = NULL;
203 unsigned int origport; 222 unsigned int origport;
204 struct TCPFwdList * iter = NULL; 223 struct TCPFwdList * iter = NULL;
205 char portstring[NI_MAXSERV]; 224 char portstring[NI_MAXSERV];
206 int sock; 225 int sock;
207 int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; 226 int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
208 227
209 /* We don't care what address they connected to */ 228 origaddr = buf_getstring(ses.payload, NULL);
210 buf_eatstring(ses.payload);
211
212 origport = buf_getint(ses.payload); 229 origport = buf_getint(ses.payload);
213 230
214 /* Find which port corresponds */ 231 /* Find which port corresponds */
215 iter = cli_opts.remotefwds; 232 iter = cli_opts.remotefwds;
216 233
217 while (iter != NULL) { 234 while (iter != NULL) {
218 if (origport == iter->listenport) { 235 if (origport == iter->listenport
236 && (strcmp(origaddr, iter->listenaddr) == 0)) {
219 break; 237 break;
220 } 238 }
221 iter = iter->next; 239 iter = iter->next;
222 } 240 }
223 241
224 if (iter == NULL) { 242 if (iter == NULL) {
225 /* We didn't request forwarding on that port */ 243 /* We didn't request forwarding on that port */
226 dropbear_log(LOG_INFO, "Server send unrequested port, from port %d", 244 cleantext(origaddr);
227 origport); 245 dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"",
246 origaddr, origport);
228 goto out; 247 goto out;
229 } 248 }
230 249
231 snprintf(portstring, sizeof(portstring), "%d", iter->connectport); 250 snprintf(portstring, sizeof(portstring), "%d", iter->connectport);
232 sock = connect_remote(iter->connectaddr, portstring, 1, NULL); 251 sock = connect_remote(iter->connectaddr, portstring, 1, NULL);
244 channel->initconn = 1; 263 channel->initconn = 1;
245 264
246 err = SSH_OPEN_IN_PROGRESS; 265 err = SSH_OPEN_IN_PROGRESS;
247 266
248 out: 267 out:
268 m_free(origaddr);
249 TRACE(("leave newtcpdirect: err %d", err)) 269 TRACE(("leave newtcpdirect: err %d", err))
250 return err; 270 return err;
251 } 271 }
252 #endif /* ENABLE_CLI_REMOTETCPFWD */ 272 #endif /* ENABLE_CLI_REMOTETCPFWD */