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