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 #ifndef PROTOTYPES_H
39 #define PROTOTYPES_H
40 
41 #include "common.h"
42 
43 #if defined(USE_PTHREAD) || defined(USE_WIN32)
44 #define USE_OS_THREADS
45 #endif
46 
47 /**************************************** forward declarations */
48 
49 typedef struct tls_data_struct TLS_DATA;
50 typedef struct sock_opt_struct SOCK_OPT;
51 
52 /**************************************** data structures */
53 
54 #ifdef USE_PTHREAD
55     typedef pthread_t THREAD_ID;
56 #endif
57 #ifdef USE_WIN32
58     typedef HANDLE THREAD_ID;
59 #endif
60 
61 #if defined (USE_WIN32)
62 #define ICON_IMAGE HICON
63 #elif defined(__APPLE__)
64 #define ICON_IMAGE void *
65 #endif
66 
67 typedef enum {
68     ICON_ERROR,
69     ICON_IDLE,
70     ICON_ACTIVE,
71     ICON_NONE /* it has to be the last one */
72 } ICON_TYPE;
73 
74 typedef enum {
75     LOG_MODE_BUFFER,
76     LOG_MODE_ERROR,
77     LOG_MODE_INFO,
78     LOG_MODE_CONFIGURED
79 } LOG_MODE;
80 
81 typedef enum {
82     LOG_ID_SEQUENTIAL,
83     LOG_ID_UNIQUE,
84     LOG_ID_THREAD,
85     LOG_ID_PROCESS
86 } LOG_ID;
87 
88 typedef enum {
89     FILE_MODE_READ,
90     FILE_MODE_APPEND,
91     FILE_MODE_OVERWRITE
92 } FILE_MODE;
93 
94 typedef union sockaddr_union {
95     struct sockaddr sa;
96     struct sockaddr_in in;
97 #ifdef USE_IPv6
98     struct sockaddr_in6 in6;
99 #endif
100 #ifdef HAVE_STRUCT_SOCKADDR_UN
101     struct sockaddr_un un;
102 #endif
103 } SOCKADDR_UNION;
104 
105 typedef struct name_list_struct {
106     char *name;
107     struct name_list_struct *next;
108 } NAME_LIST;
109 
110 typedef struct sockaddr_list {                          /* list of addresses */
111     struct sockaddr_list *parent;   /* used by copies to locate their parent */
112     SOCKADDR_UNION *addr;                     /* array of resolved addresses */
113     unsigned start;              /* initial address for round-robin failover */
114     unsigned num;                             /* how many addresses are used */
115     int passive;                                         /* listening socket */
116     NAME_LIST *names;                          /* a list of unresolved names */
117 } SOCKADDR_LIST;
118 
119 #ifndef OPENSSL_NO_COMP
120 typedef enum {
121     COMP_NONE,                           /* empty compression algorithms set */
122     COMP_DEFLATE,            /* default OpenSSL's compression algorithms set */
123     COMP_ZLIB,          /* additional historic ZLIB compression algorithm id */
124     STUNNEL_COMPS                   /* number of compression algorithms sets */
125 } COMP_TYPE;
126 #endif /* !defined(OPENSSL_NO_COMP) */
127 
128 typedef struct {
129         /* some data for TLS initialization in ssl.c */
130 #ifndef OPENSSL_NO_COMP
131     COMP_TYPE compression;                               /* compression type */
132 #endif /* !defined(OPENSSL_NO_COMP) */
133     char *egd_sock;                       /* entropy gathering daemon socket */
134     char *rand_file;                                /* file with random data */
135     long random_bytes;                      /* how many random bytes to read */
136 
137         /* some global data for stunnel.c */
138 #ifndef USE_WIN32
139 #ifdef HAVE_CHROOT
140     char *chroot_dir;
141 #endif
142     char *pidfile;
143 #endif
144 
145         /* logging-support data for log.c */
146 #ifndef USE_WIN32
147     int log_facility;                           /* debug facility for syslog */
148 #endif
149     char *output_file;
150     FILE_MODE log_file_mode;
151 
152         /* user interface configuration */
153 #ifdef ICON_IMAGE
154     ICON_IMAGE icon[ICON_NONE];                  /* user-specified GUI icons */
155 #endif
156 
157         /* on/off switches */
158     struct {
159         unsigned rand_write:1;                        /* overwrite rand_file */
160 #ifdef USE_WIN32
161         unsigned taskbar:1;                       /* enable the taskbar icon */
162 #else /* !USE_WIN32 */
163         unsigned foreground:1;
164         unsigned log_stderr:1;
165         unsigned log_syslog:1;
166 #endif
167 #ifdef USE_FIPS
168         unsigned fips:1;                           /* enable FIPS 140-2 mode */
169 #endif
170     } option;
171 } GLOBAL_OPTIONS;
172 
173 extern GLOBAL_OPTIONS global_options;
174 
175 #ifndef OPENSSL_NO_TLSEXT
176 typedef struct servername_list_struct SERVERNAME_LIST;/* forward declaration */
177 #endif /* !defined(OPENSSL_NO_TLSEXT) */
178 
179 #ifndef OPENSSL_NO_PSK
180 typedef struct psk_keys_struct {
181     char *identity;
182     unsigned char *key_val;
183     unsigned key_len;
184     struct psk_keys_struct *next;
185 } PSK_KEYS;
186 typedef struct psk_table_struct {
187     PSK_KEYS **val;
188     size_t num;
189 } PSK_TABLE;
190 #endif /* !defined(OPENSSL_NO_PSK) */
191 
192 #if OPENSSL_VERSION_NUMBER>=0x10000000L
193 typedef struct ticket_key_struct {
194     unsigned char *key_val;
195     int key_len;
196 } TICKET_KEY;
197 #endif /* OpenSSL 1.0.0 or later */
198 
199 typedef struct service_options_struct {
200     struct service_options_struct *next;   /* next node in the services list */
201     SSL_CTX *ctx;                                            /*  TLS context */
202     char *servname;        /* service name for logging & permission checking */
203     int ref;                   /* reference counter for delayed deallocation */
204 
205         /* service-specific data for stunnel.c */
206 #ifndef USE_WIN32
207     uid_t uid;
208     gid_t gid;
209 #endif
210     int bound_ports;                /* number of ports bound to this service */
211 
212         /* service-specific data for log.c */
213     int log_level;                                /* debug level for logging */
214     LOG_ID log_id;                                /* logging session id type */
215 
216         /* service-specific data for sthreads.c */
217 #ifndef USE_FORK
218     size_t stack_size;                         /* stack size for this thread */
219 #endif
220 
221         /* some global data for network.c */
222     SOCK_OPT *sock_opts;
223 
224         /* service-specific data for verify.c */
225     char *ca_dir;                              /* directory for hashed certs */
226     char *ca_file;                       /* file containing bunches of certs */
227     char *crl_dir;                              /* directory for hashed CRLs */
228     char *crl_file;                       /* file containing bunches of CRLs */
229 #ifndef OPENSSL_NO_OCSP
230     char *ocsp_url;
231     unsigned long ocsp_flags;
232 #endif /* !defined(OPENSSL_NO_OCSP) */
233 #if OPENSSL_VERSION_NUMBER>=0x10002000L
234     NAME_LIST *check_host, *check_email, *check_ip;   /* cert subject checks */
235     NAME_LIST *config;                               /* OpenSSL CONF options */
236 #endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */
237 
238         /* service-specific data for ctx.c */
239     char *cipher_list;
240 #ifndef OPENSSL_NO_TLS1_3
241     char *ciphersuites;
242 #endif /* TLS 1.3 */
243     char *cert;                                             /* cert filename */
244     char *key;                               /* pem (priv key/cert) filename */
245     long session_size, session_timeout;
246 #if OPENSSL_VERSION_NUMBER>=0x10100000L
247     int security_level;
248 #endif /* OpenSSL 1.1.0 or later */
249     long unsigned ssl_options_set;
250 #if OPENSSL_VERSION_NUMBER>=0x009080dfL
251     long unsigned ssl_options_clear;
252 #endif /* OpenSSL 0.9.8m or later */
253 #if OPENSSL_VERSION_NUMBER>=0x10100000L
254     int min_proto_version, max_proto_version;
255 #else /* OPENSSL_VERSION_NUMBER<0x10100000L */
256     SSL_METHOD *client_method, *server_method;
257 #endif /* OPENSSL_VERSION_NUMBER<0x10100000L */
258     SOCKADDR_UNION sessiond_addr;
259 #ifndef OPENSSL_NO_TLSEXT
260     char *sni;
261     SERVERNAME_LIST *servername_list_head, *servername_list_tail;
262 #endif /* !defined(OPENSSL_NO_TLSEXT) */
263 #ifndef OPENSSL_NO_PSK
264     char *psk_identity;
265     PSK_KEYS *psk_keys, *psk_selected;
266     PSK_TABLE psk_sorted;
267 #endif /* !defined(OPENSSL_NO_PSK) */
268 #ifndef OPENSSL_NO_ECDH
269     char *curves;
270 #endif /* !defined(OPENSSL_NO_ECDH) */
271 #ifndef OPENSSL_NO_ENGINE
272     ENGINE *engine;                        /* engine to read the private key */
273 #endif /* !defined(OPENSSL_NO_ENGINE) */
274 #if OPENSSL_VERSION_NUMBER>=0x10000000L
275     TICKET_KEY *ticket_key;              /* key for handling session tickets */
276     TICKET_KEY *ticket_mac;            /* key for protecting session tickets */
277 #endif /* OpenSSL 1.0.0 or later */
278 
279         /* service-specific data for client.c */
280     char *exec_name;                          /* program name for local mode */
281 #ifdef USE_WIN32
282     char *exec_args;                     /* program arguments for local mode */
283 #else
284     char **exec_args;                    /* program arguments for local mode */
285 #endif
286     SOCKADDR_UNION source_addr;
287     SOCKADDR_LIST local_addr, connect_addr, redirect_addr;
288     SOCKET *local_fd;                 /* array of accepting file descriptors */
289     SSL_SESSION **connect_session;   /* per-destination client session cache */
290     SSL_SESSION *session;    /* previous client session for delayed resolver */
291     int timeout_busy;                       /* maximum waiting for data time */
292     int timeout_close;                          /* maximum close_notify time */
293     int timeout_connect;                           /* maximum connect() time */
294     int timeout_idle;                        /* maximum idle connection time */
295     enum {FAILOVER_RR, FAILOVER_PRIO} failover;         /* failover strategy */
296     unsigned rr;   /* per-service sequential number for round-robin failover */
297     char *username;
298 
299         /* service-specific data for protocol.c */
300     char *protocol;
301     NAME_LIST *protocol_header;
302     char *protocol_host;
303     char *protocol_domain;
304     char *protocol_username;
305     char *protocol_password;
306     char *protocol_authentication;
307 
308         /* service-specific data for ui_*.c */
309 #ifdef USE_WIN32
310     LPTSTR file, help;
311 #endif
312     unsigned section_number;
313     char *chain;
314 
315         /* on/off switches */
316     struct {
317         unsigned request_cert:1;        /* request a peer certificate */
318         unsigned require_cert:1;        /* require a client certificate */
319         unsigned verify_chain:1;        /* verify certificate chain */
320         unsigned verify_peer:1;         /* verify peer certificate */
321         unsigned accept:1;              /* endpoint: accept */
322         unsigned client:1;
323         unsigned delayed_lookup:1;
324 #ifdef USE_LIBWRAP
325         unsigned libwrap:1;
326 #endif
327         unsigned local:1;               /* outgoing interface specified */
328         unsigned retry:1;               /* loop remote+program */
329         unsigned session_resume:1;      /* enable session resumption */
330         unsigned sessiond:1;
331 #ifndef USE_WIN32
332         unsigned pty:1;
333         unsigned transparent_src:1;
334 #endif
335         unsigned transparent_dst:1;     /* endpoint: transparent destination */
336         unsigned protocol_endpoint:1;   /* dynamic target from the protocol */
337         unsigned reset:1;               /* reset sockets on error */
338         unsigned renegotiation:1;
339         unsigned connect_before_ssl:1;
340 #ifndef OPENSSL_NO_OCSP
341         unsigned aia:1;                 /* Authority Information Access */
342         unsigned nonce:1;               /* send and verify OCSP nonce */
343 #endif /* !defined(OPENSSL_NO_OCSP) */
344 #ifndef OPENSSL_NO_DH
345         unsigned dh_temp_params:1;
346 #endif /* OPENSSL_NO_DH */
347 #ifndef USE_WIN32
348         unsigned log_stderr:1;          /* a copy of the global switch */
349 #endif /* USE_WIN32 */
350     } option;
351 } SERVICE_OPTIONS;
352 
353 extern SERVICE_OPTIONS service_options;
354 
355 #ifndef OPENSSL_NO_TLSEXT
356 struct servername_list_struct {
357     char *servername;
358     SERVICE_OPTIONS *opt;
359     struct servername_list_struct *next;
360 };
361 #endif /* !defined(OPENSSL_NO_TLSEXT) */
362 
363 typedef enum {
364     TYPE_NONE, TYPE_FLAG, TYPE_INT, TYPE_LINGER, TYPE_TIMEVAL, TYPE_STRING
365 } VAL_TYPE;
366 
367 typedef union {
368     int            i_val;
369     long           l_val;
370     char           c_val[16];
371     struct linger  linger_val;
372     struct timeval timeval_val;
373 } OPT_UNION;
374 
375 struct sock_opt_struct {
376     char *opt_str;
377     int  opt_level;
378     int  opt_name;
379     VAL_TYPE opt_type;
380     OPT_UNION *opt_val[3];
381 };
382 
383 typedef enum {
384     CONF_RELOAD, CONF_FILE, CONF_FD
385 } CONF_TYPE;
386 
387         /* s_poll_set definition for network.c */
388 
389 typedef struct {
390 #ifdef USE_POLL
391     struct pollfd *ufds;
392     unsigned nfds;
393     unsigned allocated;
394 #else /* select */
395     fd_set *irfds, *iwfds, *ixfds, *orfds, *owfds, *oxfds;
396     SOCKET max;
397 #ifdef USE_WIN32
398     unsigned allocated;
399 #endif
400 #endif
401     int main_thread;
402 } s_poll_set;
403 
404 typedef struct disk_file {
405 #ifdef USE_WIN32
406     HANDLE fh;
407 #else
408     int fd;
409 #endif
410     /* the interface is prepared to easily implement buffering if needed */
411 } DISK_FILE;
412 
413     /* definitions for client.c */
414 
415 typedef struct {
416     SOCKET fd; /* file descriptor */
417     int is_socket; /* file descriptor is a socket */
418 } FD;
419 
420 typedef enum {
421     RENEG_INIT, /* initial state */
422     RENEG_ESTABLISHED, /* initial handshake completed */
423     RENEG_DETECTED /* renegotiation detected */
424 } RENEG_STATE;
425 
426 typedef struct client_data_struct {
427     jmp_buf *exception_pointer;
428 
429     SSL *ssl;                                              /* TLS connection */
430     SERVICE_OPTIONS *opt;
431     TLS_DATA *tls;
432 
433 #ifdef USE_OS_THREADS
434     THREAD_ID thread_id;
435 #endif
436 #ifndef USE_FORK
437     struct client_data_struct *thread_prev, *thread_next;
438 #endif
439 
440     SOCKADDR_UNION peer_addr;                                /* peer address */
441     socklen_t peer_addr_len;
442     char *accepted_address;    /* textual representation of the peer address */
443     SOCKADDR_UNION *bind_addr;               /* address to bind() the socket */
444     SOCKADDR_LIST connect_addr;     /* either copied or resolved dynamically */
445     unsigned idx;              /* actually connected address in connect_addr */
446     FD local_rfd, local_wfd;             /* read and write local descriptors */
447     FD remote_fd;                                  /* remote file descriptor */
448     unsigned long pid;                           /* PID of the local process */
449     SOCKET fd;                                  /* temporary file descriptor */
450     RENEG_STATE reneg_state;         /* used to track renegotiation attempts */
451     unsigned long long seq;          /* sequential thread number for logging */
452     unsigned rr;    /* per-client sequential number for round-robin failover */
453 
454     /* data for transfer() function */
455     char sock_buff[BUFFSIZE];                          /* socket read buffer */
456     char ssl_buff[BUFFSIZE];                              /* TLS read buffer */
457     size_t sock_ptr, ssl_ptr;              /* index of the first unused byte */
458     FD *sock_rfd, *sock_wfd;            /* read and write socket descriptors */
459     FD *ssl_rfd, *ssl_wfd;                 /* read and write TLS descriptors */
460     uint64_t sock_bytes, ssl_bytes;       /* bytes written to socket and TLS */
461     s_poll_set *fds;                                     /* file descriptors */
462     struct {
463         unsigned psk:1;                            /* PSK identity was found */
464     } flag;
465 } CLI;
466 
467 /**************************************** prototypes for stunnel.c */
468 
469 #ifndef USE_FORK
470 extern int max_clients;
471 extern int num_clients;
472 #endif
473 extern SOCKET signal_pipe[2];
474 extern SOCKET terminate_pipe[2];
475 
476 void main_init(void);
477 int main_configure(char *, char *);
478 void main_cleanup(void);
479 int drop_privileges(int);
480 void daemon_loop(void);
481 void signal_post(uint8_t);
482 #if !defined(USE_WIN32) && !defined(USE_OS2)
483 void pid_status_hang(const char *);
484 #endif
485 void stunnel_info(int);
486 
487 /**************************************** prototypes for options.c */
488 
489 extern char *configuration_file;
490 extern unsigned number_of_sections;
491 
492 int options_cmdline(char *, char *);
493 int options_parse(CONF_TYPE);
494 void options_defaults(void);
495 void options_apply(void);
496 void options_free(int);
497 
498 void service_up_ref(SERVICE_OPTIONS *);
499 void service_free(SERVICE_OPTIONS *);
500 
501 /**************************************** prototypes for fd.c */
502 
503 #ifndef USE_FORK
504 void get_limits(void); /* setup global max_clients and max_fds */
505 #endif
506 SOCKET s_socket(int, int, int, int, char *);
507 int s_pipe(int[2], int, char *);
508 int s_socketpair(int, int, int, SOCKET[2], int, char *);
509 SOCKET s_accept(SOCKET, struct sockaddr *, socklen_t *, int, char *);
510 void set_nonblock(SOCKET, unsigned long);
511 
512 /**************************************** prototypes for log.c */
513 
514 #define SINK_SYSLOG 1
515 #define SINK_OUTFILE 2
516 
517 int log_open(int);
518 void log_close(int);
519 void log_flush(LOG_MODE);
520 void s_log(int, const char *, ...)
521 #ifdef __GNUC__
522     __attribute__((format(printf, 2, 3)));
523 #else
524     ;
525 #endif
526 char *log_id(CLI *);
527 void fatal_debug(char *, const char *, int) NORETURN;
528 #define fatal(a) fatal_debug((a), __FILE__, __LINE__)
529 void ioerror(const char *);
530 void sockerror(const char *);
531 void log_error(int, int, const char *);
532 char *s_strerror(int);
533 void bin2hexstring(const unsigned char *, size_t, char *, size_t);
534 
535 /**************************************** prototypes for pty.c */
536 
537 int pty_allocate(int *, int *, char *);
538 
539 /**************************************** prototypes for dhparam.c */
540 
541 DH *get_dh2048(void);
542 
543 /**************************************** prototypes for cron.c */
544 
545 #ifdef USE_OS_THREADS
546 extern THREAD_ID cron_thread_id;
547 #endif
548 
549 int cron_init(void);
550 
551 /**************************************** prototypes for ssl.c */
552 
553 extern int index_ssl_cli, index_ssl_ctx_opt;
554 extern int index_session_authenticated, index_session_connect_address;
555 
556 int fips_available();
557 int ssl_init(void);
558 int ssl_configure(GLOBAL_OPTIONS *);
559 
560 /**************************************** prototypes for ctx.c */
561 
562 extern SERVICE_OPTIONS *current_section;
563 
564 #ifndef OPENSSL_NO_DH
565 extern DH *dh_params;
566 extern int dh_temp_params;
567 #endif /* OPENSSL_NO_DH */
568 
569 int context_init(SERVICE_OPTIONS *);
570 #ifndef OPENSSL_NO_PSK
571 void psk_sort(PSK_TABLE *, PSK_KEYS *);
572 PSK_KEYS *psk_find(const PSK_TABLE *, const char *);
573 #endif /* !defined(OPENSSL_NO_PSK) */
574 #ifndef OPENSSL_NO_ENGINE
575 UI_METHOD *ui_stunnel(void);
576 #endif /* !defined(OPENSSL_NO_ENGINE) */
577 void print_session_id(SSL_SESSION *);
578 void sslerror(char *);
579 
580 /**************************************** prototypes for verify.c */
581 
582 int verify_init(SERVICE_OPTIONS *);
583 void print_client_CA_list(const STACK_OF(X509_NAME) *);
584 char *X509_NAME2text(X509_NAME *);
585 
586 /**************************************** prototypes for network.c */
587 
588 s_poll_set *s_poll_alloc(void);
589 void s_poll_free(s_poll_set *);
590 void s_poll_init(s_poll_set *, int);
591 void s_poll_add(s_poll_set *, SOCKET, int, int);
592 void s_poll_remove(s_poll_set *, SOCKET);
593 int s_poll_canread(s_poll_set *, SOCKET);
594 int s_poll_canwrite(s_poll_set *, SOCKET);
595 int s_poll_hup(s_poll_set *, SOCKET);
596 int s_poll_rdhup(s_poll_set *, SOCKET);
597 int s_poll_err(s_poll_set *, SOCKET);
598 int s_poll_wait(s_poll_set *, int, int);
599 void s_poll_dump(s_poll_set *, int);
600 void s_poll_sleep(int, int);
601 
602 #ifdef USE_WIN32
603 #define SIGNAL_TERMINATE        1
604 #define SIGNAL_RELOAD_CONFIG    2
605 #define SIGNAL_REOPEN_LOG       3
606 #define SIGNAL_CONNECTIONS      4
607 #else
608 #define SIGNAL_TERMINATE        SIGTERM
609 #define SIGNAL_RELOAD_CONFIG    SIGHUP
610 #define SIGNAL_REOPEN_LOG       SIGUSR1
611 #define SIGNAL_CONNECTIONS      SIGUSR2
612 #endif
613 
614 int socket_options_set(SERVICE_OPTIONS *, SOCKET, int);
615 int make_sockets(SOCKET[2]);
616 int original_dst(const SOCKET, SOCKADDR_UNION *);
617 
618 /**************************************** prototypes for client.c */
619 
620 CLI *alloc_client_session(SERVICE_OPTIONS *, SOCKET, SOCKET);
621 #if defined(USE_WIN32) || defined(USE_OS2)
622 unsigned __stdcall
623 #else
624 void *
625 #endif
626     client_thread(void *);
627 void client_main(CLI *);
628 void client_free(CLI *);
629 void throw_exception(CLI *, int) NORETURN;
630 
631 /**************************************** prototypes for network.c */
632 
633 int get_socket_error(const SOCKET);
634 int s_connect(CLI *, SOCKADDR_UNION *, socklen_t);
635 void s_write(CLI *, SOCKET fd, const void *, size_t);
636 void s_read(CLI *, SOCKET fd, void *, size_t);
637 void fd_putline(CLI *, SOCKET, const char *);
638 char *fd_getline(CLI *, SOCKET);
639 /* descriptor versions of fprintf/fscanf */
640 void fd_printf(CLI *, SOCKET, const char *, ...)
641 #ifdef __GNUC__
642     __attribute__((format(printf, 3, 4)));
643 #else
644     ;
645 #endif
646 void s_ssl_write(CLI *, const void *, int);
647 void s_ssl_read(CLI *, void *, int);
648 char *ssl_getstring(CLI *c);
649 char *ssl_getline(CLI *c);
650 void ssl_putline(CLI *c, const char *);
651 void ssl_printf(CLI *, const char *, ...)
652 #ifdef __GNUC__
653     __attribute__((format(printf, 2, 3)));
654 #else
655     ;
656 #endif
657 
658 /**************************************** prototype for protocol.c */
659 
660 typedef enum {
661     PROTOCOL_CHECK,
662     PROTOCOL_EARLY,
663     PROTOCOL_MIDDLE,
664     PROTOCOL_LATE
665 } PHASE;
666 
667 char *protocol(CLI *, SERVICE_OPTIONS *opt, const PHASE);
668 
669 /**************************************** prototypes for resolver.c */
670 
671 void resolver_init();
672 
673 unsigned name2addr(SOCKADDR_UNION *, char *, int);
674 unsigned hostport2addr(SOCKADDR_UNION *, char *, char *, int);
675 
676 unsigned name2addrlist(SOCKADDR_LIST *, char *);
677 unsigned hostport2addrlist(SOCKADDR_LIST *, char *, char *);
678 
679 void addrlist_clear(SOCKADDR_LIST *, int);
680 unsigned addrlist_dup(SOCKADDR_LIST *, const SOCKADDR_LIST *);
681 unsigned addrlist_resolve(SOCKADDR_LIST *);
682 
683 char *s_ntop(SOCKADDR_UNION *, socklen_t);
684 socklen_t addr_len(const SOCKADDR_UNION *);
685 const char *s_gai_strerror(int);
686 
687 #ifndef HAVE_GETNAMEINFO
688 
689 #ifndef NI_NUMERICHOST
690 #define NI_NUMERICHOST  2
691 #endif
692 #ifndef NI_NUMERICSERV
693 #define NI_NUMERICSERV  8
694 #endif
695 
696 #ifdef USE_WIN32
697 
698 /* rename some locally shadowed declarations */
699 #define getnameinfo     local_getnameinfo
700 
701 #ifndef _WIN32_WCE
702 typedef int (CALLBACK * GETADDRINFO) (const char *,
703     const char *, const struct addrinfo *, struct addrinfo **);
704 typedef void (CALLBACK * FREEADDRINFO) (struct addrinfo *);
705 typedef int (CALLBACK * GETNAMEINFO) (const struct sockaddr *, socklen_t,
706     char *, size_t, char *, size_t, int);
707 extern GETADDRINFO s_getaddrinfo;
708 extern FREEADDRINFO s_freeaddrinfo;
709 extern GETNAMEINFO s_getnameinfo;
710 #endif /* ! _WIN32_WCE */
711 
712 #endif /* USE_WIN32 */
713 
714 int getnameinfo(const struct sockaddr *, socklen_t,
715     char *, size_t, char *, size_t, int);
716 
717 #endif /* !defined HAVE_GETNAMEINFO */
718 
719 /**************************************** prototypes for sthreads.c */
720 
721 #ifndef USE_FORK
722 extern CLI *thread_head;
723 #endif
724 
725 #if OPENSSL_VERSION_NUMBER<0x10100004L
726 
727 #ifdef USE_OS_THREADS
728 
729 struct CRYPTO_dynlock_value {
730 #ifdef USE_PTHREAD
731     pthread_rwlock_t rwlock;
732 #endif
733 #ifdef USE_WIN32
734     CRITICAL_SECTION critical_section;
735 #endif
736 #ifdef DEBUG_LOCKS
737     const char *init_file, *read_lock_file, *write_lock_file,
738         *unlock_file, *destroy_file;
739     int init_line, read_lock_line, write_lock_line, unlock_line, destroy_line;
740 #endif
741 };
742 
743 typedef struct CRYPTO_dynlock_value CRYPTO_RWLOCK;
744 
745 #else /* USE_OS_THREADS */
746 
747 typedef void CRYPTO_RWLOCK;
748 
749 #endif /* USE_OS_THREADS */
750 
751 #endif /* OPENSSL_VERSION_NUMBER<0x10100004L */
752 
753 typedef enum {
754     LOCK_THREAD_LIST,                       /* sthreads.c */
755     LOCK_SESSION, LOCK_ADDR,
756     LOCK_CLIENTS, LOCK_SSL,                 /* client.c */
757     LOCK_REF,                               /* options.c */
758     LOCK_INET,                              /* resolver.c */
759 #ifndef USE_WIN32
760     LOCK_LIBWRAP,                           /* libwrap.c */
761 #endif
762     LOCK_LOG_BUFFER, LOCK_LOG_MODE,         /* log.c */
763     LOCK_LEAK_HASH, LOCK_LEAK_RESULTS,      /* str.c */
764 #ifndef OPENSSL_NO_DH
765     LOCK_DH,                                /* ctx.c */
766 #endif /* OPENSSL_NO_DH */
767 #ifdef USE_WIN32
768     LOCK_WIN_LOG,                           /* ui_win_gui.c */
769 #endif
770     LOCK_SECTIONS,                          /* traversing section list */
771     STUNNEL_LOCKS                           /* number of locks */
772 } LOCK_TYPE;
773 
774 extern CRYPTO_RWLOCK *stunnel_locks[STUNNEL_LOCKS];
775 
776 #if OPENSSL_VERSION_NUMBER<0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
777 /* Emulate the OpenSSL 1.1 locking API for older OpenSSL versions */
778 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
779 int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *);
780 int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *);
781 int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *);
782 void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *);
783 int CRYPTO_atomic_add(int *, int, int *, CRYPTO_RWLOCK *);
784 #endif
785 
786 int sthreads_init(void);
787 unsigned long stunnel_process_id(void);
788 unsigned long stunnel_thread_id(void);
789 int create_client(SOCKET, SOCKET, CLI *);
790 
791 #ifdef USE_UCONTEXT
792 typedef struct CONTEXT_STRUCTURE {
793     char *stack; /* CPU stack for this thread */
794     unsigned long id;
795     ucontext_t context;
796     s_poll_set *fds;
797     int ready; /* number of ready file descriptors */
798     time_t finish; /* when to finish poll() for this context */
799     struct CONTEXT_STRUCTURE *next; /* next context on a list */
800     void *tls; /* thread local storage for tls.c */
801 } CONTEXT;
802 extern CONTEXT *ready_head, *ready_tail;
803 extern CONTEXT *waiting_head, *waiting_tail;
804 #endif
805 
806 #ifdef _WIN32_WCE
807 long _beginthread(void (*)(void *), int, void *);
808 void _endthread(void);
809 #endif
810 
811 #ifdef DEBUG_STACK_SIZE
812 void stack_info(size_t, int);
813 void ignore_value(void *);
814 #endif
815 
816 /**************************************** prototypes for file.c */
817 
818 #ifndef USE_WIN32
819 DISK_FILE *file_fdopen(int);
820 #endif
821 DISK_FILE *file_open(char *, FILE_MODE mode);
822 void file_close(DISK_FILE *);
823 ssize_t file_getline(DISK_FILE *, char *, int);
824 ssize_t file_putline(DISK_FILE *, char *);
825 int file_permissions(const char *);
826 
827 #ifdef USE_WIN32
828 LPTSTR str2tstr(LPCSTR);
829 LPSTR tstr2str(LPCTSTR);
830 #endif
831 
832 /**************************************** prototypes for libwrap.c */
833 
834 int libwrap_init();
835 void libwrap_auth(CLI *);
836 
837 /**************************************** prototypes for tls.c */
838 
839 extern volatile int tls_initialized;
840 
841 void tls_init();
842 TLS_DATA *tls_alloc(CLI *, TLS_DATA *, char *);
843 void tls_cleanup();
844 void tls_set(TLS_DATA *);
845 TLS_DATA *tls_get();
846 
847 /**************************************** prototypes for str.c */
848 
849 extern TLS_DATA *ui_tls;
850 typedef struct alloc_list_struct ALLOC_LIST;
851 
852 struct tls_data_struct {
853     ALLOC_LIST *alloc_head;
854     size_t alloc_bytes, alloc_blocks;
855     CLI *c;
856     SERVICE_OPTIONS *opt;
857     char *id;
858 };
859 
860 void str_init(TLS_DATA *);
861 void str_cleanup(TLS_DATA *);
862 char *str_dup_debug(const char *, const char *, int);
863 #define str_dup(a) str_dup_debug((a), __FILE__, __LINE__)
864 char *str_dup_detached_debug(const char *, const char *, int);
865 #define str_dup_detached(a) str_dup_detached_debug((a), __FILE__, __LINE__)
866 char *str_vprintf(const char *, va_list);
867 char *str_printf(const char *, ...)
868 #ifdef __GNUC__
869     __attribute__((format(printf, 1, 2)));
870 #else
871     ;
872 #endif
873 #ifdef USE_WIN32
874 LPTSTR str_tprintf(LPCTSTR, ...);
875 #endif
876 
877 void str_canary_init();
878 void str_stats();
879 void *str_alloc_debug(size_t, const char *, int);
880 #define str_alloc(a) str_alloc_debug((a), __FILE__, __LINE__)
881 void *str_alloc_detached_debug(size_t, const char *, int);
882 #define str_alloc_detached(a) str_alloc_detached_debug((a), __FILE__, __LINE__)
883 void *str_realloc_debug(void *, size_t, const char *, int);
884 #define str_realloc(a, b) str_realloc_debug((a), (b), __FILE__, __LINE__)
885 void *str_realloc_detached_debug(void *, size_t, const char *, int);
886 #define str_realloc_detached(a, b) str_realloc_detached_debug((a), (b), __FILE__, __LINE__)
887 void str_detach_debug(void *, const char *, int);
888 #define str_detach(a) str_detach_debug((a), __FILE__, __LINE__)
889 void str_free_debug(void *, const char *, int);
890 #define str_free(a) str_free_debug((a), __FILE__, __LINE__), (a)=NULL
891 #define str_free_expression(a) str_free_debug((a), __FILE__, __LINE__)
892 
893 void leak_table_utilization(void);
894 
895 int safe_memcmp(const void *, const void *, size_t);
896 
897 /**************************************** prototypes for ui_*.c */
898 
899 void ui_config_reloaded(void);
900 void ui_new_chain(const unsigned);
901 void ui_clients(const long);
902 
903 void ui_new_log(const char *);
904 #ifdef USE_WIN32
905 void message_box(LPCTSTR, const UINT);
906 #endif /* USE_WIN32 */
907 
908 int ui_passwd_cb(char *, int, int, void *);
909 #ifndef OPENSSL_NO_ENGINE
910 int (*ui_get_opener(void)) (UI *);
911 int (*ui_get_writer(void)) (UI *, UI_STRING *);
912 int (*ui_get_reader(void)) (UI *, UI_STRING *);
913 int (*ui_get_closer(void)) (UI *);
914 #endif /* !defined(OPENSSL_NO_ENGINE) */
915 
916 #ifdef ICON_IMAGE
917 ICON_IMAGE load_icon_default(ICON_TYPE);
918 ICON_IMAGE load_icon_file(const char *);
919 #endif
920 
921 #endif /* defined PROTOTYPES_H */
922 
923 /* end of prototypes.h */
924