1 /*
2  * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3  *               2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017, 2019,
4  *               2020
5  *      Inferno Nettverk A/S, Norway.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. The above copyright notice, this list of conditions and the following
11  *    disclaimer must appear in all copies of the software, derivative works
12  *    or modified versions, and any portions thereof, aswell as in all
13  *    supporting documentation.
14  * 2. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by
17  *      Inferno Nettverk A/S, Norway.
18  * 3. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * Inferno Nettverk A/S requests users of this software to return to
33  *
34  *  Software Distribution Coordinator  or  sdc@inet.no
35  *  Inferno Nettverk A/S
36  *  Oslo Research Park
37  *  Gaustadall�en 21
38  *  NO-0349 Oslo
39  *  Norway
40  *
41  * any improvements or extensions that they make and grant Inferno Nettverk A/S
42  * the rights to redistribute these changes.
43  *
44  */
45 
46 #include "common.h"
47 #include "config_parse.h"
48 
49 static const char rcsid[] =
50 "$Id: sockd_request.c,v 1.849.4.15.2.4.4.6 2020/11/11 17:02:31 karls Exp $";
51 
52 /*
53  * XXX Should fix things so this process too can support multiple clients.
54  * Will also fix the terrible fact that we just sit around and wait if the
55  * command is bind, wasting the whole process on practically nothing.
56  */
57 
58 
59 /* start of siginfo struct for requestchild.  Just the basics for now. */
60 static struct req {
61    unsigned char             allocated;
62 
63    rule_t                    crule;           /* crule matched for client.    */
64 #if HAVE_SOCKS_HOSTID
65    rule_t                    hrule;           /* hrule matched for client.    */
66    unsigned char             hrule_isset;
67 #endif /* HAVE_SOCKS_HOSTID */
68 
69    struct sockaddr_storage   client;          /* client's address.            */
70    request_t                 request;         /* request to perform.          */
71    unsigned char             request_isvalid; /*
72                                                * request has been checked and
73                                                * is if nothing else, valid.
74                                                */
75    int                       s;               /* control-connection to client */
76    time_t                    starttime;       /* time we started handling req */
77 } reqv[1];
78 static const size_t reqc = ELEMENTS(reqv);
79 
80 static void siginfo(int sig, siginfo_t *si, void *sc);
81 
82 static int bindexternaladdr(struct sockd_io_t *io, const request_t *req,
83                             char *emsg, const size_t emsglen);
84 /*
85  * Binds an external address of the appropriate type for the request "req".
86  * Updates io.dst.laddr with the bound external address.
87  *
88  * Returns 0 on success.
89  * Returns -1 on failure, and fills in emsg with the reason.
90  */
91 
92 static void
93 auth2standard(const authmethod_t *auth, authmethod_t *stdauth);
94 /*
95  * Converts auth "auth", possibly using a non-standard method (e.g.,
96  * AUTHMETHOD_PAM_USERNAME) to a standard socks authmethod, stored in
97  * "stdauth".
98  */
99 
100 static void init_req(struct req *req, const sockd_request_t *request);
101 static void delete_req(struct req *req);
102 /*
103  * Inits and de-inits "req".  For siginfo printing.
104  */
105 
106 static void
107 initlogaddrs(const sockd_io_t *io, iologaddr_t *src, iologaddr_t *dst,
108              iologaddr_t *proxy);
109 /*
110  * inits "src", "dst", and "proxy", based on values in "io".
111  * If any of src, dst, or proxy, is NULL, that is not inited.
112  */
113 
114 static void
115 convertresponse(const response_t *oldres, response_t *newres,
116                 const int newversion);
117 /*
118  * Converts a response on form "oldres", using oldres->version,
119  * to a new response on form "newversion".
120  */
121 
122 static iostatus_t
123 dorequest(const sockd_mother_t *mother, sockd_request_t *request,
124           struct sockaddr_storage *clientudpaddr, int *weclosedfirst,
125           char *emsg, const size_t emsglen);
126 /*
127  * When a complete request has been read, this function can be
128  * called.  It will perform the request "request->req" and send the
129  * result to "mother".
130  *
131  * If the request is for a udp-associate, the address the client told
132  * us it will be sending from, if any, is stored as resolved in
133  * "clientudpaddr".
134  *
135  * "weclosedfirst" is on failure set to indicate whether we closed
136  * the connection first, or whether the client closed it first.  The
137  * latter is typically what happens during network errors or blocked
138  * requests.  In this case, "emsg" is filled in with the a text describing
139  * the problem.
140  *
141  * Returns:
142  *    If request was successfully completed: IO_NOERROR.
143  *    If request was not performed: an iostauts indicating the reason.
144  *        In this case "weclosedfirst" is also set to true or false,
145  *        indicating whether we or a peer first closed the connection.
146  */
147 
148 static int
149 reqhostisok(sockshost_t *host, const int cmd, char *emsg,
150             const size_t emsglen);
151 /*
152  * Checks that the host "host" specified in the client request with command
153  * "cmd" is ok.
154  * If necessary, it may "fixup" host also, which currently consists of
155  * converting it from an ipv4-mapped ipv6 address to a ipv4 address.
156  *
157  * Returns SOCKS_SUCCESS if everything is ok.
158  * Returns a socks failurecode if something is not ok.  "emsg" will then
159  * contain the reason.
160  */
161 
162 static int
163 flushio(int mother, sockd_io_t *io);
164 /*
165  * "flushes" a complete io object and free's any state/resources held by it.
166  * Also iolog()s that the session was accepted.
167  * "mother" is connection to mother for sending the io.
168  * "io" is the io object to send to mother.
169  *
170  * Returns 0 if the i/o object was forwarded successfully.
171  * Returns -1 if the i/o object was not forwarded.
172  *
173  */
174 
175 static void
176 proctitleupdate(const struct sockaddr_storage *from);
177 /*
178  * Updates the title of this process.
179  */
180 
181 static route_t *
182 getroute(const struct sockaddr_storage *client, request_t *req,
183          char *emsg, const size_t emsglen);
184 /*
185  * Returns the route that should be used for the request "req"
186  * from client "client", if a route is found.
187  *
188  * Returns NULL if no route is found or an error occurred.  "emsg" will then
189  * contain the reason.
190  */
191 
192 
193 static int
194 serverchain(const int targetsocket, const int clientsocket,
195             const struct sockaddr_storage *client, const request_t *req,
196             proxychaininfo_t *proxychain, authmethod_t *proxychainauth,
197             char *emsg, const size_t emsglen);
198 /*
199  * Checks if we should create a serverchain to the target on  targetsocket
200  * "targetsocket" for the request "req".
201  *
202  * "clientsocket" is the socket we accepted the client on,.
203  * "client" is the clients address.
204  *
205  * If a serverchain was created, the proxyprotocol used in the chain is set
206  * in "proxyprotocol", and further information is provided in "proxychain".
207  * If proxychain->proxyprotocol is set to PROXY_DIRECT, no server-chaining
208  * should be done.
209  *
210  * If a serverchain was established, "proxychainauth" is the authentication
211  * used with the upsteream proxy.
212  *
213  * Returns:
214  *       0: Call successful.  See proxychain for information about the results.
215  *      -1: Some error occurred.  "emsg" will contain the details.
216  */
217 
218 #if SOCKS_SERVER
219 
220 static sockd_io_t *
221 io_add(sockd_io_t *iolist, const sockd_io_t *newio);
222 /*
223  * Adds _a copy_ of the object "newio" to the list "iolist".
224  * Returns a pointer to the (new) iolist.
225  */
226 
227 static sockd_io_t *
228 io_remove(sockd_io_t *iolist, sockd_io_t *rmio);
229 /*
230  * Removes the object "rmio" from the list "iolist".
231  * Returns a pointer to the (new) iolist.
232  */
233 
234 static sockd_io_t *
235 io_find(sockd_io_t *iolist, const struct sockaddr_storage *addr);
236 /*
237  * Scans "iolist" for a object that contains "addr" as a local address.
238  * If "addr" is NULL, returns "iolist".
239  * Returns:
240  *      On success: pointer to the matching io object.
241  *      On failure: NULL.
242  */
243 #endif /* SOCKS_SERVER */
244 
245 void
run_request()246 run_request()
247 {
248    const char *function = "run_request()";
249    sockd_request_t req;
250    struct sigaction sigact;
251    fd_set *rset;
252 
253    bzero(&sigact, sizeof(sigact));
254    sigact.sa_flags     = SA_RESTART | SA_NOCLDSTOP | SA_SIGINFO;
255    sigact.sa_sigaction = siginfo;
256 
257 #if HAVE_SIGNAL_SIGINFO
258    if (sigaction(SIGINFO, &sigact, NULL) != 0)
259       serr("%s: sigaction(SIGINFO)", function);
260 #endif /* HAVE_SIGNAL_SIGINFO */
261 
262    /* same handler, for systems without SIGINFO. */
263    if (sigaction(SIGUSR1, &sigact, NULL) != 0)
264       serr("%s: sigaction(SIGINFO)", function);
265 
266    rset  = allocate_maxsize_fdset();
267    req.s = -1;
268 
269    sockd_print_child_ready_message((size_t)freedescriptors(NULL, NULL));
270 
271    while (1) {
272       /*
273        * Get request from mother, perform it, get next request.
274        */
275 #if DIAGNOSTIC
276       const int freec
277       = freedescriptors(sockscf.option.debug ? "start" : NULL, NULL);
278 #endif /* DIAGNOSTIC */
279       iostatus_t iostatus;
280       struct sockaddr_storage clientudpaddr;
281       char command, emsg[2048];
282       int fdbits, weclosedfirst;
283 
284       errno = 0; /* reset for each iteration. */
285 
286       proctitleupdate(NULL);
287 
288       FD_ZERO(rset);
289       fdbits = -1;
290 
291       if (sockscf.state.mother.s != -1) {
292          FD_SET(sockscf.state.mother.s, rset);
293          fdbits = sockscf.state.mother.s;
294       }
295 
296       /* checked so we know if mother goes away.  */
297       FD_SET(sockscf.state.mother.ack, rset);
298       fdbits = MAX(fdbits, sockscf.state.mother.ack);
299 
300       ++fdbits;
301       switch (selectn(fdbits, rset, NULL, NULL, NULL, NULL, NULL)) {
302          case -1:
303             SASSERT(ERRNOISTMP(errno));
304             continue;
305 
306          case 0:
307             SERRX(0);
308       }
309 
310       if (FD_ISSET(sockscf.state.mother.ack, rset)) { /* only eof expected. */
311          sockd_readmotherscontrolsocket(function, sockscf.state.mother.ack);
312 
313 #if HAVE_VALGRIND_VALGRIND_H
314          if (RUNNING_ON_VALGRIND) {
315             /* for some reason Valgrind complains the rset pointer is lost. */
316             free(rset);
317          }
318 #endif /* HAVE_VALGRIND_VALGRIND_H */
319 
320          sockdexit(EXIT_FAILURE);
321       }
322 
323       if (FD_ISSET(sockscf.state.mother.s, rset)) {
324          if (recv_req(sockscf.state.mother.s, &req) == -1)
325             serr("%s: failed reading new request from mother: %s",
326                  function, strerror(errno));
327       }
328 
329       iostatus = dorequest(&sockscf.state.mother,
330                            &req,
331                            &clientudpaddr,
332                            &weclosedfirst,
333                            emsg,
334                            sizeof(emsg));
335 
336       if (iostatus != IO_NOERROR) {
337          /*
338           * log the client-rule and hostid-rule close also if appropriate,
339           * as this will not be logged on the normal session-close in the i/o
340           * process because the session was not successfully established.
341           */
342          operation_t op;
343          clientinfo_t cinfo;
344          iologaddr_t src;
345          rule_t *rule;
346          size_t rused;
347          char reason[sizeof(emsg) + 1024];
348 
349          slog(LOG_DEBUG,
350               "%s: dorequest() failed.  srule_isset = %d, weclosedfirst = %d, "
351               "iostatus = %d, error: %s",
352               function, req.srule_isset, weclosedfirst, iostatus, emsg);
353 
354          log_ruleinfo_shmid(CRULE_OR_HRULE(&req), function, NULL);
355 
356          if (req.srule_isset)
357             rule = &req.srule;
358          else
359             rule = CRULE_OR_HRULE(&req);
360 
361          log_ruleinfo_shmid(rule, function, NULL);
362 
363          if (req.s == -1) {
364             SASSERTX(BAREFOOTD);
365             SASSERTX(req.state.protocol == SOCKS_UDP);
366 
367             /*
368              * nothing can have been used as we need to wait
369              * for the udp clients.
370              */
371             SHMEM_CLEAR(CRULE_OR_HRULE(&req), SHMEM_ALL, 1);
372 
373             SASSERTX(!req.srule_isset);
374          }
375 
376          /*
377           * Clean up shmem usage, whether the request failed before or
378           * after we progressed to the socks-rule level.  In the former case,
379           * no shmid-fields will be set in req->srule.
380           */
381 
382          cinfo.from = req.from;
383          HOSTIDCOPY(&req.state, &cinfo);
384 
385          switch (iostatus) {
386             case IO_BLOCK:
387                rused = 0;
388                op    = OPERATION_BLOCK;
389                break;
390 
391             case IO_CLOSE:
392                op    = OPERATION_DISCONNECT;
393                rused = 0;
394                break;
395 
396             case IO_IOERROR:
397             case IO_ERROR:
398                rused = snprintf(reason, sizeof(reason),
399                                 "request was not performed due to error");
400                op    = OPERATION_ERROR;
401                break;
402 
403             default:
404                SWARNX(iostatus);
405 
406                rused = 0;
407                op    = OPERATION_ERROR;
408          }
409 
410          if (*emsg != NUL)
411             snprintf(&reason[rused], sizeof(reason) - rused,
412                      "%s%s",
413                      rused > 0 ? ": " : "",
414                      emsg);
415 
416          if (rule->mstats_shmid != 0
417          && (rule->alarmsconfigured & ALARM_DISCONNECT))
418             alarm_add_disconnect(weclosedfirst,
419                                  rule,
420                                  ALARM_INTERNAL,
421                                  &cinfo,
422                                  strerror(errno),
423                                  sockscf.shmemfd);
424 
425          SHMEM_UNUSE(rule, &cinfo, sockscf.shmemfd, SHMEM_ALL);
426 
427          switch (req.state.protocol) {
428             case SOCKS_TCP:
429                command = SOCKD_FREESLOT_TCP;
430                break;
431 
432             case SOCKS_UDP:
433                command = SOCKD_FREESLOT_UDP;
434                break;
435 
436             default:
437                SERRX(req.state.protocol);
438          }
439 
440          if (socks_sendton(sockscf.state.mother.ack,
441                            &command,
442                            sizeof(command),
443                            sizeof(command),
444                            0,
445                            NULL,
446                            0,
447                            NULL,
448                            NULL) != sizeof(command))
449             slog(sockd_motherexists() ? LOG_WARNING : LOG_DEBUG,
450                  "%s: sending ack to mother failed: %s",
451                  function, strerror(errno));
452 
453          /*
454           * dorequest() logs the failed socks-level session close with
455           * appropriate details, but we need to log the client-level close.
456           */
457          init_iologaddr(&src,
458                         object_sockaddr,
459                         &req.to,
460                         object_sockaddr,
461                         &req.from,
462                         &req.cauth,
463                         GET_HOSTIDV(&req.state),
464                         GET_HOSTIDC(&req.state));
465 
466 #if HAVE_SOCKS_HOSTID
467          if (req.hrule_isset) {
468             req.state.command = SOCKS_HOSTID;
469             iolog(&req.hrule,
470                   &req.state,
471                   op,
472                   &src,
473                   NULL,
474                   NULL,
475                   NULL,
476                   reason,
477                   strlen(reason));
478          }
479 #endif /* HAVE_SOCKS_HOSTID */
480 
481          req.state.command  = SOCKS_ACCEPT;
482          req.state.protocol = SOCKS_TCP;
483 
484 #if !HAVE_SOCKS_RULES /* only logged if debug is enabled. */
485          if (sockscf.option.debug)
486 #endif /* HAVE_SOCKS_RULES */
487          iolog(&req.crule,
488                &req.state,
489                op,
490                &src,
491                NULL,
492                NULL,
493                NULL,
494                reason,
495                strlen(reason));
496       }
497 
498       delete_req(&reqv[0]);
499 
500 #if DIAGNOSTIC
501       if (freec != freedescriptors(sockscf.option.debug ?  "end" : NULL, NULL))
502          swarnx("%s: lost %d file descriptor%s in total while handling request",
503                 function,
504                 freec - freedescriptors(NULL, NULL),
505                 freec - freedescriptors(NULL, NULL) == 1 ? "" : "s");
506 #endif /* DIAGNOSTIC */
507    }
508 }
509 
510 void
request_preconfigload(void)511 request_preconfigload(void)
512 {
513    const char *function = "request_preconfigload()";
514 
515    slog(LOG_DEBUG, "%s", function);
516 }
517 
518 void
request_postconfigload(void)519 request_postconfigload(void)
520 {
521    const char *function = "request_postconfigload()";
522 
523    slog(LOG_DEBUG, "%s", function);
524 }
525 
526 
527 int
recv_req(s,req)528 recv_req(s, req)
529    int s;
530    sockd_request_t *req;
531 {
532    const char *function = "recv_req()";
533 #if HAVE_GSSAPI
534    char gssapistatemem[MAX_GSS_STATE];
535 #endif /* HAVE_GSSAPI */
536    struct iovec iov[2];
537    struct msghdr msg;
538    struct timeval tnow;
539    ssize_t r;
540    int ioc, fdexpect, fdreceived;
541    CMSG_AALLOC(cmsg, sizeof(int));
542 
543 #if BAREFOOTD
544    if (!ALL_UDP_BOUNCED()) {
545       /*
546        * We're the main mother.  Go through all client-rules that have a
547        * bounce-to address that requires us to listen to udp addresses and
548        * fake a request for it, without going through the negotiate child
549        * (there is nothing to negotiate).
550        */
551       rule_t *rule;
552       char sstr[MAXRULEADDRSTRING], tstr[MAXRULEADDRSTRING],
553            dstr[MAXRULEADDRSTRING], emsg[1024];
554       int foundruletobounce = 0;
555 
556       SASSERTX(pidismainmother(sockscf.state.pid));
557 
558       bzero(req, sizeof(*req));
559 
560       for (rule = sockscf.crule; rule != NULL; rule = rule->next) {
561          struct sockaddr_storage addr;
562          int gaierr;
563 
564          if (!rule->state.protocol.udp || rule->bounced)
565             continue;
566 
567          sockshost2sockaddr2(ruleaddr2sockshost(&rule->dst, NULL, SOCKS_UDP),
568                              &req->to,
569                              &gaierr,
570                              emsg,
571                              sizeof(emsg));
572 
573          if (gaierr != 0 || !IPADDRISBOUND(&req->to)) {
574             if (gaierr != 0)
575                log_resolvefailed(rule->dst.addr.domain, INTERNALIF, gaierr);
576 
577             /*
578              * this is serious since it means we won't know what address we
579              * should listen for udp packets on.
580              */
581             serr("%s: could not convert \"%s\" in destination-portion "
582                  "of %s #%lu to IP-address: %s",
583                  function,
584                  ruleaddr2string(&rule->dst, ADDRINFO_ATYPE, NULL, 0),
585                  objecttype2string(rule->type),
586                  (unsigned long)rule->number,
587                  emsg);
588          }
589 
590          if (rule->verdict == VERDICT_PASS) {
591             ruleaddr2sockaddr2(&rule->extra.bounceto,
592                                &addr,
593                                SOCKS_UDP,
594                                &gaierr,
595                                emsg,
596                                sizeof(emsg));
597 
598             if (gaierr != 0 || !IPADDRISBOUND(&addr)) {
599                if (gaierr != 0)
600                   log_resolvefailed(rule->extra.bounceto.addr.domain,
601                                     EXTERNALIF,
602                                     gaierr);
603 
604                swarn("%s: could not convert hostname \"%s\" in bounce-to "
605                      "portion of %s #%lu to IP-address: %s",
606                      function,
607                      ruleaddr2string(&rule->extra.bounceto,
608                                      ADDRINFO_ATYPE,
609                                      NULL,
610                                      0),
611                      objecttype2string(rule->type),
612                      (unsigned long)rule->number,
613                      emsg);
614 
615                /*
616                 * but don't consider it fatal.  In particular if this is
617                 * after a sighup it would be embarrassing to exit on such
618                 * an error if there are hundreds of other rules working fine.
619                 * A warning should be enough, and do it now too, rather than
620                 * waiting for a client.
621                 */
622             }
623          }
624          /* else; will not be using bounce-to address; packet is blocked. */
625 
626          sockshost2sockaddr2(ruleaddr2sockshost(&rule->src, NULL, SOCKS_UDP),
627                              &req->from,
628                              &gaierr,
629                              emsg,
630                              sizeof(emsg));
631 
632          if ((rule->src.atype == SOCKS_ADDR_DOMAIN
633          ||   rule->src.atype == SOCKS_ADDR_IFNAME)
634          && !IPADDRISBOUND(&req->from)) {
635             if (rule->src.atype        == SOCKS_ADDR_DOMAIN
636             &&  *rule->src.addr.domain == '.') {
637                /*
638                 * Rule is on ".<domain>" form.  Not resolvable.
639                 * Just use zeros for now.  Not needed till we get an
640                 * actual client, and will be updated then.
641                 */
642                bzero(&req->from, sizeof(req->from));
643                SET_SOCKADDR(&req->from, AF_INET);
644             }
645             else {
646                if (rule->src.atype == SOCKS_ADDR_DOMAIN && gaierr != 0)
647                   log_resolvefailed(rule->src.addr.domain, INTERNALIF, gaierr);
648 
649                swarn("%s: could not convert \"%s\" in source-portion of "
650                      "%s #%lu to IP-address: %s",
651                      function,
652                      ruleaddr2string(&rule->src, ADDRINFO_ATYPE, NULL, 0),
653                      objecttype2string(rule->type),
654                      (unsigned long)rule->number,
655                      emsg);
656 
657             }
658          }
659 
660          slog(LOG_DEBUG,
661               "%s: creating new udp session for clients from %s to target %s, "
662               "to be accepted on %s, for %s #%lu",
663               function,
664               ruleaddr2string(&rule->src, ADDRINFO_PORT, sstr, sizeof(sstr)),
665               ruleaddr2string(&rule->extra.bounceto,
666                               ADDRINFO_PORT,
667                               tstr,
668                               sizeof(tstr)),
669               ruleaddr2string(&rule->dst, ADDRINFO_PORT, dstr, sizeof(dstr)),
670               objecttype2string(rule->type),
671               (unsigned long)rule->number);
672 
673          req->crule                     = *rule;
674 
675          req->cauth.method              = AUTHMETHOD_NONE;
676          req->sauth.method              = AUTHMETHOD_NONE;
677          req->s                         = -1;
678 
679          req->state.command             = SOCKS_ACCEPT;
680          req->state.protocol            = SOCKS_UDP;
681 
682          req->req.version               = PROXY_SOCKS_V5;
683          req->req.command               = SOCKS_UDPASSOCIATE;
684          req->req.flag                  = 0;
685 
686          /*
687           * We can obviously only accept IPvX packets on an IPvX socket,
688           * so client must send from an IPvX address.
689           */
690          req->req.host.atype            = rule->dst.atype;
691 
692          switch (req->req.host.atype) {
693             case SOCKS_ADDR_IPV4:
694                req->req.host.addr.ipv4.s_addr = htonl(INADDR_ANY);
695                break;
696 
697             case SOCKS_ADDR_IPV6:
698                req->req.host.addr.ipv6.ip      = in6addr_any;
699                req->req.host.addr.ipv6.scopeid = rule->dst.addr.ipv6.scopeid;
700                break;
701 
702             default:
703                SERRX(req->req.host.atype);
704          }
705 
706          req->req.host.port             = htons(0);
707 
708          req->req.auth                  = &req->sauth;
709          req->req.protocol              = SOCKS_UDP;
710 
711          /*
712           * no negotiation going on here; what we want is what we get.
713           */
714          req->state.command       = req->req.command;
715          req->state.proxyprotocol = req->req.version;
716 
717          gettimeofday_monotonic(&req->state.time.accepted);
718          req->state.time.negotiatestart = req->state.time.accepted;
719          req->state.time.negotiateend   = req->state.time.accepted;
720          req->state.time.established    = req->state.time.accepted;
721 
722          rule->bounced     = 1;
723          foundruletobounce = 1;
724          break;
725       }
726 
727       if (foundruletobounce) {
728          SASSERTX(req->s == -1);
729          return 0;
730       }
731       else {
732          slog(LOG_DEBUG, "%s: no more addresses to bounce", function);
733          sockscf.state.alludpbounced = 1;
734 
735          errno = EAGAIN;
736          return -1;
737       }
738    }
739 #endif /* BAREFOOTD */
740 
741    ioc = 0;
742    bzero(iov, sizeof(iov));
743    iov[ioc].iov_base = req;
744    iov[ioc].iov_len  = sizeof(*req);
745    ++ioc;
746 
747 #if HAVE_GSSAPI
748    iov[ioc].iov_base = gssapistatemem;
749    iov[ioc].iov_len  = sizeof(gssapistatemem);
750    ++ioc;
751 #endif /* HAVE_GSSAPI */
752 
753    bzero(&msg, sizeof(msg));
754    msg.msg_iov     = iov;
755    msg.msg_iovlen  = ioc;
756    msg.msg_name    = NULL;
757    msg.msg_namelen = 0;
758 
759    /* LINTED pointer casts may be troublesome */
760    CMSG_SETHDR_RECV(msg, cmsg, CMSG_MEMSIZE(cmsg));
761 
762    if ((r = recvmsgn(s, &msg, 0)) < (ssize_t)sizeof(*req)) {
763       switch (r) {
764          case -1:
765             slog(LOG_DEBUG, "%s: recvmsg() failed: %s",
766             function, strerror(errno));
767             break;
768 
769          case 0:
770             slog(LOG_DEBUG, "%s: recvmsg(): other side closed connection",
771             function);
772             break;
773 
774          default:
775             swarnx("%s: recvmsg(): unexpected short read: %ld/%lu",
776                    function, (long)r, (unsigned long)sizeof(*req));
777       }
778 
779       return -1;
780    }
781 
782    if (socks_msghaserrors(function, &msg))
783       return -1;
784 
785    gettimeofday_monotonic(&tnow);
786    sockd_check_ipclatency("client object received from negotiate process",
787                           &req->state.time.negotiateend,
788                           &tnow,
789                           &tnow);
790 
791    SASSERTX(req->srule.bw == NULL);
792    SASSERTX(req->srule.ss == NULL);
793 
794 #if BAREFOOTD
795    if (req->req.command == SOCKS_UDPASSOCIATE)
796       fdexpect = 0; /* no client yet. */
797    else
798       fdexpect = 1; /* client. */
799 
800 #else /* SOCKS_SERVER */
801    fdexpect = 1; /* client. */
802 #endif /* SOCKS_SERVER */
803 
804    if (!CMSG_RCPTLEN_ISOK(msg, sizeof(int) * fdexpect)) {
805       swarnx("%s: received control message has the invalid len of %d",
806               function, (int)CMSG_TOTLEN(msg));
807 
808       return -1;
809    }
810 
811    fdreceived = 0;
812    if (fdexpect > 0) {
813       SASSERTX(cmsg->cmsg_level == SOL_SOCKET);
814       SASSERTX(cmsg->cmsg_type  == SCM_RIGHTS);
815 
816       CMSG_GETOBJECT(req->s, cmsg, sizeof(req->s) * fdreceived++);
817 
818       if (sockscf.option.debug >= DEBUG_VERBOSE)
819          slog(LOG_DEBUG, "%s: received fd %d (%s) ...",
820          function, req->s, socket2string(req->s, NULL, 0));
821    }
822 
823    req->req.auth = &req->sauth; /* pointer fixup */
824 
825 #if HAVE_GSSAPI
826    if (req->req.auth->method == AUTHMETHOD_GSSAPI) {
827       gss_buffer_desc gssapistate;
828 
829       r -= sizeof(*req);
830       SASSERTX(r > 0);
831 
832       if (sockscf.option.debug >= DEBUG_VERBOSE)
833          slog(LOG_DEBUG, "%s: read gssapistate of size %ld", function, (long)r);
834 
835       gssapistate.value  = gssapistatemem;
836       gssapistate.length = r;
837 
838       if (gssapi_import_state(&req->req.auth->mdata.gssapi.state.id,
839                               &gssapistate) != 0)
840          return -1;
841    }
842 #endif /* HAVE_GSSAPI */
843 
844    if (sockscf.option.debug >= DEBUG_VERBOSE)
845       slog(LOG_DEBUG,
846            "%s: received %d fds for request with method %d, req->s = %d",
847            function, fdreceived, req->req.auth->method, s);
848 
849    return 0;
850 }
851 
852 static iostatus_t
dorequest(mother,request,clientudpaddr,weclosedfirst,emsg,emsglen)853 dorequest(mother, request, clientudpaddr, weclosedfirst, emsg, emsglen)
854    const sockd_mother_t *mother;
855    sockd_request_t *request;
856    struct sockaddr_storage *clientudpaddr;
857    int *weclosedfirst;
858    char *emsg;
859    const size_t emsglen;
860 {
861    const char *function = "dorequest()";
862    iostatus_t iostatus;
863    sockd_io_t io;
864    response_t response;
865    iologaddr_t *src, srcmem, *dst, dstmem;
866    clientinfo_t cinfo;
867    size_t msglen;
868    char strhost[MAXSOCKSHOSTSTRING], buf[(MAXHOSTNAMELEN * 4) + 256];
869    int rc;
870 #if SOCKS_SERVER
871    sockshost_t expectedbindreply, bindreplydst;
872 #endif /* SOCKS_SERVER */
873 
874 #if HAVE_SOCKS_RULES
875    int permit;
876 #endif /* HAVE_SOCKS_RULES */
877 
878    *emsg = NUL;
879 
880    /*
881     * If the request fails, we will typically close first, as otherwise
882     * the reason for the request failing would typically be a network error,
883     * which there are not many checks for (typically only detected when
884     * we send the response to the client).
885     */
886    *weclosedfirst = 1;
887 
888    slog(LOG_DEBUG,
889         "%s: command %d request received from client %s.  Accepted on %s, "
890         "matched by %s #%lu, auth: %s.  Packet: %s ",
891         function,
892         request->state.command,
893         sockaddr2string(&request->from, strhost, sizeof(strhost)),
894         sockaddr2string(&request->to, NULL, 0),
895         objecttype2string(request->crule.type),
896         (unsigned long)request->crule.number,
897         method2string(request->req.auth->method),
898         socks_packet2string(&request->req, 1));
899 
900    proctitleupdate(&request->from);
901    init_req(&reqv[0], request);
902 
903    bzero(&response, sizeof(response));
904    response.host   = request->req.host;
905    response.auth   = request->req.auth;
906 
907    bzero(&io, sizeof(io));
908 
909    io.control.auth.method = AUTHMETHOD_NOTSET;
910    io.control.s           = -1;
911    io.src                 = io.control;
912 
913    io.dst.s               = -1;
914 
915    io.reqflags            = request->req.flags;
916    io.state               = request->state;
917 
918    SASSERTX(proxyprotocolisknown(io.state.proxyprotocol));
919 
920    io.crule               = request->crule;
921 
922 #if HAVE_SOCKS_HOSTID
923    io.hrule               = request->hrule;
924    io.hrule_isset         = request->hrule_isset;
925 #endif /* HAVE_SOCKS_HOSTID */
926 
927    io.cauth               = request->cauth;
928 
929 #if HAVE_NEGOTIATE_PHASE
930    CTASSERT(sizeof(io.clientdata) == sizeof(request->clientdata));
931    io.clientdatalen = request->clientdatalen;
932    memcpy(io.clientdata, request->clientdata, io.clientdatalen);
933 #endif /* HAVE_NEGOTIATE_PHASE */
934 
935    src = &srcmem;
936    init_iologaddr(src,
937                   object_sockaddr,
938                   &request->to,
939                   object_sockaddr,
940                   &request->from,
941                   request->req.auth,
942                   GET_HOSTIDV(&request->state),
943                   GET_HOSTIDC(&request->state));
944 
945    dst = NULL; /* for now. */
946 
947    /*
948     * examine client request.
949     */
950 
951    /* supported version? */
952    switch (request->req.version) {
953 #if SOCKS_SERVER || BAREFOOTD
954       case PROXY_SOCKS_V4:
955          response.version = PROXY_SOCKS_V4REPLY_VERSION;
956 
957          /* supported address format for this version? */
958          switch (request->req.host.atype) {
959             case SOCKS_ADDR_IPV4:
960                break;
961 
962             default:
963                msglen = snprintf(emsg, emsglen, "unrecognized v%d atype: %d",
964                                  request->req.version, request->req.host.atype);
965 
966                iolog(&io.crule,
967                      &io.state,
968                      OPERATION_ERROR,
969                      src,
970                      dst,
971                      NULL,
972                      NULL,
973                      emsg,
974                      msglen);
975 
976                send_failure(request->s, &response, SOCKS_ADDR_UNSUPP);
977 
978                close(request->s);
979                return IO_ERROR;
980          }
981 
982          /* recognized command for this version? */
983          switch (request->req.command) {
984             case SOCKS_BIND:
985             case SOCKS_CONNECT:
986                io.state.protocol        = SOCKS_TCP;
987                io.src.state.isconnected = 1;
988                break;
989 
990             default:
991                io.state.command = SOCKS_UNKNOWN;
992 
993                msglen = snprintf(emsg, emsglen,
994                                  "unrecognized v%d command: %d",
995                                  request->req.version, request->req.command);
996 
997                iolog(&io.crule,
998                      &io.state,
999                      OPERATION_ERROR,
1000                      src,
1001                      dst,
1002                      NULL,
1003                      NULL,
1004                      emsg,
1005                      msglen);
1006 
1007                send_failure(request->s, &response, SOCKS_CMD_UNSUPP);
1008 
1009                close(request->s);
1010                return IO_ERROR;
1011          }
1012          break; /* PROXY_SOCKS_V4 */
1013 
1014       case PROXY_SOCKS_V5:
1015          response.version = request->req.version;
1016 
1017          /* supported address format for this version? */
1018          switch (request->req.host.atype) {
1019             case SOCKS_ADDR_IPV4:
1020             case SOCKS_ADDR_IPV6:
1021             case SOCKS_ADDR_DOMAIN:
1022                break;
1023 
1024             default:
1025                msglen = snprintf(emsg, emsglen,
1026                                  "unrecognized v%d atype: %d",
1027                                  request->req.version, request->req.host.atype);
1028 
1029                iolog(&io.crule,
1030                      &io.state,
1031                      OPERATION_ERROR,
1032                      src,
1033                      dst,
1034                      NULL,
1035                      NULL,
1036                      emsg,
1037                      msglen);
1038 
1039                send_failure(request->s, &response, SOCKS_ADDR_UNSUPP);
1040 
1041                close(request->s);
1042                return IO_ERROR;
1043          }
1044 
1045          /* recognized command for this version? */
1046          switch (request->req.command) {
1047             case SOCKS_BIND:
1048             case SOCKS_CONNECT:
1049                io.state.protocol = SOCKS_TCP;
1050                break;
1051 
1052             case SOCKS_UDPASSOCIATE:
1053                io.state.protocol = SOCKS_UDP;
1054                break;
1055 
1056             default:
1057                io.state.command = SOCKS_UNKNOWN;
1058 
1059                msglen = snprintf(emsg, emsglen,
1060                                  "unrecognized v%d command: %d",
1061                                  request->req.version, request->req.command);
1062 
1063                iolog(&io.crule,
1064                      &io.state,
1065                      OPERATION_ERROR,
1066                      src,
1067                      dst,
1068                      NULL,
1069                      NULL,
1070                      emsg,
1071                      msglen);
1072 
1073                send_failure(request->s, &response, SOCKS_CMD_UNSUPP);
1074 
1075                close(request->s);
1076                return IO_ERROR;
1077          }
1078 
1079          break; /* PROXY_SOCKS_V5 */
1080 #endif /* SOCKS_SERVER || BAREFOOTD */
1081 
1082 #if COVENANT
1083       case PROXY_HTTP_10:
1084       case PROXY_HTTP_11:
1085          SASSERTX(request->req.command == SOCKS_CONNECT);
1086          SASSERTX (request->req.host.atype == SOCKS_ADDR_IPV4
1087          ||        request->req.host.atype == SOCKS_ADDR_IPV6
1088          ||        request->req.host.atype == SOCKS_ADDR_DOMAIN);
1089 
1090          response.version  = request->req.version;
1091          io.state.protocol = SOCKS_TCP;
1092          break;
1093 #endif /* COVENANT */
1094 
1095       default:
1096          SERRX(request->req.version);
1097    }
1098 
1099    rc = reqhostisok(&request->req.host, request->req.command, emsg, emsglen);
1100 
1101    if (rc != SOCKS_SUCCESS) {
1102       iolog(&io.crule,
1103             &io.state,
1104             OPERATION_ERROR,
1105             src,
1106             dst,
1107             NULL,
1108             NULL,
1109             emsg,
1110             strlen(emsg));
1111 
1112       send_failure(request->s, &response, rc);
1113 
1114       close(request->s);
1115       return IO_ERROR;
1116    }
1117 
1118    /*
1119     * packet looks ok to, fill in remaining bits and check rules.
1120     */
1121    reqv[0].request_isvalid = 1;
1122 
1123    switch (request->req.command) {
1124 #if SOCKS_SERVER
1125       case SOCKS_BIND:
1126          /*
1127           * Bind is a bit cumbersome.
1128           * We first need to check if the bind request is allowed, and then
1129           * we transform io.dst to something completely different to check
1130           * if the bindreply is allowed.
1131           */
1132 
1133          io.src.s                  = request->s;
1134          io.src.state.isconnected = 1;
1135          io.src.laddr             = request->to;
1136          io.src.raddr             = request->from;
1137          io.src.auth              = *request->req.auth;
1138          sockaddr2sockshost(&io.src.raddr, &io.src.host);
1139 
1140          io.dst.host = request->req.host;
1141 
1142          if (io.dst.host.atype            == SOCKS_ADDR_IPV4
1143          &&  io.dst.host.addr.ipv4.s_addr == htonl(BINDEXTENSION_IPADDR)) {
1144             slog(LOG_DEBUG, "%s: bind extension enabled for request from %s",
1145                  function, sockaddr2string(&request->from, NULL, 0));
1146 
1147             io.state.extension.bind = 1;
1148          }
1149          else
1150             io.state.extension.bind = 0;
1151 
1152          /*
1153           * Semantics in v4 and v5 are slightly different, so if v4
1154           * convert to corresponding v5 semantics, so we later can
1155           * treat v4 and v5 as the same (mostly).
1156           */
1157          switch (request->req.version) {
1158             case PROXY_SOCKS_V5:
1159                /*
1160                 * One popular interpretation is that the port always gives
1161                 * the desired port, rather than the port the client
1162                 * previously connected to.  So that is what we assume,
1163                 * and we convert the v4 request to something that can match
1164                 * that.
1165                 */
1166                break;
1167 
1168             case PROXY_SOCKS_V4:
1169                /*
1170                 * If the address is 0, assume port is port client
1171                 * wants to bind.  If not, best we can try for is to
1172                 * use same port as client used for connecting to us.
1173                 */
1174                SASSERTX(request->req.host.atype == SOCKS_ADDR_IPV4);
1175 
1176                if (request->req.host.addr.ipv4.s_addr != htonl(0))
1177                   request->req.host.port = GET_SOCKADDRPORT(&request->to);
1178                /* else; assume port already set to what client wants to bind. */
1179                break;
1180 
1181             default:
1182                SERRX(request->req.version);
1183          }
1184 
1185          break;
1186 #endif /* SOCKS_SERVER */
1187 
1188       case SOCKS_CONNECT:
1189          io.src.s                 = request->s;
1190          io.src.state.isconnected = 1;
1191          io.src.laddr             = request->to;
1192          io.src.raddr             = request->from;
1193          io.src.auth              = *request->req.auth;
1194          sockaddr2sockshost(&io.src.raddr, &io.src.host);
1195 
1196          io.dst.host              = request->req.host;
1197          break;
1198 
1199       case SOCKS_UDPASSOCIATE:
1200          /*
1201           * some things will change, but some things, auth included, will
1202           * stay the same.
1203           */
1204 
1205 #if HAVE_CONTROL_CONNECTION
1206          io.control.s                 = request->s;
1207          io.control.state.isconnected = 1;
1208          io.control.state.isconnected = 1;
1209          io.control.laddr             = request->to;
1210          io.control.raddr             = request->from;
1211          io.control.auth              = *request->req.auth;
1212 
1213          /* let src get the same credentials as control. */
1214          io.src.auth                  = *request->req.auth;
1215 
1216          sockaddr2sockshost(&io.control.raddr, &io.control.host);
1217 #endif /* HAVE_CONTROL_CONNECTION */
1218 
1219          io.src.host = request->req.host;
1220          sockshost2sockaddr(&io.src.host, &io.src.raddr);
1221 
1222          bzero(&io.src.laddr, sizeof(io.src.laddr));
1223          SET_SOCKADDR(&io.src.laddr, io.src.raddr.ss_family);
1224 
1225          /* needs to be done so caller can shmem_unuse() correct cinfo. */
1226          *clientudpaddr = io.src.raddr;
1227 
1228          /*
1229           * for UDP_ASSOCIATE we are getting the clients UDP address in the
1230           * request, not the target destination.  Destination address will
1231           * be contained in each socks udp packet received, and checked in
1232           * the i/o process for each destination for each packet.
1233           */
1234          break;
1235 
1236       default:
1237          SERRX(request->req.command);
1238    }
1239 
1240    /*
1241     * Update now that we have parsed the request and know what is what.
1242     */
1243    init_iologaddr(src,
1244                   object_sockaddr,
1245                   &io.src.laddr,
1246                   object_sockshost,
1247                   &io.src.host,
1248                   &io.src.auth,
1249                   GET_HOSTIDV(&io.state),
1250                   GET_HOSTIDC(&io.state));
1251 
1252    if (io.state.protocol == SOCKS_TCP) { /* also know parts of dst now. */
1253       dst = &dstmem;
1254 
1255       init_iologaddr(dst,
1256                      object_none,
1257                      NULL,
1258                      object_sockshost,
1259                      &io.dst.host,
1260                      &io.dst.auth,
1261                      NULL,
1262                      0);
1263 
1264       switch (request->req.command) {
1265 #if SOCKS_SERVER
1266          case SOCKS_BIND:
1267             /*
1268              * Figure out what address to expect the bind reply from.
1269              * Unfortunately, this is a mishmash of different interpretations.
1270              *
1271              * The socks v4 standard is pretty strict about the meaning,
1272              * while the v5 is much more ambiguous.
1273              *
1274              * Unfortunately the meaning given in these standard provides
1275              * limited usability, so people "interpret" the standards more
1276              * loose to get more practical functionality out of them.
1277              *
1278              * - If the client provided an ip address when requesting the
1279              *   bind, we should only return remote connections matching
1280              *   that ip address.  The portnumber we should ignore.
1281              *
1282              * - If the client did not provide an ip address (set it to 0),
1283              *   we should probably try to match neither ip nor port,
1284              *   but should try to bind the requested portnumber locally.
1285              *
1286              * The standard is not very clear in this area, but the above
1287              * interpretation seems most practical.
1288              */
1289 
1290             if (io.state.extension.bind) { /* multiple connections. */
1291                sockaddr2sockshost(&request->from, &io.dst.host);
1292                bindreplydst           = io.dst.host;
1293 
1294                bzero(&expectedbindreply, sizeof(expectedbindreply));
1295                expectedbindreply.atype = SOCKS_ADDR_IPV4;
1296             }
1297             else { /* only one connection; bindreply over control-channel. */
1298                bindreplydst = io.src.host;
1299 
1300                if (io.dst.host.addr.ipv4.s_addr == htonl(0)) {
1301                   bzero(&expectedbindreply, sizeof(expectedbindreply));
1302                   expectedbindreply.atype = SOCKS_ADDR_IPV4;
1303                }
1304                else
1305                   expectedbindreply = io.dst.host;
1306 
1307                expectedbindreply.port = htons(0);
1308             }
1309 
1310             slog(LOG_DEBUG, "%s: expecting bindreply from %s",
1311                  function, sockshost2string(&expectedbindreply, NULL, 0));
1312             break;
1313 
1314 #endif /* SOCKS_SERVER */
1315 
1316          case SOCKS_CONNECT:
1317 #if 0
1318             /*
1319              * Set SO_REUSEADDR to limit the chances that we run out of
1320              * available TCP ports to use.
1321              * We however need to handle the case of us trying to connect
1322              * from the same port (due to the client connecting from the
1323              * same port) to the same destination multiple times, which
1324              * we don't do yet.  Thus disabled.
1325              */
1326             rc = 1;
1327             if (setsockopt(io.dst.s, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof(rc))
1328             != 0)
1329                swarn("%s: setsockopt(SO_REUSEADDR)", function);
1330 #endif
1331             break;
1332 
1333          default:
1334             SERRX(request->req.command);
1335       }
1336    }
1337 
1338 #if HAVE_SOCKS_RULES
1339    /*
1340     * rules permit?
1341     */
1342    switch (request->req.command) {
1343 #if SOCKS_SERVER
1344       case SOCKS_BIND: {
1345          sockshost_t boundhost;
1346 
1347          /*
1348           * For the bind-command, we need to bind the external
1349           * address before rulespermits(), as the external address
1350           * is the "dst" address that rulespermit() will check.
1351           */
1352          if (bindexternaladdr(&io, &request->req, buf, sizeof(buf)) == 0)
1353             SASSERTX(io.dst.s != -1);
1354          else {
1355             msglen = snprintf(emsg, emsglen,
1356                               "could not get address to use on external "
1357                               "side: %s",
1358                               buf);
1359 
1360             iolog(&io.crule,
1361                   &io.state,
1362                   OPERATION_ERROR,
1363                   src,
1364                   dst,
1365                   NULL,
1366                   NULL,
1367                   emsg,
1368                   msglen);
1369 
1370             send_failure(CONTROLIO(&io)->s, &response, SOCKS_NETUNREACH);
1371 
1372             close_iodescriptors(&io);
1373             return IO_ERROR;
1374          }
1375 
1376          sockaddr2sockshost(&io.dst.laddr, &boundhost);
1377          permit = rulespermit(request->s,
1378                               &request->from,
1379                               &request->to,
1380                               &io.cauth,
1381                               &io.src.auth,
1382                               &io.srule,
1383                               &io.state,
1384                               &io.src.host,
1385                               &boundhost,
1386                               NULL,
1387                               emsg,
1388                               emsglen);
1389 
1390          /*
1391           * XXX we should check whether it's possible receive any bindreply
1392           * also.  No need to stick around if no replies will be allowed.
1393           */
1394 
1395          break;
1396       }
1397 #endif /* SOCKS_SERVER */
1398 
1399       case SOCKS_CONNECT: {
1400          sockshost_t dsthostmatched;
1401 
1402          permit = rulespermit(request->s,
1403                               &request->from,
1404                               &request->to,
1405                               &io.cauth,
1406                               &io.src.auth,
1407                               &io.srule,
1408                               &io.state,
1409                               &io.src.host,
1410                               &io.dst.host,
1411                               &dsthostmatched,
1412                               emsg,
1413                               emsglen);
1414 
1415          if (permit) {
1416             if (!sockshostareeq(&io.dst.host, &dsthostmatched)) {
1417                /*
1418                 * this is the address we have to connect to.
1419                 */
1420                slog(LOG_DEBUG,
1421                     "%s: client requested target %s, we will use %s",
1422                     function,
1423                     sockshost2string(&io.dst.host, strhost, sizeof(strhost)),
1424                     sockshost2string(&dsthostmatched, NULL, 0));
1425 
1426                request->req.host = io.dst.host = dsthostmatched;
1427             }
1428          }
1429 
1430          break;
1431       }
1432 
1433 #if HAVE_UDP_SUPPORT
1434       case SOCKS_UDPASSOCIATE: {
1435          /*
1436           * UDP is slightly more complex since the client is allowed to send
1437           * an "incomplete" address when setting up the udp associate.
1438           * If it does that, we may not be able to give a conclusive verdict
1439           * here on whether any packets will be allowed from it or not.
1440           * If the verdict would be deny regardless of what address the
1441           * client would send the udp packet from we can however make a
1442           * conclusive verdict now.
1443           *
1444           * Destination address can vary for each packet so we use NULL for
1445           * that until we get an packet.
1446           *
1447           * Another complication is what to do about resource-limits and
1448           * which addresses to consider when doing the socks-level
1449           * rulespermit().  Since the udp destination address can vary
1450           * for each packet, it does not make sense to allocate/free
1451           * resources (sessionlimits, bandwidth limits, etc.) for each
1452           * packet, even though have to do a rulespermit() on each packet.
1453           * It seems better to consider the rule matched by rulespermit()
1454           * here, based on the client's TCP control address, to be "the"
1455           * rule.  That allows us to allocate resources here for udp
1456           * clients, the same way as we do it for tcp clients, rather than
1457           * have a lot of complicated stuff for handling it in the i/o
1458           * process.
1459           *
1460           * The procedure thus becomes that we use the clients TCP
1461           * address to evaluate what resources to allocate, and then
1462           * use the clients UDP address to evaluate whether each individual
1463           * packet should be passed through.  If the client sends us it's
1464           * UDP address in the udpassociate request, we can also evaluate
1465           * here whether it's at all possible that any udp packets from
1466           * it will be let through.  If not, we can just as well block it
1467           * now, rather than waste resources on a client that will never
1468           * be allowed to forward any packets.
1469           */
1470          sockshost_t *srchost;
1471 
1472          if (SOCKSHOSTISBOUND(&io.src.host)) {
1473             srchost = &io.src.host;
1474 
1475             slog(LOG_DEBUG,
1476                  "%s: got a complete UDP source address (%s) so can make a "
1477                  "conclusive verdict now",
1478                  function, sockshost2string(&io.src.host, NULL, 0));
1479          }
1480          else {
1481             slog(LOG_DEBUG,
1482                  "%s: got an incomplete UDP source address (%s) so may not "
1483                  "be able to make a conclusive verdict yet",
1484                  function, sockshost2string(&io.src.host, NULL, 0));
1485 
1486             srchost = NULL;
1487          }
1488 
1489          if (srchost != NULL) {
1490             /*
1491              * Don't know target address of course (can be vary), but
1492              * if no packets at all are permitted from the source address,
1493              * we can know for sure no packets will be permitted.
1494              */
1495             permit = rulespermit(request->s,
1496                                  &request->from,
1497                                  &request->to,
1498                                  &io.cauth,
1499                                  &io.control.auth, /* accept this for src too */
1500                                  &io.srule,
1501                                  &io.state,
1502                                  srchost,
1503                                  NULL,
1504                                  NULL,
1505                                  emsg,
1506                                  emsglen);
1507          }
1508 
1509          if (srchost == NULL
1510          || (srchost != NULL && permit)) {
1511             /*
1512              * Either don't know the source address, or the source address
1513              * is permitted, so go on and do the check against the
1514              * control-connection address to, to know what resources to
1515              * allocate.
1516              */
1517             permit = rulespermit(request->s,
1518                                  &request->from,
1519                                  &request->to,
1520                                  &io.cauth,
1521                                  &io.control.auth,
1522                                  &io.srule,
1523                                  &io.state,
1524                                  &io.control.host,
1525                                  NULL,
1526                                  NULL,
1527                                  emsg,
1528                                  emsglen);
1529          }
1530 
1531          break;
1532       }
1533 #endif /* HAVE_UDP_SUPPORT */
1534 
1535       default:
1536          SERRX(request->req.command);
1537    }
1538 
1539    /*
1540     * Update now that auth, if any, is set.
1541     */
1542    src->auth_isset = 1;
1543    src->auth       = io.src.auth;
1544 
1545    /*
1546     * Let the socks-rule inherit the appropriate settings from the
1547     * lower level rule, but don't bother if rule does not permit anyway.
1548     */
1549    if (permit) {
1550       /*
1551        * Have to handle the monitor-rules with care now.
1552        * If the target was not known at the client-rule level (as is the
1553        * case for Dante), it may mean the results of the monitormatch()
1554        * done in the negotiate process is not the same as it would be now,
1555        * now that the target is know (for the tcp case).
1556        *
1557        * We don't want to let a session use more than one monitor, so
1558        * what we do is this:
1559        * - If the session matches a different monitor at this (socks-rule)
1560        *   level, we use that monitor and disregard the monitor we matched
1561        *   at the client-rule level, if any.
1562        *   How do we handle the monitor we disregard, though?  The same
1563        *   way we do when we normally close a side on our own (rather than
1564        *   as a response to the client closing).  This decrements the
1565        *   session counter in the monitor and increments the disconnect
1566        *   counter for disconnects done by ourselves, which should set
1567        *   things correct.
1568        *
1569        * - If the session does not match a different monitor at this level,
1570        *   we continue to use the one matched at the client-level, if any.
1571        *
1572        * This matches our hardcoded behaviour where we consider
1573        * monitor-settings to always be inherited.
1574        */
1575 
1576       cinfo.from = request->from;
1577       HOSTIDCOPY(&request->state, &cinfo);
1578 
1579       rc = rule_inheritoruse(CRULE_OR_HRULE(&io),
1580                              &cinfo,
1581                              &io.srule,
1582                              &cinfo,
1583                              ALARM_INTERNAL,
1584                              emsg,
1585                              emsglen);
1586 
1587       /* wait until here so we have the correct shmem-settings. */
1588       request->srule         = io.srule;
1589       request->srule_isset = 1;
1590 
1591       if (rc != 0) {
1592          /*
1593           * Use from lower-level rule, as rule_inheritoruse() will
1594           * have cleared the monitor fields, after unusing if necessary.
1595           */
1596          if (CRULE_OR_HRULE(request)->mstats_shmid != 0
1597          && (CRULE_OR_HRULE(request)->alarmsconfigured & ALARM_DISCONNECT))
1598             alarm_add_disconnect(0,
1599                                  CRULE_OR_HRULE(request),
1600                                  ALARM_INTERNAL,
1601                                  &cinfo,
1602                                  strerror(errno),
1603                                  sockscf.shmemfd);
1604 
1605          permit = 0;
1606       }
1607    }
1608    else {
1609       request->srule       = io.srule;
1610       request->srule_isset = 1;
1611       SHMEM_MOVE(CRULE_OR_HRULE(request), &request->srule, SHMEM_ALL);
1612    }
1613 
1614    if (!permit) {
1615       iolog(IORULE(&io),
1616             &io.state,
1617             OPERATION_BLOCK,
1618             src,
1619             dst,
1620             NULL,
1621             NULL,
1622             emsg,
1623             strlen(emsg));
1624 
1625 #if HAVE_NEGOTIATE_PHASE
1626       send_failure(CONTROLIO(&io)->s, &response, SOCKS_NOTALLOWED);
1627 #endif /* HAVE_NEGOTIATE_PHASE  */
1628 
1629       snprintf(buf, sizeof(buf),
1630                "blocked by higher-level %s #%lu%s%s",
1631                objecttype2string(IORULE(&io)->type),
1632                (unsigned long)IORULE(&io)->number,
1633                *emsg == NUL ? "" : ": ",
1634                emsg);
1635 
1636       strncpy(emsg, buf, emsglen - 1);
1637       emsg[emsglen - 1] = NUL;
1638 
1639       close_iodescriptors(&io);
1640       return IO_BLOCK;
1641    }
1642 
1643    SASSERTX(permit);
1644 
1645 
1646 #else /* !HAVE_SOCKS_RULES */
1647 
1648    /*
1649     * copy over auth from lower level.
1650     */
1651    io.src.auth = io.control.auth = io.cauth;
1652 
1653    /*
1654     * no actually socks-rules, just copy over from crule to reduce
1655     * the amount of #ifdefs, as most is identical.
1656     *
1657     * Resourcelimits should always be set in the crule, so make sure
1658     * we clear that however.
1659     */
1660    io.srule       = io.crule;
1661    io.srule.type  = object_srule;
1662 
1663    SHMEM_CLEAR(&io.srule, SHMEM_ALL, 1);
1664 #endif /* !HAVE_SOCKS_RULES */
1665 
1666    if (io.state.protocol == SOCKS_TCP) { /* udp src.s not created yet. */
1667       if (io.dst.s == -1) {
1668          if (bindexternaladdr(&io, &request->req, buf, sizeof(buf)) == 0)
1669             SASSERTX(io.dst.s != -1);
1670          else {
1671             msglen = snprintf(emsg, emsglen,
1672                               "could not bind address to use on external "
1673                               "side: %s",
1674                               buf);
1675 
1676             iolog(&io.crule,
1677                   &io.state,
1678                   OPERATION_ERROR,
1679                   src,
1680                   dst,
1681                   NULL,
1682                   NULL,
1683                   emsg,
1684                   msglen);
1685 
1686             send_failure(CONTROLIO(&io)->s, &response, SOCKS_NETUNREACH);
1687 
1688             close_iodescriptors(&io);
1689             return IO_ERROR;
1690          }
1691 
1692          setconfsockoptions(io.src.s,
1693                             io.src.s,
1694                             io.state.protocol,
1695                             1,
1696                             io.srule.socketoptionc,
1697                             io.srule.socketoptionv,
1698                             SOCKETOPT_ANYTIME | SOCKETOPT_POST,
1699                             0 /* should be set already. */);
1700       }
1701 
1702       sockaddr2sockshost(&io.dst.laddr, &dst->local);
1703       dst->local_isset = 1;
1704    }
1705    else
1706       io.dst.s = -1; /* will be set up in the i/o process when/if needed. */
1707 
1708    /*
1709     * Redirect if necessary and set socket options for target side.
1710     */
1711    if (io.state.protocol == SOCKS_TCP) {
1712       SASSERTX(io.dst.s != -1);
1713 
1714       if (redirect(io.dst.s,
1715                    &io.dst.laddr,
1716 #if !BAREFOOTD
1717                    &io.dst.host,
1718 #endif /* !BAREFOOTD */
1719                    request->req.command,
1720                    &io.srule.rdr_from
1721 #if !BAREFOOTD
1722                  , &io.srule.rdr_to
1723 #endif /* !BAREFOOTD */
1724                    ) != 0) {
1725 
1726          if (io.srule.log.error) {
1727             msglen = snprintf(emsg, emsglen,
1728                               "redirect() failed: %s", strerror(errno));
1729             iolog(&io.srule,
1730                    &io.state,
1731                    OPERATION_ERROR,
1732                    src,
1733                    dst,
1734                    NULL,
1735                    NULL,
1736                    emsg,
1737                    msglen);
1738          }
1739 
1740          send_failure(CONTROLIO(&io)->s,
1741                       &response,
1742                       errno2reply(errno, response.version));
1743 
1744          close_iodescriptors(&io);
1745          return IO_ERROR;
1746       }
1747 
1748       setsockoptions(io.dst.s, io.dst.laddr.ss_family, SOCK_STREAM, 0);
1749 
1750       setconfsockoptions(io.dst.s,
1751                          CONTROLIO(&io)->s,
1752                          SOCKS_TCP,
1753                          0,
1754                          io.srule.socketoptionc,
1755                          io.srule.socketoptionv,
1756                          SOCKETOPT_PRE | SOCKETOPT_ANYTIME,
1757                          SOCKETOPT_PRE | SOCKETOPT_ANYTIME);
1758    }
1759 
1760    errno = 0;
1761    if (serverchain(io.dst.s,
1762                    CONTROLIO(&io)->s,
1763                    &io.src.raddr,
1764                    &request->req,
1765                    &io.state.proxychain,
1766                    io.state.protocol == SOCKS_TCP ? &io.dst.auth : NULL,
1767                    buf,
1768                    sizeof(buf)) == 0) {
1769       if (io.state.proxychain.proxyprotocol != PROXY_DIRECT) {
1770          socklen_t sinlen;
1771 
1772          /*
1773           * In case a redirect statement in the route changed laddr.
1774           */
1775          sinlen = sizeof(io.dst.laddr);
1776          if (getsockname(io.dst.s, TOSA(&io.dst.laddr), &sinlen) != 0) {
1777             slog(LOG_DEBUG,
1778                  "%s: strange ... serverchain() succeeded, but now "
1779                  "getsockname(2) failed: %s",
1780                  function, strerror(errno));
1781 
1782             if (io.srule.log.error) {
1783                msglen = snprintf(emsg, emsglen,
1784                                  "getsockname(io.dst.s) failed: %s",
1785                                  strerror(errno));
1786 
1787                iolog(&io.srule,
1788                      &io.state,
1789                      OPERATION_ERROR,
1790                      src,
1791                      dst,
1792                      NULL,
1793                      NULL,
1794                      emsg,
1795                      msglen);
1796             }
1797 
1798             *weclosedfirst = 0;
1799 
1800             close_iodescriptors(&io);
1801 
1802             return IO_ERROR;
1803          }
1804 
1805          io.src.state.isconnected = 1;
1806 
1807          sinlen = sizeof(io.dst.raddr);
1808          if (getpeername(io.dst.s, TOSA(&io.dst.raddr), &sinlen) != 0) {
1809             slog(LOG_DEBUG,
1810                  "%s: strange ... serverchain() succeeded, but now "
1811                  "getpeername(2) failed: %s",
1812                  function, strerror(errno));
1813 
1814             if (io.srule.log.error) {
1815                msglen = snprintf(emsg, emsglen,
1816                                  "getpeername(io.dst.s) failed: %s",
1817                                  strerror(errno));
1818 
1819                iolog(&io.srule,
1820                      &io.state,
1821                      OPERATION_ERROR,
1822                      src,
1823                      dst,
1824                      NULL,
1825                      NULL,
1826                      emsg,
1827                      msglen);
1828             }
1829 
1830             *weclosedfirst = 0;
1831 
1832             close_iodescriptors(&io);
1833 
1834             return IO_ERROR;
1835          }
1836 
1837          io.dst.state.isconnected = 1;
1838 
1839          setconfsockoptions(io.dst.s,
1840                             request->s,
1841                             io.state.protocol,
1842                             0,
1843                             io.srule.socketoptionc,
1844                             io.srule.socketoptionv,
1845                             SOCKETOPT_POST,
1846                             SOCKETOPT_POST);
1847 
1848          if (SHMEMRULE(&io)->mstats_shmid != 0
1849          && (SHMEMRULE(&io)->alarmsconfigured & ALARM_DISCONNECT))
1850             alarm_add_connect(SHMEMRULE(&io),
1851                               ALARM_EXTERNAL,
1852                               &cinfo,
1853                               sockscf.shmemfd);
1854 
1855          io.reqinfo.command = (io.state.protocol == SOCKS_TCP ?
1856                                  SOCKD_FREESLOT_TCP : SOCKD_FREESLOT_UDP);
1857 
1858          if (flushio(mother->s, &io) == 0)
1859             return IO_NOERROR;
1860          else
1861             return IO_ERROR;
1862       }
1863       /* else: go direct.  */
1864    }
1865    else { /* some error occurred. */
1866       msglen = snprintf(emsg, emsglen, "serverchain failed: %s", buf);
1867 
1868       iolog(IORULE(&io),
1869             &io.state,
1870             OPERATION_ERROR,
1871             src,
1872             dst,
1873             NULL,
1874             NULL,
1875             emsg,
1876             msglen);
1877 
1878       send_failure(request->s,
1879                    &response,
1880                    errno2reply(errno,
1881                    response.version));
1882 
1883       close_iodescriptors(&io);
1884       return IO_ERROR;
1885    }
1886 
1887    SASSERTX(io.state.proxychain.proxyprotocol == PROXY_DIRECT);
1888 
1889    /*
1890     * Set up missing bits of io, and then and send it to mother.
1891     */
1892 
1893    socks_set_responsevalue(&response,
1894                            sockscode(response.version, SOCKS_SUCCESS));
1895 
1896    rc       = 0;
1897    iostatus = IO_NOERROR;
1898 
1899    switch (io.state.command) {
1900 #if SOCKS_SERVER
1901       case SOCKS_BIND: {
1902          sockd_io_t *iolist;
1903          sockd_io_t bindio;         /* send this to iochild.  */
1904          socklen_t len;
1905          enum socketindex { client, childpipe, ourpipe, reply, remote };
1906 
1907          /* array of sockets, indexed by above enums.  -1 if not open. */
1908          int sv[(int)(remote) + 1] = { -1, -1, -1, -1, -1 }, emfile;
1909 
1910          /*
1911           * - io.dst gives the address bound on behalf of the client (io.src).
1912           * - expectedbindreply give the address to expect the bindreply from.
1913           * - bindreplydst give the address to send the bindreply to.
1914           */
1915 
1916          msglen = 0;
1917 
1918          if (io.state.extension.bind)
1919             dst->peer_isset = 0;
1920          else {
1921             dst->peer_isset = 1;
1922             dst->peer       = io.dst.host;
1923          }
1924 
1925          if (listen(io.dst.s, SOCKD_MAXCLIENTQUEUE) != 0) {
1926             msglen = snprintf(emsg, emsglen,
1927                               "listen(2) on bindreply socket failed: %s",
1928                               strerror(errno));
1929 
1930             swarnx("%s: %s", function, emsg);
1931 
1932             iostatus = IO_ERROR;
1933             rc       = -1;
1934          }
1935 
1936          if (rc == 0) {
1937             SASSERTX(sv[ELEMENTS(sv) - 1] == -1);
1938             if (io.state.extension.bind) {
1939                int pipev[2];
1940 
1941                /*
1942                 * The problem is that both we and the process which receives
1943                 * the io packet needs to know when the client closes it's
1944                 * connection, but _we_ need to receive a query from the
1945                 * client on the connection as well, and the io process would
1946                 * get confused about that.  We try to hack around that
1947                 * by making a "dummy" descriptor that the io process can
1948                 * check as all other control connections and which we
1949                 * can close when the client closes the real control connection,
1950                 * so the io process can detect it.
1951                 * Not very nice, no.
1952                 */
1953 
1954                if (socketpair(AF_LOCAL, SOCK_STREAM, 0, pipev) == 0) {
1955                   sv[childpipe] = pipev[0];
1956                   sv[ourpipe]   = pipev[1];
1957                }
1958                else {
1959                   msglen = snprintf(emsg, emsglen,
1960                                     "socketpair() failed: %s", strerror(errno));
1961 
1962                   swarnx("%s: %s", function, emsg);
1963 
1964                   iostatus = IO_ERROR;
1965                   rc       = -1;
1966                }
1967             }
1968          }
1969 
1970          if (rc == 0) {
1971             /*
1972              * let client know what address we bound to on it's behalf.
1973              */
1974 
1975             sockaddr2sockshost(&io.dst.laddr, &response.host);
1976             if (send_response(request->s, &response) != 0) {
1977                msglen = snprintf(emsg, emsglen,
1978                                  "sending response to client failed: %s",
1979                                  strerror(errno));
1980 
1981                iostatus = IO_IOERROR;
1982                rc       = -1;
1983             }
1984          }
1985 
1986          if (rc != 0) {
1987             iolog(&io.srule,
1988                   &io.state,
1989                   OPERATION_ERROR,
1990                   src,
1991                   dst,
1992                   NULL,
1993                   NULL,
1994                   emsg,
1995                   msglen);
1996 
1997             send_failure(request->s, &response, SOCKS_FAILURE);
1998             close_iodescriptors(&io);
1999             break;
2000          }
2001 
2002          iolog(&io.srule,
2003                &io.state,
2004                OPERATION_CONNECT,
2005                src,
2006                dst,
2007                NULL,
2008                NULL,
2009                NULL,
2010                0);
2011 
2012          emfile = 0;
2013          iolist = NULL;
2014 
2015          bindio               = io; /* quick init of most stuff. */
2016 
2017          bindio.state.command = SOCKS_BINDREPLY;
2018 
2019          bindio.dst.host = bindreplydst;
2020 
2021          if (bindio.state.extension.bind) {
2022             sockshost2sockaddr(&bindio.dst.host, &bindio.dst.raddr);
2023 
2024             /* won't create socket for this til we connect to the client. */
2025             bzero(&bindio.dst.laddr, sizeof(bindio.dst.laddr));
2026             SET_SOCKADDR(&bindio.dst.laddr, AF_INET);
2027             TOIN(&bindio.dst.laddr)->sin_addr.s_addr = htonl(INADDR_ANY);
2028             TOIN(&bindio.dst.laddr)->sin_port        = htons(0);
2029          }
2030          else {
2031             bindio.dst.laddr           = io.src.laddr;
2032             bindio.dst.raddr           = io.src.raddr;
2033          }
2034 
2035          bindio.dst.auth = io.src.auth;
2036 
2037          bindio.src.auth.method  = AUTHMETHOD_NOTSET;
2038          bindio.src.laddr        = io.dst.laddr;
2039          sockaddr2sockshost(&bindio.src.laddr, &bindio.src.host);
2040 
2041          /*
2042           * don't know what peer will be til we accept(2) it.
2043           */
2044          bzero(&bindio.src.raddr, sizeof(bindio.src.raddr));
2045          SET_SOCKADDR(&bindio.src.raddr, bindio.src.laddr.ss_family);
2046 
2047          bindio.cmd.bind.host = io.dst.host;
2048          bindio.cmd.bind.rule = io.srule;
2049 
2050          /*
2051           * if we are using the bind extension, keep accepting connections
2052           * until client closes the control-connection.  If not, break
2053           * after the first.
2054           */
2055 
2056          sv[client] = io.src.s;
2057 
2058          /*
2059           * XXX this is to complicated and needs to be cleaned up.
2060           */
2061          while (1) {
2062             static fd_set *rset;
2063             iologaddr_t replysrc, replydst;
2064             ruleaddr_t ruleaddr;
2065             struct sockaddr_storage remoteaddr; /* remote address accepted.   */
2066             struct sockaddr_storage replyaddr;  /* addr of bindreply socket.  */
2067             int replyredirect, fdbits;
2068 
2069             init_iologaddr(&replysrc,
2070                            object_sockaddr,
2071                            &bindio.src.laddr,
2072                            object_none, /* will know after accept(2). */
2073                            NULL,
2074                            NULL,
2075                            GET_HOSTIDV(&io.state),
2076                            GET_HOSTIDC(&io.state));
2077 
2078 
2079             if (bindio.state.extension.bind) {
2080                init_iologaddr(&replydst,
2081                               object_none, /* will know when connecting back. */
2082                               NULL,
2083                               object_sockshost,
2084                               &bindio.dst.host,
2085                               NULL,
2086                               NULL,
2087                               0);
2088             }
2089             else
2090                replydst = *src;
2091 
2092             if (rset == NULL)
2093                rset = allocate_maxsize_fdset();
2094 
2095             FD_ZERO(rset);
2096 
2097             /* some sockets change, most remain the same. */
2098             sv[reply]  = -1;
2099             sv[remote] = -1;
2100 
2101             /*
2102              * select(2) on ack-pipe to mother (eof only expected),
2103              * from client (eof only, unless bind extension),
2104              * and from socket we listen for a bindreply on.
2105              */
2106 
2107             fdbits = -1;
2108 
2109             FD_SET(mother->ack, rset);
2110             fdbits = MAX(fdbits, mother->ack);
2111 
2112             FD_SET(sv[client], rset);
2113             fdbits = MAX(fdbits, sv[client]);
2114 
2115             if (!emfile) {
2116                FD_SET(io.dst.s, rset);
2117                fdbits = MAX(fdbits, io.dst.s);
2118             }
2119 
2120             ++fdbits;
2121             if ((rc = selectn(fdbits, rset, NULL, NULL, NULL, NULL, NULL))
2122             <= 0) {
2123                SASSERT(ERRNOISTMP(errno));
2124                continue;
2125             }
2126 
2127             if (FD_ISSET(mother->ack, rset)) {
2128                slog(LOG_DEBUG,
2129                     "%s: socket to mother is readable.  Since we can only "
2130                     "handle one client at a time, this should only happen if "
2131                     "mother closes the connection.  ",
2132                     function);
2133 
2134                break; /* return to caller, and handle it there. */
2135             }
2136 
2137             if (FD_ISSET(sv[client], rset)) {
2138                /*
2139                 * nothing is normally expected on control connection so
2140                 * assume it's a bind extension query or eof.
2141                 */
2142                request_t query;
2143                response_t queryresponse;
2144                negotiate_state_t state;
2145                struct sockaddr_storage queryaddr;
2146                negotiate_result_t res;
2147 
2148                bzero(&state, sizeof(state));
2149                bzero(&query, sizeof(query));
2150                bzero(&queryresponse, sizeof(queryresponse));
2151 
2152                query.auth         = request->req.auth;
2153                queryresponse.auth = query.auth;
2154 
2155                switch (res = recv_sockspacket(sv[client], &query, &state)) {
2156                   case NEGOTIATE_CONTINUE:
2157                      slog(LOG_DEBUG,
2158                           "%s: did not receive full request, continuing",
2159                           function);
2160 
2161                      continue;
2162 
2163                   case NEGOTIATE_EOF:
2164                   case NEGOTIATE_ERROR: {
2165                      operation_t op;
2166 
2167                      if (res == NEGOTIATE_ERROR) {
2168                         msglen
2169                         = snprintf(emsg, emsglen,
2170                                    "receiving request from client failed (%s)",
2171                                    strerror(errno));
2172 
2173                         op = OPERATION_ERROR;
2174 
2175                         if (ERRNOISNETWORK(errno)) {
2176                            iostatus = IO_IOERROR;
2177                            *weclosedfirst = 0;
2178                         }
2179                         else
2180                            iostatus = IO_ERROR;
2181                      }
2182                      else {
2183                         msglen = snprintf(emsg, emsglen, "eof from client");
2184                         op             = OPERATION_DISCONNECT;
2185                         iostatus       = IO_CLOSE;
2186                         *weclosedfirst = 0;
2187                      }
2188 
2189                      iolog(&io.srule,
2190                            &io.state,
2191                            op,
2192                            src,
2193                            dst,
2194                            NULL,
2195                            NULL,
2196                            emsg,
2197                            msglen);
2198 
2199                      rc = -1; /* session ended, nothing to forward. */
2200                      break;
2201                   }
2202 
2203                   case NEGOTIATE_FINISHED: {
2204                      sockd_io_t *fio;
2205 
2206                      slog(LOG_DEBUG, "received bind resolve request: %s",
2207                           socks_packet2string(&query, 1));
2208 
2209                      switch (query.version) {
2210                         case PROXY_SOCKS_V4:
2211                            queryresponse.version = PROXY_SOCKS_V4REPLY_VERSION;
2212                            break;
2213 
2214                         case PROXY_SOCKS_V5:
2215                            queryresponse.version = query.version;
2216                            break;
2217 
2218                         default:
2219                            SERRX(query.version);
2220                      }
2221 
2222                      sockshost2sockaddr(&query.host, &queryaddr);
2223                      if ((fio = io_find(iolist, &queryaddr)) == NULL) {
2224                         queryresponse.host.atype            = SOCKS_ADDR_IPV4;
2225                         queryresponse.host.addr.ipv4.s_addr = htonl(0);
2226                         queryresponse.host.port             = htons(0);
2227                      }
2228                      else {
2229                         SASSERTX(fio->state.command == SOCKS_BINDREPLY);
2230                         SASSERTX(sockaddrareeq(&fio->dst.laddr, &queryaddr, 0));
2231 
2232                         sockaddr2sockshost(&fio->src.raddr,
2233                                            &queryresponse.host);
2234                      }
2235 
2236                      if ((rc = send_response(sv[client], &queryresponse)) == 0){
2237                         if (fio != NULL) {
2238                            fio->reqinfo.command = SOCKD_NOP;
2239                            if (flushio(mother->s, fio) != 0)
2240                               return IO_ERROR;
2241 
2242                            emfile = MAX(0, emfile - 3); /* flushio() closes 3 */
2243                            iolist = io_remove(iolist, fio);
2244                         }
2245                         /* else; nothing to flush yet. */
2246                      }
2247                      else {
2248                         msglen
2249                         = snprintf(emsg, emsglen,
2250                                    "sending bind-response to client failed: %s",
2251                                    strerror(errno));
2252 
2253                         iolog(&io.srule,
2254                               &io.state,
2255                               OPERATION_ERROR,
2256                               src,
2257                               dst,
2258                               NULL,
2259                               NULL,
2260                               emsg,
2261                               msglen);
2262 
2263                         *weclosedfirst = 0;
2264                         iostatus       = IO_IOERROR;
2265                         rc             = -1; /* session ended. */
2266                      }
2267 
2268                      break;
2269                   }
2270 
2271                   default:
2272                      SERRX(res);
2273                }
2274 
2275                if (rc == -1)
2276                   break;
2277             }
2278 
2279             if (!FD_ISSET(io.dst.s, rset))
2280                continue;
2281 
2282             len = sizeof(remoteaddr);
2283             if ((sv[remote] = acceptn(io.dst.s, &remoteaddr, &len))
2284             == -1) {
2285                msglen = snprintf(emsg, emsglen,
2286                                  "failed to accept(2) bindreply: %s",
2287                                  strerror(errno));
2288 
2289                   iolog(&io.srule,
2290                         &io.state,
2291                         OPERATION_ERROR,
2292                         &replysrc,
2293                         &replydst,
2294                         NULL,
2295                         NULL,
2296                         emsg,
2297                         msglen);
2298 
2299                switch (errno) {
2300 #ifdef EPROTO
2301                   case EPROTO:         /* overloaded SVR4 error */
2302 #endif /* EPROTO */
2303                   case EWOULDBLOCK:    /* BSD */
2304                   case ECONNABORTED:   /* POSIX */
2305 
2306                   /* rest appears to be Linux stuff according to Apache src. */
2307 #ifdef ECONNRESET
2308                   case ECONNRESET:
2309 #endif /* ECONNRESET */
2310 #ifdef ETIMEDOUT
2311                   case ETIMEDOUT:
2312 #endif /* ETIMEDOUT */
2313 #ifdef EHOSTUNREACH
2314                   case EHOSTUNREACH:
2315 #endif /* EHOSTUNREACH */
2316 #ifdef ENETUNREACH
2317                   case ENETUNREACH:
2318 #endif /* ENETUNREACH */
2319                      continue;
2320 
2321                   case EMFILE:
2322                   case ENFILE:
2323                      ++emfile;
2324                      continue;
2325                }
2326 
2327                iostatus = IO_IOERROR;
2328                break; /* errno is not ok, end. */
2329             }
2330 
2331             slog(LOG_DEBUG, "%s: got a bindreply from %s",
2332                  function, sockaddr2string(&remoteaddr, NULL, 0));
2333 
2334             sockaddr2sockshost(&remoteaddr, &bindio.src.host);
2335             bindio.src.raddr    = remoteaddr;
2336             replysrc.peer_isset = 1;
2337             replysrc.peer       = bindio.src.host;
2338 
2339             /*
2340              * Accepted a connection.  Does remote address match requested?
2341              */
2342 
2343             if (io.state.extension.bind
2344             || (  expectedbindreply.atype            == SOCKS_ADDR_IPV4
2345                && expectedbindreply.addr.ipv4.s_addr == htonl(0))
2346             || addrmatch(sockshost2ruleaddr(&expectedbindreply, &ruleaddr),
2347                          &bindio.src.host,
2348                          NULL,
2349                          SOCKS_TCP,
2350                          1)) {
2351                permit = rulespermit(sv[remote],
2352                                     &remoteaddr,
2353                                     &io.dst.laddr,
2354                                     NULL,
2355                                     &bindio.src.auth,
2356                                     &bindio.srule,
2357                                     &bindio.state,
2358                                     &bindio.src.host,
2359                                     &bindio.dst.host,
2360                                     NULL,
2361                                     emsg,
2362                                     emsglen);
2363                replysrc.auth_isset = 1;
2364                replysrc.auth       = bindio.src.auth;
2365             }
2366             else {
2367                bindio.srule.number  = 0;
2368                bindio.srule.verdict = VERDICT_BLOCK;
2369 
2370                snprintf(emsg, emsglen,
2371                        "expected bindreply from %s, but got it from %s",
2372                         sockshost2string(&expectedbindreply,
2373                                          strhost,
2374                                          sizeof(strhost)),
2375                         sockshost2string(&bindio.src.host, NULL, 0));
2376 
2377                permit = 0;
2378             }
2379 
2380             if (permit) {
2381                /*
2382                 * Now we need to decide whether we should inherit from
2383                 * bindreply-rule to bind-request rule.
2384                 *
2385                 * If we are using the bind-extension, we will keep waiting
2386                 * for new bindreplies, so we can not free the resources
2387                 * allocated for the bindrequest, meaning the bindreply
2388                 * rule has to allocate new resources for itself.
2389                 *
2390                 * If we are not using the bind extension, we will not
2391                 * wait for any more replies and the bindreply-rule's
2392                 * resource limits should replace the bindrequest-rule's
2393                 * limits, or inherit from the bindrequest-rule.
2394                 */
2395                const int doinherit = (bindio.state.extension.bind == 0);
2396 
2397                slog(LOG_DEBUG,
2398                     "%s: bindreply-limits in %s #%lu should %s "
2399                     "bindrequest-limits in %s #%lu",
2400                     function,
2401                     objecttype2string(bindio.srule.type),
2402                     (unsigned long)bindio.srule.number,
2403                     doinherit ? "consider inheriting" : "be aggregated with",
2404                     objecttype2string(io.srule.type),
2405                     (unsigned long)io.srule.number);
2406 
2407                if (doinherit) {
2408                   rc = rule_inheritoruse(&io.srule,
2409                                          &cinfo,
2410                                          &bindio.srule,
2411                                          &cinfo, /* always socks client */
2412                                          ALARM_INTERNAL,
2413                                          emsg,
2414                                          emsglen);
2415 
2416                   if (rc != 0) {
2417                      permit               = 0;
2418                      bindio.srule.verdict = VERDICT_BLOCK;
2419                   }
2420                }
2421                else {
2422                   if (shmem_userule(&bindio.srule, &cinfo, emsg, emsglen) != 0){
2423                      permit               = 0;
2424                      bindio.srule.verdict = VERDICT_BLOCK;
2425                   }
2426                }
2427 
2428                if (!permit) {
2429                   SHMEM_CLEAR(&bindio.srule, SHMEM_ALL, 1); /* did not use. */
2430 
2431                   if (!bindio.state.extension.bind) {
2432                      /*
2433                       * Will not wait for more connections.  Update the
2434                       * disconnect counter.
2435                       * Use settings in io.srule, as rule_inheritoruse() will
2436                       * have cleared the monitor fields, after unusing if
2437                       * necessary, while io.srule will still be containing
2438                       * the correct once, after the rulespermit() on the
2439                       * bind /request/.
2440                       */
2441                      if (io.srule.mstats_shmid != 0
2442                      && (io.srule.alarmsconfigured & ALARM_DISCONNECT))
2443                         alarm_add_disconnect(0,
2444                                              &io.srule,
2445                                              ALARM_INTERNAL,
2446                                              &cinfo,
2447                                              strerror(errno),
2448                                              sockscf.shmemfd);
2449                   }
2450 
2451                   /* wait until here so we get the correct shmem-settings. */
2452                   request->srule = bindio.srule;
2453                   SASSERTX(request->srule_isset);
2454                }
2455             }
2456 
2457             if (!permit) {
2458                iolog(&bindio.srule,
2459                      &bindio.state,
2460                      OPERATION_BLOCK,
2461                      &replysrc,
2462                      &replydst,
2463                      NULL,
2464                      NULL,
2465                      emsg,
2466                      strlen(emsg));
2467 
2468                if (!bindio.state.extension.bind) {
2469                   /*
2470                    * can only accept one client, and that one failed,
2471                    * so assume it's better to end it rather than possibly
2472                    * wait forever for another client.
2473                    */
2474                   size_t len = snprintf(emsg, emsglen,
2475                                         "bind-reply from %s blocked by "
2476                                         "%s #%lu",
2477                                         sockaddr2string(&bindio.src.raddr,
2478                                                         NULL,
2479                                                         0),
2480                                         objecttype2string(bindio.srule.type),
2481                                         (unsigned long)bindio.srule.number);
2482 
2483                   response.host = bindio.src.host;
2484                   send_failure(sv[client], &response, SOCKS_NOTALLOWED);
2485 
2486                   /*
2487                    * log the close of the opened bind session also.
2488                    */
2489                   errno = 0; /* in case send_failure() sets it. */
2490                   iolog(&io.srule,
2491                         &io.state,
2492                         OPERATION_BLOCK,
2493                         src,
2494                         dst,
2495                         NULL,
2496                         NULL,
2497                         emsg,
2498                         len);
2499 
2500                   iostatus = IO_BLOCK;
2501                   break;
2502                }
2503                else {
2504                   close(sv[remote]);
2505                   continue; /* wait for next client, but will there be one? */
2506                }
2507             }
2508 
2509             errno = 0;
2510             if (redirect(sv[reply],
2511                          &remoteaddr,
2512                          bindio.state.extension.bind ? &bindreplydst : NULL,
2513                          SOCKS_BINDREPLY,
2514                          &bindio.srule.rdr_from,
2515                          &bindio.srule.rdr_to) != 0) {
2516 
2517                   msglen = snprintf(emsg, emsglen,
2518                                     "redirect() failed: %s", strerror(errno));
2519 
2520                   iolog(&bindio.srule,
2521                         &bindio.state,
2522                         OPERATION_ERROR,
2523                         &replysrc,
2524                         &replydst,
2525                         NULL,
2526                         NULL,
2527                         emsg,
2528                         msglen);
2529 
2530                close(sv[remote]);
2531                close(sv[reply]);
2532 
2533                SHMEM_UNUSE(&bindio.srule,
2534                            &cinfo,
2535                            sockscf.shmemfd,
2536                            SHMEM_ALL);
2537                continue;
2538             }
2539             else {
2540                bindio.dst.host = bindreplydst;
2541                sockshost2sockaddr(&bindio.dst.host, &bindio.dst.raddr);
2542             }
2543 
2544 
2545             /*
2546              * Someone connected to socket we listen to on behalf of client.
2547              * If the destination to forward the reply is not the same
2548              * as the control address (bind extension), we need to connect
2549              * to it.  Otherwise we will pass the data over the same
2550              * connection as the client connection (which is the implicit
2551              * control * connection in this case).
2552              */
2553 
2554             if (bindio.state.extension.bind)
2555                replyredirect = 1;
2556             else {
2557                if (!sockshostareeq(&bindreplydst, &io.src.host)) {
2558                   slog(LOG_DEBUG,
2559                        "%s: need to forward reply to %s, "
2560                        "due to redirect-module?",
2561                        function, sockshost2string(&bindreplydst, NULL, 0));
2562 
2563                   replyredirect = 1; /* must be using redirect() module. */
2564                }
2565                else
2566                   replyredirect = 0;
2567             }
2568 
2569             if (bindio.state.extension.bind || replyredirect) {
2570                /*
2571                 * need to create a new socket to use for connecting
2572                 * to the destination address; not sending the data over
2573                 * the control-socket.
2574                 */
2575                if ((sv[reply] = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
2576                   if (io.srule.log.error)
2577                      swarn("%s: socket(SOCK_STREAM)", function);
2578 
2579                   switch (errno) {
2580                      case EMFILE:
2581                      case ENFILE:
2582                         ++emfile;
2583                         /* FALLTHROUGH */
2584 
2585                      case ENOBUFS:
2586                         close(sv[remote]);
2587                         SHMEM_UNUSE(&bindio.srule,
2588                                     &cinfo,
2589                                     sockscf.shmemfd,
2590                                     SHMEM_ALL);
2591                         continue;
2592                   }
2593 
2594                   iostatus = IO_IOERROR;
2595                   break; /* errno is not ok. */
2596                }
2597 
2598                setsockoptions(sv[reply], AF_INET, SOCK_STREAM, 1);
2599                setconfsockoptions(sv[client],
2600                                   sv[reply],
2601                                   bindio.state.protocol,
2602                                   1,
2603                                   bindio.srule.socketoptionc,
2604                                   bindio.srule.socketoptionv,
2605                                   SOCKETOPT_PRE | SOCKETOPT_ANYTIME,
2606                                   SOCKETOPT_PRE | SOCKETOPT_ANYTIME);
2607 
2608                replyaddr = io.src.laddr; /* just to init. */
2609                SET_SOCKADDRPORT(&replyaddr, htons(0));
2610 
2611                if (socks_bind(sv[reply], &replyaddr, 0) != 0) {
2612                   log_bind_failed(function, SOCKS_TCP, &replyaddr);
2613 
2614                   iostatus = IO_IOERROR;
2615                   break;
2616                }
2617 
2618                bindio.dst.laddr = replyaddr;
2619                replydst.peer_isset = 1;
2620                sockaddr2sockshost(&bindio.dst.laddr, &replydst.peer);
2621 
2622                slog(LOG_DEBUG,
2623                     "%s: connecting to %s to forward bindreply from %s",
2624                     function,
2625                     sockshost2string(&bindreplydst, strhost, sizeof(strhost)),
2626                     sockshost2string(&bindio.src.host, NULL, 0));
2627 
2628                if (socks_connecthost(sv[reply],
2629                                      INTERNALIF,
2630                                      &bindreplydst,
2631                                      NULL,
2632                                      NULL,
2633                                      bindio.srule.timeout.connect ?
2634                                   (long)bindio.srule.timeout.connect : (long)-1,
2635                                      emsg,
2636                                      emsglen) != 0) {
2637                   iolog(&bindio.srule,
2638                         &bindio.state,
2639                         OPERATION_ERROR,
2640                         &replysrc,
2641                         &replydst,
2642                         NULL,
2643                         NULL,
2644                         emsg,
2645                         strlen(emsg));
2646 
2647                   /* log the close of the opened bind session also. */
2648                   iolog(&io.srule,
2649                         &io.state,
2650                         OPERATION_ERROR,
2651                         src,
2652                         dst,
2653                         NULL,
2654                         NULL,
2655                         emsg,
2656                         strlen(emsg));
2657 
2658                   iostatus = IO_IOERROR;
2659                   break;
2660                }
2661 
2662                setconfsockoptions(sv[client],
2663                                   sv[reply],
2664                                   bindio.state.protocol,
2665                                   1,
2666                                   bindio.srule.socketoptionc,
2667                                   bindio.srule.socketoptionv,
2668                                   SOCKETOPT_POST,
2669                                   SOCKETOPT_POST);
2670 
2671                if (replyredirect) {
2672                   close(sv[client]);
2673                   sv[client] = sv[reply];
2674                   sv[reply]  = -1;
2675                }
2676             }
2677 
2678             if (bindio.state.extension.bind) {
2679                /*
2680                 * flushio() will close all descriptors set in io packet,
2681                 * so dup what we need to keep going.
2682                 */
2683 
2684                if ((bindio.control.s = dup(sv[childpipe])) == -1) {
2685                   switch (errno) {
2686                      case EMFILE:
2687                      case ENFILE:
2688                         if (bindio.srule.log.error)
2689                            swarn("%s: dup()", function);
2690 
2691                         ++emfile;
2692                         close(sv[remote]);
2693                         continue;
2694 
2695                      default:
2696                         SERR(bindio.control.s);
2697                   }
2698                }
2699             }
2700 
2701             if (bindio.state.extension.bind || replyredirect) {
2702                if (bindio.state.extension.bind)
2703                   bindio.dst.s = sv[reply];
2704                else /* replyredirect */
2705                   bindio.dst.s = sv[client];
2706             }
2707             else
2708                bindio.dst = io.src;
2709 
2710             bindio.src.s = sv[remote];
2711 
2712             bindio.src.state.isconnected = 1;
2713             bindio.dst.state.isconnected = 1;
2714 
2715             if (bindio.srule.mstats_shmid != 0
2716             && (bindio.srule.alarmsconfigured & ALARM_DISCONNECT))
2717                alarm_add_connect(&bindio.srule,
2718                                  ALARM_EXTERNAL,
2719                                  &cinfo,
2720                                  sockscf.shmemfd);
2721 
2722             if (bindio.state.extension.bind)
2723                /* add to list, client will query. */
2724                iolist = io_add(iolist, &bindio);
2725             else {
2726                response.host = bindio.src.host;
2727 
2728                if (send_response(sv[client], &response) != 0) {
2729                   close_iodescriptors(&io);
2730                   iostatus = IO_IOERROR;
2731                }
2732                else {
2733                   bindio.reqinfo.command
2734                   = (bindio.state.protocol == SOCKS_TCP ?
2735                                        SOCKD_FREESLOT_TCP : SOCKD_FREESLOT_UDP);
2736 
2737                   if (flushio(mother->s, &bindio) != 0)
2738                      return IO_ERROR;
2739                }
2740 
2741                /* flushio() closes these, not closev(). */
2742                sv[client] = sv[remote] = -1;
2743             }
2744 
2745             if (!bindio.state.extension.bind)
2746                break; /* only one connection to relay; flushed on to mother. */
2747          }
2748 
2749          if (bindio.state.extension.bind) {
2750             sockd_io_t *rmio;
2751 
2752             /* delete any connections we have queued. */
2753             while ((rmio = io_find(iolist, NULL)) != NULL) {
2754                close_iodescriptors(rmio);
2755                iolist = io_remove(iolist, rmio);
2756             }
2757          }
2758 
2759          /* not accepting any more connections on this socket. */
2760          close(io.dst.s);
2761 
2762          closev(ELEMENTS(sv), sv);
2763          break;
2764       }
2765 #endif /* SOCKS_SERVER */
2766 
2767       case SOCKS_CONNECT: {
2768          rc = socks_connecthost(io.dst.s,
2769                                 EXTERNALIF,
2770                                 &io.dst.host,
2771                                 &io.dst.laddr,
2772                                 &io.dst.raddr,
2773                                 (long)0, /* wait for completion in i/o child. */
2774                                 emsg,
2775                                 emsglen);
2776 
2777          if (rc == 0) {
2778             io.dst.state.isconnected = 1;
2779 
2780 #if HAVE_NEGOTIATE_PHASE
2781             if (SOCKS_SERVER || io.reqflags.httpconnect) {
2782                errno = 0;
2783                if (send_connectresponse(request->s, errno, &io) != 0) {
2784                   *weclosedfirst = 0;
2785                   iostatus       = IO_IOERROR;
2786 
2787                   snprintf(emsg, emsglen,
2788                            "could not send connect response to client: %s",
2789                            strerror(errno));
2790 
2791                   close_iodescriptors(&io);
2792                   break;
2793                }
2794             }
2795 #endif /* HAVE_NEGOTIATE_PHASE */
2796          }
2797          else {
2798             if (errno == EINPROGRESS)
2799                /*
2800                 * we don't wait for the result but instead push the io object
2801                 * on to i/o process.  This allows the connect(2)-time to
2802                 * overlap with the sending of the io-object to the io-process.
2803                 */
2804                rc = 0;
2805             else {
2806                rc       = -1;
2807                iostatus = IO_IOERROR;
2808 
2809 #if HAVE_NEGOTIATE_PHASE
2810 
2811                SASSERTX(errno != 0);
2812                if (send_connectresponse(request->s, errno, &io) != 0)
2813                   slog(LOG_DEBUG,
2814                        "%s: could not send connect response to client: %s",
2815                        function, strerror(errno));
2816 
2817 #else /* !HAVE_NEGOTIATE_PHASE */
2818 
2819                if (ERRNOISRST(errno))
2820                   sockd_rstonclose(io.dst.s); /* no other way to tell client. */
2821 
2822 #endif /* !HAVE_NEGOTIATE_PHASE */
2823             }
2824          }
2825 
2826          if (rc != 0) {
2827             iolog(&io.srule,
2828                   &io.state,
2829                   OPERATION_ERROR,
2830                   src,
2831                   dst,
2832                   NULL,
2833                   NULL,
2834                   emsg,
2835                   strlen(emsg));
2836 
2837             close_iodescriptors(&io);
2838          }
2839          else {
2840             if (SHMEMRULE(&io)->mstats_shmid != 0
2841             && (SHMEMRULE(&io)->alarmsconfigured & ALARM_DISCONNECT))
2842                /*
2843                 * Connect(2) in progress or already completed, so add it now.
2844                 */
2845                alarm_add_connect(SHMEMRULE(&io),
2846                                  ALARM_EXTERNAL,
2847                                  &cinfo,
2848                                  sockscf.shmemfd);
2849 
2850             io.src.state.isconnected = 1;
2851 
2852             SASSERTX(io.state.proxychain.proxyprotocol == PROXY_DIRECT);
2853             io.reqinfo.command = (io.state.protocol == SOCKS_TCP ?
2854                                        SOCKD_FREESLOT_TCP : SOCKD_FREESLOT_UDP);
2855 
2856             if (flushio(mother->s, &io) != 0)
2857                return IO_ERROR;
2858          }
2859 
2860          break;
2861       }
2862 
2863 #if HAVE_UDP_SUPPORT
2864       case SOCKS_UDPASSOCIATE: {
2865          /*
2866           * create socket we will receive datagrams from client on.
2867           * Let the created socket be of the same address family as
2868           * the client tells us it will send packets from.  Note that
2869           * even if the client sends us an all-zero address now, even
2870           * the all-zero address will have to have it's family
2871           * specified, as either ipv4 or ipv6.
2872           *
2873           * Exception is if the client does something so strange as to
2874           * send us a hostname.  In that case base ourselves on the type
2875           * of the (possibly first of several) addresses the hostname
2876           * resolved to.
2877           */
2878          socklen_t boundlen;
2879          int gaierr;
2880 #if SOCKS_SERVER
2881          int triesleft;
2882 #endif /* SOCKS_SERVER */
2883 
2884          sockshost2sockaddr2(&io.src.host,
2885                              &io.src.raddr,
2886                              &gaierr,
2887                              buf,
2888                              sizeof(buf));
2889 
2890          if (gaierr != 0) {
2891             SASSERTX(io.src.host.atype == SOCKS_ADDR_DOMAIN);
2892 
2893             log_resolvefailed(io.src.host.addr.domain, INTERNALIF, gaierr);
2894 
2895             msglen = snprintf(emsg, emsglen,
2896                               "client says it will send us UDP packets from "
2897                               "hostname \"%s\", but we are unable to resolve "
2898                               "that hostname",
2899                               sockshost2string(&io.src.host, NULL, 0));
2900 
2901             rc = SOCKS_HOSTUNREACH;
2902          }
2903          else
2904             rc = SOCKS_SUCCESS;
2905 
2906          if (rc == SOCKS_SUCCESS) {
2907             /*
2908              * Ok so far.  Now figure out what address to bind on the
2909              * internal side (io.src.laddr).
2910              */
2911 
2912             if (request->to.ss_family == io.src.raddr.ss_family)
2913                /*
2914                 * Client connected to us on the same type of address it wants
2915                 * to send us packets from, so should be ok to use the same
2916                 * ipaddress for receiving udp packets as it tcp-connected to us
2917                 * on.  The portnumber we will set later.
2918                 */
2919                io.src.laddr = request->to;
2920             else {
2921                 if (getinaddr(&io.src.laddr, &io.src.raddr, emsg, emsglen)
2922                 == NULL) {
2923                   slog(LOG_DEBUG,
2924                        "%s: could not find %s on internal side to bind "
2925                        "for accepting UDP packets from client %s: %s",
2926                        function,
2927                        safamily2string(io.src.raddr.ss_family),
2928                        sockaddr2string2(&io.src.raddr, 0, NULL, 0),
2929                        emsg);
2930 
2931                      rc = SOCKS_ADDR_UNSUPP;
2932                }
2933             }
2934          }
2935 
2936          if (rc == SOCKS_SUCCESS) {
2937             SASSERTX(io.src.laddr.ss_family == AF_INET
2938             ||       io.src.laddr.ss_family == AF_INET6);
2939 
2940             /*
2941              * create socket of the same type as client will send us data
2942              * from.
2943              */
2944             if ((io.src.s = socket(io.src.laddr.ss_family, SOCK_DGRAM, 0))
2945             == -1) {
2946                msglen = snprintf(emsg, emsglen,
2947                                  "could not create socket(): %s",
2948                                  strerror(errno));
2949 
2950                swarnx("%s: %s", function, emsg);
2951 
2952                rc = SOCKS_FAILURE;
2953             }
2954          }
2955 
2956          if (rc != SOCKS_SUCCESS) {
2957             iolog(IORULE(&io),
2958                   &io.state,
2959                   OPERATION_ERROR,
2960                   src,
2961                   dst,
2962                   NULL,
2963                   NULL,
2964                   emsg,
2965                   msglen);
2966 
2967             send_failure(request->s, &response, rc);
2968 
2969             close_iodescriptors(&io);
2970 
2971             iostatus = IO_IOERROR;
2972             break;
2973          }
2974 
2975          SASSERTX(IPADDRISBOUND(&io.src.laddr));
2976          SASSERTX(safamily_issupported(io.src.laddr.ss_family));
2977 
2978          setsockoptions(io.src.s, io.src.laddr.ss_family, SOCK_DGRAM, 1);
2979 
2980          setconfsockoptions(io.src.s,
2981                             io.control.s,
2982                             io.state.protocol,
2983                             1,
2984                             io.srule.socketoptionc,
2985                             io.srule.socketoptionv,
2986                             SOCKETOPT_PRE | SOCKETOPT_ANYTIME,
2987                             SOCKETOPT_PRE | SOCKETOPT_ANYTIME);
2988 
2989 #if BAREFOOTD
2990          if ((rc = socks_bind(io.src.s, &io.src.laddr, 1)) == 0)
2991             rc = SOCKS_SUCCESS;
2992          else
2993             rc = SOCKS_FAILURE;
2994 
2995 #else /* SOCKS_SERVER */
2996          /*
2997           * bind client-side address for receiving UDP packets, so we can tell
2998           * the client where to send it's packets.
2999           * XXX should perhaps have a global udprange option also, for clients
3000           *     that don't know what address they will be sending from.  This
3001           *     rule is possibly not the one the client will finaly end up
3002           *     using, in which the udprange specification would not apply,
3003           *     but how can we know if the client doesn't tell us it's source
3004           *     address.
3005           * XXX add check for privileges on startup if range is privileged
3006           */
3007          if (io.srule.udprange.op == range)
3008             triesleft = MIN(10,
3009             ntohs(io.srule.udprange.end) - ntohs(io.srule.udprange.start) + 1);
3010          else
3011             triesleft = 1;
3012 
3013          do {
3014             if (io.srule.udprange.op == range) {
3015                SET_SOCKADDRPORT(&io.src.laddr,
3016                                 htons(ntohs(io.srule.udprange.start)
3017                                 + (random()
3018                                    % (ntohs(io.srule.udprange.end)
3019                                       - ntohs(io.srule.udprange.start) + 1))));
3020 
3021                slog(LOG_DEBUG,
3022                     "%s: random port selected for udp in range %u - %u: %u.  "
3023                     "Trying that first",
3024                     function,
3025                     ntohs(io.srule.udprange.start),
3026                     ntohs(io.srule.udprange.end),
3027                     ntohs(GET_SOCKADDRPORT(&io.src.laddr)));
3028             }
3029             else
3030                SET_SOCKADDRPORT(&io.src.laddr, htons(0));
3031 
3032             rc = socks_bind(io.src.s, &io.src.laddr, 0);
3033          } while (rc == -1 && (errno == EADDRINUSE || ERRNOISACCES(errno))
3034          && io.srule.udprange.op == range && --triesleft > 0);
3035 
3036          if (rc == 0)
3037             rc = SOCKS_SUCCESS;
3038         else
3039             rc = SOCKS_FAILURE;
3040 #endif /* SOCKS_SERVER */
3041 
3042          if (rc != SOCKS_SUCCESS) {
3043             if (io.srule.udprange.op != none) {
3044                /*
3045                 * Sigh.  No luck.  Will need to try every port in range.
3046                 */
3047 
3048                slog(LOG_DEBUG,
3049                      "%s: failed to bind udp port in range %u - %u by "
3050                      "random selection.  Doing a sequential search now ...",
3051                      function,
3052                      ntohs(io.srule.udprange.start),
3053                      ntohs(io.srule.udprange.end));
3054 
3055                rc = socks_bindinrange(io.src.s,
3056                                       &io.src.laddr,
3057                                       io.srule.udprange.start,
3058                                       io.srule.udprange.end,
3059                                       io.srule.udprange.op);
3060                if (rc != 0) {
3061                   rc = SOCKS_FAILURE;
3062                   snprintf(emsg, emsglen, "no free ports in range to bind");
3063                }
3064             }
3065             else
3066                snprintf(emsg, emsglen, "could not bind local address %s: %s",
3067                        sockaddr2string(&io.src.laddr, strhost, sizeof(strhost)),
3068                         strerror(errno));
3069          }
3070 
3071          if (rc != SOCKS_SUCCESS) {
3072             iolog(IORULE(&io),
3073                   &io.state,
3074                   OPERATION_ERROR,
3075                   src,
3076                   dst,
3077                   NULL,
3078                   NULL,
3079                   emsg,
3080                   strlen(emsg));
3081 
3082             send_failure(request->s, &response, rc);
3083             close_iodescriptors(&io);
3084 
3085             iostatus = IO_IOERROR;
3086 
3087             break;
3088          }
3089 
3090          if (ADDRISBOUND(&io.src.raddr)) {
3091             /*
3092              * more efficient to be connected to the client.
3093              */
3094 
3095             slog(LOG_DEBUG, "%s: connecting to udp client at address %s",
3096                  function, sockaddr2string(&io.src.raddr, NULL, 0));
3097 
3098             if (socks_connecthost(io.src.s,
3099                                   INTERNALIF,
3100                                   sockaddr2sockshost(&io.src.raddr, NULL),
3101                                   NULL,
3102                                   NULL,
3103                                   (long)-1,
3104                                   emsg,
3105                                   emsglen) != 0) {
3106                iolog(IORULE(&io),
3107                      &io.state,
3108                      OPERATION_ERROR,
3109                      src,
3110                      dst,
3111                      NULL,
3112                      NULL,
3113                      emsg,
3114                      strlen(emsg));
3115 
3116                send_failure(request->s, &response, SOCKS_HOSTUNREACH);
3117 
3118                close_iodescriptors(&io);
3119 
3120                iostatus = IO_IOERROR;
3121                break;
3122             }
3123 
3124             io.src.state.isconnected = 1;
3125          }
3126 
3127          io.dst.state.isconnected = 0;
3128 
3129          boundlen = sizeof(io.src.laddr);
3130          if (getsockname(io.src.s, TOSA(&io.src.laddr), &boundlen) != 0) {
3131             msglen = snprintf(emsg, emsglen,
3132                               "getsockname() failed: %s", strerror(errno));
3133 
3134             iolog(IORULE(&io),
3135                   &io.state,
3136                   OPERATION_ERROR,
3137                   src,
3138                   dst,
3139                   NULL,
3140                   NULL,
3141                   emsg,
3142                   msglen);
3143 
3144             send_failure(request->s, &response, SOCKS_FAILURE);
3145             close_iodescriptors(&io);
3146 
3147             iostatus = IO_IOERROR;
3148             break;
3149          }
3150 
3151          slog(LOG_DEBUG, "%s: address bound on client side for udp: %s",
3152               function, sockaddr2string(&io.src.laddr, NULL, 0));
3153 
3154          /* external side will be bound in i/o process. */
3155 
3156          if (request->req.flag & SOCKS_USECLIENTPORT
3157          &&  sockscf.compat.draft_5_05)
3158             if (GET_SOCKADDRPORT(&io.src.raddr)
3159             ==  GET_SOCKADDRPORT(&io.dst.laddr))
3160                response.flag |= SOCKS_USECLIENTPORT;
3161 
3162          sockaddr2sockshost(&io.src.laddr, &response.host);
3163 
3164          if (send_response(request->s, &response) == 0) {
3165             io.reqinfo.command = (io.state.protocol == SOCKS_TCP ?
3166                                        SOCKD_FREESLOT_TCP : SOCKD_FREESLOT_UDP);
3167             if (flushio(mother->s, &io) != 0)
3168                return IO_ERROR;
3169          }
3170          else {
3171             close_iodescriptors(&io);
3172             *weclosedfirst = 0;
3173             iostatus       = IO_IOERROR;
3174          }
3175 
3176          break;
3177       }
3178 #endif /* HAVE_UDP_SUPPORT */
3179 
3180       default:
3181          SERRX(io.state.command);
3182    }
3183 
3184    rc = errno;
3185    SASSERTX(close(request->s) == -1);
3186    errno = rc;
3187 
3188    return iostatus;
3189 }
3190 
3191 static int
reqhostisok(host,cmd,emsg,emsglen)3192 reqhostisok(host, cmd, emsg, emsglen)
3193    sockshost_t *host;
3194    const int cmd;
3195    char *emsg;
3196    const size_t emsglen;
3197 {
3198    const char *function = "reqhostisok()";
3199    struct sockaddr_storage addr;
3200    int gaierr, musthaveaddr, musthaveport;
3201 
3202    slog(LOG_DEBUG, "%s: host %s, command %s",
3203         function, sockshost2string(host, NULL, 0), command2string(cmd));
3204 
3205    if (host->atype == SOCKS_ADDR_IPV6
3206    && IN6_IS_ADDR_V4MAPPED(&host->addr.ipv6.ip)) {
3207       /*
3208        * We never use that.  Either we have IPv4 available on the interface,
3209        * in which case we create a regular IPv4 socket to use, or we do not,
3210        * in which case the request will not be performed.
3211        *
3212        * We do not mix IPv4 and IPv6 traffic on the same socket, even though
3213        * that is supported by some systems.  Instead we convert the address
3214        * to an IPv4 address and proceed as usual.
3215        */
3216       sockshost_t convertedhost;
3217 
3218       convertedhost = *host;
3219       ipv4_mapped_to_regular(&host->addr.ipv6.ip, &convertedhost.addr.ipv4);
3220 
3221       host->atype     = SOCKS_ADDR_IPV4;
3222       host->addr.ipv4 = convertedhost.addr.ipv4;
3223    }
3224 
3225    sockshost2sockaddr2(host, &addr, &gaierr, emsg, emsglen);
3226 
3227    if (host->atype == SOCKS_ADDR_DOMAIN) {
3228       if (addr.ss_family == AF_UNSPEC) {
3229          if (gaierr != 0)
3230             log_resolvefailed(host->addr.domain,
3231                               cmd == SOCKS_UDPASSOCIATE ?
3232                                                         INTERNALIF : EXTERNALIF,
3233                               gaierr);
3234 
3235          return SOCKS_HOSTUNREACH;
3236       }
3237 
3238       SASSERTX(gaierr == 0);
3239 
3240       slog(LOG_DEBUG, "%s: hostname %s in %s-request resolved to address %s",
3241            function,
3242            sockshost2string(host, NULL, 0),
3243            command2string(cmd),
3244            sockaddr2string(&addr, NULL, 0));
3245    }
3246 
3247    switch (cmd) {
3248       case SOCKS_BIND:
3249          if (host->atype            == SOCKS_ADDR_IPV4
3250          &&  host->addr.ipv4.s_addr == htonl(BINDEXTENSION_IPADDR))
3251             break;
3252 
3253          /* FALLTHROUGH */
3254 
3255       case SOCKS_CONNECT:
3256          if (host->atype == SOCKS_ADDR_IPV4
3257          ||  host->atype == SOCKS_ADDR_IPV6) {
3258             if (!external_has_global_safamily(atype2safamily(host->atype))) {
3259                snprintf(emsg, emsglen,
3260                         "connect to %s requested, but no %s configured "
3261                         "for our usage on the external interface",
3262                         atype2string(host->atype),
3263                         atype2string(host->atype));
3264 
3265                return SOCKS_ADDR_UNSUPP;
3266             }
3267          }
3268 
3269          break;
3270 
3271       case SOCKS_UDPASSOCIATE:
3272          if (host->atype == SOCKS_ADDR_IPV4
3273          ||  host->atype == SOCKS_ADDR_IPV6) {
3274             if (!internal_has_safamily(atype2safamily(host->atype))) {
3275                /*
3276                 * If client insists on using an address-type we can not
3277                 * accept packets from things will fail later of course,
3278                 * but that is up to client.  If the client has provided a
3279                 * real IP-address (rather than zero) here however, we can
3280                 * abort things now as we cannot receive packets from that
3281                 * address and our check for whether the client is sending
3282                 * from the address it told us (not zero) will fail, if
3283                 * we ever get that far.
3284                 */
3285 
3286                snprintf(emsg, emsglen,
3287                         "client wants to send us UDP packets from %s, but no "
3288                         "%s configured for our usage on the internal interface",
3289                         atype2string(host->atype),
3290                         atype2string(host->atype));
3291 
3292                slog(LOG_DEBUG, "%s: %s", function, emsg);
3293 
3294                if (SOCKSHOST_ADDRISBOUND(host))
3295                   return SOCKS_ADDR_UNSUPP;
3296             }
3297          }
3298 
3299          break;
3300 
3301       default:
3302          SERRX(cmd);
3303    }
3304 
3305    switch (cmd) {
3306       case SOCKS_BIND:
3307          musthaveaddr = 0;
3308          musthaveport = 0;
3309          break;
3310 
3311       case SOCKS_CONNECT:
3312          musthaveaddr = 1;
3313          musthaveport = 1;
3314          break;
3315 
3316       case SOCKS_UDPASSOCIATE:
3317          musthaveaddr = 0;
3318          musthaveport = 0;
3319          break;
3320 
3321       default:
3322          SERRX(cmd);
3323    }
3324 
3325    if (musthaveaddr && !IPADDRISBOUND(&addr)) {
3326       snprintf(emsg, emsglen, "unbound ipaddress (%s) in request",
3327                sockaddr2string(&addr, NULL, 0));
3328 
3329       return SOCKS_ADDR_UNSUPP;
3330    }
3331 
3332    if (musthaveport && GET_SOCKADDRPORT(&addr) == htons(0)) {
3333       snprintf(emsg, emsglen, "unbound port (%s) in request",
3334                sockaddr2string(&addr, NULL, 0));
3335 
3336       return SOCKS_ADDR_UNSUPP;
3337    }
3338 
3339    /*
3340     * Anything special we need to check for this command or address?
3341     */
3342    switch (cmd) {
3343       case SOCKS_CONNECT:
3344          if (addrindex_on_listenlist(sockscf.internal.addrc,
3345                                      sockscf.internal.addrv,
3346                                      &addr,
3347                                      SOCKS_TCP /* only listen on TCP. */)
3348          != -1) {
3349             snprintf(emsg, emsglen,
3350                      "client is requesting a connection to the same address "
3351                      "we listen to new clients on: %s.  Very suspicious.   "
3352                      "For security reasons that is not allowed, as otherwise "
3353                      "one client could trivially use up all our resources "
3354                      "by going into a loop sending a stream of requests that "
3355                      "all asked us to connect to ourselves",
3356                      sockaddr2string(&addr, NULL, 0));
3357 
3358             return SOCKS_NOTALLOWED;
3359          }
3360          break;
3361 
3362       case SOCKS_UDPASSOCIATE: {
3363          break;
3364 
3365 #if 0
3366          /*
3367           * Not a problem in Dante due to either one of:
3368           *
3369           * a) Dante does not bind any address on the external side
3370           *    until it has received the first UDP packet from the client.
3371           *
3372           * b) Dante does not listen for replies from the address it
3373           *    bound on the external side until is has forwarded at
3374           *    least one packet from the client.
3375           */
3376          int isoninternal = 0, isonexternal = 0;
3377 
3378          /* don't care about port when matching IP-address here. */
3379          SET_SOCKADDRPORT(&addr, htons(0));
3380 
3381          if (addrindex_on_listenlist(sockscf.internal.addrc,
3382                                      sockscf.internal.addrv,
3383                                      &addr,
3384                                      SOCKS_TCP /* only listen on TCP. */) != -1)
3385             isoninternal = 1;
3386          else if (addrindex_on_externallist(&sockscf.external, &addr) != -1)
3387             isonexternal = 1;
3388 
3389          if (isoninternal || isonexternal) {
3390             /*
3391              * We don't allow udpassociate requests that claim to come
3392              * from the same ipaddresses we listen to ourselves.
3393              * This is for safety reasons, as otherwise it's too easy
3394              * to create dos-problems by e.g. making us loop udp packets
3395              * internally forever.  Could happen like this:
3396              *
3397              * 1) Client sends udpassociate request with address ipaddrX.portY,
3398              *    indicating it will send Dante packets from this address,
3399              *    and also indicating Dante should send udp-replies to that
3400              *    address.
3401              *
3402              * 2) Dante accepts the request, and binds a random port on the,
3403              *    the external side.  This random port happens to be portY.
3404              *    So Dante has now bound ipaddrX.portY on the external side,
3405              *    planing to use it to forward packets from the socks client
3406              *    to the socksclient's target.
3407              *
3408              * 3) Dante receives an udp packet ("reply") on ipaddrX.portY.
3409              *    This packet Dante is supposed to send to the client,
3410              *    so it encapsulates it with an UDP header, and sends it to
3411              *    the address the client specified in 1), which is also
3412              *    the same address Dante bound in 2).
3413              *
3414              * 4) Dante receives a new udp packet, same way as in 3.  But
3415              *    this packet it packet which Dante sent.  Again Dante
3416              *    adds a socks header, and forwards it to what it thinks
3417              *    is the client address.
3418              *
3419              * 5) Goto 3.
3420              *
3421              * But not a problem in Dante due to a) or b).
3422              */
3423             snprintf(emsg, emsglen,
3424                      "local client claims to be listening on the same "
3425                      "IP-address as we use on the %s side (%s).  "
3426                      "For security reasons that is not allowed",
3427                      isoninternal ? "internal" : "external",
3428                      sockaddr2string(&addr, NULL, 0));
3429 
3430             return SOCKS_NOTALLOWED;
3431          }
3432 #endif /* 0 no (longer) a problem i Dante. */
3433 
3434          break;
3435       }
3436 
3437       default:
3438          break;
3439    }
3440 
3441    return SOCKS_SUCCESS;
3442 }
3443 
3444 
3445 static int
flushio(mother,io)3446 flushio(mother, io)
3447    int mother;
3448    sockd_io_t *io;
3449 {
3450    const char *function = "flushio()";
3451    int dolog;
3452 
3453    SASSERTX(io->allocated == 0);
3454 
3455    switch (io->state.command) {
3456       case SOCKS_CONNECT:
3457          SASSERTX(io->control.s == -1);
3458 
3459          SASSERTX(io->src.state.isconnected);
3460          SASSERTX(io->src.s     != -1);
3461          SASSERTX(io->dst.s     != -1);
3462          break;
3463 
3464       case SOCKS_BINDREPLY:
3465          if (io->state.extension.bind)
3466             SASSERTX(io->control.s != -1);
3467          else
3468             SASSERTX(io->control.s == -1);
3469 
3470          SASSERTX(io->src.s != -1);
3471          SASSERTX(io->dst.s != -1);
3472 
3473          SASSERTX(io->src.state.isconnected);
3474          SASSERTX(io->dst.state.isconnected);
3475          break;
3476 
3477       case SOCKS_UDPASSOCIATE:
3478          SASSERTX(!io->dst.state.isconnected);
3479          SASSERTX(io->dst.s == -1);
3480 
3481 #if HAVE_CONTROL_CONNECTION
3482          SASSERTX(io->control.s != -1);
3483          SASSERTX(io->control.state.isconnected);
3484 
3485          SASSERTX(io->src.s     != -1);
3486 
3487 #else /* !HAVE_CONTROL_CONNECTION */
3488          SASSERTX(io->control.s == -1);
3489 
3490 #endif /* HAVE_CONTROL_CONNECTION */
3491 
3492          break;
3493 
3494       default:
3495          SERRX(io->state.command);
3496    }
3497 
3498 #if HAVE_GSSAPI
3499    if (CONTROLIO(io)->auth.method == AUTHMETHOD_GSSAPI) {
3500       OM_uint32 minor_status, major_status, maxlen;
3501       char emsg[1024];
3502 
3503       major_status
3504       = gss_wrap_size_limit(&minor_status,
3505                             CONTROLIO(io)->auth.mdata.gssapi.state.id,
3506                             CONTROLIO(io)->auth.mdata.gssapi.state.protection
3507                             == GSSAPI_CONFIDENTIALITY ?
3508                                  GSS_REQ_CONF : GSS_REQ_INT,
3509                             GSS_C_QOP_DEFAULT,
3510                             (OM_uint32)(MAXGSSAPITOKENLEN - GSSAPI_HLEN),
3511                             &maxlen);
3512 
3513       if (gss_err_isset(major_status, minor_status, emsg, sizeof(emsg)))
3514          serrx("%s: gss_wrap_size_limit() failed: %s", function, emsg);
3515 
3516       if (maxlen == 0)
3517          serrx("%s: for a token of length %d, gss_wrap_size_limit() returned "
3518                "%d.  The kerberos library might not fully support the "
3519                "configured encoding type",
3520                function, MAXGSSAPITOKENLEN - GSSAPI_HLEN, maxlen);
3521 
3522       if (sockscf.option.debug >= DEBUG_VERBOSE)
3523          slog(LOG_DEBUG, "%s: gss_wrap_size_limit() for fd %d is %lu",
3524               function, CONTROLIO(io)->s, (unsigned long)maxlen);
3525 
3526       CONTROLIO(io)->auth.mdata.gssapi.state.maxgssdata = maxlen;
3527 
3528       if (io->src.auth.method == AUTHMETHOD_GSSAPI)
3529          io->src.auth.mdata.gssapi.state.maxgssdata = maxlen;
3530 
3531       if (io->dst.auth.method == AUTHMETHOD_GSSAPI)
3532          io->dst.auth.mdata.gssapi.state.maxgssdata = maxlen;
3533    }
3534 #endif /* HAVE_GSSAPI */
3535 
3536    if (io->state.command == SOCKS_CONNECT) {
3537       /*
3538        * Need to save all the socketoptions that we can not set now but
3539        * with which we must wait until the connection has been fully
3540        * established.  The i/o child will have to set them if the connect(2)
3541        * completes successfully.
3542        */
3543       size_t i;
3544 
3545       for (i = 0; i < io->srule.socketoptionc; ++i) {
3546          if (!io->srule.socketoptionv[i].isinternalside
3547          &&   (io->srule.socketoptionv[i].info == NULL
3548            ||  io->srule.socketoptionv[i].info->calltype == postonly)) {
3549             if (io->srule.socketoptionc >= ELEMENTS(io->extsocketoptionv)) {
3550                swarnx("%s: one or more socket options from socks-rule #%lu "
3551                       "could not be set on fd %d because the hardcoded "
3552                       "limit for number of options that can be set on the "
3553                       "external side is %lu",
3554                       function,
3555                       (unsigned long)io->srule.number,
3556                       io->dst.s,
3557                       (unsigned long)ELEMENTS(io->extsocketoptionv));
3558 
3559                break;
3560             }
3561 
3562             io->extsocketoptionv[io->extsocketoptionc++]
3563             = io->srule.socketoptionv[i];
3564          }
3565       }
3566    }
3567 
3568    gettimeofday_monotonic(&io->state.time.requestend);
3569 
3570    if (io->state.command                  == SOCKS_CONNECT
3571    &&  io->state.proxychain.proxyprotocol == PROXY_DIRECT)
3572          ; /* not established yet. */
3573    else
3574       gettimeofday_monotonic(&io->state.time.established);
3575 
3576    /* only the shemid's should be set, not the memory. */
3577    SASSERTX(io->crule.bw == NULL);
3578    SASSERTX(io->crule.ss == NULL);
3579    SASSERTX(io->srule.bw == NULL);
3580    SASSERTX(io->srule.ss == NULL);
3581 
3582    slog(LOG_DEBUG,
3583         "%s: io->control.s = fd %d, io->src.s = fd %d, io->dst.s = fd %d",
3584         function, io->control.s, io->src.s, io->dst.s);
3585 
3586    if (io->state.command == SOCKS_UDPASSOCIATE)
3587 #if BAREFOOTD
3588       dolog = 0; /* log when we get an actual client, not just the setup. */
3589 #else /* Dante */
3590       dolog = 1;
3591 #endif /* Dante */
3592 
3593    else if (io->src.state.isconnected && io->dst.state.isconnected)
3594       dolog = 1;
3595    else
3596       dolog = 0; /* don't know status yet.  I/O child will have to log it. */
3597 
3598    if (dolog) {
3599       iologaddr_t src, dst, proxy;
3600 
3601       if (io->state.protocol == SOCKS_TCP
3602       &&  io->srule.log.tcpinfo
3603       &&  io->dst.state.isconnected) {
3604          int fdv[] = { CLIENTIO(io)->s, EXTERNALIO(io)->s };
3605 
3606          io->state.tcpinfo = get_tcpinfo(ELEMENTS(fdv), fdv, NULL, 0);
3607       }
3608 
3609       initlogaddrs(io,
3610                    &src,
3611                    io->state.protocol == SOCKS_TCP ? &dst : NULL,
3612                    &proxy);
3613 
3614       iolog(&io->srule,
3615             &io->state,
3616             OPERATION_CONNECT,
3617             &src,
3618             io->state.protocol == SOCKS_TCP ? &dst : NULL,
3619             NULL,
3620             io->state.proxychain.proxyprotocol == PROXY_DIRECT ? NULL : &proxy,
3621             NULL,
3622             0);
3623 
3624       io->state.tcpinfo = NULL;
3625    }
3626 
3627    if (send_io(mother, io) != 0) {
3628 #if HAVE_NEGOTIATE_PHASE
3629       response_t response;
3630 #endif /* HAVE_NEGOTIATE_PHASE */
3631       iologaddr_t src, dst, proxy;
3632 
3633       if (sockd_motherexists())
3634         swarn("%s: sending io object with local client %s to mother failed",
3635               function,
3636              sockaddr2string(&CONTROLIO(io)->raddr, NULL, 0));
3637 
3638 #if HAVE_NEGOTIATE_PHASE
3639       if (io->state.proxychain.proxyprotocol == PROXY_DIRECT) {
3640          create_response(NULL,
3641                          &CONTROLIO(io)->auth,
3642                          io->state.proxyprotocol,
3643                          (int)errno2reply(errno, io->state.proxyprotocol),
3644                          &response);
3645 
3646          if (send_response(CONTROLIO(io)->s, &response) != 0) {
3647             slog(LOG_DEBUG,
3648                  "%s: send_response to client %s on fd %d failed: %s",
3649                  function,
3650                  sockshost2string(&CONTROLIO(io)->host, NULL, 0),
3651                  CONTROLIO(io)->s,
3652                  strerror(errno));
3653          }
3654       }
3655       /* else; success response should have been send already. */
3656 #endif /* HAVE_NEGOTIATE_PHASE */
3657 
3658       initlogaddrs(io,
3659                    &src,
3660                    io->state.protocol == SOCKS_TCP ? &dst : NULL,
3661                    &proxy);
3662 
3663       iolog(&io->srule,
3664             &io->state,
3665             OPERATION_ERROR,
3666             &src,
3667             io->state.protocol == SOCKS_TCP ? &dst : NULL,
3668             NULL,
3669             io->state.proxychain.proxyprotocol == PROXY_DIRECT ? NULL : &proxy,
3670             NULL,
3671             0);
3672 
3673       close_iodescriptors(io);
3674       return -1;
3675    }
3676 
3677    close_iodescriptors(io);
3678    return 0;
3679 }
3680 
3681 static void
proctitleupdate(from)3682 proctitleupdate(from)
3683    const struct sockaddr_storage *from;
3684 {
3685    setproctitle("%s: %s",
3686                 childtype2string(sockscf.state.type),
3687                 from == NULL ?  "0/1" : "1/1");
3688 }
3689 
3690 static route_t *
getroute(client,req,emsg,emsglen)3691 getroute(client, req, emsg, emsglen)
3692    const struct sockaddr_storage *client;
3693    request_t *req;
3694    char *emsg;
3695    const size_t emsglen;
3696 {
3697    const char *function = "getroute()";
3698    const int originalreqversion = req->version;
3699    static route_t routemem;
3700    authmethod_t auth;
3701    route_t *route;
3702 
3703    slog(LOG_DEBUG, "%s: request: %s, authmethod %d",
3704         function, socks_packet2string(req, 1), req->auth->method);
3705 
3706    bzero(&routemem, sizeof(routemem));
3707 
3708    if (sockscf.route == NULL) {
3709       slog(LOG_DEBUG, "%s: no routes, faking direct route", function);
3710 
3711       routemem.gw.state.proxyprotocol.direct = 1;
3712       return &routemem;
3713    }
3714 
3715    /*
3716     * We can reuse the authentication the client provided to us when
3717     * authentication to an upstream proxy, unless the operator has
3718     * explicitly set the methods supported by this route to "none".
3719     *
3720     * In some cases, we need to convert the method from a non-standard
3721     * method to a standard socks method however.
3722     */
3723 
3724    auth2standard(req->auth, &auth);
3725    *req->auth = auth;
3726 
3727    switch (req->command) {
3728       case SOCKS_BIND:
3729       case SOCKS_CONNECT:
3730          break;
3731 
3732       case SOCKS_UDPASSOCIATE:
3733          /*
3734           * Client should send us the address it will send us
3735           * udp packets from.  Not related to target address,
3736           * so bzero it (INADDR_ANY) as the address given here
3737           * is nothing we can use in relation to a route-lookup.
3738           */
3739          bzero(&req->host.addr, sizeof(req->host.addr));
3740          req->host.port = htons(0);
3741 
3742          switch (req->host.atype) {
3743             case SOCKS_ADDR_IPV4:
3744             case SOCKS_ADDR_IPV6:
3745                break;
3746 
3747             case SOCKS_ADDR_DOMAIN:
3748                req->host.atype = SOCKS_ADDR_IPV4; /* any ipaddress type */
3749                break;
3750 
3751             default:
3752                SERRX(req->host.atype);
3753          }
3754          break;
3755 
3756       default:
3757          SERRX(req->command);
3758    }
3759 
3760    /* best if we can find a direct route, so look for that first. */
3761    req->version = PROXY_DIRECT;
3762 
3763    route = socks_requestpolish(req,
3764                                sockaddr2sockshost(client, NULL),
3765                                &req->host);
3766    if (route == NULL) {
3767       if (req->command    == SOCKS_CONNECT
3768       &&  req->host.atype == SOCKS_ADDR_DOMAIN) {
3769          /*
3770           * Possibly there is a route supporting an ipaddress destination,
3771           * even if there was no route supporting the hostname destination
3772           * (e.g., there is only socks v4 route).  Therefor try resolving the
3773           * destination locally before giving up on finding a route.
3774           *
3775           * We will need to resolve the destination sooner or later
3776           * anyway, so if it's not already in our hostcache, there should
3777           * not be a big penalty incurred by adding it now before doing
3778           * a route lookup again.
3779           */
3780          struct sockaddr_storage saddr;
3781          int gaierr;
3782 
3783          slog(LOG_DEBUG,
3784               "%s: no hostname-route for destination %s found.  Trying to "
3785               "resolve and do route lookup again",
3786               function, sockshost2string(&req->host, NULL, 0));
3787 
3788          sockshost2sockaddr2(&req->host, &saddr, &gaierr, emsg, emsglen);
3789 
3790          if (gaierr != 0) {
3791             log_resolvefailed(req->host.addr.domain, EXTERNALIF, gaierr);
3792             return NULL;
3793          }
3794 
3795          /*
3796           * Retry the request using the original request data, but
3797           * change the hostname to the resolved address.
3798           */
3799 
3800          sockaddr2sockshost(&saddr, &req->host);
3801 
3802          if (req->version   == PROXY_SOCKS_V4
3803          &&  saddr.ss_family != AF_INET)
3804             /*
3805              * v4 only supports ipv4, so no choice but changing it.
3806              */
3807             req->version = PROXY_SOCKS_V5;
3808          else
3809             req->version = originalreqversion;
3810 
3811          return getroute(client, req, emsg, emsglen);
3812       }
3813       else {
3814          if (req->command != SOCKS_CONNECT)
3815             snprintf(emsg, emsglen,
3816                      "command %s is not supported by serverchaining and no "
3817                      "direct route found",
3818                      command2string(req->command));
3819          else
3820             snprintf(emsg, emsglen,
3821                      "no usable serverchain route to target found");
3822 
3823          return NULL;
3824       }
3825    }
3826 
3827    SASSERTX(route != NULL);
3828    routemem = *route;
3829 
3830    return &routemem;
3831 }
3832 
3833 static int
serverchain(targetsocket,clientsocket,client,req,proxychain,proxychainauth,emsg,emsglen)3834 serverchain(targetsocket, clientsocket, client, req,
3835             proxychain, proxychainauth, emsg, emsglen)
3836    const int targetsocket;
3837    const int clientsocket;
3838    const struct sockaddr_storage *client;
3839    const request_t *req;
3840    proxychaininfo_t *proxychain;
3841    authmethod_t *proxychainauth;
3842    char *emsg;
3843    size_t emsglen;
3844 {
3845    const char *function = "serverchain()";
3846    response_t response;
3847    route_t *route;
3848    socks_t packet;
3849    char lemsg[512];
3850    int rc, flags;
3851 
3852    slog(LOG_DEBUG, "%s: client %s, auth %s, request %s",
3853         function,
3854         sockaddr2string(client, NULL, 0),
3855         method2string(req->auth->method),
3856         socks_packet2string(req, 1));
3857 
3858    bzero(&packet, sizeof(packet));
3859    packet.state.auth = *req->auth;
3860    packet.req        = *req;
3861 
3862    packet.req.auth = &packet.state.auth;
3863    packet.res.auth = &packet.state.auth;
3864 
3865    if ((route = getroute(client, &packet.req, emsg, emsglen)) == NULL)
3866       return -1;
3867 
3868    if (route->gw.state.proxyprotocol.direct) {
3869       slog(LOG_DEBUG, "%s: using direct system calls for fd %d",
3870            function, targetsocket);
3871 
3872       proxychain->proxyprotocol = PROXY_DIRECT;
3873       return 0;
3874    }
3875 
3876    if (socks_routesetup(targetsocket, targetsocket, route, emsg, emsglen) != 0){
3877       swarnx("%s: socks_routesetup() failed: %s", function, emsg);
3878       return -1;
3879    }
3880 
3881    if ((route = socks_connectroute(targetsocket,
3882                                    &packet,
3883                                    sockaddr2sockshost(client, NULL),
3884                                    &packet.req.host,
3885                                    lemsg,
3886                                    sizeof(lemsg))) == NULL) {
3887       snprintf(emsg, emsglen,
3888                "could not connect to upstream proxyserver: %s", lemsg);
3889 
3890       return -1;
3891    }
3892 
3893    proxychain->proxyprotocol = packet.req.version;
3894 
3895    /*
3896     * we're not interested the extra hassle of negotiating over a
3897     * non-blocking socket so set it to blocking while we use it.
3898     */
3899    if ((flags = setblocking(targetsocket, "server-chaining")) == -1)
3900       return -1;
3901 
3902    rc = socks_negotiate(targetsocket,
3903                         targetsocket,
3904                         &packet,
3905                         route,
3906                         emsg,
3907                         emsglen);
3908 
3909    if (fcntl(targetsocket, F_SETFL, flags) == -1)
3910       swarn("%s: fcntl(2) failed to restore flags on fd %d to %d",
3911             function, targetsocket, flags);
3912 
3913    if (rc != 0) {
3914       slog(LOG_DEBUG, "%s: socks_negotiate() failed: %s",
3915            function, strerror(errno));
3916 
3917       return -1;
3918    }
3919 
3920    /* Use request-version as response-version differs in v4 (is 0 there). */
3921    proxychain->proxyprotocol = (int)packet.req.version;
3922 
3923    switch (packet.req.command) {
3924       case SOCKS_CONNECT:
3925          proxychain->extaddr = packet.res.host;
3926          break;
3927 
3928       default:
3929          SERRX(packet.req.command);
3930    }
3931 
3932    *proxychainauth = *packet.req.auth;
3933 
3934    convertresponse(&packet.res, &response, req->version);
3935    response.auth = req->auth; /* must use the auth negotiated with client. */
3936 
3937    if (send_response(clientsocket, &response) != 0)
3938       return -1;
3939 
3940    slog(LOG_DEBUG,
3941         "%s: external address used by upstream proxy is %s.  "
3942         "Authmethod upstream is %s, authmethod downstream is %s",
3943         function,
3944         sockshost2string(&proxychain->extaddr, NULL, 0),
3945         method2string(proxychainauth->method),
3946         method2string(response.auth->method));
3947 
3948 
3949    return 0;
3950 }
3951 
3952 static void
convertresponse(oldres,newres,newversion)3953 convertresponse(oldres, newres, newversion)
3954    const response_t *oldres;
3955    response_t *newres;
3956    const int newversion;
3957 {
3958    const char *function = "convertresponse()";
3959    int genericreply;
3960 
3961    if (oldres->version == newversion
3962    || (    newversion     == PROXY_SOCKS_V4
3963        && oldres->version == PROXY_SOCKS_V4REPLY_VERSION)) {
3964       *newres = *oldres;
3965       return;
3966    }
3967 
3968    /*
3969     * first convert the genericreply code from whatever old version to the
3970     * corresponding socks v5 generic reply code.  Then convert from the
3971     * v5 replycode to whatever new version.
3972     */
3973    switch (oldres->version) {
3974       case PROXY_HTTP_10:
3975       case PROXY_HTTP_11:
3976          switch (oldres->reply.http) {
3977             case HTTP_SUCCESS:
3978                genericreply = SOCKS_SUCCESS;
3979                break;
3980 
3981             case HTTP_NOTALLOWED:
3982             case HTTP_FORBIDDEN:
3983             case HTTP_PROXYAUTHREQUIRED:
3984                genericreply = SOCKS_NOTALLOWED;
3985                break;
3986 
3987             case HTTP_HOSTUNREACH:
3988                genericreply = SOCKS_HOSTUNREACH;
3989                break;
3990 
3991             default:
3992                genericreply = SOCKS_FAILURE;
3993                break;
3994          }
3995          break;
3996 
3997       case PROXY_UPNP:
3998          switch (oldres->reply.upnp) {
3999             case UPNP_SUCCESS:
4000                genericreply = SOCKS_SUCCESS;
4001                break;
4002 
4003             default:
4004                genericreply = SOCKS_FAILURE;
4005                break;
4006          }
4007          break;
4008 
4009       case PROXY_SOCKS_V4REPLY_VERSION:
4010          switch (oldres->reply.socks) {
4011             case SOCKSV4_SUCCESS:
4012                genericreply = SOCKS_SUCCESS;
4013                break;
4014 
4015             case SOCKSV4_NO_IDENTD:
4016             case SOCKSV4_BAD_ID:
4017                genericreply = SOCKS_NOTALLOWED;
4018                break;
4019 
4020             default:
4021                genericreply = SOCKS_FAILURE;
4022                break;
4023          }
4024          break;
4025 
4026       case PROXY_SOCKS_V5: /* default; what we use as the generic replycode. */
4027          genericreply = oldres->reply.socks;
4028          break;
4029 
4030       default:
4031          swarnx("%s: unknown proxy protocol: %d", function, oldres->version);
4032          genericreply = SOCKS_FAILURE;
4033    }
4034 
4035    switch (newversion) {
4036       case PROXY_SOCKS_V4:
4037          if (oldres->host.atype == SOCKS_ADDR_IPV4)
4038             newres->host = oldres->host;
4039          else {
4040             /*
4041              * v4 only supports ipaddr, so if the address is not an IP address,
4042              * we need to resolve it before responding.
4043              */
4044             struct sockaddr_storage addr;
4045 
4046             sockshost2sockaddr(&oldres->host, &addr);
4047             if (IPADDRISBOUND(&addr))
4048                sockaddr2sockshost(&addr, &newres->host);
4049             else {
4050                swarnx("%s: can not resolve hostname %s",
4051                       function, sockshost2string(&oldres->host, NULL, 0));
4052 
4053                genericreply = SOCKS_FAILURE;
4054             }
4055          }
4056 
4057          newres->version = PROXY_SOCKS_V4REPLY_VERSION;
4058          break;
4059 
4060       case PROXY_SOCKS_V5:
4061          /*
4062           * only flagbits in v5, and old version was obviously not that,
4063           * so we have no flagbits to copy.
4064          */
4065          newres->flag    = 0;
4066 
4067          newres->host    = oldres->host;
4068          newres->version = newversion;
4069          break;
4070 
4071       default:
4072          SERRX(newversion);
4073    }
4074 
4075    socks_set_responsevalue(newres, sockscode(newversion, genericreply));
4076 
4077    slog(LOG_DEBUG,
4078         "%s: converted from version %d to version %d.  Old response value "
4079         "was %d, new is %d",
4080         function,
4081         oldres->version,
4082         newres->version,
4083         socks_get_responsevalue(oldres),
4084         socks_get_responsevalue(newres));
4085 }
4086 
4087 static void
init_req(req,request)4088 init_req(req, request)
4089    struct req *req;
4090    const sockd_request_t *request;
4091 {
4092 
4093    req->starttime        = time_monotonic(NULL);
4094 
4095    req->crule            = request->crule;
4096 #if HAVE_SOCKS_HOSTID
4097    req->hrule            = request->hrule;
4098    req->hrule_isset      = request->hrule_isset;
4099 #endif /* HAVE_SOCKS_HOSTID */
4100 
4101    req->client           = request->from;
4102    req->request_isvalid  = 1;
4103    req->request          = request->req;
4104    req->s                = request->s;
4105 
4106 #if HAVE_NEGOTIATE_PHASE
4107    socks_allocbuffer(req->s, SOCK_STREAM);
4108 #endif /* HAVE_NEGOTIATE_PHASE */
4109 
4110    req->allocated        = 1;
4111 }
4112 
4113 static void
delete_req(req)4114 delete_req(req)
4115    struct req *req;
4116 {
4117 
4118 #if HAVE_NEGOTIATE_PHASE
4119    socks_freebuffer(req->s);
4120 #endif /* HAVE_NEGOTIATE_PHASE */
4121 
4122    req->allocated = req->request_isvalid = 0;
4123 }
4124 
4125 /* ARGSUSED */
4126 static void
siginfo(sig,si,sc)4127 siginfo(sig, si, sc)
4128    int sig;
4129    siginfo_t *si;
4130    void *sc;
4131 {
4132    const char *function = "siginfo()";
4133    const int errno_s = errno;
4134    time_t tnow;
4135    unsigned long days, hours, minutes, seconds;
4136    size_t i;
4137 
4138    SIGNAL_PROLOGUE(sig, si, errno_s);
4139 
4140    seconds = (unsigned long)socks_difftime(time_monotonic(&tnow),
4141                                            sockscf.stat.boot);
4142 
4143    seconds2days(&seconds, &days, &hours, &minutes);
4144 
4145    slog(LOG_INFO, "request-child up %lu day%s, %lu:%.2lu:%.2lu",
4146                   days, days == 1 ? "" : "s", hours, minutes, seconds);
4147 
4148    for (i = 0; i < reqc; ++i) {
4149       char *tcpinfo, reqinfo[64];
4150 
4151       if (!reqv[i].allocated)
4152          continue;
4153 
4154       if (CRULE_OR_HRULE(&reqv[i])->log.tcpinfo) {
4155          int fdv[] = { reqv[i].s };
4156 
4157          tcpinfo = get_tcpinfo(ELEMENTS(fdv), fdv, NULL, 0);
4158       }
4159       else
4160          tcpinfo = NULL;
4161 
4162       if (reqv[i].request_isvalid)
4163          snprintf(reqinfo, sizeof(reqinfo),
4164                   "%s %s-request",
4165                   protocol2string(reqv[i].request.protocol),
4166                   command2string(reqv[i].request.command));
4167       else
4168          snprintf(reqinfo, sizeof(reqinfo), "request");
4169 
4170       slog(LOG_INFO,
4171            "%s: %s in progress for %lds"
4172            "%s%s%s",
4173            sockaddr2string(&reqv[i].client, NULL, 0),
4174            reqinfo,
4175            (long)socks_difftime(tnow, reqv[i].starttime),
4176            tcpinfo == NULL ? "" : "\n",
4177            tcpinfo == NULL ? "" : "   TCP_INFO:\n",
4178            tcpinfo == NULL ? "" : tcpinfo);
4179    }
4180 
4181    SIGNAL_EPILOGUE(sig, si, errno_s);
4182 }
4183 
4184 static void
initlogaddrs(io,src,dst,proxy)4185 initlogaddrs(io, src, dst, proxy)
4186       const sockd_io_t *io;
4187       iologaddr_t *src;
4188       iologaddr_t *dst;
4189       iologaddr_t *proxy;
4190 {
4191 
4192    if (src != NULL)
4193       init_iologaddr(src,
4194                      object_sockaddr,
4195                      &io->src.laddr,
4196                      object_sockshost,
4197                      &io->src.host,
4198                      &io->src.auth,
4199                      GET_HOSTIDV(&io->state),
4200                      GET_HOSTIDC(&io->state));
4201 
4202    if (dst != NULL)
4203       init_iologaddr(dst,
4204                      object_sockaddr,
4205                      &io->dst.laddr,
4206                      object_sockshost,
4207                      &io->dst.host,
4208                      io->state.proxychain.proxyprotocol == PROXY_DIRECT ?
4209                         &io->dst.auth : NULL,
4210                      NULL,
4211                      0);
4212 
4213    if (proxy != NULL && io->state.proxychain.proxyprotocol != PROXY_DIRECT)
4214       init_iologaddr(proxy,
4215                      object_sockaddr,
4216                      &io->dst.raddr,
4217                      object_sockshost,
4218                      &io->state.proxychain.extaddr,
4219                      &io->dst.auth,
4220                      NULL,
4221                      0);
4222 }
4223 
4224 static int
bindexternaladdr(io,_req,emsg,emsglen)4225 bindexternaladdr(io, _req, emsg, emsglen)
4226    sockd_io_t *io;
4227    const request_t *_req;
4228    char *emsg;
4229    const size_t emsglen;
4230 {
4231    const char *function = "bindexternaladdr()";
4232    const sockshost_t *target;
4233    request_t req;
4234    authmethod_t auth;
4235    route_t *route;
4236    int rc;
4237 
4238 
4239    slog(LOG_DEBUG, "%s: request: %s, authmethod %d",
4240         function, socks_packet2string(_req, 1), _req->auth->method);
4241 
4242    /*
4243     * Don't let getroute() modify our data.
4244     */
4245    auth     = *_req->auth;
4246    req      = *_req;
4247    req.auth = &auth;
4248 
4249    /*
4250     * If we have a non-direct route we need to use for the request,
4251     * the address we should bind is an address we can connect to the
4252     * upstream proxyserver from.  I.e., in this context, the target is
4253     * the proxyserver, not the address given by the client.
4254     */
4255 
4256    if ((route = getroute(&io->src.raddr, &req, emsg, emsglen)) == NULL)
4257       return -1;
4258 
4259    if (route->gw.state.proxyprotocol.direct)
4260       target = &req.host;
4261    else
4262       target = &route->gw.addr;
4263 
4264    /*
4265     * Find address to bind for client.  First the ipaddress.
4266     */
4267    if (getoutaddr(&io->dst.laddr,
4268                   &io->src.laddr,
4269                   &io->src.raddr,
4270                   req.command,
4271                   target,
4272                   emsg,
4273                   emsglen) == NULL)
4274       return -1;
4275 
4276    if (PORTISRESERVED(GET_SOCKADDRPORT(&io->dst.laddr))
4277    && !sockscf.compat.sameport) {
4278       slog(LOG_DEBUG,
4279            "%s: would normally try to bind the privileged port %u, but "
4280            "\"compatibility: sameport\" is not set, so just binding an porty",
4281            function, ntohs(GET_SOCKADDRPORT(&io->dst.laddr)));
4282 
4283       SET_SOCKADDRPORT(&io->dst.laddr, htons(0));
4284    }
4285 
4286    io->dst.s = socket(io->dst.laddr.ss_family,
4287                       io->state.protocol == SOCKS_TCP ?
4288                            SOCK_STREAM : SOCK_DGRAM,
4289                       0);
4290 
4291    if (io->dst.s == -1) {
4292       snprintf(emsg, emsglen, "could not create socket: %s", strerror(errno));
4293       return -1;
4294    }
4295 
4296    if (io->state.extension.bind && io->state.command == SOCKS_BIND) {
4297       rc = 1;
4298       if (setsockopt(io->dst.s, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof(rc)) != 0)
4299          swarn("%s: setsockopt(SO_REUSEADDR)", function);
4300    }
4301 
4302    if ((rc = socks_bind(io->dst.s, &io->dst.laddr, 0)) != 0) {
4303       /*
4304        * no such luck.  Bind any port then.
4305        */
4306       const in_port_t port_desired = GET_SOCKADDRPORT(&io->dst.laddr);
4307 
4308       SET_SOCKADDRPORT(&io->dst.laddr, htons(0));
4309 
4310       if ((rc = socks_bind(io->dst.s, &io->dst.laddr, 0)) == 0)
4311          slog(LOG_DEBUG,
4312                "%s: bound different port than desired (bound %u, not %u)",
4313                function,
4314                ntohs(port_desired),
4315                ntohs(GET_SOCKADDRPORT(&io->dst.laddr)));
4316    }
4317 
4318    if (rc != 0) {
4319       log_bind_failed(function, SOCKS_TCP, &io->dst.laddr);
4320 
4321       snprintf(emsg, emsglen,
4322                "failed to bind address on external side: %s", strerror(errno));
4323 
4324       return -1;
4325    }
4326 
4327    log_boundexternaladdress(function, &io->dst.laddr);
4328 
4329    return 0;
4330 }
4331 
4332 static void
auth2standard(auth,stdauth)4333 auth2standard(auth, stdauth)
4334    const authmethod_t *auth;
4335    authmethod_t *stdauth;
4336 {
4337    const char *function = "auth2standard()";
4338 
4339    bzero(stdauth, sizeof(*stdauth));
4340 
4341    switch (auth->method) {
4342       case AUTHMETHOD_NONE:
4343          stdauth->method = auth->method;
4344          break;
4345 
4346       case AUTHMETHOD_UNAME:
4347          stdauth->mdata.uname = auth->mdata.uname;
4348          stdauth->method      = auth->method;
4349          break;
4350 
4351 #if HAVE_GSSAPI
4352       case AUTHMETHOD_GSSAPI:
4353          stdauth->mdata.gssapi = auth->mdata.gssapi;
4354          stdauth->method       = auth->method;
4355          break;
4356 #endif /* HAVE_GSSAPI */
4357 
4358 #if HAVE_PAM
4359       case AUTHMETHOD_PAM_USERNAME: {
4360          const authmethod_pam_t *pam = &auth->mdata.pam;
4361 
4362          STRCPY_ASSERTSIZE(stdauth->mdata.uname.name, pam->name);
4363 
4364          STRCPY_ASSERTSIZE(stdauth->mdata.uname.password, pam->password);
4365 
4366          stdauth->method = AUTHMETHOD_UNAME;
4367          break;
4368       }
4369 #endif /* HAVE_PAM */
4370 
4371 #if HAVE_BSDAUTH
4372       case AUTHMETHOD_BSDAUTH: {
4373          const authmethod_bsd_t *bsd = &auth->mdata.bsd;
4374 
4375          STRCPY_ASSERTSIZE(stdauth->mdata.uname.name, bsd->name);
4376 
4377          STRCPY_ASSERTSIZE(stdauth->mdata.uname.password, bsd->password);
4378 
4379          stdauth->method = AUTHMETHOD_UNAME;
4380          break;
4381       }
4382 #endif /* HAVE_BSDAUTH */
4383 
4384       default:
4385          stdauth->method = AUTHMETHOD_NONE;
4386    }
4387 
4388    if (auth->method != stdauth->method)
4389       slog(LOG_DEBUG, "%s: converted from authmethod %d (%s) to %d (%s)",
4390            function,
4391            auth->method,
4392            method2string(auth->method),
4393            stdauth->method,
4394            method2string(stdauth->method));
4395 }
4396 
4397 
4398 #if SOCKS_SERVER
4399 static sockd_io_t *
io_add(iolist,newio)4400 io_add(iolist, newio)
4401    sockd_io_t *iolist;
4402    const sockd_io_t *newio;
4403 {
4404    const char *function = "io_add()";
4405    sockd_io_t *io, *previo;
4406 
4407    SASSERTX(newio->next == NULL);
4408 
4409    previo = io = iolist;
4410    while (io != NULL) {
4411       previo = io;
4412       io = io->next;
4413    }
4414 
4415    if ((io = malloc(sizeof(*newio))) == NULL)
4416       swarnx("%s: %s", function, NOMEM);
4417    else {
4418       *io = *newio;
4419 
4420       if (previo == NULL)
4421          previo = io;
4422       else
4423          previo->next = io;
4424    }
4425 
4426    return iolist == NULL ? previo : iolist;
4427 }
4428 
4429 static sockd_io_t *
io_remove(iolist,rmio)4430 io_remove(iolist, rmio)
4431    sockd_io_t *iolist;
4432    sockd_io_t *rmio;
4433 {
4434    sockd_io_t *io, *previo;
4435 
4436    SASSERTX(iolist != NULL);
4437 
4438    if (iolist == rmio) {
4439       iolist = rmio->next;
4440       free(rmio);
4441       return iolist;
4442    }
4443 
4444    previo = iolist;
4445    io = iolist->next;
4446    while (io != NULL) {
4447       if (io == rmio) {
4448          previo->next = rmio->next;
4449          free(rmio);
4450          break;
4451       }
4452 
4453       previo = io;
4454       io = io->next;
4455    }
4456 
4457    return iolist;
4458 }
4459 
4460 static sockd_io_t *
io_find(iolist,addr)4461 io_find(iolist, addr)
4462    sockd_io_t *iolist;
4463    const struct sockaddr_storage *addr;
4464 {
4465    sockd_io_t *io;
4466 
4467    if (addr == NULL)
4468       return iolist;
4469 
4470    io = iolist;
4471    while (io != NULL)
4472       if (sockaddrareeq(&io->src.laddr, addr, 0)
4473       ||  sockaddrareeq(&io->dst.laddr, addr, 0)
4474       ||  sockaddrareeq(&io->control.laddr, addr, 0))
4475          return io;
4476       else
4477          io = io->next;
4478 
4479    return NULL;
4480 }
4481 
4482 #endif /* SOCKS_SERVER */
4483