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