Mercurial > dropbear
comparison cli-tcpfwd.c @ 578:44f486b72427
- tcpfwd bindaddr support against trunk. needs merging.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 27 Feb 2010 11:51:19 +0000 |
parents | c3f2ec71e3d4 |
children | 8c737cd7c1af |
comparison
equal
deleted
inserted
replaced
576:c470649fb627 | 578:44f486b72427 |
---|---|
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, |
64 | 66 |
65 TRACE(("enter setup_localtcp")) | 67 TRACE(("enter setup_localtcp")) |
66 | 68 |
67 for (iter = cli_opts.localfwds->first; iter; iter = iter->next) { | 69 for (iter = cli_opts.localfwds->first; iter; iter = iter->next) { |
68 struct TCPFwdEntry * fwd = (struct TCPFwdEntry*)iter->item; | 70 struct TCPFwdEntry * fwd = (struct TCPFwdEntry*)iter->item; |
69 ret = cli_localtcp(fwd->listenport, | 71 ret = cli_localtcp( |
72 fwd->listenaddr, | |
73 fwd->listenport, | |
70 fwd->connectaddr, | 74 fwd->connectaddr, |
71 fwd->connectport); | 75 fwd->connectport); |
72 if (ret == DROPBEAR_FAILURE) { | 76 if (ret == DROPBEAR_FAILURE) { |
73 dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d", | 77 dropbear_log(LOG_WARNING, "Failed local port forward %s:%d:%s:%d", |
78 fwd->listenaddr, | |
74 fwd->listenport, | 79 fwd->listenport, |
75 fwd->connectaddr, | 80 fwd->connectaddr, |
76 fwd->connectport); | 81 fwd->connectport); |
77 } | 82 } |
78 } | 83 } |
79 TRACE(("leave setup_localtcp")) | 84 TRACE(("leave setup_localtcp")) |
80 | 85 |
81 } | 86 } |
82 | 87 |
83 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, | 88 static int cli_localtcp(const char* listenaddr, |
89 unsigned int listenport, | |
90 const char* remoteaddr, | |
84 unsigned int remoteport) { | 91 unsigned int remoteport) { |
85 | 92 |
86 struct TCPListener* tcpinfo = NULL; | 93 struct TCPListener* tcpinfo = NULL; |
87 int ret; | 94 int ret; |
88 | 95 |
92 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener)); | 99 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener)); |
93 | 100 |
94 tcpinfo->sendaddr = m_strdup(remoteaddr); | 101 tcpinfo->sendaddr = m_strdup(remoteaddr); |
95 tcpinfo->sendport = remoteport; | 102 tcpinfo->sendport = remoteport; |
96 | 103 |
97 if (opts.listen_fwd_all) { | 104 if (listenaddr) |
98 tcpinfo->listenaddr = m_strdup(""); | 105 { |
99 } else { | 106 tcpinfo->listenaddr = m_strdup(listenaddr); |
100 tcpinfo->listenaddr = m_strdup("localhost"); | 107 } |
108 else | |
109 { | |
110 if (opts.listen_fwd_all) { | |
111 tcpinfo->listenaddr = m_strdup(""); | |
112 } else { | |
113 tcpinfo->listenaddr = m_strdup("localhost"); | |
114 } | |
101 } | 115 } |
102 tcpinfo->listenport = listenport; | 116 tcpinfo->listenport = listenport; |
103 | 117 |
104 tcpinfo->chantype = &cli_chan_tcplocal; | 118 tcpinfo->chantype = &cli_chan_tcplocal; |
105 tcpinfo->tcp_type = direct; | 119 tcpinfo->tcp_type = direct; |
113 return ret; | 127 return ret; |
114 } | 128 } |
115 #endif /* ENABLE_CLI_LOCALTCPFWD */ | 129 #endif /* ENABLE_CLI_LOCALTCPFWD */ |
116 | 130 |
117 #ifdef ENABLE_CLI_REMOTETCPFWD | 131 #ifdef ENABLE_CLI_REMOTETCPFWD |
118 static void send_msg_global_request_remotetcp(int port) { | 132 static void send_msg_global_request_remotetcp(const char *addr, int port) { |
119 | 133 |
120 char* listenspec = NULL; | 134 char* listenspec = NULL; |
121 TRACE(("enter send_msg_global_request_remotetcp")) | 135 TRACE(("enter send_msg_global_request_remotetcp")) |
122 | 136 |
123 CHECKCLEARTOWRITE(); | 137 CHECKCLEARTOWRITE(); |
124 buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); | 138 buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); |
125 buf_putstring(ses.writepayload, "tcpip-forward", 13); | 139 buf_putstring(ses.writepayload, "tcpip-forward", 13); |
126 buf_putbyte(ses.writepayload, 1); /* want_reply */ | 140 buf_putbyte(ses.writepayload, 1); /* want_reply */ |
127 if (opts.listen_fwd_all) { | 141 buf_putstring(ses.writepayload, addr, strlen(addr)); |
128 listenspec = ""; | |
129 } else { | |
130 listenspec = "localhost"; | |
131 } | |
132 /* TODO: IPv6? */; | |
133 buf_putstring(ses.writepayload, listenspec, strlen(listenspec)); | |
134 buf_putint(ses.writepayload, port); | 142 buf_putint(ses.writepayload, port); |
135 | 143 |
136 encrypt_packet(); | 144 encrypt_packet(); |
137 | 145 |
138 TRACE(("leave send_msg_global_request_remotetcp")) | 146 TRACE(("leave send_msg_global_request_remotetcp")) |
171 m_list_elem *iter; | 179 m_list_elem *iter; |
172 TRACE(("enter setup_remotetcp")) | 180 TRACE(("enter setup_remotetcp")) |
173 | 181 |
174 for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { | 182 for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { |
175 struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item; | 183 struct TCPFwdEntry *fwd = (struct TCPFwdEntry*)iter->item; |
176 send_msg_global_request_remotetcp(fwd->listenport); | 184 if (!fwd->listenaddr) |
185 { | |
186 // we store the addresses so that we can compare them | |
187 // when the server sends them back | |
188 if (opts.listen_fwd_all) { | |
189 fwd->listenaddr = m_strdup(""); | |
190 } else { | |
191 fwd->listenaddr = m_strdup("localhost"); | |
192 } | |
193 } | |
194 send_msg_global_request_remotetcp(fwd->listenaddr, fwd->listenport); | |
177 } | 195 } |
178 | 196 |
179 TRACE(("leave setup_remotetcp")) | 197 TRACE(("leave setup_remotetcp")) |
180 } | 198 } |
181 | 199 |
182 static int newtcpforwarded(struct Channel * channel) { | 200 static int newtcpforwarded(struct Channel * channel) { |
183 | 201 |
202 char *origaddr = NULL; | |
184 unsigned int origport; | 203 unsigned int origport; |
185 m_list_elem * iter = NULL; | 204 m_list_elem * iter = NULL; |
186 struct TCPFwdEntry *fwd; | 205 struct TCPFwdEntry *fwd; |
187 char portstring[NI_MAXSERV]; | 206 char portstring[NI_MAXSERV]; |
188 int sock; | 207 int sock; |
189 int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; | 208 int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; |
190 | 209 |
191 /* We don't care what address they connected to */ | 210 origaddr = buf_getstring(ses.payload, NULL); |
192 buf_eatstring(ses.payload); | |
193 | |
194 origport = buf_getint(ses.payload); | 211 origport = buf_getint(ses.payload); |
195 | 212 |
196 /* Find which port corresponds */ | 213 /* Find which port corresponds */ |
197 for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { | 214 for (iter = cli_opts.remotefwds->first; iter; iter = iter->next) { |
198 fwd = (struct TCPFwdEntry*)iter->item; | 215 fwd = (struct TCPFwdEntry*)iter->item; |
199 if (origport == fwd->listenport) { | 216 if (origport == fwd->listenport |
217 && (strcmp(origaddr, fwd->listenaddr) == 0)) { | |
200 break; | 218 break; |
201 } | 219 } |
202 } | 220 } |
203 | 221 |
204 if (iter == NULL) { | 222 if (iter == NULL) { |
205 /* We didn't request forwarding on that port */ | 223 /* We didn't request forwarding on that port */ |
206 dropbear_log(LOG_INFO, "Server send unrequested port, from port %d", | 224 cleantext(origaddr); |
207 origport); | 225 dropbear_log(LOG_INFO, "Server sent unrequested forward from \"%s:%d\"", |
226 origaddr, origport); | |
208 goto out; | 227 goto out; |
209 } | 228 } |
210 | 229 |
211 snprintf(portstring, sizeof(portstring), "%d", fwd->connectport); | 230 snprintf(portstring, sizeof(portstring), "%d", fwd->connectport); |
212 sock = connect_remote(fwd->connectaddr, portstring, 1, NULL); | 231 sock = connect_remote(fwd->connectaddr, portstring, 1, NULL); |
224 channel->initconn = 1; | 243 channel->initconn = 1; |
225 | 244 |
226 err = SSH_OPEN_IN_PROGRESS; | 245 err = SSH_OPEN_IN_PROGRESS; |
227 | 246 |
228 out: | 247 out: |
248 m_free(origaddr); | |
229 TRACE(("leave newtcpdirect: err %d", err)) | 249 TRACE(("leave newtcpdirect: err %d", err)) |
230 return err; | 250 return err; |
231 } | 251 } |
232 #endif /* ENABLE_CLI_REMOTETCPFWD */ | 252 #endif /* ENABLE_CLI_REMOTETCPFWD */ |