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