Mercurial > dropbear
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 */ |