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