/* * stunnel TLS offloading and load-balancing proxy * Copyright (C) 1998-2017 Michal Trojnara * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see . * * Linking stunnel statically or dynamically with other modules is making * a combined work based on stunnel. Thus, the terms and conditions of * the GNU General Public License cover the whole combination. * * In addition, as a special exception, the copyright holder of stunnel * gives you permission to combine stunnel with free software programs or * libraries that are released under the GNU LGPL and with code included * in the standard release of OpenSSL under the OpenSSL License (or * modified versions of such code, with unchanged license). You may copy * and distribute such a system following the terms of the GNU GPL for * stunnel and the licenses of the other code concerned. * * Note that people who make modified versions of stunnel are not obligated * to grant this special exception for their modified versions; it is their * choice whether to do so. The GNU General Public License gives permission * to release a modified version without this exception; this exception * also makes it possible to release a modified version which carries * forward this exception. */ #ifndef PROTOTYPES_H #define PROTOTYPES_H #include "common.h" /**************************************** forward declarations */ typedef struct tls_data_struct TLS_DATA; /**************************************** data structures */ #if defined (USE_WIN32) #define ICON_IMAGE HICON #elif defined(__APPLE__) #define ICON_IMAGE void * #endif typedef enum { ICON_ERROR, ICON_IDLE, ICON_ACTIVE, ICON_NONE /* it has to be the last one */ } ICON_TYPE; typedef enum { LOG_MODE_BUFFER, LOG_MODE_ERROR, LOG_MODE_INFO, LOG_MODE_CONFIGURED } LOG_MODE; typedef enum { LOG_ID_SEQUENTIAL, LOG_ID_UNIQUE, LOG_ID_THREAD, LOG_ID_PROCESS } LOG_ID; typedef enum { FILE_MODE_READ, FILE_MODE_APPEND, FILE_MODE_OVERWRITE } FILE_MODE; typedef union sockaddr_union { struct sockaddr sa; struct sockaddr_in in; #ifdef USE_IPv6 struct sockaddr_in6 in6; #endif #ifdef HAVE_STRUCT_SOCKADDR_UN struct sockaddr_un un; #endif } SOCKADDR_UNION; typedef struct name_list_struct { char *name; struct name_list_struct *next; } NAME_LIST; typedef struct sockaddr_list { /* list of addresses */ struct sockaddr_list *parent; /* used by copies to locate their parent */ SOCKADDR_UNION *addr; /* array of resolved addresses */ SOCKET *fd; /* array of accepting file descriptors */ SSL_SESSION **session; /* array of cached client sessions */ unsigned start; /* initial address for round-robin failover */ unsigned num; /* how many addresses are used */ int passive; /* listening socket */ NAME_LIST *names; /* a list of unresolved names */ } SOCKADDR_LIST; #ifndef OPENSSL_NO_COMP typedef enum { COMP_NONE, COMP_DEFLATE, COMP_ZLIB } COMP_TYPE; #endif /* !defined(OPENSSL_NO_COMP) */ typedef struct { /* some data for TLS initialization in ssl.c */ #ifndef OPENSSL_NO_COMP COMP_TYPE compression; /* compression type */ #endif /* !defined(OPENSSL_NO_COMP) */ char *egd_sock; /* entropy gathering daemon socket */ char *rand_file; /* file with random data */ long random_bytes; /* how many random bytes to read */ /* some global data for stunnel.c */ #ifndef USE_WIN32 #ifdef HAVE_CHROOT char *chroot_dir; #endif char *pidfile; #endif /* logging-support data for log.c */ #ifndef USE_WIN32 int log_facility; /* debug facility for syslog */ #endif char *output_file; FILE_MODE log_file_mode; /* user interface configuration */ #ifdef ICON_IMAGE ICON_IMAGE icon[ICON_NONE]; /* user-specified GUI icons */ #endif /* on/off switches */ struct { unsigned rand_write:1; /* overwrite rand_file */ #ifdef USE_WIN32 unsigned taskbar:1; /* enable the taskbar icon */ #else /* !USE_WIN32 */ unsigned foreground:1; unsigned log_stderr:1; unsigned log_syslog:1; #endif #ifdef USE_FIPS unsigned fips:1; /* enable FIPS 140-2 mode */ #endif } option; } GLOBAL_OPTIONS; extern GLOBAL_OPTIONS global_options; #ifndef OPENSSL_NO_TLSEXT typedef struct servername_list_struct SERVERNAME_LIST;/* forward declaration */ #endif /* !defined(OPENSSL_NO_TLSEXT) */ #ifndef OPENSSL_NO_PSK typedef struct psk_keys_struct { char *identity; unsigned char *key_val; size_t key_len; struct psk_keys_struct *next; } PSK_KEYS; typedef struct psk_table_struct { PSK_KEYS **val; size_t num; } PSK_TABLE; #endif /* !defined(OPENSSL_NO_PSK) */ typedef struct service_options_struct { struct service_options_struct *next; /* next node in the services list */ SSL_CTX *ctx; /* TLS context */ char *servname; /* service name for logging & permission checking */ /* service-specific data for stunnel.c */ #ifndef USE_WIN32 uid_t uid; gid_t gid; #endif /* service-specific data for log.c */ int log_level; /* debug level for logging */ LOG_ID log_id; /* logging session id type */ /* service-specific data for sthreads.c */ #ifndef USE_FORK size_t stack_size; /* stack size for this thread */ #endif /* service-specific data for verify.c */ char *ca_dir; /* directory for hashed certs */ char *ca_file; /* file containing bunches of certs */ char *crl_dir; /* directory for hashed CRLs */ char *crl_file; /* file containing bunches of CRLs */ #ifndef OPENSSL_NO_OCSP char *ocsp_url; unsigned long ocsp_flags; #endif /* !defined(OPENSSL_NO_OCSP) */ #if OPENSSL_VERSION_NUMBER>=0x10002000L NAME_LIST *check_host, *check_email, *check_ip; /* cert subject checks */ NAME_LIST *config; /* OpenSSL CONF options */ #endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */ /* service-specific data for ctx.c */ char *cipher_list; char *cert; /* cert filename */ char *key; /* pem (priv key/cert) filename */ long session_size, session_timeout; long unsigned ssl_options_set; #if OPENSSL_VERSION_NUMBER>=0x009080dfL long unsigned ssl_options_clear; #endif /* OpenSSL 0.9.8m or later */ SSL_METHOD *client_method, *server_method; SOCKADDR_UNION sessiond_addr; #ifndef OPENSSL_NO_TLSEXT char *sni; SERVERNAME_LIST *servername_list_head, *servername_list_tail; #endif /* !defined(OPENSSL_NO_TLSEXT) */ #ifndef OPENSSL_NO_PSK char *psk_identity; PSK_KEYS *psk_keys, *psk_selected; PSK_TABLE psk_sorted; #endif /* !defined(OPENSSL_NO_PSK) */ #ifndef OPENSSL_NO_ECDH int curve; #endif /* !defined(OPENSSL_NO_ECDH) */ #ifndef OPENSSL_NO_ENGINE ENGINE *engine; /* engine to read the private key */ #endif /* !defined(OPENSSL_NO_ENGINE) */ /* service-specific data for client.c */ SSL_SESSION *session; /* recently used session */ char *exec_name; /* program name for local mode */ #ifdef USE_WIN32 char *exec_args; /* program arguments for local mode */ #else char **exec_args; /* program arguments for local mode */ #endif SOCKADDR_UNION source_addr; SOCKADDR_LIST local_addr, connect_addr, redirect_addr; int timeout_busy; /* maximum waiting for data time */ int timeout_close; /* maximum close_notify time */ int timeout_connect; /* maximum connect() time */ int timeout_idle; /* maximum idle connection time */ enum {FAILOVER_RR, FAILOVER_PRIO} failover; /* failover strategy */ unsigned seq; /* sequential number for round-robin failover */ char *username; /* service-specific data for protocol.c */ char * protocol; char *protocol_host; char *protocol_domain; char *protocol_username; char *protocol_password; char *protocol_authentication; /* service-specific data for ui_*.c */ #ifdef USE_WIN32 LPTSTR file, help; #endif unsigned section_number; char *chain; /* on/off switches */ struct { unsigned request_cert:1; /* request a peer certificate */ unsigned require_cert:1; /* require a client certificate */ unsigned verify_chain:1; /* verify certificate chain */ unsigned verify_peer:1; /* verify peer certificate */ unsigned accept:1; /* endpoint: accept */ unsigned client:1; unsigned delayed_lookup:1; #ifdef USE_LIBWRAP unsigned libwrap:1; #endif unsigned local:1; /* outgoing interface specified */ unsigned retry:1; /* loop remote+program */ unsigned sessiond:1; #ifndef OPENSSL_NO_TLSEXT unsigned sni:1; /* endpoint: sni */ #endif /* !defined(OPENSSL_NO_TLSEXT) */ #ifndef USE_WIN32 unsigned pty:1; unsigned transparent_src:1; #endif unsigned transparent_dst:1; /* endpoint: transparent destination */ unsigned protocol_endpoint:1; /* dynamic target from the protocol */ unsigned reset:1; /* reset sockets on error */ unsigned renegotiation:1; unsigned connect_before_ssl:1; #ifndef OPENSSL_NO_OCSP unsigned aia:1; /* Authority Information Access */ unsigned nonce:1; /* send and verify OCSP nonce */ #endif /* !defined(OPENSSL_NO_OCSP) */ #ifndef OPENSSL_NO_DH unsigned dh_needed:1; #endif /* OPENSSL_NO_DH */ } option; } SERVICE_OPTIONS; extern SERVICE_OPTIONS service_options; #ifndef OPENSSL_NO_TLSEXT struct servername_list_struct { char *servername; SERVICE_OPTIONS *opt; struct servername_list_struct *next; }; #endif /* !defined(OPENSSL_NO_TLSEXT) */ typedef enum { TYPE_NONE, TYPE_FLAG, TYPE_INT, TYPE_LINGER, TYPE_TIMEVAL, TYPE_STRING } VAL_TYPE; typedef union { int i_val; long l_val; char c_val[16]; struct linger linger_val; struct timeval timeval_val; } OPT_UNION; typedef struct { char *opt_str; int opt_level; int opt_name; VAL_TYPE opt_type; OPT_UNION *opt_val[3]; } SOCK_OPT; typedef enum { CONF_RELOAD, CONF_FILE, CONF_FD } CONF_TYPE; /* s_poll_set definition for network.c */ typedef struct { #ifdef USE_POLL struct pollfd *ufds; unsigned nfds; unsigned allocated; #else /* select */ fd_set *irfds, *iwfds, *ixfds, *orfds, *owfds, *oxfds; SOCKET max; #ifdef USE_WIN32 unsigned allocated; #endif #endif } s_poll_set; typedef struct disk_file { #ifdef USE_WIN32 HANDLE fh; #else int fd; #endif /* the interface is prepared to easily implement buffering if needed */ } DISK_FILE; /* definitions for client.c */ typedef struct { SOCKET fd; /* file descriptor */ int is_socket; /* file descriptor is a socket */ } FD; typedef enum { RENEG_INIT, /* initial state */ RENEG_ESTABLISHED, /* initial handshake completed */ RENEG_DETECTED /* renegotiation detected */ } RENEG_STATE; typedef struct { jmp_buf err; /* 64-bit platforms require jmp_buf to be 16-byte aligned */ SSL *ssl; /* TLS connection */ SERVICE_OPTIONS *opt; TLS_DATA *tls; SOCKADDR_UNION peer_addr; /* peer address */ socklen_t peer_addr_len; SOCKADDR_UNION *bind_addr; /* address to bind() the socket */ SOCKADDR_LIST connect_addr; /* either copied or resolved dynamically */ unsigned idx; /* actually connected address in connect_addr */ FD local_rfd, local_wfd; /* read and write local descriptors */ FD remote_fd; /* remote file descriptor */ /* IP for explicit local bind or transparent proxy */ unsigned long pid; /* PID of the local process */ SOCKET fd; /* temporary file descriptor */ RENEG_STATE reneg_state; /* used to track renegotiation attempts */ unsigned long long seq; /* sequential thread number for logging */ /* data for transfer() function */ char sock_buff[BUFFSIZE]; /* socket read buffer */ char ssl_buff[BUFFSIZE]; /* TLS read buffer */ size_t sock_ptr, ssl_ptr; /* index of the first unused byte */ FD *sock_rfd, *sock_wfd; /* read and write socket descriptors */ FD *ssl_rfd, *ssl_wfd; /* read and write TLS descriptors */ uint64_t sock_bytes, ssl_bytes; /* bytes written to socket and TLS */ s_poll_set *fds; /* file descriptors */ } CLI; /**************************************** prototypes for stunnel.c */ #ifndef USE_FORK extern long max_clients; extern volatile long num_clients; #endif void main_init(void); int main_configure(char *, char *); void main_cleanup(void); int drop_privileges(int); void daemon_loop(void); void unbind_ports(void); int bind_ports(void); void signal_post(int); #if !defined(USE_WIN32) && !defined(USE_OS2) void child_status(void); /* dead libwrap or 'exec' process detected */ #endif void stunnel_info(int); /**************************************** prototypes for options.c */ extern char configuration_file[PATH_MAX]; extern unsigned number_of_sections; int options_cmdline(char *, char *); int options_parse(CONF_TYPE); void options_defaults(void); void options_apply(void); /**************************************** prototypes for fd.c */ #ifndef USE_FORK void get_limits(void); /* setup global max_clients and max_fds */ #endif SOCKET s_socket(int, int, int, int, char *); int s_pipe(int[2], int, char *); int s_socketpair(int, int, int, SOCKET[2], int, char *); SOCKET s_accept(SOCKET, struct sockaddr *, socklen_t *, int, char *); void set_nonblock(SOCKET, unsigned long); /**************************************** prototypes for log.c */ #if !defined(USE_WIN32) && !defined(__vms) void syslog_open(void); void syslog_close(void); #endif int log_open(void); void log_close(void); void log_flush(LOG_MODE); void s_log(int, const char *, ...) #ifdef __GNUC__ __attribute__((format(printf, 2, 3))); #else ; #endif char *log_id(CLI *); void fatal_debug(char *, const char *, int); #define fatal(a) fatal_debug((a), __FILE__, __LINE__) void ioerror(const char *); void sockerror(const char *); void log_error(int, int, const char *); char *s_strerror(int); /**************************************** prototypes for pty.c */ int pty_allocate(int *, int *, char *); /**************************************** prototypes for dhparam.c */ DH *get_dh2048(void); /**************************************** prototypes for cron.c */ int cron_init(void); /**************************************** prototypes for ssl.c */ extern int index_ssl_cli, index_ssl_ctx_opt; extern int index_session_authenticated, index_session_connect_address; int ssl_init(void); int ssl_configure(GLOBAL_OPTIONS *); /**************************************** prototypes for ctx.c */ extern SERVICE_OPTIONS *current_section; #ifndef OPENSSL_NO_DH extern DH *dh_params; extern int dh_needed; #endif /* OPENSSL_NO_DH */ int context_init(SERVICE_OPTIONS *); #ifndef OPENSSL_NO_PSK void psk_sort(PSK_TABLE *, PSK_KEYS *); PSK_KEYS *psk_find(const PSK_TABLE *, const char *); #endif /* !defined(OPENSSL_NO_PSK) */ void sslerror(char *); /**************************************** prototypes for verify.c */ int verify_init(SERVICE_OPTIONS *); void print_client_CA_list(const STACK_OF(X509_NAME) *); char *X509_NAME2text(X509_NAME *); /**************************************** prototypes for network.c */ s_poll_set *s_poll_alloc(void); void s_poll_free(s_poll_set *); void s_poll_init(s_poll_set *); void s_poll_add(s_poll_set *, SOCKET, int, int); void s_poll_remove(s_poll_set *, SOCKET); int s_poll_canread(s_poll_set *, SOCKET); int s_poll_canwrite(s_poll_set *, SOCKET); int s_poll_hup(s_poll_set *, SOCKET); int s_poll_rdhup(s_poll_set *, SOCKET); int s_poll_err(s_poll_set *, SOCKET); int s_poll_wait(s_poll_set *, int, int); void s_poll_dump(s_poll_set *, int); #ifdef USE_WIN32 #define SIGNAL_RELOAD_CONFIG 1 #define SIGNAL_REOPEN_LOG 2 #define SIGNAL_TERMINATE 3 #else #define SIGNAL_RELOAD_CONFIG SIGHUP #define SIGNAL_REOPEN_LOG SIGUSR1 #define SIGNAL_TERMINATE SIGTERM #endif int set_socket_options(SOCKET, int); int make_sockets(SOCKET[2]); int original_dst(const SOCKET, SOCKADDR_UNION *); /**************************************** prototypes for client.c */ CLI *alloc_client_session(SERVICE_OPTIONS *, SOCKET, SOCKET); void *client_thread(void *); void client_main(CLI *); /**************************************** prototypes for network.c */ int get_socket_error(const SOCKET); int s_connect(CLI *, SOCKADDR_UNION *, socklen_t); void s_write(CLI *, SOCKET fd, const void *, size_t); void s_read(CLI *, SOCKET fd, void *, size_t); void fd_putline(CLI *, SOCKET, const char *); char *fd_getline(CLI *, SOCKET); /* descriptor versions of fprintf/fscanf */ void fd_printf(CLI *, SOCKET, const char *, ...) #ifdef __GNUC__ __attribute__((format(printf, 3, 4))); #else ; #endif void s_ssl_write(CLI *, const void *, int); void s_ssl_read(CLI *, void *, int); char *ssl_getstring(CLI *c); char *ssl_getline(CLI *c); void ssl_putline(CLI *c, const char *); /**************************************** prototype for protocol.c */ typedef enum { PROTOCOL_CHECK, PROTOCOL_EARLY, PROTOCOL_MIDDLE, PROTOCOL_LATE } PHASE; char *protocol(CLI *, SERVICE_OPTIONS *opt, const PHASE); /**************************************** prototypes for resolver.c */ void resolver_init(); unsigned name2addr(SOCKADDR_UNION *, char *, int); unsigned hostport2addr(SOCKADDR_UNION *, char *, char *, int); unsigned name2addrlist(SOCKADDR_LIST *, char *); unsigned hostport2addrlist(SOCKADDR_LIST *, char *, char *); void addrlist_clear(SOCKADDR_LIST *, int); unsigned addrlist_dup(SOCKADDR_LIST *, const SOCKADDR_LIST *); unsigned addrlist_resolve(SOCKADDR_LIST *); char *s_ntop(SOCKADDR_UNION *, socklen_t); socklen_t addr_len(const SOCKADDR_UNION *); const char *s_gai_strerror(int); #ifndef HAVE_GETNAMEINFO #ifndef NI_NUMERICHOST #define NI_NUMERICHOST 2 #endif #ifndef NI_NUMERICSERV #define NI_NUMERICSERV 8 #endif #ifdef USE_WIN32 /* rename some locally shadowed declarations */ #define getnameinfo local_getnameinfo #ifndef _WIN32_WCE typedef int (CALLBACK * GETADDRINFO) (const char *, const char *, const struct addrinfo *, struct addrinfo **); typedef void (CALLBACK * FREEADDRINFO) (struct addrinfo FAR *); typedef int (CALLBACK * GETNAMEINFO) (const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int); extern GETADDRINFO s_getaddrinfo; extern FREEADDRINFO s_freeaddrinfo; extern GETNAMEINFO s_getnameinfo; #endif /* ! _WIN32_WCE */ #endif /* USE_WIN32 */ int getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int); #endif /* !defined HAVE_GETNAMEINFO */ /**************************************** prototypes for sthreads.c */ #if defined(USE_PTHREAD) || defined(USE_WIN32) struct CRYPTO_dynlock_value { #ifdef USE_PTHREAD pthread_rwlock_t rwlock; #endif #ifdef USE_WIN32 CRITICAL_SECTION critical_section; #endif const char *init_file, *read_lock_file, *write_lock_file, *read_unlock_file, *write_unlock_file, *destroy_file; int init_line, read_lock_line, write_lock_line, read_unlock_line, write_unlock_line, destroy_line; }; typedef enum { LOCK_SESSION, LOCK_ADDR, LOCK_CLIENTS, LOCK_SSL, /* client.c */ LOCK_INET, /* resolver.c */ #ifndef USE_WIN32 LOCK_LIBWRAP, /* libwrap.c */ #endif LOCK_LOG_BUFFER, LOCK_LOG_MODE, /* log.c */ LOCK_LEAK_HASH, LOCK_LEAK_RESULTS, /* str.c */ #ifndef OPENSSL_NO_DH LOCK_DH, /* ctx.c */ #endif /* OPENSSL_NO_DH */ STUNNEL_LOCKS /* number of locks */ } LOCK_TYPE; extern struct CRYPTO_dynlock_value stunnel_locks[STUNNEL_LOCKS]; void stunnel_rwlock_init_debug(struct CRYPTO_dynlock_value *, const char *, int); void stunnel_read_lock_debug(struct CRYPTO_dynlock_value *, const char *, int); void stunnel_write_lock_debug(struct CRYPTO_dynlock_value *, const char *, int); void stunnel_read_unlock_debug(struct CRYPTO_dynlock_value *, const char *, int); void stunnel_write_unlock_debug(struct CRYPTO_dynlock_value *, const char *, int); void stunnel_rwlock_destroy_debug(struct CRYPTO_dynlock_value *, const char *, int); #define stunnel_rwlock_init(x) stunnel_rwlock_init_debug((x),__FILE__,__LINE__) #define stunnel_read_lock(x) stunnel_read_lock_debug((x),__FILE__,__LINE__) #define stunnel_write_lock(x) stunnel_write_lock_debug((x),__FILE__,__LINE__) #define stunnel_read_unlock(x) stunnel_read_unlock_debug((x),__FILE__,__LINE__) #define stunnel_write_unlock(x) stunnel_write_unlock_debug((x),__FILE__,__LINE__) #define stunnel_rwlock_destroy(x) stunnel_rwlock_destroy_debug((x),__FILE__,__LINE__) #if OPENSSL_VERSION_NUMBER<0x10100004L #define CRYPTO_atomic_add(addr,amount,result,type) \ *result = type ? CRYPTO_add(addr,amount,type) : (*addr+=amount) #endif #else /* defined(USE_PTHREAD) || defined(USE_WIN32) */ #define stunnel_rwlock_init(x) {} #define stunnel_read_lock(x) {} #define stunnel_write_lock(x) {} #define stunnel_read_unlock(x) {} #define stunnel_write_unlock(x) {} #define stunnel_rwlock_destroy(x) {} #endif /* defined(USE_PTHREAD) || defined(USE_WIN32) */ int sthreads_init(void); unsigned long stunnel_process_id(void); unsigned long stunnel_thread_id(void); int create_client(SOCKET, SOCKET, CLI *, void *(*)(void *)); #ifdef USE_UCONTEXT typedef struct CONTEXT_STRUCTURE { char *stack; /* CPU stack for this thread */ unsigned long id; ucontext_t context; s_poll_set *fds; int ready; /* number of ready file descriptors */ time_t finish; /* when to finish poll() for this context */ struct CONTEXT_STRUCTURE *next; /* next context on a list */ void *tls; /* thread local storage for tls.c */ } CONTEXT; extern CONTEXT *ready_head, *ready_tail; extern CONTEXT *waiting_head, *waiting_tail; #endif #ifdef _WIN32_WCE long _beginthread(void (*)(void *), int, void *); void _endthread(void); #endif #ifdef DEBUG_STACK_SIZE void stack_info(int); #endif /**************************************** prototypes for file.c */ #ifndef USE_WIN32 DISK_FILE *file_fdopen(int); #endif DISK_FILE *file_open(char *, FILE_MODE mode); void file_close(DISK_FILE *); ssize_t file_getline(DISK_FILE *, char *, int); ssize_t file_putline(DISK_FILE *, char *); int file_permissions(const char *); #ifdef USE_WIN32 LPTSTR str2tstr(LPCSTR); LPSTR tstr2str(LPCTSTR); #endif /**************************************** prototypes for libwrap.c */ int libwrap_init(); void libwrap_auth(CLI *, char *); /**************************************** prototypes for tls.c */ extern volatile int tls_initialized; void tls_init(); TLS_DATA *tls_alloc(CLI *, TLS_DATA *, char *); void tls_cleanup(); void tls_set(TLS_DATA *); TLS_DATA *tls_get(); /**************************************** prototypes for str.c */ extern TLS_DATA *ui_tls; typedef struct alloc_list_struct ALLOC_LIST; struct tls_data_struct { ALLOC_LIST *alloc_head; size_t alloc_bytes, alloc_blocks; CLI *c; SERVICE_OPTIONS *opt; char *id; }; void str_init(TLS_DATA *); void str_cleanup(TLS_DATA *); char *str_dup_debug(const char *, const char *, int); #define str_dup(a) str_dup_debug((a), __FILE__, __LINE__) char *str_vprintf(const char *, va_list); char *str_printf(const char *, ...) #ifdef __GNUC__ __attribute__((format(printf, 1, 2))); #else ; #endif #ifdef USE_WIN32 LPTSTR str_tprintf(LPCTSTR, ...); #endif void str_canary_init(); void str_stats(); void *str_alloc_debug(size_t, const char *, int); #define str_alloc(a) str_alloc_debug((a), __FILE__, __LINE__) void *str_alloc_detached_debug(size_t, const char *, int); #define str_alloc_detached(a) str_alloc_detached_debug((a), __FILE__, __LINE__) void *str_realloc_detached_debug(void *, size_t, const char *, int); void *str_realloc_debug(void *, size_t, const char *, int); #define str_realloc(a, b) str_realloc_debug((a), (b), __FILE__, __LINE__) void str_detach_debug(void *, const char *, int); #define str_detach(a) str_detach_debug((a), __FILE__, __LINE__) void str_free_debug(void *, const char *, int); #define str_free(a) str_free_debug((a), __FILE__, __LINE__), (a)=NULL #define str_free_expression(a) str_free_debug((a), __FILE__, __LINE__) int safe_memcmp(const void *, const void *, size_t); /**************************************** prototypes for ui_*.c */ void ui_config_reloaded(void); void ui_new_chain(const unsigned); void ui_clients(const long); void ui_new_log(const char *); #ifdef USE_WIN32 void message_box(LPCTSTR, const UINT); #endif /* USE_WIN32 */ int ui_passwd_cb(char *, int, int, void *); #ifndef OPENSSL_NO_ENGINE UI_METHOD *UI_stunnel(void); #endif /* !defined(OPENSSL_NO_ENGINE) */ #ifdef ICON_IMAGE ICON_IMAGE load_icon_default(ICON_TYPE); ICON_IMAGE load_icon_file(const char *); #endif #endif /* defined PROTOTYPES_H */ /* end of prototypes.h */