1 /*
2 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2004, 2005, 2006, 2008, 2009,
3 * 2010, 2011, 2012, 2013
4 * Inferno Nettverk A/S, Norway. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. The above copyright notice, this list of conditions and the following
10 * disclaimer must appear in all copies of the software, derivative works
11 * or modified versions, and any portions thereof, aswell as in all
12 * supporting documentation.
13 * 2. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by
16 * Inferno Nettverk A/S, Norway.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Inferno Nettverk A/S requests users of this software to return to
32 *
33 * Software Distribution Coordinator or sdc@inet.no
34 * Inferno Nettverk A/S
35 * Oslo Research Park
36 * Gaustadall�en 21
37 * NO-0349 Oslo
38 * Norway
39 *
40 * any improvements or extensions that they make and grant Inferno Nettverk A/S
41 * the rights to redistribute these changes.
42 *
43 */
44
45 #include "common.h"
46
47 static const char rcsid[] =
48 "$Id: Rbind.c,v 1.215 2013/10/27 15:24:42 karls Exp $";
49
50 int
Rbind(s,_name,namelen)51 Rbind(s, _name, namelen)
52 int s;
53 const struct sockaddr *_name;
54 socklen_t namelen;
55 {
56 const char *function = "Rbind()";
57 struct sockaddr_storage namemem, *name = &namemem;
58 authmethod_t auth;
59 socksfd_t socksfd;
60 socklen_t len;
61 socks_t packet;
62 char emsg[256];
63 int val, rc, flags, errno_s;
64
65 clientinit();
66
67 /* hack for performance testing. */
68 if (socks_getenv(ENV_SOCKS_BINDLOCALONLY, dontcare) != NULL)
69 return bind(s, _name, namelen);
70
71 if (_name == NULL) {
72 slog(LOG_DEBUG, "%s: fd %d, _name = %p",
73 function, s, _name);
74
75 return bind(s, _name, namelen);
76 }
77
78 usrsockaddrcpy(name, TOCSS(_name), salen(_name->sa_family));
79
80 slog(LOG_DEBUG, "%s, fd %d, address %s",
81 function, s, sockaddr2string(TOSS(name), NULL, 0));
82
83 /*
84 * Nothing can be called before Rbind(), delete any old cruft.
85 */
86 socks_rmaddr(s, 1);
87
88 if (TOSA(name)->sa_family != AF_INET) {
89 slog(LOG_INFO, "%s: fd %d, unsupported af %s, system fallback",
90 function, s, safamily2string(name->ss_family));
91
92 return bind(s, _name, namelen);
93 }
94
95 if (socks_socketisforlan(s)) {
96 slog(LOG_INFO, "%s: fd %d is for lan only, system bind fallback",
97 function, s);
98
99 return bind(s, _name, namelen);
100 }
101
102 bzero(&auth, sizeof(auth));
103 auth.method = AUTHMETHOD_NOTSET;
104
105 bzero(&packet, sizeof(packet));
106 packet.req.version = PROXY_DIRECT;
107 packet.req.command = SOCKS_BIND;
108 packet.req.host.atype = SOCKS_ADDR_IPV4;
109 packet.req.host.addr.ipv4 = TOIN(&sockscf.state.lastconnect)->sin_addr;
110 packet.req.host.port = GET_SOCKADDRPORT(name);
111 packet.req.auth = &auth;
112
113 len = sizeof(val);
114 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &val, &len) != 0) {
115 swarn("%s: getsockopt(SO_TYPE)", function);
116 return -1;
117 }
118
119 switch (val) {
120 case SOCK_DGRAM:
121 packet.req.protocol = SOCKS_UDP;
122 break;
123
124 case SOCK_STREAM:
125 packet.req.protocol = SOCKS_TCP;
126 break;
127
128 default:
129 swarnx("%s: unknown socket-type %d, falling back to system bind(2)",
130 function, val);
131
132 return bind(s, _name, namelen);
133 }
134
135 bzero(&socksfd, sizeof(socksfd));
136
137 if ((socksfd.route = socks_requestpolish(&packet.req, NULL, NULL)) == NULL) {
138 /*
139 * If we just do a local bind, and pretend things are ok, that
140 * means our client can fetch the local address we bound and
141 * send it to a peer, which can then send data to us without going
142 * via the proxy. If that is not configured by routes (and direct
143 * fallback is presumably disabled), we can not be sure our client
144 * wants that to happen. If the client us running in an environment
145 * where it is more important to not leak traffic outside of the
146 * proxy connection, it surly does not want us to make a best
147 * effort to transfer the traffic; it has to flow via the proxy
148 * or not flow at all.
149 *
150 * So what we do is pretend we've bound an address, but we have
151 * not really done that, not even locally.
152 * This should prevent us from receiving non-proxied traffic, but
153 * might make things work for a subset of other operations, where
154 * the client does not expect to receive traffic before it has sent
155 * any itself (i.e., sendt UDP packets or performed a TCP (or UDP)
156 * connect), and where it does not expect to use the local address it
157 * thinks it has bound to set up a rendezvous of any sort.
158 *
159 * This should prevent us from leaking traffic directly, while still
160 * having a chance of things working without requiring an explicit
161 * direct route for e.g. UDP bind, which is not supported by most
162 * of the proxy protocols we support, and perhaps even work in
163 * cases where we are just using a primitive http proxy that only
164 * supports connect(2).
165 *
166 * Note that this is not the same that happens for a direct route,
167 * because we do not actually bind a local address and we will
168 * not be able to accept any traffic on this socket until the
169 * client first sends traffic on this socket (at which point some
170 * sort of local address will have to be bound).
171 */
172
173 slog(LOG_INFO,
174 "%s: no route found for binding %s address %s. Pretending we've "
175 "done it anyway. This may result in strange errors later, but "
176 "there is also a fair chance this will work, if the client does "
177 "not actually plan to use the bound address for anything until "
178 "after it has itself sendt the first traffic",
179 function,
180 protocol2string(packet.req.protocol),
181 sockaddr2string(name, NULL, 0));
182
183 errno = 0;
184 return 0;
185 }
186
187 packet.version = packet.req.version;
188
189 if (socksfd.route->gw.state.proxyprotocol.direct) {
190 slog(LOG_DEBUG, "%s: using system bind(2) for fd %d", function, s);
191 return bind(s, _name, namelen);
192 }
193 /*
194 * Else: client requests us to bind a specific port, but if we are
195 * socksifying that request, there is no need to bind any port locally.
196 */
197
198 /*
199 * no separate control socket (except bind-extension case, but
200 * that is dealt with in Raccept().
201 */
202 socksfd.control = s;
203
204 if (socks_routesetup(socksfd.control, s, socksfd.route, emsg, sizeof(emsg))
205 != 0) {
206 swarnx("%s: socks_routesetup() failed: %s", function, emsg);
207
208 if (socksfd.control != s)
209 close(socksfd.control);
210
211 return -1;
212 }
213
214 /*
215 * we're not interested the extra hassle of negotiating over
216 * a non-blocking socket, so make sure it's blocking while we
217 * use it.
218 */
219 flags = setblocking(socksfd.control, "socket used for negotiation");
220
221 socksfd.route = socks_connectroute(socksfd.control,
222 &packet,
223 NULL,
224 NULL,
225 emsg,
226 sizeof(emsg));
227
228 if (socksfd.route == NULL || socksfd.route->gw.state.proxyprotocol.direct) {
229 if (flags != -1)
230 if (fcntl(socksfd.control, F_SETFL, flags) == -1)
231 swarn("%s: fcntl(s)", function);
232 }
233
234 if (socksfd.route == NULL) {
235 swarnx("%s: could not connect route: %s", function, emsg);
236
237 errno = EADDRNOTAVAIL;
238 return -1;
239 }
240
241 if (socksfd.route->gw.state.proxyprotocol.direct) {
242 slog(LOG_INFO,
243 "%s: strange ... did our previously found route get blacklisted "
244 "in the meantime? Using system bind(2) for fd %d",
245 function, s);
246
247 return bind(s, _name, namelen);
248 }
249
250 rc = socks_negotiate(s,
251 socksfd.control,
252 &packet,
253 socksfd.route,
254 emsg,
255 sizeof(emsg));
256
257 errno_s = errno;
258
259 if (flags != -1)
260 if (fcntl(socksfd.control, F_SETFL, flags) == -1)
261 swarn("%s: fcntl(s)", function);
262
263 if (rc != 0) {
264 errno = errno_s;
265
266 swarnx("%s: socks_negotiate() failed: %s", function, emsg);
267
268 slog(LOG_DEBUG,
269 "%s: returning after socks_negotiate() failure with errno = %d (%s)",
270 function, errno, strerror(errno));
271
272 return -1;
273 }
274
275 update_after_negotiate(&packet, &socksfd);
276
277 if (packet.req.protocol == SOCKS_TCP)
278 socksfd.state.protocol.tcp = 1;
279 else if (packet.req.protocol == SOCKS_UDP)
280 socksfd.state.protocol.udp = 1;
281
282 socksfd.state.version = packet.req.version;
283 sockshost2sockaddr(&packet.res.host, &socksfd.remote);
284
285 switch (packet.req.version) {
286 case PROXY_SOCKS_V4:
287 if (TOIN(&socksfd.remote)->sin_addr.s_addr == htonl(0)) {
288 /*
289 * v4 specific; server doesn't say, so should set it to address
290 * we connected to for the control connection.
291 */
292 struct sockaddr_in addr;
293
294 len = sizeof(addr);
295 if (getpeername(socksfd.control, TOSA(&addr), &len) != 0)
296 SERR(-1);
297
298 TOIN(&socksfd.remote)->sin_addr = addr.sin_addr;
299 }
300 /* FALLTHROUGH */
301
302 case PROXY_SOCKS_V5:
303 socksfd.reply = socksfd.remote; /* same IP address. */
304 socksfd.state.acceptpending = socksfd.route->gw.state.extension.bind;
305 break;
306
307 case PROXY_UPNP:
308 /* don't know what address connection will be forwarded from yet. */
309 socksfd.state.acceptpending = 1;
310 break;
311
312 default:
313 SERRX(packet.req.version);
314 }
315
316 /* did we get the requested port? */
317 if (TOIN(name)->sin_port != htons(0)
318 && TOIN(name)->sin_port != TOIN(&socksfd.remote)->sin_port) { /* no. */
319 socks_freebuffer(socksfd.control);
320
321 slog(LOG_INFO,
322 "%s: proxyserver did not let us bind the requested port, %u. "
323 "Proxyserver offered us instead port %u, so failing",
324 function,
325 ntohs(GET_SOCKADDRPORT(name)),
326 ntohs(GET_SOCKADDRPORT(&socksfd.remote)));
327
328 errno = EADDRINUSE;
329 return -1;
330 }
331
332 len = sizeof(socksfd.local);
333 if (getsockname(s, TOSA(&socksfd.local), &len) != 0) {
334 swarn("%s: getsockname() of fd %d failed", function, s);
335 return -1;
336 }
337
338 slog(LOG_DEBUG, "%s: address of fd %d is %s",
339 function, s, sockaddr2string(&socksfd.local, NULL, 0));
340
341
342 if (socksfd.control != s) {
343 len = sizeof(socksfd.server);
344 if (getpeername(socksfd.control, TOSA(&socksfd.server), &len) != 0) {
345 return -1;
346 }
347 }
348
349 if (socksfd.state.acceptpending)
350 /*
351 * will accept(2) connection on control as for normal sockets,
352 * so no need to use a buffer for the control/listening socket;
353 * if a buffer is needed it will be for connection we later accept(2).
354 */
355 socks_freebuffer(socksfd.control);
356
357 switch (socksfd.state.version) {
358 case PROXY_SOCKS_V4:
359 case PROXY_SOCKS_V5:
360 case PROXY_UPNP:
361 socks_addaddr(s, &socksfd, 1);
362 break;
363
364 default:
365 SERRX(socksfd.state.version);
366 }
367
368 slog(LOG_INFO, "%s: successfully bound address %s for fd %d",
369 function, sockaddr2string(&socksfd.remote, NULL, 0), s);
370
371 return 0;
372 }
373
374 #if 0
375 /*
376 * Disabled since this idea will not work due to NAT. :-/
377 */
378
379 static int socks_bind_udp(const int s, struct sockaddr_storage *addr);
380 /*
381 * Attempts to bind udp address "addr" at the socks server for socket "s".
382 *
383 * Returns 0 on success, -1 on failure, with errno set appropriately if so.
384 */
385
386 static int
387 socks_bind_udp(s, addr)
388 const int s;
389 struct sockaddr_storage *addr;
390 {
391 /*
392 * The socks protocol does not support binding udp sockets, but we try
393 * to implement the same by creating a normal socks udp association
394 * and sending a packet to ourselves. The senders address for that
395 * packet should be the address the socks server is using on our
396 * behalf.
397 * Unfortunately this does not work in most personal cases due to
398 * NAT - the socks server on the other side of the NAT-box can not send
399 * data to our (private) address.
400 */
401 const char *function = "socks_bind_udp()";
402 const int errno_s = errno;
403 struct sockaddr_storage from;
404 socksfd_t socksfd;
405 socklen_t len;
406 ssize_t rc;
407 char *p, emsg[1024], buf[256];
408
409 errno = EADDRNOTAVAIL; /* default errorcode. */
410
411 slog(LOG_INFO, "%s: fd %d, address %s",
412 function, s, sockaddr2string(addr, NULL, 0));
413
414 /*
415 * Hackish and fragile, but need to do the things necessary udpsetup()
416 * can understand this really is our fd, and not something that slipped
417 * through the cracks.
418 */
419
420 bzero(&socksfd, sizeof(socksfd));
421
422 socksfd.state.command = SOCKS_BIND;
423
424 len = sizeof(socksfd.local);
425 if (getsockname(s, TOSA(&socksfd.local), &len) == -1)
426 return -1;
427
428 socks_addaddr(s, &socksfd, 1);
429
430 socksfd.route = udpsetup(s,
431 &socksfd.local,
432 SOCKS_SEND,
433 0,
434 emsg,
435 sizeof(emsg));
436
437 if (socksfd.route == NULL) {
438 slog(LOG_INFO, "%s: udpsetup() for udp bind on fd %d failed: %s",
439 function, s, emsg);
440
441 return -1;
442 }
443
444 if (socks_getaddr(s, &socksfd, 1) == 0) {
445 swarnx("%s: strange, socks_getaddr() on fd %d failed after udpsetup()",
446 function, s);
447
448 return -1;
449 }
450
451 slog(LOG_INFO,
452 "%s: created udp association for data fd %d successfully. Now trying "
453 "to send a small packet to ourselves on address %s",
454 function, s, sockaddr2string(&socksfd.local, NULL, 0));
455
456 p = "I just want to know what address you are using on my behalf";
457 if (Rsendto(s, p, strlen(p), 0, TOSA(&socksfd.local), sizeof(socksfd.local))
458 != (ssize_t)strlen(p)) {
459 slog(LOG_INFO,
460 "%s: send of packet to ourselves at address %s to finish setting "
461 "up udp bind for fd %d failed",
462 function, sockaddr2string(&socksfd.local, NULL, 0), s);
463
464 return -1;
465 }
466
467 slog(LOG_DEBUG,
468 "%s: successfully sent udp packet to ourselves on address %s "
469 "via proxy. Now waiting for the reply",
470 function, sockaddr2string(&socksfd.local, NULL, 0));
471
472 len = sizeof(from);
473 if ((rc = recvfrom(s, buf, sizeof(buf), 0, TOSA(&from), &len))
474 != (ssize_t)strlen(p)) {
475 swarn("%s: expected to receive our own udp packet of length %lu back, "
476 "but received %ld byte%s instead",
477 function,
478 (unsigned long)strlen(p),
479 (long)rc,
480 rc == 1 ? "" : "s");
481
482 return -1;
483 }
484
485 if (strcmp(buf, p) == 0)
486 slog(LOG_INFO, "%s: received our own %lu bytes from %s: all as expected",
487 function, rc, sockaddr2string(&from, NULL, 0));
488 else {
489 char visbuf[sizeof(buf) * 4];
490
491 swarnx("%s: bytes received from %s not what we expected. "
492 "Expected %s, got %s",
493 function,
494 sockaddr2string(&from, NULL, 0),
495 p,
496 str2vis(buf, rc, visbuf, sizeof(visbuf)));
497
498 return -1;
499 }
500
501 return -1;
502
503 errno = errno_s;;
504 return 0;
505 }
506
507 #endif
508