1 /*
2  *   stunnel       TLS offloading and load-balancing proxy
3  *   Copyright (C) 1998-2021 Michal Trojnara <Michal.Trojnara@stunnel.org>
4  *
5  *   This program is free software; you can redistribute it and/or modify it
6  *   under the terms of the GNU General Public License as published by the
7  *   Free Software Foundation; either version 2 of the License, or (at your
8  *   option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  *   See the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License along
16  *   with this program; if not, see <http://www.gnu.org/licenses>.
17  *
18  *   Linking stunnel statically or dynamically with other modules is making
19  *   a combined work based on stunnel. Thus, the terms and conditions of
20  *   the GNU General Public License cover the whole combination.
21  *
22  *   In addition, as a special exception, the copyright holder of stunnel
23  *   gives you permission to combine stunnel with free software programs or
24  *   libraries that are released under the GNU LGPL and with code included
25  *   in the standard release of OpenSSL under the OpenSSL License (or
26  *   modified versions of such code, with unchanged license). You may copy
27  *   and distribute such a system following the terms of the GNU GPL for
28  *   stunnel and the licenses of the other code concerned.
29  *
30  *   Note that people who make modified versions of stunnel are not obligated
31  *   to grant this special exception for their modified versions; it is their
32  *   choice whether to do so. The GNU General Public License gives permission
33  *   to release a modified version without this exception; this exception
34  *   also makes it possible to release a modified version which carries
35  *   forward this exception.
36  */
37 
38 #include "common.h"
39 #include "prototypes.h"
40 
41 /* http://www.openssl.org/support/faq.html#PROG2 */
42 #ifdef USE_WIN32
43 
44 #ifdef __GNUC__
45 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
46 #pragma GCC diagnostic push
47 #endif /* __GNUC__>=4.6 */
48 #pragma GCC diagnostic ignored "-Wpedantic"
49 #endif /* __GNUC__ */
50 
51 #include <openssl/applink.c>
52 
53 #ifdef __GNUC__
54 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
55 #pragma GCC diagnostic pop
56 #endif /* __GNUC__>=4.6 */
57 #endif /* __GNUC__ */
58 
59 #endif /* USE_WIN32 */
60 
61 /**************************************** prototypes */
62 
63 #ifdef __INNOTEK_LIBC__
64 struct sockaddr_un {
65     u_char  sun_len;             /* sockaddr len including null */
66     u_char  sun_family;          /* AF_OS2 or AF_UNIX */
67     char    sun_path[108];       /* path name */
68 };
69 #endif
70 
71 #if !defined(USE_WIN32) && !defined(USE_OS2)
72 NOEXPORT void pid_status_nohang(const char *);
73 NOEXPORT void status_info(int, int, const char *);
74 #endif
75 NOEXPORT int accept_connection(SERVICE_OPTIONS *, unsigned);
76 NOEXPORT int exec_connect_start(void);
77 NOEXPORT void unbind_ports(void);
78 NOEXPORT void unbind_port(SERVICE_OPTIONS *, unsigned);
79 NOEXPORT int bind_ports(void);
80 NOEXPORT SOCKET bind_port(SERVICE_OPTIONS *, int, unsigned);
81 #ifdef HAVE_CHROOT
82 NOEXPORT int change_root(void);
83 #endif
84 NOEXPORT int pipe_init(SOCKET [2], char *);
85 NOEXPORT int signal_pipe_dispatch(void);
86 NOEXPORT void reload_config();
87 NOEXPORT int process_connections(void);
88 NOEXPORT char *signal_name(int);
89 
90 /**************************************** global variables */
91 
92 SOCKET signal_pipe[2]={INVALID_SOCKET, INVALID_SOCKET};
93 SOCKET terminate_pipe[2]={INVALID_SOCKET, INVALID_SOCKET};
94 
95 #ifndef USE_FORK
96 int max_clients=0;
97 /* -1 before a valid config is loaded, then the current number of clients */
98 int num_clients=-1;
99 #endif
100 s_poll_set *fds; /* file descriptors of listening sockets */
101 int systemd_fds; /* number of file descriptors passed by systemd */
102 int listen_fds_start; /* base for systemd-provided file descriptors */
103 
104 /**************************************** startup */
105 
main_init()106 void main_init() { /* one-time initialization */
107 #ifdef USE_SYSTEMD
108     int i;
109 
110     systemd_fds=sd_listen_fds(1);
111     if(systemd_fds<0)
112         fatal("systemd initialization failed");
113     listen_fds_start=SD_LISTEN_FDS_START;
114     /* set non-blocking mode on systemd file descriptors */
115     for(i=0; i<systemd_fds; ++i)
116         set_nonblock(listen_fds_start+i, 1);
117 #else
118     systemd_fds=0; /* no descriptors received */
119     listen_fds_start=3; /* the value is not really important */
120 #endif
121     /* basic initialization contains essential functions required for logging
122      * subsystem to function properly, thus all errors here are fatal */
123     if(ssl_init()) /* initialize TLS library */
124         fatal("TLS initialization failed");
125     if(sthreads_init()) /* initialize critical sections & TLS callbacks */
126         fatal("Threads initialization failed");
127     options_defaults(); /* initialize defaults */
128     options_apply(); /* apply the defaults */
129 #ifndef USE_FORK
130     get_limits(); /* required by setup_fd() */
131 #endif
132     fds=s_poll_alloc();
133     if(pipe_init(signal_pipe, "signal_pipe"))
134         fatal("Signal pipe initialization failed: "
135             "check your personal firewall");
136     if(pipe_init(terminate_pipe, "terminate_pipe"))
137         fatal("Terminate pipe initialization failed: "
138             "check your personal firewall");
139     stunnel_info(LOG_NOTICE);
140     if(systemd_fds>0)
141         s_log(LOG_INFO, "Systemd socket activation: %d descriptors received",
142             systemd_fds);
143 }
144 
145 /* return values:
146    0 - configuration accepted
147    1 - error
148    2 - information printed
149 */
150 
151     /* configuration-dependent initialization */
main_configure(char * arg1,char * arg2)152 int main_configure(char *arg1, char *arg2) {
153     int cmdline_status;
154 
155     log_flush(LOG_MODE_BUFFER);
156     cmdline_status=options_cmdline(arg1, arg2);
157     if(cmdline_status) { /* cannot proceed */
158         log_flush(LOG_MODE_ERROR);
159         return cmdline_status;
160     }
161     options_free(1); /* free the defaults */
162     options_apply(); /* apply the new options */
163     str_canary_init(); /* needs prng initialization from options_cmdline */
164     /* log_open(SINK_SYSLOG) must be called before change_root()
165      * to be able to access /dev/log socket */
166     log_open(SINK_SYSLOG);
167     if(bind_ports()) { /* initial binding failed - restoring the defaults */
168         unbind_ports(); /* unbind the successfully bound ports */
169         options_free(1); /* free the current options */
170         options_defaults(); /* initialize defaults */
171         options_apply(); /* apply the defaults */
172         log_flush(LOG_MODE_ERROR);
173         return 1;
174     }
175 
176 #ifdef HAVE_CHROOT
177     /* change_root() must be called before drop_privileges()
178      * since chroot() needs root privileges */
179     if(change_root()) {
180         log_flush(LOG_MODE_ERROR);
181         return 1;
182     }
183 #endif /* HAVE_CHROOT */
184 
185     if(drop_privileges(1)) {
186         log_flush(LOG_MODE_ERROR);
187         return 1;
188     }
189 
190     /* log_open(SINK_OUTFILE) must be called after drop_privileges()
191      * or logfile rotation won't be possible */
192     if(log_open(SINK_OUTFILE)) {
193         log_flush(LOG_MODE_ERROR);
194         return 1;
195     }
196 #ifndef USE_FORK
197     num_clients=0; /* the first valid config */
198 #endif
199     /* log_flush(LOG_MODE_CONFIGURED) must be called before daemonize()
200      * since daemonize() invalidates stderr */
201     log_flush(LOG_MODE_CONFIGURED);
202     return 0;
203 }
204 
drop_privileges(int critical)205 int drop_privileges(int critical) {
206 #if defined(USE_WIN32) || defined(__vms) || defined(USE_OS2)
207     (void)critical; /* squash the unused parameter warning */
208 #else
209 #ifdef HAVE_SETGROUPS
210     gid_t gr_list[1];
211 #endif
212 
213     /* set uid and gid */
214     if(service_options.gid) {
215         if(setgid(service_options.gid) && critical) {
216             sockerror("setgid");
217             return 1;
218         }
219 #ifdef HAVE_SETGROUPS
220         gr_list[0]=service_options.gid;
221         if(setgroups(1, gr_list) && critical) {
222             sockerror("setgroups");
223             return 1;
224         }
225 #endif
226     }
227     if(service_options.uid) {
228         if(setuid(service_options.uid) && critical) {
229             sockerror("setuid");
230             return 1;
231         }
232     }
233 #endif /* standard Unix */
234     return 0;
235 }
236 
237 #ifdef __GNUC__
238 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || defined(__clang__)
239 #pragma GCC diagnostic push
240 #pragma GCC diagnostic ignored "-Wunused-result"
241 #endif /* __GNUC__>=4.6 */
242 #endif /* __GNUC__ */
main_cleanup()243 void main_cleanup() {
244 #ifdef USE_OS_THREADS
245     CLI *c;
246     unsigned i, threads;
247     THREAD_ID *thread_list;
248 
249     CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_THREAD_LIST]);
250     threads=0;
251     for(c=thread_head; c; c=c->thread_next) /* count client threads */
252         threads++;
253     thread_list=str_alloc((threads+1)*sizeof(THREAD_ID));
254     i=0;
255     for(c=thread_head; c; c=c->thread_next) { /* copy client threads */
256         thread_list[i++]=c->thread_id;
257         s_log(LOG_DEBUG, "Terminating a thread for [%s]", c->opt->servname);
258     }
259     if(cron_thread_id) { /* append cron_thread_id if used */
260         thread_list[threads++]=cron_thread_id;
261         s_log(LOG_DEBUG, "Terminating the cron thread");
262     }
263     CRYPTO_THREAD_unlock(stunnel_locks[LOCK_THREAD_LIST]);
264 
265     if(threads) {
266         s_log(LOG_NOTICE, "Terminating %u service thread(s)", threads);
267         writesocket(terminate_pipe[1], "", 1);
268         for(i=0; i<threads; ++i) { /* join client threads */
269 #ifdef USE_PTHREAD
270             if(pthread_join(thread_list[i], NULL))
271                 s_log(LOG_ERR, "pthread_join() failed");
272 #endif
273 #ifdef USE_WIN32
274             if(WaitForSingleObject(thread_list[i], INFINITE)==WAIT_FAILED)
275                 ioerror("WaitForSingleObject");
276             if(!CloseHandle(thread_list[i]))
277                 ioerror("CloseHandle");
278 #endif
279         }
280         s_log(LOG_NOTICE, "Service threads terminated");
281     }
282 
283     str_free(thread_list);
284 #endif /* USE_OS_THREADS */
285 
286     unbind_ports();
287     s_poll_free(fds);
288     fds=NULL;
289 #if 0
290     str_stats(); /* main thread allocation tracking */
291 #endif
292     log_flush(LOG_MODE_BUFFER); /* no more logs */
293     log_close(SINK_SYSLOG|SINK_OUTFILE);
294 }
295 #ifdef __GNUC__
296 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
297 #pragma GCC diagnostic pop
298 #endif /* __GNUC__>=4.6 */
299 #endif /* __GNUC__ */
300 
301 /**************************************** Unix-specific initialization */
302 
303 #if !defined(USE_WIN32) && !defined(USE_OS2)
304 
pid_status_nohang(const char * info)305 NOEXPORT void pid_status_nohang(const char *info) {
306     int pid, status;
307 
308 #ifdef HAVE_WAITPID /* POSIX.1 */
309     s_log(LOG_DEBUG, "Retrieving pid statuses with waitpid()");
310     while((pid=waitpid(-1, &status, WNOHANG))>0)
311         status_info(pid, status, info);
312 #elif defined(HAVE_WAIT4) /* 4.3BSD */
313     s_log(LOG_DEBUG, "Retrieving pid statuses with wait4()");
314     while((pid=wait4(-1, &status, WNOHANG, NULL))>0)
315         status_info(pid, status, info);
316 #else /* no support for WNOHANG */
317     pid_status_hang(info);
318 #endif
319 }
320 
pid_status_hang(const char * info)321 void pid_status_hang(const char *info) {
322     int pid, status;
323 
324     s_log(LOG_DEBUG, "Retrieving a pid status with wait()");
325     if((pid=wait(&status))>0)
326         status_info(pid, status, info);
327 }
328 
status_info(int pid,int status,const char * info)329 NOEXPORT void status_info(int pid, int status, const char *info) {
330 #ifdef WIFSIGNALED
331     if(WIFSIGNALED(status)) {
332         char *sig_name=signal_name(WTERMSIG(status));
333         s_log(LOG_INFO, "%s %d terminated on %s", info, pid, sig_name);
334         str_free(sig_name);
335     } else {
336         s_log(LOG_INFO, "%s %d finished with code %d",
337             info, pid, WEXITSTATUS(status));
338     }
339 #else
340     s_log(LOG_INFO, "%s %d finished with status %d", info, pid, status);
341 #endif
342 }
343 
344 #endif /* !defined(USE_WIN32) && !defined(USE_OS2) */
345 
346 /**************************************** main loop accepting connections */
347 
daemon_loop(void)348 void daemon_loop(void) {
349     if(cron_init()) { /* initialize periodic events */
350         s_log(LOG_CRIT, "Cron initialization failed");
351         exit(1);
352     }
353     if(exec_connect_start()) {
354         s_log(LOG_CRIT, "Failed to start exec+connect services");
355         exit(1);
356     }
357     while(1) {
358         int temporary_lack_of_resources=0;
359         int num=s_poll_wait(fds, -1, -1);
360         if(num>=0) {
361             SERVICE_OPTIONS *opt;
362             s_log(LOG_DEBUG, "Found %d ready file descriptor(s)", num);
363             if(service_options.log_level>=LOG_DEBUG) /* performance optimization */
364                 s_poll_dump(fds, LOG_DEBUG);
365             if(s_poll_canread(fds, signal_pipe[0]))
366                 if(signal_pipe_dispatch()) /* SIGNAL_TERMINATE or error */
367                     break; /* terminate daemon_loop */
368             for(opt=service_options.next; opt; opt=opt->next) {
369                 unsigned i;
370                 for(i=0; i<opt->local_addr.num; ++i) {
371                     SOCKET fd=opt->local_fd[i];
372                     if(fd!=INVALID_SOCKET &&
373                             s_poll_canread(fds, fd) &&
374                             accept_connection(opt, i))
375                         temporary_lack_of_resources=1;
376                 }
377             }
378         } else {
379             log_error(LOG_NOTICE, get_last_socket_error(),
380                 "daemon_loop: s_poll_wait");
381             temporary_lack_of_resources=1;
382         }
383         if(temporary_lack_of_resources) {
384             s_log(LOG_NOTICE,
385                 "Accepting new connections suspended for 1 second");
386             s_poll_sleep(1, 0); /* to avoid log trashing */
387         }
388     }
389     leak_table_utilization();
390 }
391 
392     /* return 1 when a short delay is needed before another try */
accept_connection(SERVICE_OPTIONS * opt,unsigned i)393 NOEXPORT int accept_connection(SERVICE_OPTIONS *opt, unsigned i) {
394     SOCKADDR_UNION addr;
395     char *from_address;
396     SOCKET s, fd=opt->local_fd[i];
397     socklen_t addrlen;
398 
399     addrlen=sizeof addr;
400     for(;;) {
401         s=s_accept(fd, &addr.sa, &addrlen, 1, "local socket");
402         if(s!=INVALID_SOCKET) /* success! */
403             break;
404         switch(get_last_socket_error()) {
405             case S_EINTR: /* interrupted by a signal */
406                 break; /* retry now */
407             case S_EMFILE:
408 #ifdef S_ENFILE
409             case S_ENFILE:
410 #endif
411 #ifdef S_ENOBUFS
412             case S_ENOBUFS:
413 #endif
414 #ifdef S_ENOMEM
415             case S_ENOMEM:
416 #endif
417                 return 1; /* temporary lack of resources */
418             default:
419                 return 0; /* any other error */
420         }
421     }
422     from_address=s_ntop(&addr, addrlen);
423     s_log(LOG_DEBUG, "Service [%s] accepted (FD=%ld) from %s",
424         opt->servname, (long)s, from_address);
425     str_free(from_address);
426 #ifdef USE_FORK
427     RAND_add("", 1, 0.0); /* each child needs a unique entropy pool */
428 #else
429     if(max_clients && num_clients>=max_clients) {
430         s_log(LOG_WARNING, "Connection rejected: too many clients (>=%d)",
431             max_clients);
432         closesocket(s);
433         return 0;
434     }
435 #endif
436 #ifndef USE_FORK
437     service_up_ref(opt);
438 #endif
439     if(create_client(fd, s, alloc_client_session(opt, s, s))) {
440         s_log(LOG_ERR, "Connection rejected: create_client failed");
441         closesocket(s);
442 #ifndef USE_FORK
443         service_free(opt);
444 #endif
445         return 0;
446     }
447     return 0;
448 }
449 
450 /**************************************** initialization helpers */
451 
exec_connect_start(void)452 NOEXPORT int exec_connect_start(void) {
453     SERVICE_OPTIONS *opt;
454 
455     for(opt=service_options.next; opt; opt=opt->next) {
456         if(opt->exec_name && opt->connect_addr.names) {
457             s_log(LOG_DEBUG, "Starting exec+connect service [%s]",
458                 opt->servname);
459 #ifndef USE_FORK
460             service_up_ref(opt);
461 #endif
462             if(create_client(INVALID_SOCKET, INVALID_SOCKET,
463                     alloc_client_session(opt, INVALID_SOCKET, INVALID_SOCKET))) {
464                 s_log(LOG_ERR, "Failed to start exec+connect service [%s]",
465                     opt->servname);
466 #ifndef USE_FORK
467                 service_free(opt);
468 #endif
469                 return 1; /* fatal error */
470             }
471         }
472     }
473     return 0; /* OK */
474 }
475 
476 /* clear fds, close old ports */
unbind_ports(void)477 NOEXPORT void unbind_ports(void) {
478     SERVICE_OPTIONS *opt;
479 
480     s_poll_init(fds, 1);
481 
482     for(opt=service_options.next; opt; opt=opt->next) {
483         unsigned i;
484 
485         s_log(LOG_DEBUG, "Unbinding service [%s]", opt->servname);
486 
487         /* "accept" service */
488         for(i=0; i<opt->local_addr.num; ++i)
489             unbind_port(opt, i);
490 
491         /* "exec+connect" service */
492         if(opt->exec_name && opt->connect_addr.names) {
493             /* create exec+connect services             */
494             /* FIXME: this is just a crude workaround   */
495             /*        is it better to kill the service? */
496             /* FIXME: this won't work with FORK threads */
497             opt->option.retry=0;
498         }
499 
500         s_log(LOG_DEBUG, "Service [%s] closed", opt->servname);
501     }
502 }
503 
unbind_port(SERVICE_OPTIONS * opt,unsigned i)504 NOEXPORT void unbind_port(SERVICE_OPTIONS *opt, unsigned i) {
505     SOCKET fd=opt->local_fd[i];
506 #ifdef HAVE_STRUCT_SOCKADDR_UN
507     SOCKADDR_UNION *addr=opt->local_addr.addr+i;
508     struct stat sb; /* buffer for lstat() */
509 #endif
510 
511     if(fd==INVALID_SOCKET)
512         return;
513     opt->local_fd[i]=INVALID_SOCKET;
514 
515     if(fd<(SOCKET)listen_fds_start ||
516             fd>=(SOCKET)(listen_fds_start+systemd_fds))
517         closesocket(fd);
518     s_log(LOG_DEBUG, "Service [%s] closed (FD=%ld)",
519         opt->servname, (long)fd);
520 
521 #ifdef HAVE_STRUCT_SOCKADDR_UN
522     if(addr->sa.sa_family==AF_UNIX) {
523         if(lstat(addr->un.sun_path, &sb))
524             sockerror(addr->un.sun_path);
525         else if(!S_ISSOCK(sb.st_mode))
526             s_log(LOG_ERR, "Not a socket: %s",
527                 addr->un.sun_path);
528         else if(unlink(addr->un.sun_path))
529             sockerror(addr->un.sun_path);
530         else
531             s_log(LOG_DEBUG, "Socket removed: %s",
532                 addr->un.sun_path);
533     }
534 #endif
535 }
536 
537 /* open new ports, update fds */
bind_ports(void)538 NOEXPORT int bind_ports(void) {
539     SERVICE_OPTIONS *opt;
540     int listening_section;
541 
542 #ifdef USE_LIBWRAP
543     /* execute after options_cmdline() to know service_options.next,
544      * but as early as possible to avoid leaking file descriptors */
545     /* retry on each bind_ports() in case stunnel.conf was reloaded
546        without "libwrap = no" */
547     libwrap_init();
548 #endif /* USE_LIBWRAP */
549 
550     s_poll_init(fds, 1);
551 
552     /* allow clean unbind_ports() even though
553        bind_ports() was not fully performed */
554     for(opt=service_options.next; opt; opt=opt->next) {
555         unsigned i;
556         for(i=0; i<opt->local_addr.num; ++i)
557             opt->local_fd[i]=INVALID_SOCKET;
558     }
559 
560     listening_section=0;
561     for(opt=service_options.next; opt; opt=opt->next) {
562         opt->bound_ports=0;
563         if(opt->local_addr.num) { /* ports to bind for this service */
564             unsigned i;
565             s_log(LOG_DEBUG, "Binding service [%s]", opt->servname);
566             for(i=0; i<opt->local_addr.num; ++i) {
567                 SOCKET fd;
568                 fd=bind_port(opt, listening_section, i);
569                 opt->local_fd[i]=fd;
570                 if(fd!=INVALID_SOCKET) {
571                     s_poll_add(fds, fd, 1, 0);
572                     ++opt->bound_ports;
573                 }
574             }
575             if(!opt->bound_ports) {
576                 s_log(LOG_ERR, "Binding service [%s] failed", opt->servname);
577                 return 1;
578             }
579             ++listening_section;
580         } else if(opt->exec_name && opt->connect_addr.names) {
581             s_log(LOG_DEBUG, "Skipped exec+connect service [%s]", opt->servname);
582 #ifndef OPENSSL_NO_TLSEXT
583         } else if(!opt->option.client && opt->sni) {
584             s_log(LOG_DEBUG, "Skipped SNI slave service [%s]", opt->servname);
585 #endif
586         } else { /* each service must define two endpoints */
587             s_log(LOG_ERR, "Invalid service [%s]", opt->servname);
588             return 1;
589         }
590     }
591     if(listening_section<systemd_fds) {
592         s_log(LOG_ERR,
593             "Too many listening file descriptors received from systemd, got %d",
594             systemd_fds);
595         return 1;
596     }
597     return 0; /* OK */
598 }
599 
bind_port(SERVICE_OPTIONS * opt,int listening_section,unsigned i)600 NOEXPORT SOCKET bind_port(SERVICE_OPTIONS *opt, int listening_section, unsigned i) {
601     SOCKET fd;
602     SOCKADDR_UNION *addr=opt->local_addr.addr+i;
603 #ifdef HAVE_STRUCT_SOCKADDR_UN
604     struct stat sb; /* buffer for lstat() */
605 #endif
606 
607     if(listening_section<systemd_fds) {
608         fd=(SOCKET)(listen_fds_start+listening_section);
609         s_log(LOG_DEBUG,
610             "Listening file descriptor received from systemd (FD=%ld)",
611             (long)fd);
612     } else {
613         fd=s_socket(addr->sa.sa_family, SOCK_STREAM, 0, 1, "accept socket");
614         if(fd==INVALID_SOCKET)
615             return INVALID_SOCKET;
616         s_log(LOG_DEBUG, "Listening file descriptor created (FD=%ld)",
617             (long)fd);
618     }
619 
620     if(socket_options_set(opt, fd, 0)<0) {
621         closesocket(fd);
622         return INVALID_SOCKET;
623     }
624 
625     /* we don't bind or listen on a socket inherited from systemd */
626     if(listening_section>=systemd_fds) {
627         if(bind(fd, &addr->sa, addr_len(addr))) {
628             int err=get_last_socket_error();
629             char *requested_bind_address;
630 
631             /* local socket can't be unnamed */
632             requested_bind_address=s_ntop(addr, addr_len(addr));
633             s_log(LOG_NOTICE, "Binding service [%s] to %s: %s (%d)",
634                 opt->servname, requested_bind_address, s_strerror(err), err);
635             str_free(requested_bind_address);
636             closesocket(fd);
637             return INVALID_SOCKET;
638         }
639         if(listen(fd, SOMAXCONN)) {
640             sockerror("listen");
641             closesocket(fd);
642             return INVALID_SOCKET;
643         }
644     }
645 
646 #ifdef HAVE_STRUCT_SOCKADDR_UN
647     /* chown the UNIX socket, errors are ignored */
648     if(addr->sa.sa_family==AF_UNIX &&
649             (opt->uid || opt->gid)) {
650         /* fchown() does *not* work on UNIX sockets */
651         if(!lchown(addr->un.sun_path, opt->uid, opt->gid))
652             s_log(LOG_DEBUG,
653                 "Socket chown succeeded: %s, UID=%u, GID=%u",
654                 addr->un.sun_path,
655                 (unsigned)opt->uid, (unsigned)opt->gid);
656         else if(lstat(addr->un.sun_path, &sb))
657             sockerror(addr->un.sun_path);
658         else if(sb.st_uid==opt->uid && sb.st_gid==opt->gid)
659             s_log(LOG_DEBUG,
660                 "Socket chown unneeded: %s, UID=%u, GID=%u",
661                 addr->un.sun_path,
662                 (unsigned)opt->uid, (unsigned)opt->gid);
663         else
664             s_log(LOG_ERR, "Socket chown failed: %s, UID=%u, GID=%u",
665                 addr->un.sun_path,
666                 (unsigned)opt->uid, (unsigned)opt->gid);
667     }
668 #endif
669 
670     {
671         SOCKADDR_UNION assigned_addr;
672         socklen_t assigned_addr_len=sizeof assigned_addr;
673         char *assigned_bind_address;
674 
675         if(getsockname(fd, &assigned_addr.sa, &assigned_addr_len)) {
676             sockerror("getsockname");
677             closesocket(fd);
678             return INVALID_SOCKET;
679         }
680         assigned_bind_address=s_ntop(&assigned_addr, addr_len(&assigned_addr));
681         s_log(LOG_INFO, "Service [%s] (FD=%ld) bound to %s",
682             opt->servname, (long)fd, assigned_bind_address);
683         str_free(assigned_bind_address);
684     }
685     return fd;
686 }
687 
688 #ifdef HAVE_CHROOT
change_root(void)689 NOEXPORT int change_root(void) {
690     if(!global_options.chroot_dir)
691         return 0;
692     if(chroot(global_options.chroot_dir)) {
693         sockerror("chroot");
694         return 1;
695     }
696     if(chdir("/")) {
697         sockerror("chdir");
698         return 1;
699     }
700     s_log(LOG_NOTICE, "Switched to chroot directory: %s", global_options.chroot_dir);
701     return 0;
702 }
703 #endif /* HAVE_CHROOT */
704 
705 /**************************************** signal pipe handling */
706 
pipe_init(SOCKET socket_vector[2],char * name)707 NOEXPORT int pipe_init(SOCKET socket_vector[2], char *name) {
708 #ifdef USE_WIN32
709     (void)name; /* squash the unused parameter warning */
710 
711     if(make_sockets(socket_vector))
712         return 1;
713 #elif defined(__INNOTEK_LIBC__)
714     /* Innotek port of GCC can not use select on a pipe:
715      * use local socket instead */
716     struct sockaddr_un un;
717     fd_set set_pipe;
718     int pipe_in;
719 
720     FD_ZERO(&set_pipe);
721     socket_vector[0]=s_socket(PF_OS2, SOCK_STREAM, 0, 0, "socket#1");
722     socket_vector[1]=s_socket(PF_OS2, SOCK_STREAM, 0, 0, "socket#2");
723 
724     /* connect the two endpoints */
725     memset(&un, 0, sizeof un);
726     un.sun_len=sizeof un;
727     un.sun_family=AF_OS2;
728     sprintf(un.sun_path, "\\socket\\stunnel-%s-%u", name, getpid());
729     /* make the first endpoint listen */
730     bind(socket_vector[0], (struct sockaddr *)&un, sizeof un);
731     listen(socket_vector[0], 1);
732     connect(socket_vector[1], (struct sockaddr *)&un, sizeof un);
733     FD_SET(socket_vector[0], &set_pipe);
734     if(select(socket_vector[0]+1, &set_pipe, NULL, NULL, NULL)>0) {
735         pipe_in=socket_vector[0];
736         socket_vector[0]=s_accept(socket_vector[0], NULL, 0, 0, "accept");
737         closesocket(pipe_in);
738     } else {
739         sockerror("select");
740         return 1;
741     }
742 #else /* Unix */
743     if(s_pipe(socket_vector, 1, name))
744         return 1;
745 #endif /* USE_WIN32 */
746     return 0;
747 }
748 
749 #ifdef __GNUC__
750 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || defined(__clang__)
751 #pragma GCC diagnostic push
752 #pragma GCC diagnostic ignored "-Wunused-result"
753 #endif /* __GNUC__>=4.6 */
754 #endif /* __GNUC__ */
signal_post(uint8_t sig)755 void signal_post(uint8_t sig) {
756     /* no meaningful way here to handle the result */
757     writesocket(signal_pipe[1], (char *)&sig, 1);
758 }
759 #ifdef __GNUC__
760 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
761 #pragma GCC diagnostic pop
762 #endif /* __GNUC__>=4.6 */
763 #endif /* __GNUC__ */
764 
765 /* make a single attempt to dispatch a signal from the signal pipe */
766 /* return 1 on SIGNAL_TERMINATE or a fatal error, 0 otherwise */
signal_pipe_dispatch(void)767 NOEXPORT int signal_pipe_dispatch(void) {
768     uint8_t sig=0xff;
769     ssize_t num;
770     char *sig_name;
771 
772     s_log(LOG_DEBUG, "Dispatching a signal from the signal pipe");
773     num=readsocket(signal_pipe[0], (char *)&sig, 1);
774     if(num!=1) {
775         if(num) {
776             if(get_last_socket_error()==S_EWOULDBLOCK) {
777                 s_log(LOG_DEBUG, "Signal pipe is empty");
778                 return 0;
779             }
780             sockerror("signal pipe read");
781         } else {
782             s_log(LOG_ERR, "Signal pipe closed");
783         }
784         s_poll_remove(fds, signal_pipe[0]);
785         closesocket(signal_pipe[0]);
786         closesocket(signal_pipe[1]);
787         if(pipe_init(signal_pipe, "signal_pipe")) {
788             s_log(LOG_ERR,
789                 "Signal pipe reinitialization failed; terminating");
790             return 1;
791         }
792         s_poll_add(fds, signal_pipe[0], 1, 0);
793         s_log(LOG_ERR, "Signal pipe reinitialized");
794         return 0;
795     }
796 
797     switch(sig) {
798 #ifndef USE_WIN32
799     case SIGCHLD:
800         s_log(LOG_DEBUG, "Processing SIGCHLD");
801 #ifdef USE_FORK
802         pid_status_nohang("Process"); /* client process */
803 #else /* USE_UCONTEXT || USE_PTHREAD */
804         pid_status_nohang("Child process"); /* 'exec' process */
805 #endif /* defined USE_FORK */
806         return 0;
807 #endif /* !defind USE_WIN32 */
808     case SIGNAL_TERMINATE:
809         s_log(LOG_DEBUG, "Processing SIGNAL_TERMINATE");
810         s_log(LOG_NOTICE, "Terminated");
811         return 1;
812     case SIGNAL_RELOAD_CONFIG:
813         s_log(LOG_DEBUG, "Processing SIGNAL_RELOAD_CONFIG");
814         reload_config();
815         return 0;
816     case SIGNAL_REOPEN_LOG:
817         s_log(LOG_DEBUG, "Processing SIGNAL_REOPEN_LOG");
818         log_flush(LOG_MODE_BUFFER);
819         log_close(SINK_OUTFILE);
820         log_open(SINK_OUTFILE);
821         log_flush(LOG_MODE_CONFIGURED);
822         s_log(LOG_NOTICE, "Log file reopened");
823         return 0;
824     case SIGNAL_CONNECTIONS:
825         return process_connections();
826     default:
827         sig_name=signal_name(sig);
828         s_log(LOG_ERR, "Received %s; terminating", sig_name);
829         str_free(sig_name);
830         return 1;
831     }
832 }
833 
reload_config()834 NOEXPORT void reload_config() {
835     static int delay=10; /* default of 10ms */
836 #ifdef HAVE_CHROOT
837     struct stat sb;
838 #endif /* HAVE_CHROOT */
839 
840     if(options_parse(CONF_RELOAD)) {
841         s_log(LOG_ERR, "Failed to reload the configuration file");
842         return;
843     }
844     unbind_ports();
845     log_flush(LOG_MODE_BUFFER);
846 #ifdef HAVE_CHROOT
847     /* we don't close SINK_SYSLOG if chroot is enabled and
848      * there is no /dev/log inside it, which could allow
849      * openlog(3) to reopen the syslog socket later */
850     if(global_options.chroot_dir && stat("/dev/log", &sb))
851         log_close(SINK_OUTFILE);
852     else
853 #endif /* HAVE_CHROOT */
854         log_close(SINK_SYSLOG|SINK_OUTFILE);
855     /* there is no race condition here:
856      * client threads are not allowed to use global options */
857     options_free(1); /* free the current options */
858     options_apply(); /* apply the new options */
859     /* we hope that a sane openlog(3) implementation won't
860      * attempt to reopen /dev/log if it's already open */
861     log_open(SINK_SYSLOG|SINK_OUTFILE);
862     log_flush(LOG_MODE_CONFIGURED);
863     ui_config_reloaded();
864     /* we use "|" instead of "||" to attempt initialization of both subsystems */
865     if(bind_ports() | exec_connect_start()) { /* failed */
866         unbind_ports();
867         s_poll_sleep(delay/1000, delay%1000); /* sleep to avoid log trashing */
868         signal_post(SIGNAL_RELOAD_CONFIG); /* retry */
869         delay*=2;
870         if(delay > 10000) /* limit to 10s */
871             delay=10000;
872     } else { /* success */
873         delay=10; /* reset back to 10ms */
874     }
875 }
876 
877 #ifdef __GNUC__
878 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
879 #pragma GCC diagnostic push
880 #endif /* __GNUC__>=4.6 */
881 #pragma GCC diagnostic ignored "-Wformat"
882 #pragma GCC diagnostic ignored "-Wformat-extra-args"
883 #endif /* __GNUC__ */
process_connections()884 NOEXPORT int process_connections() {
885 #ifndef USE_FORK
886     CLI *c;
887 
888     s_log(LOG_NOTICE, "Active connections:");
889     CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_THREAD_LIST]);
890     for(c=thread_head; c; c=c->thread_next) {
891         s_log(LOG_NOTICE, "Service [%s]: "
892             "%llu byte(s) sent to TLS, "
893             "%llu byte(s) sent to socket",
894             c->opt->servname,
895             (unsigned long long)c->ssl_bytes,
896             (unsigned long long)c->sock_bytes);
897     }
898     CRYPTO_THREAD_unlock(stunnel_locks[LOCK_THREAD_LIST]);
899 #endif /* USE_FORK */
900     return 0; /* continue execution */
901 }
902 #ifdef __GNUC__
903 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
904 #pragma GCC diagnostic pop
905 #endif /* __GNUC__>=4.6 */
906 #endif /* __GNUC__ */
907 
908 /**************************************** signal name decoding */
909 
910 #define check_signal(s) if(signum==s) return str_dup(#s);
911 
signal_name(int signum)912 NOEXPORT char *signal_name(int signum) {
913 #ifdef SIGHUP
914     check_signal(SIGHUP)
915 #endif
916 #ifdef SIGINT
917     check_signal(SIGINT)
918 #endif
919 #ifdef SIGQUIT
920     check_signal(SIGQUIT)
921 #endif
922 #ifdef SIGILL
923     check_signal(SIGILL)
924 #endif
925 #ifdef SIGTRAP
926     check_signal(SIGTRAP)
927 #endif
928 #ifdef SIGABRT
929     check_signal(SIGABRT)
930 #endif
931 #ifdef SIGIOT
932     check_signal(SIGIOT)
933 #endif
934 #ifdef SIGBUS
935     check_signal(SIGBUS)
936 #endif
937 #ifdef SIGFPE
938     check_signal(SIGFPE)
939 #endif
940 #ifdef SIGKILL
941     check_signal(SIGKILL)
942 #endif
943 #ifdef SIGUSR1
944     check_signal(SIGUSR1)
945 #endif
946 #ifdef SIGSEGV
947     check_signal(SIGSEGV)
948 #endif
949 #ifdef SIGUSR2
950     check_signal(SIGUSR2)
951 #endif
952 #ifdef SIGPIPE
953     check_signal(SIGPIPE)
954 #endif
955 #ifdef SIGALRM
956     check_signal(SIGALRM)
957 #endif
958 #ifdef SIGTERM
959     check_signal(SIGTERM)
960 #endif
961 #ifdef SIGSTKFLT
962     check_signal(SIGSTKFLT)
963 #endif
964 #ifdef SIGCHLD
965     check_signal(SIGCHLD)
966 #endif
967 #ifdef SIGCONT
968     check_signal(SIGCONT)
969 #endif
970 #ifdef SIGSTOP
971     check_signal(SIGSTOP)
972 #endif
973 #ifdef SIGTSTP
974     check_signal(SIGTSTP)
975 #endif
976 #ifdef SIGTTIN
977     check_signal(SIGTTIN)
978 #endif
979 #ifdef SIGTTOU
980     check_signal(SIGTTOU)
981 #endif
982 #ifdef SIGURG
983     check_signal(SIGURG)
984 #endif
985 #ifdef SIGXCPU
986     check_signal(SIGXCPU)
987 #endif
988 #ifdef SIGXFSZ
989     check_signal(SIGXFSZ)
990 #endif
991 #ifdef SIGVTALRM
992     check_signal(SIGVTALRM)
993 #endif
994 #ifdef SIGPROF
995     check_signal(SIGPROF)
996 #endif
997 #ifdef SIGWINCH
998     check_signal(SIGWINCH)
999 #endif
1000 #ifdef SIGIO
1001     check_signal(SIGIO)
1002 #endif
1003 #ifdef SIGPOLL
1004     check_signal(SIGPOLL)
1005 #endif
1006 #ifdef SIGLOST
1007     check_signal(SIGLOST)
1008 #endif
1009 #ifdef SIGPWR
1010     check_signal(SIGPWR)
1011 #endif
1012 #ifdef SIGSYS
1013     check_signal(SIGSYS)
1014 #endif
1015 #ifdef SIGUNUSED
1016     check_signal(SIGUNUSED)
1017 #endif
1018     return str_printf("signal %d", signum);
1019 }
1020 
1021 /**************************************** log build details */
1022 
str_cat(char * dst,const char * src)1023 static char *str_cat(char *dst, const char *src) {
1024     dst=str_realloc(dst, strlen(dst) + strlen(src) + 1);
1025     strcat(dst, src);
1026     return dst;
1027 }
1028 
stunnel_info(int level)1029 void stunnel_info(int level) {
1030     int tls_feature_found=0;
1031     char *features;
1032 
1033     s_log(level, "stunnel " STUNNEL_VERSION " on " HOST " platform");
1034     if(strcmp(OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION))) {
1035         s_log(level, "Compiled with " OPENSSL_VERSION_TEXT);
1036         s_log(level, "Running  with %s", OpenSSL_version(OPENSSL_VERSION));
1037 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1038         if((OPENSSL_version_major()<<8 | OPENSSL_version_minor()) !=
1039                 OPENSSL_VERSION_NUMBER>>20)
1040 #else /* OpenSSL version < 3.0.0 */
1041         if(OpenSSL_version_num()>>12 != OPENSSL_VERSION_NUMBER>>12)
1042 #endif /* OpenSSL version >= 3.0.0 */
1043             s_log(level, "Update OpenSSL shared libraries or rebuild stunnel");
1044     } else {
1045         s_log(level, "Compiled/running with " OPENSSL_VERSION_TEXT);
1046     }
1047 
1048     features=str_dup("Threading:");
1049 #ifdef USE_UCONTEXT
1050     features=str_cat(features, "UCONTEXT");
1051 #endif
1052 #ifdef USE_PTHREAD
1053     features=str_cat(features, "PTHREAD");
1054 #endif
1055 #ifdef USE_WIN32
1056     features=str_cat(features, "WIN32");
1057 #endif
1058 #ifdef USE_FORK
1059     features=str_cat(features, "FORK");
1060 #endif
1061 
1062     features=str_cat(features, " Sockets:");
1063 #ifdef USE_POLL
1064     features=str_cat(features, "POLL");
1065 #else /* defined(USE_POLL) */
1066     features=str_cat(features, "SELECT");
1067 #endif /* defined(USE_POLL) */
1068     /* supported IP version parameter */
1069     features=str_cat(features, ",IPv");
1070 #if defined(USE_WIN32) && !defined(_WIN32_WCE)
1071     features=str_cat(features, s_getaddrinfo ? "6" : "4");
1072 #else /* defined(USE_WIN32) */
1073 #if defined(USE_IPv6)
1074     features=str_cat(features, "6");
1075 #else /* defined(USE_IPv6) */
1076     features=str_cat(features, "4");
1077 #endif /* defined(USE_IPv6) */
1078 #endif /* defined(USE_WIN32) */
1079 #ifdef USE_SYSTEMD
1080     features=str_cat(features, ",SYSTEMD");
1081 #endif /* defined(USE_SYSTEMD) */
1082 
1083     features=str_cat(features, " TLS:");
1084 #ifndef OPENSSL_NO_ENGINE
1085     features=str_cat(features, "ENGINE");
1086     tls_feature_found=1;
1087 #endif /* !defined(OPENSSL_NO_ENGINE) */
1088     if(fips_available()) {
1089         if(tls_feature_found)
1090             features=str_cat(features, ",");
1091         features=str_cat(features, "FIPS");
1092         tls_feature_found=1;
1093     }
1094 #ifndef OPENSSL_NO_OCSP
1095     if(tls_feature_found)
1096         features=str_cat(features, ",");
1097     features=str_cat(features, "OCSP");
1098     tls_feature_found=1;
1099 #endif /* !defined(OPENSSL_NO_OCSP) */
1100 #ifndef OPENSSL_NO_PSK
1101     if(tls_feature_found)
1102         features=str_cat(features, ",");
1103     features=str_cat(features, "PSK");
1104     tls_feature_found=1;
1105 #endif /* !defined(OPENSSL_NO_PSK) */
1106 #ifndef OPENSSL_NO_TLSEXT
1107     if(tls_feature_found)
1108         features=str_cat(features, ",");
1109     features=str_cat(features, "SNI");
1110     tls_feature_found=1;
1111 #endif /* !defined(OPENSSL_NO_TLSEXT) */
1112     if(!tls_feature_found)
1113         features=str_cat(features, "NONE");
1114 
1115 #ifdef USE_LIBWRAP
1116     features=str_cat(features, " Auth:LIBWRAP");
1117 #endif
1118 
1119     s_log(level, "%s", features);
1120     str_free(features);
1121 
1122 #ifdef errno
1123 #define xstr(a) str(a)
1124 #define str(a) #a
1125     s_log(LOG_DEBUG, "errno: " xstr(errno));
1126 #endif /* errno */
1127 }
1128 
1129 /* end of stunnel.c */
1130