1 /*
2  * Copyright (c) 1997, 1998, 1999, 2001, 2003, 2008, 2009, 2010, 2011, 2012,
3  *               2013, 2014, 2016
4  *      Inferno Nettverk A/S, Norway.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. The above copyright notice, this list of conditions and the following
10  *    disclaimer must appear in all copies of the software, derivative works
11  *    or modified versions, and any portions thereof, aswell as in all
12  *    supporting documentation.
13  * 2. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by
16  *      Inferno Nettverk A/S, Norway.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * Inferno Nettverk A/S requests users of this software to return to
32  *
33  *  Software Distribution Coordinator  or  sdc@inet.no
34  *  Inferno Nettverk A/S
35  *  Oslo Research Park
36  *  Gaustadall�en 21
37  *  NO-0349 Oslo
38  *  Norway
39  *
40  * any improvements or extensions that they make and grant Inferno Nettverk A/S
41  * the rights to redistribute these changes.
42  *
43  */
44 
45 #include "common.h"
46 
47 static const char rcsid[] =
48 "$Id: sockd_socket.c,v 1.170.4.1.2.2 2017/01/31 08:17:39 karls Exp $";
49 
50 #define MAXSOCKETOPTIONS ( 1 /* TCP_NODELAY || SO_BROADCAST                  */\
51                          + 1 /* SO_TIMESTAMP                                 */\
52                          + 1 /* SO_OOBINLINE                                 */\
53                          + 1 /* SO_KEEPALIVE                                 */\
54                          + 1 /* SO_SNDBUF   || SO_SNDBUFFORCE                */\
55                          + 1 /* SO_RCVBUF   || SO_RCVBUFFORCE                */\
56                          + 1 /* IPV6_V6ONLY                                  */\
57           )
58 #define MAXOPTIONNAME   (16) /* max length of any of the option names above. */
59 typedef struct {
60    unsigned char     wantprivileges;
61    int               level;
62    int               optname;
63    int               optval;
64    size_t            optlen;
65    char              textname[MAXOPTIONNAME];
66 } socketoptions_t;
67 
68 static size_t
69 getoptions(const sa_family_t family, const int type, const int isclientside,
70            socketoptions_t *optionsv, const size_t optionsc);
71 /*
72  * Fills in "optionsv" with the correct values for a socket of family "family"
73  * and type "type".
74  * "isclientside" indicates if the socket is to be used on the client side
75  * or not.
76  *
77  * Returns the number of options set (always <= MAXSOCKETOPTIONS).
78  */
79 
80 int
sockd_unconnect(s,oldpeer)81 sockd_unconnect(s, oldpeer)
82    const int s;
83    const struct sockaddr_storage *oldpeer;
84 {
85    const char *function = "sockd_unconnect()";
86    struct sockaddr_storage local, remote, newlocal;
87    socklen_t addrlen;
88    char buf[MAXSOCKADDRSTRING];
89    int havepeer;
90 
91    addrlen = sizeof(local);
92    if (getsockname(s, TOSA(&local), &addrlen) != 0) {
93       swarn("%s: getsockname()", function);
94       return -1;
95    }
96 
97    if (getpeername(s, TOSA(&remote), &addrlen) != 0) {
98 #if HAVE_LINUX_BUGS
99       if (oldpeer != NULL && GET_SOCKADDRPORT(oldpeer) == htons(0))
100          /*
101           * Linux bug; accepts udp connect(2) to port 0, but getpeername(2)
102           * on the same socket afterwards fails.
103           */
104          ;
105       else
106 #endif /* HAVE_LINUX_BUGS */
107 
108       {
109          swarn("%s: could not unconnect fd %d from %s",
110                function,
111                s,
112                oldpeer == NULL ? "N/A" : sockaddr2string(oldpeer, NULL, 0));
113 
114          if (!ERRNOISTMP(errno))
115             SWARN(errno); /* not bound?  Should not happen. */
116       }
117 
118       havepeer = 0;
119    }
120    else
121       havepeer = 1;
122 
123    slog(LOG_DEBUG, "%s: unconnecting fd %d, currently connected from %s to %s",
124         function,
125         s,
126         sockaddr2string(&local, buf, sizeof(buf)),
127         havepeer ? sockaddr2string(&remote, NULL, 0) : "nothing");
128 
129    bzero(&remote, sizeof(remote));
130    SET_SOCKADDR(&remote, AF_UNSPEC);
131 
132    if (connect(s, TOSA(&remote), salen(remote.ss_family)) != 0)
133       slog(LOG_DEBUG, "%s: connect to %s failed: %s",
134            function, sockaddr2string(&remote, NULL, 0), strerror(errno));
135 
136    /*
137     * May need to re-bind the socket after unconnect to make sure we get the
138     * same address as we had before, as some systems only keep the portnumber
139     * if not. :-/  Check first.
140     */
141    addrlen = sizeof(newlocal);
142    if (getsockname(s, TOSA(&newlocal), &addrlen) != 0) {
143       swarn("%s: getsockname() failed the second time", function);
144       return -1;
145    }
146 
147    if (sockaddrareeq(&local, &newlocal, 0))
148       return 0; /* ok, no problem on this system. */
149 
150    /*
151     * Ack, need to try to rebind the socket. :-/
152     */
153 
154    if (socks_bind(s, &local, 1) != 0) {
155       char a[MAXSOCKADDRSTRING], b[MAXSOCKADDRSTRING];
156       int new_s;
157 
158       slog(LOG_DEBUG, "%s: re-bind(2) after unconnecting failed: %s.  "
159                       "Current address is %s (was %s).  Trying to create a "
160                       "new socket instead, though we might loose some packets "
161                       "doing so",
162                       function,
163                       strerror(errno),
164                       sockaddr2string(&newlocal, a, sizeof(a)),
165                       sockaddr2string(&local, b, sizeof(b)));
166 
167       /*
168        * There is an unfortunate race here, as while we create the new
169        * socket packets could come in on the old socket, and those packets
170        * will be lost.
171        */
172 
173       new_s = 1;
174       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &new_s, sizeof(new_s)) != 0)
175          swarn("%s: setsockopt(SO_REUSEADDR)", function);
176 
177       if ((new_s = socketoptdup(s, -1)) == -1) {
178          swarn("%s: socketoptdup(%d) failed", function, s);
179          return -1;
180       }
181 
182       if (socks_bind(new_s, &local, 1) != 0) {
183          slog(LOG_DEBUG, "%s: bind of new socket also failed: %s",
184               function, strerror(errno));
185 
186          close(new_s);
187          return 0;
188       }
189 
190       slog(LOG_DEBUG, "%s: bind of new socket to address %s succeeded",
191            function, sockaddr2string(&local, NULL, 0));
192 
193       if (dup2(new_s, s) == -1) {
194          swarn("%s: dup2() failed", function);
195 
196          close(new_s);
197          return 0;
198       }
199 
200       close(new_s);
201    }
202 
203    return 0;
204 }
205 
206 void
sockd_rstonclose(s)207 sockd_rstonclose(s)
208    const int s;
209 {
210    const char *function = "sockd_rstonclose()";
211    /* try to make the kernel generate a TCP RST for the other end upon close. */
212    const struct linger linger = { 1, 0 };
213 
214    if (setsockopt(s,
215                   SOL_SOCKET,
216                   SO_LINGER,
217                   &linger,
218                   sizeof(linger)) != 0)
219       slog(LOG_DEBUG,
220            "%s: setsockopt(fd %d, SO_LINGER) failed: %s",
221            function, s, strerror(errno));
222 }
223 
224 int
bindinternal(protocol)225 bindinternal(protocol)
226    const int protocol;
227 {
228    const char *function = "bindinternal()";
229    size_t i;
230 
231    for (i = 0; i < sockscf.internal.addrc; ++i) {
232       listenaddress_t *l = &sockscf.internal.addrv[i];
233       int val;
234 
235       if (l->protocol != protocol)
236          continue;
237 
238       if (l->s != -1) {
239          slog(LOG_DEBUG, "%s: address %s should be bound to fd %d already",
240               function,
241               sockaddr2string(&l->addr, NULL, 0),
242               l->s);
243 
244          SASSERTX(fdisopen(l->s));
245 
246          /*
247           * config-based socket options need to be (re)set though.
248           * XXX missing code to unset any previously set options.
249           */
250          setconfsockoptions(l->s,
251                             l->s,
252                             SOCKS_TCP,
253                             1,
254                             0,
255                             NULL,
256                             0,
257                             SOCKETOPT_PRE | SOCKETOPT_ANYTIME);
258 
259          continue;
260       }
261 
262       if ((l->s = socket(l->addr.ss_family, SOCK_STREAM, 0)) == -1) {
263          swarn("%s: could not create %s socket(2)",
264                function, safamily2string(l->addr.ss_family));
265 
266          return -1;
267       }
268 
269       setsockoptions(l->s, l->addr.ss_family, SOCK_STREAM, 1);
270 
271       /*
272        * This breaks the principle that we should only set socket options
273        * on sockets used for data (rather than sockets used for the control
274        * messages), but some options can only be set at pre-connect time,
275        * so if we do not set them here, we will never be able to set them.
276        * Possibly we should limit the settings here to the options that
277        * can _only_ be set at pre-connect time, so that at least other
278        * options are not set unnecessarily.
279        */
280 
281        /* XXX missing code to unset any previously set options. */
282       setconfsockoptions(l->s,
283                          l->s,
284                          SOCKS_TCP,
285                          1,
286                          0,
287                          NULL,
288                          0,
289                          SOCKETOPT_PRE | SOCKETOPT_ANYTIME);
290 
291       val = 1;
292       if (setsockopt(l->s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != 0)
293          swarn("%s: setsockopt(SO_REUSEADDR)", function);
294 
295 #if !HAVE_PRIVILEGES
296 {
297       /*
298        * Specialcase this so that if we are started as root we do bind
299        * the listen port requested, regardless of whether user.privileged is
300        * set to root or not.  Allows a user who does not want Dante to
301        * run as root, ever, but does want Dante to bind a privileged port
302        * when initially starting, get what he wants.
303        */
304       socklen_t len;
305       uid_t old_euid;
306       int changed_euid = 0;
307 
308       len = salen(l->addr.ss_family);
309 
310       if (PORTISRESERVED(GET_SOCKADDRPORT(&l->addr))) {
311          old_euid = geteuid();
312 
313          if (old_euid != 0) {
314             if (seteuid(0) == 0) {
315                sockscf.state.euid = 0;
316                changed_euid       = 1;
317             }
318          }
319       }
320 
321       if ((val = bind(l->s, TOSA(&l->addr), len)) == -1 && errno == EADDRINUSE)
322          /* retry once. */
323          val = bind(l->s, TOSA(&l->addr), len);
324 
325       if (changed_euid) {
326          if (seteuid(old_euid) == 0)
327             sockscf.state.euid = old_euid;
328       }
329 }
330 #else /* HAVE_PRIVILEGES */
331 
332       val = socks_bind(l->s, &l->addr, 1);
333 
334 #endif /* HAVE_PRIVILEGES */
335 
336       if (val != 0) {
337          swarn("%s: bind of address %s (address #%lu/%lu) for server to "
338                "listen on failed",
339                function,
340                sockaddr2string(&l->addr, NULL, 0),
341                (unsigned long)i + 1,
342                (unsigned long)sockscf.internal.addrc);
343 
344          return -1;
345       }
346 
347       val = 1;
348       if (setsockopt(l->s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) != 0)
349          swarn("%s: setsockopt(SO_REUSEADDR)", function);
350 
351       if (listen(l->s, SOCKD_MAXCLIENTQUEUE) == -1) {
352          swarn("%s: listen(%d) failed", function, SOCKD_MAXCLIENTQUEUE);
353          return -1;
354       }
355 
356       /*
357        * We want to accept(2) the client on a non-blocking descriptor.
358        */
359       if (setnonblocking(l->s, "accepting new clients") == -1)
360          return -1;
361    }
362 
363    return 0;
364 }
365 
366 void
setsockoptions(s,family,type,isclientside)367 setsockoptions(s, family, type, isclientside)
368    const int s;
369    const sa_family_t family;
370    const int type;
371    const int isclientside;
372 {
373    const char *function = "setsockoptions()";
374    socketoptions_t optionsv[MAXSOCKETOPTIONS];
375    size_t optc, i;
376 
377    slog(LOG_DEBUG, "%s: fd %d, type = %d, isclientside = %d",
378         function, s, type, isclientside);
379 
380    /*
381     * Our default builtin options.
382     */
383    optc = getoptions(family, type, isclientside, optionsv, ELEMENTS(optionsv));
384    slog(LOG_DEBUG, "%s: %lu options to set", function, (unsigned long)optc);
385 
386    for (i = 0; i < optc; ++i) {
387       int rc;
388 
389       SASSERTX(*optionsv[i].textname  != NUL);
390 
391       if (optionsv[i].wantprivileges)
392          sockd_priv(SOCKD_PRIV_PRIVILEGED, PRIV_ON);
393 
394       rc = setsockopt(s,
395                       optionsv[i].level,
396                       optionsv[i].optname,
397                       &optionsv[i].optval,
398                       optionsv[i].optlen);
399 
400       if (optionsv[i].wantprivileges)
401          sockd_priv(SOCKD_PRIV_PRIVILEGED, PRIV_OFF);
402 
403       if (rc != 0) {
404          if (optionsv[i].optname == SO_BROADCAST
405          &&  type                == SOCK_DGRAM
406          &&  errno               == EPROTO)
407             ; /* SO_BROADCAST is not always supported. */
408          else
409             swarn("%s: setsockopt(%s) to value %d on fd %d failed",
410                   function, optionsv[i].textname, optionsv[i].optval, s);
411       }
412    }
413 
414    (void)setnonblocking(s, function);
415 
416    if (sockscf.option.debug) {
417       socklen_t len;
418       int sndbuf, rcvbuf;
419 
420       len = sizeof(sndbuf);
421       if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len) != 0) {
422          swarn("%s: could not get the size of SO_SNDBUF for fd %d",
423                function, s);
424 
425          sndbuf = -1;
426       }
427 
428       len = sizeof(rcvbuf);
429       if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len) != 0) {
430          swarn("%s: could not get the size of SO_RCVBUF for fd %d",
431                function, s);
432 
433          rcvbuf = -1;
434       }
435 
436       slog(LOG_DEBUG,
437            "%s: buffer sizes for fd %d are: SO_SNDBUF: %d, SO_RCVBUF: %d",
438            function, s, sndbuf, rcvbuf);
439    }
440 
441 #if DIAGNOSTIC
442    checksockoptions(s, family, type, isclientside);
443 #endif /* DIAGNOSTIC */
444 }
445 
446 #if DIAGNOSTIC
447 void
checksockoptions(s,family,type,isclientside)448 checksockoptions(s, family, type, isclientside)
449    const int s;
450    const sa_family_t family;
451    const int type;
452    const int isclientside;
453 {
454    const char *function = "checksockoptions()";
455    socketoptions_t optionsv[MAXSOCKETOPTIONS];
456    size_t optc, i;
457    int val;
458 
459    slog(LOG_DEBUG, "%s: fd %d, type = %d, isclientside = %d",
460         function, s, type, isclientside);
461 
462    optc = getoptions(family, type, isclientside, optionsv, ELEMENTS(optionsv));
463    for (i = 0; i < optc; ++i) {
464       socklen_t vallen = sizeof(val);
465       int rc;
466 
467 #if HAVE_LINUX_BUGS
468 #if defined(SO_SNDBUFFORCE) || defined(SO_RCVBUFFORCE)
469       /*
470        * Crazy Linux ... one name to set it, another one to get it.
471        */
472       if (optionsv[i].optname == SO_SNDBUFFORCE)
473          optionsv[i].optname = SO_SNDBUF;
474       else if (optionsv[i].optname == SO_RCVBUFFORCE)
475          optionsv[i].optname = SO_RCVBUF;
476 #endif /* SO_SNDBUFFORCE || SO_RCVBUFFORCE */
477 #endif /* HAVE_LINUX_BUGS */
478 
479       rc = getsockopt(s,
480                       optionsv[i].level,
481                       optionsv[i].optname,
482                       &val,
483                       &vallen);
484 
485       if (rc != 0) {
486          if (type == SOCK_STREAM && errno == ECONNRESET)
487             continue; /* presumably failed while transferring the descriptor. */
488 
489          if (optionsv[i].optname == SO_BROADCAST
490          &&  type                == SOCK_DGRAM
491          &&  errno               == EPROTO)
492             continue; /* SO_BROADCAST is not always supported. */
493 
494          swarn("%s: could not get socket option %s on fd %d",
495                function, optionsv[i].textname, s);
496       }
497 
498       if (val != optionsv[i].optval) {
499          if ((optionsv[i].optval == 1) && val)
500             ; /* assume it's a boolean; true, but not necessarily 1. */
501          else if ((   optionsv[i].optname == SO_SNDBUF
502                    || optionsv[i].optname == SO_RCVBUF)) {
503             if (val < optionsv[i].optval)
504                slog(LOG_INFO,
505                     "%s: socketoption %s on fd %d should be %d, but is %d",
506                     function,
507                     optionsv[i].textname,
508                     s,
509                     optionsv[i].optval,
510                     val);
511          }
512          else
513             slog((type == SOCK_DGRAM && optionsv[i].optname == SO_BROADCAST) ?
514                  LOG_DEBUG : LOG_WARNING,
515                  "%s: socket option %s on fd %d should be %d, but is %d",
516                  function,
517                  optionsv[i].textname,
518                  s,
519                  optionsv[i].optval,
520                  val);
521       }
522    }
523 
524    if ((val = fcntl(s, F_GETFL, 0)) == -1)
525       swarn("%s: fcntl() failed to get descriptor flags of fd %d",
526             function, s);
527    else {
528       if (! (val & O_NONBLOCK))
529          swarn("%s: fd %d is blocking", function, s);
530    }
531 }
532 
533 #endif /* DIAGNOSTIC */
534 
535 static size_t
getoptions(family,type,isclientside,optionsv,optionsc)536 getoptions(family, type, isclientside, optionsv, optionsc)
537    const sa_family_t family;
538    const int type;
539    const int isclientside;
540    socketoptions_t *optionsv;
541    const size_t optionsc;
542 {
543    size_t optc;
544 
545    optc = 0;
546    switch (type) {
547       case SOCK_STREAM:
548          optionsv[optc].wantprivileges = 0;
549          optionsv[optc].level          = IPPROTO_TCP;
550          optionsv[optc].optname        = TCP_NODELAY;
551          optionsv[optc].optval         = 1;
552          optionsv[optc].optlen         = sizeof(optionsv[optc].optval);
553          STRCPY_ASSERTSIZE(optionsv[optc].textname, "TCP_NODELAY");
554          ++optc;
555          SASSERTX(optc <= optionsc);
556 
557          optionsv[optc].wantprivileges = 0;
558          optionsv[optc].level          = SOL_SOCKET;
559          optionsv[optc].optname        = SO_OOBINLINE;
560          optionsv[optc].optval         = 1;
561          optionsv[optc].optlen         = sizeof(optionsv[optc].optval);
562          STRCPY_ASSERTSIZE(optionsv[optc].textname, "SO_OOBINLINE");
563          ++optc;
564          SASSERTX(optc <= optionsc);
565 
566          if (sockscf.option.keepalive) {
567             optionsv[optc].wantprivileges = 0;
568             optionsv[optc].level          = SOL_SOCKET;
569             optionsv[optc].optname        = SO_KEEPALIVE;
570             optionsv[optc].optval         = 1;
571             optionsv[optc].optlen         = sizeof(optionsv[optc].optval);
572             STRCPY_ASSERTSIZE(optionsv[optc].textname, "SO_KEEPALIVE");
573             ++optc;
574             SASSERTX(optc <= optionsc);
575          }
576 
577          break;
578 
579       case SOCK_DGRAM:
580          optionsv[optc].wantprivileges = 0;
581          optionsv[optc].level          = SOL_SOCKET;
582          optionsv[optc].optname        = SO_BROADCAST;
583          optionsv[optc].optval         = 1;
584          optionsv[optc].optlen         = sizeof(optionsv[optc].optval);
585          STRCPY_ASSERTSIZE(optionsv[optc].textname, "SO_BROADCAST");
586          ++optc;
587          SASSERTX(optc <= optionsc);
588 
589 #if HAVE_SO_TIMESTAMP
590          optionsv[optc].wantprivileges = 0;
591          optionsv[optc].level          = SOL_SOCKET;
592          optionsv[optc].optname        = SO_TIMESTAMP;
593          optionsv[optc].optval         = 1;
594          optionsv[optc].optlen         = sizeof(optionsv[optc].optval);
595          STRCPY_ASSERTSIZE(optionsv[optc].textname, "SO_TIMESTAMP");
596          ++optc;
597          SASSERTX(optc <= optionsc);
598 #endif /* HAVE_SO_TIMESTAMP */
599 
600          break;
601 
602       default:
603          SERRX(type);
604    }
605 
606    SASSERTX(optc <= optionsc);
607    return optc;
608 }
609