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 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
42 #define DEFAULT_CURVES "X25519:P-256:X448:P-521:P-384"
43 #else /* OpenSSL version < 1.1.1 */
44 #define DEFAULT_CURVES "prime256v1"
45 #endif /* OpenSSL version >= 1.1.1 */
46 
47 #if defined(_WIN32_WCE) && !defined(CONFDIR)
48 #define CONFDIR "\\stunnel"
49 #endif
50 
51 #define CONFLINELEN (16*1024)
52 
53 #define INVALID_SSL_OPTION ((long unsigned)-1)
54 
55 typedef enum {
56     CMD_SET_DEFAULTS,   /* set default values */
57     CMD_SET_COPY,       /* duplicate from new_service_options */
58     CMD_FREE,           /* deallocate memory */
59     CMD_SET_VALUE,      /* set a user-specified value */
60     CMD_INITIALIZE,     /* initialize the global options or a section */
61     CMD_PRINT_DEFAULTS, /* print default values */
62     CMD_PRINT_HELP      /* print help */
63 } CMD;
64 
65 NOEXPORT int options_file(char *, CONF_TYPE, SERVICE_OPTIONS **);
66 NOEXPORT int init_section(int, SERVICE_OPTIONS **);
67 #ifdef USE_WIN32
68 struct dirent {
69     char d_name[MAX_PATH];
70 };
71 int scandir(const char *, struct dirent ***,
72     int (*)(const struct dirent *),
73     int (*)(const struct dirent **, const struct dirent **));
74 int alphasort(const struct dirent **, const struct dirent **);
75 #endif
76 NOEXPORT char *parse_global_option(CMD, GLOBAL_OPTIONS *, char *, char *);
77 NOEXPORT char *parse_service_option(CMD, SERVICE_OPTIONS **, char *, char *);
78 
79 #ifndef OPENSSL_NO_TLSEXT
80 NOEXPORT char *sni_init(SERVICE_OPTIONS *);
81 NOEXPORT void sni_free(SERVICE_OPTIONS *);
82 #endif /* !defined(OPENSSL_NO_TLSEXT) */
83 
84 #if OPENSSL_VERSION_NUMBER>=0x10100000L
85 NOEXPORT int str_to_proto_version(const char *);
86 #else /* OPENSSL_VERSION_NUMBER<0x10100000L */
87 NOEXPORT char *tls_methods_set(SERVICE_OPTIONS *, const char *);
88 NOEXPORT char *tls_methods_check(SERVICE_OPTIONS *);
89 #endif /* OPENSSL_VERSION_NUMBER<0x10100000L */
90 
91 NOEXPORT char *parse_debug_level(char *, SERVICE_OPTIONS *);
92 
93 #ifndef OPENSSL_NO_PSK
94 NOEXPORT PSK_KEYS *psk_read(char *);
95 NOEXPORT PSK_KEYS *psk_dup(PSK_KEYS *);
96 NOEXPORT void psk_free(PSK_KEYS *);
97 #endif /* !defined(OPENSSL_NO_PSK) */
98 
99 #if OPENSSL_VERSION_NUMBER>=0x10000000L
100 NOEXPORT TICKET_KEY *key_read(char *, char *);
101 NOEXPORT TICKET_KEY *key_dup(TICKET_KEY *);
102 NOEXPORT void key_free(TICKET_KEY *);
103 #endif /* OpenSSL 1.0.0 or later */
104 
105 typedef struct {
106     char *name;
107     long unsigned value;
108 } SSL_OPTION;
109 
110 static const SSL_OPTION ssl_opts[] = {
111     {"MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG},
112     {"NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG},
113 #ifdef SSL_OP_LEGACY_SERVER_CONNECT
114     {"LEGACY_SERVER_CONNECT", SSL_OP_LEGACY_SERVER_CONNECT},
115 #endif
116     {"NETSCAPE_REUSE_CIPHER_CHANGE_BUG",
117         SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG},
118 #ifdef SSL_OP_TLSEXT_PADDING
119     {"TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING},
120 #endif
121     {"MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER},
122 #ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
123     {"SAFARI_ECDHE_ECDSA_BUG", SSL_OP_SAFARI_ECDHE_ECDSA_BUG},
124 #endif
125     {"SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG},
126     {"TLS_D5_BUG", SSL_OP_TLS_D5_BUG},
127     {"TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG},
128 #ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
129     {"MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING},
130 #endif
131     {"SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG},
132 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
133     {"DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS},
134 #endif
135     {"ALL", SSL_OP_ALL},
136 #ifdef SSL_OP_NO_QUERY_MTU
137     {"NO_QUERY_MTU", SSL_OP_NO_QUERY_MTU},
138 #endif
139 #ifdef SSL_OP_COOKIE_EXCHANGE
140     {"COOKIE_EXCHANGE", SSL_OP_COOKIE_EXCHANGE},
141 #endif
142 #ifdef SSL_OP_NO_TICKET
143     {"NO_TICKET", SSL_OP_NO_TICKET},
144 #endif
145 #ifdef SSL_OP_CISCO_ANYCONNECT
146     {"CISCO_ANYCONNECT", SSL_OP_CISCO_ANYCONNECT},
147 #endif
148 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
149     {"NO_SESSION_RESUMPTION_ON_RENEGOTIATION",
150         SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION},
151 #endif
152 #ifdef SSL_OP_NO_COMPRESSION
153     {"NO_COMPRESSION", SSL_OP_NO_COMPRESSION},
154 #endif
155 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
156     {"ALLOW_UNSAFE_LEGACY_RENEGOTIATION",
157         SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION},
158 #endif
159 #ifdef SSL_OP_SINGLE_ECDH_USE
160     {"SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE},
161 #endif
162     {"SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE},
163     {"EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA},
164 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
165     {"CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE},
166 #endif
167     {"TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG},
168     {"NO_SSLv2", SSL_OP_NO_SSLv2},
169     {"NO_SSLv3", SSL_OP_NO_SSLv3},
170     {"NO_TLSv1", SSL_OP_NO_TLSv1},
171 #ifdef SSL_OP_NO_TLSv1_1
172     {"NO_TLSv1.1", SSL_OP_NO_TLSv1_1},
173 #else /* ignore if unsupported by OpenSSL */
174     {"NO_TLSv1.1", 0},
175 #endif
176 #ifdef SSL_OP_NO_TLSv1_2
177     {"NO_TLSv1.2", SSL_OP_NO_TLSv1_2},
178 #else /* ignore if unsupported by OpenSSL */
179     {"NO_TLSv1.2", 0},
180 #endif
181 #ifdef SSL_OP_NO_TLSv1_3
182     {"NO_TLSv1.3", SSL_OP_NO_TLSv1_3},
183     {"NO_TLSv1_3", SSL_OP_NO_TLSv1_3}, /* keep compatibility with our typo */
184 #else /* ignore if unsupported by OpenSSL */
185     {"NO_TLSv1.3", 0},
186     {"NO_TLSv1_3", 0}, /* keep compatibility with our typo */
187 #endif
188     {"PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1},
189     {"PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2},
190     {"NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG},
191 #ifdef SSL_OP_NON_EXPORT_FIRST
192     {"NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST},
193 #endif
194     {"NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG},
195 #ifdef SSL_OP_CRYPTOPRO_TLSEXT_BUG
196     {"CRYPTOPRO_TLSEXT_BUG", SSL_OP_CRYPTOPRO_TLSEXT_BUG},
197 #endif
198 #ifdef SSL_OP_NO_DTLSv1
199     {"NO_DTLSv1", SSL_OP_NO_DTLSv1},
200 #endif
201 #ifdef SSL_OP_NO_DTLSv1_2
202     {"NO_DTLSv1_2", SSL_OP_NO_DTLSv1_2},
203 #endif
204 #ifdef SSL_OP_NO_SSL_MASK
205     {"NO_SSL_MASK", SSL_OP_NO_SSL_MASK},
206 #endif
207 #ifdef SSL_OP_NO_DTLS_MASK
208     {"NO_DTLS_MASK", SSL_OP_NO_DTLS_MASK},
209 #endif
210 #ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
211     {"NO_ENCRYPT_THEN_MAC", SSL_OP_NO_ENCRYPT_THEN_MAC},
212 #endif
213 #ifdef SSL_OP_ALLOW_NO_DHE_KEX
214     {"ALLOW_NO_DHE_KEX", SSL_OP_ALLOW_NO_DHE_KEX},
215 #endif
216 #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
217     {"ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT},
218 #endif
219 #ifdef SSL_OP_NO_RENEGOTIATION
220     {"NO_RENEGOTIATION", SSL_OP_NO_RENEGOTIATION},
221 #endif
222 #ifdef SSL_OP_PRIORITIZE_CHACHA
223     {"PRIORITIZE_CHACHA", SSL_OP_PRIORITIZE_CHACHA},
224 #endif
225 #ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION
226     {"ALLOW_CLIENT_RENEGOTIATION", SSL_OP_ALLOW_CLIENT_RENEGOTIATION},
227 #endif
228 #ifdef SSL_OP_BIT
229     {"BIT", SSL_OP_BIT},
230 #endif
231 #ifdef SSL_OP_CLEANSE_PLAINTEXT
232     {"CLEANSE_PLAINTEXT", SSL_OP_CLEANSE_PLAINTEXT},
233 #endif
234 #ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES
235     {"DISABLE_TLSEXT_CA_NAMES", SSL_OP_DISABLE_TLSEXT_CA_NAMES},
236 #endif
237 #ifdef SSL_OP_ENABLE_KTLS
238     {"ENABLE_KTLS", SSL_OP_ENABLE_KTLS},
239 #endif
240 #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
241     {"IGNORE_UNEXPECTED_EOF", SSL_OP_IGNORE_UNEXPECTED_EOF},
242 #endif
243 #ifdef SSL_OP_NO_ANTI_REPLAY
244     {"NO_ANTI_REPLAY", SSL_OP_NO_ANTI_REPLAY},
245 #endif
246 #ifdef SSL_OP_NO_EXTENDED_MASTER_SECRET
247     {"NO_EXTENDED_MASTER_SECRET", SSL_OP_NO_EXTENDED_MASTER_SECRET},
248 #endif
249     {NULL, 0}
250 };
251 
252 NOEXPORT long unsigned parse_ssl_option(char *);
253 NOEXPORT void print_ssl_options(void);
254 
255 NOEXPORT SOCK_OPT *socket_options_init(void);
256 NOEXPORT void socket_option_set_int(SOCK_OPT *, char *, int, int);
257 NOEXPORT SOCK_OPT *socket_options_dup(SOCK_OPT *);
258 NOEXPORT void socket_options_free(SOCK_OPT *);
259 NOEXPORT int socket_options_print(void);
260 NOEXPORT char *socket_option_text(VAL_TYPE, OPT_UNION *);
261 NOEXPORT int socket_option_parse(SOCK_OPT *, char *);
262 
263 #ifndef OPENSSL_NO_OCSP
264 NOEXPORT unsigned long parse_ocsp_flag(char *);
265 #endif /* !defined(OPENSSL_NO_OCSP) */
266 
267 #ifndef OPENSSL_NO_ENGINE
268 NOEXPORT void engine_reset_list(void);
269 NOEXPORT char *engine_auto(void);
270 NOEXPORT char *engine_open(const char *);
271 NOEXPORT char *engine_ctrl(const char *, const char *);
272 NOEXPORT char *engine_default(const char *);
273 NOEXPORT char *engine_init(void);
274 NOEXPORT ENGINE *engine_get_by_id(const char *);
275 NOEXPORT ENGINE *engine_get_by_num(const int);
276 #endif /* !defined(OPENSSL_NO_ENGINE) */
277 
278 NOEXPORT char *include_config(char *, SERVICE_OPTIONS **);
279 
280 NOEXPORT void print_syntax(void);
281 
282 NOEXPORT void name_list_append(NAME_LIST **, char *);
283 NOEXPORT void name_list_dup(NAME_LIST **, NAME_LIST *);
284 NOEXPORT void name_list_free(NAME_LIST *);
285 #ifndef USE_WIN32
286 NOEXPORT char **arg_alloc(char *);
287 NOEXPORT char **arg_dup(char **);
288 NOEXPORT void arg_free(char **arg);
289 #endif
290 
291 char *configuration_file=NULL;
292 
293 GLOBAL_OPTIONS global_options;
294 SERVICE_OPTIONS service_options;
295 unsigned number_of_sections=0;
296 
297 static GLOBAL_OPTIONS new_global_options;
298 static SERVICE_OPTIONS new_service_options;
299 
300 static char *option_not_found=
301     "Specified option name is not valid here";
302 
303 static char *stunnel_cipher_list=
304     "HIGH:!aNULL:!SSLv2:!DH:!kDHEPSK";
305 
306 #ifndef OPENSSL_NO_TLS1_3
307 static char *stunnel_ciphersuites=
308     "TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256";
309 #endif /* TLS 1.3 */
310 
311 /**************************************** parse commandline parameters */
312 
313 /* return values:
314    0 - configuration accepted
315    1 - error
316    2 - information printed
317 */
318 
options_cmdline(char * arg1,char * arg2)319 int options_cmdline(char *arg1, char *arg2) {
320     char *name;
321     CONF_TYPE type;
322 
323 #ifdef USE_WIN32
324     (void)arg2; /* squash the unused parameter warning */
325 #endif
326     if(!arg1) {
327         name=
328 #ifdef CONFDIR
329             CONFDIR
330 #ifdef USE_WIN32
331             "\\"
332 #else
333             "/"
334 #endif
335 #endif
336             "stunnel.conf";
337         type=CONF_FILE;
338     } else if(!strcasecmp(arg1, "-help")) {
339         parse_global_option(CMD_PRINT_HELP, NULL, NULL, NULL);
340         parse_service_option(CMD_PRINT_HELP, NULL, NULL, NULL);
341         log_flush(LOG_MODE_INFO);
342         return 2;
343     } else if(!strcasecmp(arg1, "-version")) {
344         parse_global_option(CMD_PRINT_DEFAULTS, NULL, NULL, NULL);
345         parse_service_option(CMD_PRINT_DEFAULTS, NULL, NULL, NULL);
346         log_flush(LOG_MODE_INFO);
347         return 2;
348     } else if(!strcasecmp(arg1, "-sockets")) {
349         socket_options_print();
350         log_flush(LOG_MODE_INFO);
351         return 2;
352     } else if(!strcasecmp(arg1, "-options")) {
353         print_ssl_options();
354         log_flush(LOG_MODE_INFO);
355         return 2;
356     } else
357 #ifndef USE_WIN32
358     if(!strcasecmp(arg1, "-fd")) {
359         if(!arg2) {
360             s_log(LOG_ERR, "No file descriptor specified");
361             print_syntax();
362             return 1;
363         }
364         name=arg2;
365         type=CONF_FD;
366     } else
367 #endif
368     {
369         name=arg1;
370         type=CONF_FILE;
371     }
372 
373     if(type==CONF_FILE) {
374 #ifdef HAVE_REALPATH
375         char *buffer=NULL, *real_path;
376 #ifdef MAXPATHLEN
377         /* a workaround for pre-POSIX.1-2008 4.4BSD and Solaris */
378         buffer=malloc(MAXPATHLEN);
379 #endif
380         real_path=realpath(name, buffer);
381         if(!real_path) {
382             free(buffer);
383             s_log(LOG_ERR, "Invalid configuration file name \"%s\"", name);
384             ioerror("realpath");
385             return 1;
386         }
387         configuration_file=str_dup(real_path);
388         free(real_path);
389 #else
390         configuration_file=str_dup(name);
391 #endif
392 #ifndef USE_WIN32
393     } else if(type==CONF_FD) {
394         configuration_file=str_dup(name);
395 #endif
396     }
397     return options_parse(type);
398 }
399 
400 /**************************************** parse configuration file */
401 
options_parse(CONF_TYPE type)402 int options_parse(CONF_TYPE type) {
403     SERVICE_OPTIONS *section;
404 
405     options_defaults();
406     section=&new_service_options;
407     /* options_file() is a recursive function, so the last section of the
408      * configuration file section needs to be initialized separately */
409     if(options_file(configuration_file, type, &section) ||
410             init_section(1, &section)) {
411         s_log(LOG_ERR, "Configuration failed");
412         options_free(0); /* free the new options */
413         return 1;
414     }
415     s_log(LOG_NOTICE, "Configuration successful");
416     return 0;
417 }
418 
options_file(char * path,CONF_TYPE type,SERVICE_OPTIONS ** section_ptr)419 NOEXPORT int options_file(char *path, CONF_TYPE type,
420         SERVICE_OPTIONS **section_ptr) {
421     DISK_FILE *df;
422     char line_text[CONFLINELEN], *errstr;
423     char config_line[CONFLINELEN], *config_opt, *config_arg;
424     int i, line_number=0;
425 #ifndef USE_WIN32
426     int fd;
427     char *tmp_str;
428 #endif
429 
430     s_log(LOG_NOTICE, "Reading configuration from %s %s",
431         type==CONF_FD ? "descriptor" : "file", path);
432 #ifndef USE_WIN32
433     if(type==CONF_FD) { /* file descriptor */
434         fd=(int)strtol(path, &tmp_str, 10);
435         if(tmp_str==path || *tmp_str) { /* not a number */
436             s_log(LOG_ERR, "Invalid file descriptor number");
437             print_syntax();
438             return 1;
439         }
440         df=file_fdopen(fd);
441     } else
442 #endif
443         df=file_open(path, FILE_MODE_READ);
444     if(!df) {
445         s_log(LOG_ERR, "Cannot open configuration file");
446         if(type!=CONF_RELOAD)
447             print_syntax();
448         return 1;
449     }
450 
451     while(file_getline(df, line_text, CONFLINELEN)>=0) {
452         memcpy(config_line, line_text, CONFLINELEN);
453         ++line_number;
454         config_opt=config_line;
455         if(line_number==1) {
456             if(config_opt[0]==(char)0xef &&
457                     config_opt[1]==(char)0xbb &&
458                     config_opt[2]==(char)0xbf) {
459                 s_log(LOG_NOTICE, "UTF-8 byte order mark detected");
460                 config_opt+=3;
461             } else {
462                 s_log(LOG_NOTICE, "UTF-8 byte order mark not detected");
463             }
464         }
465 
466         while(isspace((unsigned char)*config_opt))
467             ++config_opt; /* remove initial whitespaces */
468         for(i=(int)strlen(config_opt)-1; i>=0 && isspace((unsigned char)config_opt[i]); --i)
469             config_opt[i]='\0'; /* remove trailing whitespaces */
470         if(config_opt[0]=='\0' || config_opt[0]=='#' || config_opt[0]==';') /* empty or comment */
471             continue;
472 
473         if(config_opt[0]=='[' && config_opt[strlen(config_opt)-1]==']') { /* new section */
474             if(init_section(0, section_ptr)) {
475                 file_close(df);
476                 return 1;
477             }
478 
479             /* append a new SERVICE_OPTIONS structure to the list */
480             {
481                 SERVICE_OPTIONS *new_section;
482                 new_section=str_alloc_detached(sizeof(SERVICE_OPTIONS));
483                 new_section->next=NULL;
484                 (*section_ptr)->next=new_section;
485                 *section_ptr=new_section;
486             }
487 
488             /* initialize the newly allocated section */
489             ++config_opt;
490             config_opt[strlen(config_opt)-1]='\0';
491             (*section_ptr)->servname=str_dup_detached(config_opt);
492             (*section_ptr)->session=NULL;
493             parse_service_option(CMD_SET_COPY, section_ptr, NULL, NULL);
494             continue;
495         }
496 
497         config_arg=strchr(config_line, '=');
498         if(!config_arg) {
499             s_log(LOG_ERR, "%s:%d: \"%s\": No '=' found",
500                 path, line_number, line_text);
501             file_close(df);
502             return 1;
503         }
504         *config_arg++='\0'; /* split into option name and argument value */
505         for(i=(int)strlen(config_opt)-1; i>=0 && isspace((unsigned char)config_opt[i]); --i)
506             config_opt[i]='\0'; /* remove trailing whitespaces */
507         while(isspace((unsigned char)*config_arg))
508             ++config_arg; /* remove initial whitespaces */
509 
510         errstr=option_not_found;
511         /* try global options first (e.g. for 'debug') */
512         if(!new_service_options.next)
513             errstr=parse_global_option(CMD_SET_VALUE, &new_global_options, config_opt, config_arg);
514         if(errstr==option_not_found)
515             errstr=parse_service_option(CMD_SET_VALUE, section_ptr, config_opt, config_arg);
516         if(errstr) {
517             s_log(LOG_ERR, "%s:%d: \"%s\": %s",
518                 path, line_number, line_text, errstr);
519             file_close(df);
520             return 1;
521         }
522     }
523     file_close(df);
524     return 0;
525 }
526 
init_section(int eof,SERVICE_OPTIONS ** section_ptr)527 NOEXPORT int init_section(int eof, SERVICE_OPTIONS **section_ptr) {
528     char *errstr;
529 
530 #ifndef USE_WIN32
531     (*section_ptr)->option.log_stderr=new_global_options.option.log_stderr;
532 #endif /* USE_WIN32 */
533 
534     if(*section_ptr==&new_service_options) {
535         /* end of global options or inetd mode -> initialize globals */
536         errstr=parse_global_option(CMD_INITIALIZE, &new_global_options, NULL, NULL);
537         if(errstr) {
538             s_log(LOG_ERR, "Global options: %s", errstr);
539             return 1;
540         }
541     }
542 
543     if(*section_ptr!=&new_service_options || eof) {
544         /* end service section or inetd mode -> initialize service */
545         errstr=parse_service_option(CMD_INITIALIZE, section_ptr, NULL, NULL);
546         if(errstr) {
547             if(*section_ptr==&new_service_options)
548                 s_log(LOG_ERR, "Inetd mode: %s", errstr);
549             else
550                 s_log(LOG_ERR, "Service [%s]: %s",
551                     (*section_ptr)->servname, errstr);
552             return 1;
553         }
554     }
555     return 0;
556 }
557 
558 #ifdef USE_WIN32
559 
scandir(const char * dirp,struct dirent *** namelist,int (* filter)(const struct dirent *),int (* compar)(const struct dirent **,const struct dirent **))560 int scandir(const char *dirp, struct dirent ***namelist,
561         int (*filter)(const struct dirent *),
562         int (*compar)(const struct dirent **, const struct dirent **)) {
563     WIN32_FIND_DATA data;
564     HANDLE h;
565     unsigned num=0, allocated=0;
566     LPTSTR path, pattern;
567     char *name;
568     DWORD saved_errno;
569 
570     (void)filter; /* squash the unused parameter warning */
571     (void)compar; /* squash the unused parameter warning */
572     path=str2tstr(dirp);
573     pattern=str_tprintf(TEXT("%s\\*"), path);
574     str_free(path);
575     h=FindFirstFile(pattern, &data);
576     saved_errno=GetLastError();
577     str_free(pattern);
578     SetLastError(saved_errno);
579     if(h==INVALID_HANDLE_VALUE)
580         return -1;
581     *namelist=NULL;
582     do {
583         if(num>=allocated) {
584             allocated+=16;
585             *namelist=realloc(*namelist, allocated*sizeof(**namelist));
586         }
587         (*namelist)[num]=malloc(sizeof(struct dirent));
588         if(!(*namelist)[num])
589             return -1;
590         name=tstr2str(data.cFileName);
591         strncpy((*namelist)[num]->d_name, name, MAX_PATH-1);
592         (*namelist)[num]->d_name[MAX_PATH-1]='\0';
593         str_free(name);
594         ++num;
595     } while(FindNextFile(h, &data));
596     FindClose(h);
597     return (int)num;
598 }
599 
alphasort(const struct dirent ** a,const struct dirent ** b)600 int alphasort(const struct dirent **a, const struct dirent **b) {
601     (void)a; /* squash the unused parameter warning */
602     (void)b; /* squash the unused parameter warning */
603     /* most Windows filesystem return sorted data */
604     return 0;
605 }
606 
607 #endif
608 
options_defaults()609 void options_defaults() {
610     SERVICE_OPTIONS *service;
611 
612     /* initialize globals *before* opening the config file */
613     memset(&new_global_options, 0, sizeof(GLOBAL_OPTIONS));
614     memset(&new_service_options, 0, sizeof(SERVICE_OPTIONS));
615     new_service_options.next=NULL;
616 
617     parse_global_option(CMD_SET_DEFAULTS, &new_global_options, NULL, NULL);
618     service=&new_service_options;
619     parse_service_option(CMD_SET_DEFAULTS, &service, NULL, NULL);
620 }
621 
options_apply()622 void options_apply() { /* apply default/validated configuration */
623     unsigned num=0;
624     SERVICE_OPTIONS *section;
625 
626     CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_SECTIONS]);
627 
628     memcpy(&global_options, &new_global_options, sizeof(GLOBAL_OPTIONS));
629     memset(&new_global_options, 0, sizeof(GLOBAL_OPTIONS));
630 
631     /* service_options are used for inetd mode and to enumerate services */
632     for(section=new_service_options.next; section; section=section->next)
633         section->section_number=num++;
634     memcpy(&service_options, &new_service_options, sizeof(SERVICE_OPTIONS));
635     memset(&new_service_options, 0, sizeof(SERVICE_OPTIONS));
636     number_of_sections=num;
637 
638     CRYPTO_THREAD_unlock(stunnel_locks[LOCK_SECTIONS]);
639 }
640 
options_free(int current)641 void options_free(int current) {
642     GLOBAL_OPTIONS *global=current?&global_options:&new_global_options;
643     SERVICE_OPTIONS *service=current?&service_options:&new_service_options;
644 
645     parse_global_option(CMD_FREE, global, NULL, NULL);
646 
647     CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_SECTIONS]);
648     while(service) {
649         SERVICE_OPTIONS *tmp=service;
650         service=service->next;
651         tmp->next=NULL;
652         service_free(tmp);
653     }
654     CRYPTO_THREAD_unlock(stunnel_locks[LOCK_SECTIONS]);
655 }
656 
service_up_ref(SERVICE_OPTIONS * section)657 void service_up_ref(SERVICE_OPTIONS *section) {
658 #ifdef USE_OS_THREADS
659     int ref;
660 
661     CRYPTO_atomic_add(&section->ref, 1, &ref, stunnel_locks[LOCK_REF]);
662 #else
663     ++(section->ref);
664 #endif
665 }
666 
service_free(SERVICE_OPTIONS * section)667 void service_free(SERVICE_OPTIONS *section) {
668     int ref;
669 
670 #ifdef USE_OS_THREADS
671     CRYPTO_atomic_add(&section->ref, -1, &ref, stunnel_locks[LOCK_REF]);
672 #else
673     ref=--(section->ref);
674 #endif
675     if(ref<0)
676         fatal("Negative section reference counter");
677     if(ref==0)
678         parse_service_option(CMD_FREE, &section, NULL, NULL);
679 }
680 
681 /**************************************** global options */
682 
parse_global_option(CMD cmd,GLOBAL_OPTIONS * options,char * opt,char * arg)683 NOEXPORT char *parse_global_option(CMD cmd, GLOBAL_OPTIONS *options, char *opt, char *arg) {
684     void *tmp;
685 
686     if(cmd==CMD_PRINT_DEFAULTS || cmd==CMD_PRINT_HELP) {
687         s_log(LOG_NOTICE, " ");
688         s_log(LOG_NOTICE, "Global options:");
689     }
690 
691     /* chroot */
692 #ifdef HAVE_CHROOT
693     switch(cmd) {
694     case CMD_SET_DEFAULTS:
695         options->chroot_dir=NULL;
696         break;
697     case CMD_SET_COPY: /* not used for global options */
698         break;
699     case CMD_FREE:
700         tmp=options->chroot_dir;
701         options->chroot_dir=NULL;
702         str_free(tmp);
703         break;
704     case CMD_SET_VALUE:
705         if(strcasecmp(opt, "chroot"))
706             break;
707         options->chroot_dir=str_dup(arg);
708         return NULL; /* OK */
709     case CMD_INITIALIZE:
710         break;
711     case CMD_PRINT_DEFAULTS:
712         break;
713     case CMD_PRINT_HELP:
714         s_log(LOG_NOTICE, "%-22s = directory to chroot stunnel process", "chroot");
715         break;
716     }
717 #endif /* HAVE_CHROOT */
718 
719     /* compression */
720 #ifndef OPENSSL_NO_COMP
721     switch(cmd) {
722     case CMD_SET_DEFAULTS:
723         options->compression=COMP_NONE;
724         break;
725     case CMD_SET_COPY: /* not used for global options */
726         break;
727     case CMD_FREE:
728         break;
729     case CMD_SET_VALUE:
730         if(strcasecmp(opt, "compression"))
731             break;
732 #if OPENSSL_VERSION_NUMBER < 0x10100000L
733         /* only allow compression with OpenSSL 0.9.8 or later
734          * with OpenSSL #1468 zlib memory leak fixed */
735         if(OpenSSL_version_num()<0x00908051L) /* 0.9.8e-beta1 */
736             return "Compression unsupported due to a memory leak";
737 #endif /* OpenSSL version < 1.1.0 */
738         if(!strcasecmp(arg, "deflate"))
739             options->compression=COMP_DEFLATE;
740         else if(!strcasecmp(arg, "zlib"))
741             options->compression=COMP_ZLIB;
742         else
743             return "Specified compression type is not available";
744         return NULL; /* OK */
745     case CMD_INITIALIZE:
746         break;
747     case CMD_PRINT_DEFAULTS:
748         break;
749     case CMD_PRINT_HELP:
750         s_log(LOG_NOTICE, "%-22s = compression type",
751             "compression");
752         break;
753     }
754 #endif /* !defined(OPENSSL_NO_COMP) */
755 
756     /* EGD */
757     switch(cmd) {
758     case CMD_SET_DEFAULTS:
759 #ifdef EGD_SOCKET
760         options->egd_sock=EGD_SOCKET;
761 #else
762         options->egd_sock=NULL;
763 #endif
764         break;
765     case CMD_SET_COPY: /* not used for global options */
766         break;
767     case CMD_FREE:
768         tmp=options->egd_sock;
769         options->egd_sock=NULL;
770         str_free(tmp);
771         break;
772     case CMD_SET_VALUE:
773         if(strcasecmp(opt, "EGD"))
774             break;
775         options->egd_sock=str_dup(arg);
776         return NULL; /* OK */
777     case CMD_INITIALIZE:
778         break;
779     case CMD_PRINT_DEFAULTS:
780 #ifdef EGD_SOCKET
781         s_log(LOG_NOTICE, "%-22s = %s", "EGD", EGD_SOCKET);
782 #endif
783         break;
784     case CMD_PRINT_HELP:
785         s_log(LOG_NOTICE, "%-22s = path to Entropy Gathering Daemon socket", "EGD");
786         break;
787     }
788 
789 #ifndef OPENSSL_NO_ENGINE
790 
791     /* engine */
792     switch(cmd) {
793     case CMD_SET_DEFAULTS:
794         engine_reset_list();
795         break;
796     case CMD_SET_COPY: /* not used for global options */
797         break;
798     case CMD_FREE:
799         /* FIXME: investigate if we can free it */
800         break;
801     case CMD_SET_VALUE:
802         if(strcasecmp(opt, "engine"))
803             break;
804         if(!strcasecmp(arg, "auto"))
805             return engine_auto();
806         else
807             return engine_open(arg);
808     case CMD_INITIALIZE:
809         engine_init();
810         break;
811     case CMD_PRINT_DEFAULTS:
812         break;
813     case CMD_PRINT_HELP:
814         s_log(LOG_NOTICE, "%-22s = auto|engine_id",
815             "engine");
816         break;
817     }
818 
819     /* engineCtrl */
820     switch(cmd) {
821     case CMD_SET_DEFAULTS:
822         break;
823     case CMD_SET_COPY: /* not used for global options */
824         break;
825     case CMD_FREE:
826         break;
827     case CMD_SET_VALUE:
828         if(strcasecmp(opt, "engineCtrl"))
829             break;
830         {
831             char *tmp_str=strchr(arg, ':');
832             if(tmp_str)
833                 *tmp_str++='\0';
834             return engine_ctrl(arg, tmp_str);
835         }
836     case CMD_INITIALIZE:
837         break;
838     case CMD_PRINT_DEFAULTS:
839         break;
840     case CMD_PRINT_HELP:
841         s_log(LOG_NOTICE, "%-22s = cmd[:arg]",
842             "engineCtrl");
843         break;
844     }
845 
846     /* engineDefault */
847     switch(cmd) {
848     case CMD_SET_DEFAULTS:
849         break;
850     case CMD_SET_COPY: /* not used for global options */
851         break;
852     case CMD_FREE:
853         break;
854     case CMD_SET_VALUE:
855         if(strcasecmp(opt, "engineDefault"))
856             break;
857         return engine_default(arg);
858     case CMD_INITIALIZE:
859         break;
860     case CMD_PRINT_DEFAULTS:
861         break;
862     case CMD_PRINT_HELP:
863         s_log(LOG_NOTICE, "%-22s = TASK_LIST",
864             "engineDefault");
865         break;
866     }
867 
868 #endif /* !defined(OPENSSL_NO_ENGINE) */
869 
870     /* fips */
871     switch(cmd) {
872     case CMD_SET_DEFAULTS:
873 #ifdef USE_FIPS
874 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
875         options->option.fips=0;
876 #else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
877         options->option.fips=FIPS_mode()?1:0;
878 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
879 #endif /* USE_FIPS */
880         break;
881     case CMD_SET_COPY: /* not used for global options */
882         break;
883     case CMD_FREE:
884         break;
885     case CMD_SET_VALUE:
886         if(strcasecmp(opt, "fips"))
887             break;
888         if(!strcasecmp(arg, "yes")) {
889 #ifdef USE_FIPS
890             options->option.fips=1;
891 #else
892             return "FIPS support is not available";
893 #endif /* USE_FIPS */
894         } else if(!strcasecmp(arg, "no")) {
895 #ifdef USE_FIPS
896 #if OPENSSL_VERSION_NUMBER < 0x30000000L
897             if(FIPS_mode())
898                 return "Failed to override system-wide FIPS mode";
899 #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
900             options->option.fips=0;
901 #endif /* USE_FIPS */
902         } else {
903             return "The argument needs to be either 'yes' or 'no'";
904         }
905         return NULL; /* OK */
906     case CMD_INITIALIZE:
907         break;
908     case CMD_PRINT_DEFAULTS:
909 #ifdef USE_FIPS
910 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
911         if(fips_available())
912             s_log(LOG_NOTICE, "%-22s = %s", "fips", "no");
913 #else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
914         if(fips_available())
915             s_log(LOG_NOTICE, "%-22s = %s", "fips", FIPS_mode()?"yes":"no");
916 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
917 #endif /* USE_FIPS */
918         break;
919     case CMD_PRINT_HELP:
920         if(fips_available())
921             s_log(LOG_NOTICE, "%-22s = yes|no FIPS 140-2 mode",
922                 "fips");
923         break;
924     }
925 
926     /* foreground */
927 #ifndef USE_WIN32
928     switch(cmd) {
929     case CMD_SET_DEFAULTS:
930         options->option.foreground=0;
931         options->option.log_stderr=0;
932         break;
933     case CMD_SET_COPY: /* not used for global options */
934         break;
935     case CMD_FREE:
936         break;
937     case CMD_SET_VALUE:
938         if(strcasecmp(opt, "foreground"))
939             break;
940         if(!strcasecmp(arg, "yes")) {
941             options->option.foreground=1;
942             options->option.log_stderr=1;
943         } else if(!strcasecmp(arg, "quiet")) {
944             options->option.foreground=1;
945             options->option.log_stderr=0;
946         } else if(!strcasecmp(arg, "no")) {
947             options->option.foreground=0;
948             options->option.log_stderr=0;
949         } else
950             return "The argument needs to be either 'yes', 'quiet' or 'no'";
951         return NULL; /* OK */
952     case CMD_INITIALIZE:
953         break;
954     case CMD_PRINT_DEFAULTS:
955         break;
956     case CMD_PRINT_HELP:
957         s_log(LOG_NOTICE, "%-22s = yes|quiet|no foreground mode (don't fork, log to stderr)",
958             "foreground");
959         break;
960     }
961 #endif
962 
963 #ifdef ICON_IMAGE
964 
965     /* iconActive */
966     switch(cmd) {
967     case CMD_SET_DEFAULTS:
968         options->icon[ICON_ACTIVE]=load_icon_default(ICON_ACTIVE);
969         break;
970     case CMD_SET_COPY: /* not used for global options */
971         break;
972     case CMD_FREE:
973         /* FIXME: investigate if we can free it */
974         break;
975     case CMD_SET_VALUE:
976         if(strcasecmp(opt, "iconActive"))
977             break;
978         if(!(options->icon[ICON_ACTIVE]=load_icon_file(arg)))
979             return "Failed to load the specified icon";
980         return NULL; /* OK */
981     case CMD_INITIALIZE:
982         break;
983     case CMD_PRINT_DEFAULTS:
984         break;
985     case CMD_PRINT_HELP:
986         s_log(LOG_NOTICE, "%-22s = icon when connections are established", "iconActive");
987         break;
988     }
989 
990     /* iconError */
991     switch(cmd) {
992     case CMD_SET_DEFAULTS:
993         options->icon[ICON_ERROR]=load_icon_default(ICON_ERROR);
994         break;
995     case CMD_SET_COPY: /* not used for global options */
996         break;
997     case CMD_FREE:
998         /* FIXME: investigate if we can free it */
999         break;
1000     case CMD_SET_VALUE:
1001         if(strcasecmp(opt, "iconError"))
1002             break;
1003         if(!(options->icon[ICON_ERROR]=load_icon_file(arg)))
1004             return "Failed to load the specified icon";
1005         return NULL; /* OK */
1006     case CMD_INITIALIZE:
1007         break;
1008     case CMD_PRINT_DEFAULTS:
1009         break;
1010     case CMD_PRINT_HELP:
1011         s_log(LOG_NOTICE, "%-22s = icon for invalid configuration file", "iconError");
1012         break;
1013     }
1014 
1015     /* iconIdle */
1016     switch(cmd) {
1017     case CMD_SET_DEFAULTS:
1018         options->icon[ICON_IDLE]=load_icon_default(ICON_IDLE);
1019         break;
1020     case CMD_SET_COPY: /* not used for global options */
1021         break;
1022     case CMD_FREE:
1023         /* FIXME: investigate if we can free it */
1024         break;
1025     case CMD_SET_VALUE:
1026         if(strcasecmp(opt, "iconIdle"))
1027             break;
1028         if(!(options->icon[ICON_IDLE]=load_icon_file(arg)))
1029             return "Failed to load the specified icon";
1030         return NULL; /* OK */
1031     case CMD_INITIALIZE:
1032         break;
1033     case CMD_PRINT_DEFAULTS:
1034         break;
1035     case CMD_PRINT_HELP:
1036         s_log(LOG_NOTICE, "%-22s = icon when no connections were established", "iconIdle");
1037         break;
1038     }
1039 
1040 #endif /* ICON_IMAGE */
1041 
1042     /* log */
1043     switch(cmd) {
1044     case CMD_SET_DEFAULTS:
1045         options->log_file_mode=FILE_MODE_APPEND;
1046         break;
1047     case CMD_SET_COPY: /* not used for global options */
1048         break;
1049     case CMD_FREE:
1050         break;
1051     case CMD_SET_VALUE:
1052         if(strcasecmp(opt, "log"))
1053             break;
1054         if(!strcasecmp(arg, "append"))
1055             options->log_file_mode=FILE_MODE_APPEND;
1056         else if(!strcasecmp(arg, "overwrite"))
1057             options->log_file_mode=FILE_MODE_OVERWRITE;
1058         else
1059             return "The argument needs to be either 'append' or 'overwrite'";
1060         return NULL; /* OK */
1061     case CMD_INITIALIZE:
1062         break;
1063     case CMD_PRINT_DEFAULTS:
1064         break;
1065     case CMD_PRINT_HELP:
1066         s_log(LOG_NOTICE, "%-22s = append|overwrite log file",
1067             "log");
1068         break;
1069     }
1070 
1071     /* output */
1072     switch(cmd) {
1073     case CMD_SET_DEFAULTS:
1074         options->output_file=NULL;
1075         break;
1076     case CMD_SET_COPY: /* not used for global options */
1077         break;
1078     case CMD_FREE:
1079         tmp=options->output_file;
1080         options->output_file=NULL;
1081         str_free(tmp);
1082         break;
1083     case CMD_SET_VALUE:
1084         if(strcasecmp(opt, "output"))
1085             break;
1086         options->output_file=str_dup(arg);
1087         return NULL; /* OK */
1088     case CMD_INITIALIZE:
1089 #ifndef USE_WIN32
1090         if(!options->option.foreground /* daemonize() used */ &&
1091                 options->output_file /* log file enabled */ &&
1092                 options->output_file[0]!='/' /* relative path */)
1093             return "Log file must include full path name";
1094 #endif
1095         break;
1096     case CMD_PRINT_DEFAULTS:
1097         break;
1098     case CMD_PRINT_HELP:
1099         s_log(LOG_NOTICE, "%-22s = file to append log messages", "output");
1100         break;
1101     }
1102 
1103     /* pid */
1104 #ifndef USE_WIN32
1105     switch(cmd) {
1106     case CMD_SET_DEFAULTS:
1107         options->pidfile=NULL; /* do not create a pid file */
1108         break;
1109     case CMD_SET_COPY: /* not used for global options */
1110         break;
1111     case CMD_FREE:
1112         tmp=options->pidfile;
1113         options->pidfile=NULL;
1114         str_free(tmp);
1115         break;
1116     case CMD_SET_VALUE:
1117         if(strcasecmp(opt, "pid"))
1118             break;
1119         if(arg[0]) /* is argument not empty? */
1120             options->pidfile=str_dup(arg);
1121         else
1122             options->pidfile=NULL; /* empty -> do not create a pid file */
1123         return NULL; /* OK */
1124     case CMD_INITIALIZE:
1125         if(!options->option.foreground /* daemonize() used */ &&
1126                 options->pidfile /* pid file enabled */ &&
1127                 options->pidfile[0]!='/' /* relative path */)
1128             return "Pid file must include full path name";
1129         break;
1130     case CMD_PRINT_DEFAULTS:
1131         break;
1132     case CMD_PRINT_HELP:
1133         s_log(LOG_NOTICE, "%-22s = pid file", "pid");
1134         break;
1135     }
1136 #endif
1137 
1138     /* RNDbytes */
1139     switch(cmd) {
1140     case CMD_SET_DEFAULTS:
1141         options->random_bytes=RANDOM_BYTES;
1142         break;
1143     case CMD_SET_COPY: /* not used for global options */
1144         break;
1145     case CMD_FREE:
1146         break;
1147     case CMD_SET_VALUE:
1148         if(strcasecmp(opt, "RNDbytes"))
1149             break;
1150         {
1151             char *tmp_str;
1152             options->random_bytes=(long)strtol(arg, &tmp_str, 10);
1153             if(tmp_str==arg || *tmp_str) /* not a number */
1154                 return "Illegal number of bytes to read from random seed files";
1155         }
1156         return NULL; /* OK */
1157     case CMD_INITIALIZE:
1158         break;
1159     case CMD_PRINT_DEFAULTS:
1160         s_log(LOG_NOTICE, "%-22s = %d", "RNDbytes", RANDOM_BYTES);
1161         break;
1162     case CMD_PRINT_HELP:
1163         s_log(LOG_NOTICE, "%-22s = bytes to read from random seed files", "RNDbytes");
1164         break;
1165     }
1166 
1167     /* RNDfile */
1168     switch(cmd) {
1169     case CMD_SET_DEFAULTS:
1170 #ifdef RANDOM_FILE
1171         options->rand_file=str_dup(RANDOM_FILE);
1172 #else
1173         options->rand_file=NULL;
1174 #endif
1175         break;
1176     case CMD_SET_COPY: /* not used for global options */
1177         break;
1178     case CMD_FREE:
1179         tmp=options->rand_file;
1180         options->rand_file=NULL;
1181         str_free(tmp);
1182         break;
1183     case CMD_SET_VALUE:
1184         if(strcasecmp(opt, "RNDfile"))
1185             break;
1186         options->rand_file=str_dup(arg);
1187         return NULL; /* OK */
1188     case CMD_INITIALIZE:
1189         break;
1190     case CMD_PRINT_DEFAULTS:
1191 #ifdef RANDOM_FILE
1192         s_log(LOG_NOTICE, "%-22s = %s", "RNDfile", RANDOM_FILE);
1193 #endif
1194         break;
1195     case CMD_PRINT_HELP:
1196         s_log(LOG_NOTICE, "%-22s = path to file with random seed data", "RNDfile");
1197         break;
1198     }
1199 
1200     /* RNDoverwrite */
1201     switch(cmd) {
1202     case CMD_SET_DEFAULTS:
1203         options->option.rand_write=1;
1204         break;
1205     case CMD_SET_COPY: /* not used for global options */
1206         break;
1207     case CMD_FREE:
1208         break;
1209     case CMD_SET_VALUE:
1210         if(strcasecmp(opt, "RNDoverwrite"))
1211             break;
1212         if(!strcasecmp(arg, "yes"))
1213             options->option.rand_write=1;
1214         else if(!strcasecmp(arg, "no"))
1215             options->option.rand_write=0;
1216         else
1217             return "The argument needs to be either 'yes' or 'no'";
1218         return NULL; /* OK */
1219     case CMD_INITIALIZE:
1220         break;
1221     case CMD_PRINT_DEFAULTS:
1222         s_log(LOG_NOTICE, "%-22s = yes", "RNDoverwrite");
1223         break;
1224     case CMD_PRINT_HELP:
1225         s_log(LOG_NOTICE, "%-22s = yes|no overwrite seed datafiles with new random data",
1226             "RNDoverwrite");
1227         break;
1228     }
1229 
1230     /* syslog */
1231 #ifndef USE_WIN32
1232     switch(cmd) {
1233     case CMD_SET_DEFAULTS:
1234         options->option.log_syslog=1;
1235         break;
1236     case CMD_SET_COPY: /* not used for global options */
1237         break;
1238     case CMD_FREE:
1239         break;
1240     case CMD_SET_VALUE:
1241         if(strcasecmp(opt, "syslog"))
1242             break;
1243         if(!strcasecmp(arg, "yes"))
1244             options->option.log_syslog=1;
1245         else if(!strcasecmp(arg, "no"))
1246             options->option.log_syslog=0;
1247         else
1248             return "The argument needs to be either 'yes' or 'no'";
1249         return NULL; /* OK */
1250     case CMD_INITIALIZE:
1251         break;
1252     case CMD_PRINT_DEFAULTS:
1253         break;
1254     case CMD_PRINT_HELP:
1255         s_log(LOG_NOTICE, "%-22s = yes|no send logging messages to syslog",
1256             "syslog");
1257         break;
1258     }
1259 #endif
1260 
1261     /* taskbar */
1262 #ifdef USE_WIN32
1263     switch(cmd) {
1264     case CMD_SET_DEFAULTS:
1265         options->option.taskbar=1;
1266         break;
1267     case CMD_SET_COPY: /* not used for global options */
1268         break;
1269     case CMD_FREE:
1270         break;
1271     case CMD_SET_VALUE:
1272         if(strcasecmp(opt, "taskbar"))
1273             break;
1274         if(!strcasecmp(arg, "yes"))
1275             options->option.taskbar=1;
1276         else if(!strcasecmp(arg, "no"))
1277             options->option.taskbar=0;
1278         else
1279             return "The argument needs to be either 'yes' or 'no'";
1280         return NULL; /* OK */
1281     case CMD_INITIALIZE:
1282         break;
1283     case CMD_PRINT_DEFAULTS:
1284         s_log(LOG_NOTICE, "%-22s = yes", "taskbar");
1285         break;
1286     case CMD_PRINT_HELP:
1287         s_log(LOG_NOTICE, "%-22s = yes|no enable the taskbar icon", "taskbar");
1288         break;
1289     }
1290 #endif
1291 
1292     /* final checks */
1293     switch(cmd) {
1294     case CMD_SET_DEFAULTS:
1295         break;
1296     case CMD_SET_COPY:
1297         break;
1298     case CMD_FREE:
1299         memset(options, 0, sizeof(GLOBAL_OPTIONS));
1300         break;
1301     case CMD_SET_VALUE:
1302         return option_not_found;
1303     case CMD_INITIALIZE:
1304         /* FIPS needs to be initialized as early as possible */
1305         if(ssl_configure(options)) /* configure global TLS settings */
1306             return "Failed to initialize TLS";
1307     case CMD_PRINT_DEFAULTS:
1308         break;
1309     case CMD_PRINT_HELP:
1310         break;
1311     }
1312     return NULL; /* OK */
1313 }
1314 
1315 /**************************************** service-level options */
1316 
parse_service_option(CMD cmd,SERVICE_OPTIONS ** section_ptr,char * opt,char * arg)1317 NOEXPORT char *parse_service_option(CMD cmd, SERVICE_OPTIONS **section_ptr,
1318         char *opt, char *arg) {
1319     SERVICE_OPTIONS *section;
1320     int endpoints=0;
1321 #ifndef USE_WIN32
1322     struct group *gr;
1323     struct passwd *pw;
1324 #endif
1325 
1326     section=section_ptr ? *section_ptr : NULL;
1327 
1328     if(cmd==CMD_SET_DEFAULTS || cmd==CMD_SET_COPY) {
1329         section->ref=1;
1330         if(section==&service_options)
1331             s_log(LOG_ERR, "INTERNAL ERROR: Initializing deployed section defaults");
1332         else if(section==&new_service_options)
1333             s_log(LOG_INFO, "Initializing inetd mode configuration");
1334         else
1335             s_log(LOG_INFO, "Initializing service [%s]", section->servname);
1336     } else if(cmd==CMD_FREE) {
1337         if(section==&service_options)
1338             s_log(LOG_DEBUG, "Deallocating deployed section defaults");
1339         else if(section==&new_service_options)
1340             s_log(LOG_DEBUG, "Deallocating temporary section defaults");
1341         else
1342             s_log(LOG_DEBUG, "Deallocating section [%s]", section->servname);
1343     } else if(cmd==CMD_PRINT_DEFAULTS || cmd==CMD_PRINT_HELP) {
1344         s_log(LOG_NOTICE, " ");
1345         s_log(LOG_NOTICE, "Service-level options:");
1346     }
1347 
1348     /* accept */
1349     switch(cmd) {
1350     case CMD_SET_DEFAULTS:
1351         addrlist_clear(&section->local_addr, 1);
1352         section->local_fd=NULL;
1353         break;
1354     case CMD_SET_COPY:
1355         addrlist_clear(&section->local_addr, 1);
1356         section->local_fd=NULL;
1357         name_list_dup(&section->local_addr.names,
1358             new_service_options.local_addr.names);
1359         break;
1360     case CMD_FREE:
1361         name_list_free(section->local_addr.names);
1362         str_free(section->local_addr.addr);
1363         str_free(section->local_fd);
1364         break;
1365     case CMD_SET_VALUE:
1366         if(strcasecmp(opt, "accept"))
1367             break;
1368         section->option.accept=1;
1369         name_list_append(&section->local_addr.names, arg);
1370         return NULL; /* OK */
1371     case CMD_INITIALIZE:
1372         if(section->local_addr.names) {
1373             unsigned i;
1374             if(!addrlist_resolve(&section->local_addr))
1375                 return "Cannot resolve accept target";
1376             section->local_fd=str_alloc_detached(section->local_addr.num*sizeof(SOCKET));
1377             for(i=0; i<section->local_addr.num; ++i)
1378                 section->local_fd[i]=INVALID_SOCKET;
1379             ++endpoints;
1380         }
1381         break;
1382     case CMD_PRINT_DEFAULTS:
1383         break;
1384     case CMD_PRINT_HELP:
1385         s_log(LOG_NOTICE, "%-22s = [host:]port accept connections on specified host:port",
1386             "accept");
1387         break;
1388     }
1389 
1390     /* CApath */
1391     switch(cmd) {
1392     case CMD_SET_DEFAULTS:
1393 #if 0
1394         section->ca_dir=(char *)X509_get_default_cert_dir();
1395 #endif
1396         section->ca_dir=NULL;
1397         break;
1398     case CMD_SET_COPY:
1399         section->ca_dir=str_dup_detached(new_service_options.ca_dir);
1400         break;
1401     case CMD_FREE:
1402         str_free(section->ca_dir);
1403         break;
1404     case CMD_SET_VALUE:
1405         if(strcasecmp(opt, "CApath"))
1406             break;
1407         str_free(section->ca_dir);
1408         if(arg[0]) /* not empty */
1409             section->ca_dir=str_dup_detached(arg);
1410         else
1411             section->ca_dir=NULL;
1412         return NULL; /* OK */
1413     case CMD_INITIALIZE:
1414         break;
1415     case CMD_PRINT_DEFAULTS:
1416 #if 0
1417         s_log(LOG_NOTICE, "%-22s = %s", "CApath",
1418             section->ca_dir ? section->ca_dir : "(none)");
1419 #endif
1420         break;
1421     case CMD_PRINT_HELP:
1422         s_log(LOG_NOTICE, "%-22s = CA certificate directory for 'verify' option",
1423             "CApath");
1424         break;
1425     }
1426 
1427     /* CAfile */
1428     switch(cmd) {
1429     case CMD_SET_DEFAULTS:
1430 #if 0
1431         section->ca_file=(char *)X509_get_default_certfile();
1432 #endif
1433         section->ca_file=NULL;
1434         break;
1435     case CMD_SET_COPY:
1436         section->ca_file=str_dup_detached(new_service_options.ca_file);
1437         break;
1438     case CMD_FREE:
1439         str_free(section->ca_file);
1440         break;
1441     case CMD_SET_VALUE:
1442         if(strcasecmp(opt, "CAfile"))
1443             break;
1444         str_free(section->ca_file);
1445         if(arg[0]) /* not empty */
1446             section->ca_file=str_dup_detached(arg);
1447         else
1448             section->ca_file=NULL;
1449         return NULL; /* OK */
1450     case CMD_INITIALIZE:
1451         break;
1452     case CMD_PRINT_DEFAULTS:
1453 #if 0
1454         s_log(LOG_NOTICE, "%-22s = %s", "CAfile",
1455             section->ca_file ? section->ca_file : "(none)");
1456 #endif
1457         break;
1458     case CMD_PRINT_HELP:
1459         s_log(LOG_NOTICE, "%-22s = CA certificate file for 'verify' option",
1460             "CAfile");
1461         break;
1462     }
1463 
1464     /* cert */
1465     switch(cmd) {
1466     case CMD_SET_DEFAULTS:
1467         section->cert=NULL;
1468         break;
1469     case CMD_SET_COPY:
1470         section->cert=str_dup_detached(new_service_options.cert);
1471         break;
1472     case CMD_FREE:
1473         str_free(section->cert);
1474         break;
1475     case CMD_SET_VALUE:
1476         if(strcasecmp(opt, "cert"))
1477             break;
1478         str_free(section->cert);
1479         section->cert=str_dup_detached(arg);
1480         return NULL; /* OK */
1481     case CMD_INITIALIZE:
1482 #ifndef OPENSSL_NO_PSK
1483         if(section->psk_keys)
1484             break;
1485 #endif /* !defined(OPENSSL_NO_PSK) */
1486 #ifndef OPENSSL_NO_ENGINE
1487         if(section->engine)
1488             break;
1489 #endif /* !defined(OPENSSL_NO_ENGINE) */
1490         if(!section->option.client && !section->cert)
1491             return "TLS server needs a certificate";
1492         break;
1493     case CMD_PRINT_DEFAULTS:
1494         break; /* no default certificate */
1495     case CMD_PRINT_HELP:
1496         s_log(LOG_NOTICE, "%-22s = certificate chain", "cert");
1497         break;
1498     }
1499 
1500 #if OPENSSL_VERSION_NUMBER>=0x10002000L
1501 
1502     /* checkEmail */
1503     switch(cmd) {
1504     case CMD_SET_DEFAULTS:
1505         section->check_email=NULL;
1506         break;
1507     case CMD_SET_COPY:
1508         name_list_dup(&section->check_email,
1509             new_service_options.check_email);
1510         break;
1511     case CMD_FREE:
1512         name_list_free(section->check_email);
1513         break;
1514     case CMD_SET_VALUE:
1515         if(strcasecmp(opt, "checkEmail"))
1516             break;
1517         name_list_append(&section->check_email, arg);
1518         return NULL; /* OK */
1519     case CMD_INITIALIZE:
1520         if(section->check_email && !section->option.verify_chain && !section->option.verify_peer)
1521             return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled";
1522         break;
1523     case CMD_PRINT_DEFAULTS:
1524         break;
1525     case CMD_PRINT_HELP:
1526         s_log(LOG_NOTICE, "%-22s = peer certificate email address",
1527             "checkEmail");
1528         break;
1529     }
1530 
1531     /* checkHost */
1532     switch(cmd) {
1533     case CMD_SET_DEFAULTS:
1534         section->check_host=NULL;
1535         break;
1536     case CMD_SET_COPY:
1537         name_list_dup(&section->check_host,
1538             new_service_options.check_host);
1539         break;
1540     case CMD_FREE:
1541         name_list_free(section->check_host);
1542         break;
1543     case CMD_SET_VALUE:
1544         if(strcasecmp(opt, "checkHost"))
1545             break;
1546         name_list_append(&section->check_host, arg);
1547         return NULL; /* OK */
1548     case CMD_INITIALIZE:
1549         if(section->check_host && !section->option.verify_chain && !section->option.verify_peer)
1550             return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled";
1551         break;
1552     case CMD_PRINT_DEFAULTS:
1553         break;
1554     case CMD_PRINT_HELP:
1555         s_log(LOG_NOTICE, "%-22s = peer certificate host name pattern",
1556             "checkHost");
1557         break;
1558     }
1559 
1560     /* checkIP */
1561     switch(cmd) {
1562     case CMD_SET_DEFAULTS:
1563         section->check_ip=NULL;
1564         break;
1565     case CMD_SET_COPY:
1566         name_list_dup(&section->check_ip,
1567             new_service_options.check_ip);
1568         break;
1569     case CMD_FREE:
1570         name_list_free(section->check_ip);
1571         break;
1572     case CMD_SET_VALUE:
1573         if(strcasecmp(opt, "checkIP"))
1574             break;
1575         name_list_append(&section->check_ip, arg);
1576         return NULL; /* OK */
1577     case CMD_INITIALIZE:
1578         if(section->check_ip && !section->option.verify_chain && !section->option.verify_peer)
1579             return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled";
1580         break;
1581     case CMD_PRINT_DEFAULTS:
1582         break;
1583     case CMD_PRINT_HELP:
1584         s_log(LOG_NOTICE, "%-22s = peer certificate IP address",
1585             "checkIP");
1586         break;
1587     }
1588 
1589 #endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */
1590 
1591     /* ciphers */
1592     switch(cmd) {
1593     case CMD_SET_DEFAULTS:
1594         section->cipher_list=NULL;
1595         break;
1596     case CMD_SET_COPY:
1597         section->cipher_list=str_dup_detached(new_service_options.cipher_list);
1598         break;
1599     case CMD_FREE:
1600         str_free(section->cipher_list);
1601         break;
1602     case CMD_SET_VALUE:
1603         if(strcasecmp(opt, "ciphers"))
1604             break;
1605         str_free(section->cipher_list);
1606         section->cipher_list=str_dup_detached(arg);
1607         return NULL; /* OK */
1608     case CMD_INITIALIZE:
1609         if(!section->cipher_list) {
1610             /* this is only executed for global options, because
1611              * section->cipher_list is no longer NULL in sections */
1612 #ifdef USE_FIPS
1613             if(new_global_options.option.fips)
1614                 section->cipher_list=str_dup_detached("FIPS");
1615             else
1616 #endif /* USE_FIPS */
1617                 section->cipher_list=str_dup_detached(stunnel_cipher_list);
1618         }
1619         break;
1620     case CMD_PRINT_DEFAULTS:
1621         if(fips_available()) {
1622             s_log(LOG_NOTICE, "%-22s = %s %s", "ciphers",
1623                 "FIPS", "(with \"fips = yes\")");
1624             s_log(LOG_NOTICE, "%-22s = %s %s", "ciphers",
1625                 stunnel_cipher_list, "(with \"fips = no\")");
1626         } else {
1627             s_log(LOG_NOTICE, "%-22s = %s", "ciphers", stunnel_cipher_list);
1628         }
1629         break;
1630     case CMD_PRINT_HELP:
1631         s_log(LOG_NOTICE, "%-22s = permitted ciphers for TLS 1.2 or older", "ciphers");
1632         break;
1633     }
1634 
1635 #ifndef OPENSSL_NO_TLS1_3
1636     /* ciphersuites */
1637     switch(cmd) {
1638     case CMD_SET_DEFAULTS:
1639         section->ciphersuites=NULL;
1640         break;
1641     case CMD_SET_COPY:
1642         section->ciphersuites=str_dup_detached(new_service_options.ciphersuites);
1643         break;
1644     case CMD_FREE:
1645         str_free(section->ciphersuites);
1646         break;
1647     case CMD_SET_VALUE:
1648         if(strcasecmp(opt, "ciphersuites"))
1649             break;
1650         str_free(section->ciphersuites);
1651         section->ciphersuites=str_dup_detached(arg);
1652         return NULL; /* OK */
1653     case CMD_INITIALIZE:
1654         if(!section->ciphersuites) {
1655             /* this is only executed for global options, because
1656              * section->ciphersuites is no longer NULL in sections */
1657             section->ciphersuites=str_dup_detached(stunnel_ciphersuites);
1658         }
1659         break;
1660     case CMD_PRINT_DEFAULTS:
1661         s_log(LOG_NOTICE, "%-22s = %s %s", "ciphersuites", stunnel_ciphersuites, "(with TLSv1.3)");
1662         break;
1663     case CMD_PRINT_HELP:
1664         s_log(LOG_NOTICE, "%-22s = permitted ciphersuites for TLS 1.3", "ciphersuites");
1665         break;
1666     }
1667 #endif /* TLS 1.3 */
1668 
1669     /* client */
1670     switch(cmd) {
1671     case CMD_SET_DEFAULTS:
1672         section->option.client=0;
1673         break;
1674     case CMD_SET_COPY:
1675         section->option.client=new_service_options.option.client;
1676         break;
1677     case CMD_FREE:
1678         break;
1679     case CMD_SET_VALUE:
1680         if(strcasecmp(opt, "client"))
1681             break;
1682         if(!strcasecmp(arg, "yes"))
1683             section->option.client=1;
1684         else if(!strcasecmp(arg, "no"))
1685             section->option.client=0;
1686         else
1687             return "The argument needs to be either 'yes' or 'no'";
1688         return NULL; /* OK */
1689     case CMD_INITIALIZE:
1690         break;
1691     case CMD_PRINT_DEFAULTS:
1692         break;
1693     case CMD_PRINT_HELP:
1694         s_log(LOG_NOTICE, "%-22s = yes|no client mode (remote service uses TLS)",
1695             "client");
1696         break;
1697     }
1698 
1699 #if OPENSSL_VERSION_NUMBER>=0x10002000L
1700 
1701     /* config */
1702     switch(cmd) {
1703     case CMD_SET_DEFAULTS:
1704         section->config=NULL;
1705         break;
1706     case CMD_SET_COPY:
1707         name_list_dup(&section->config, new_service_options.config);
1708         break;
1709     case CMD_FREE:
1710         name_list_free(section->config);
1711         break;
1712     case CMD_SET_VALUE:
1713         if(strcasecmp(opt, "config"))
1714             break;
1715         name_list_append(&section->config, arg);
1716         return NULL; /* OK */
1717     case CMD_INITIALIZE:
1718         break;
1719     case CMD_PRINT_DEFAULTS:
1720         break;
1721     case CMD_PRINT_HELP:
1722         s_log(LOG_NOTICE, "%-22s = command[:parameter] to execute",
1723             "config");
1724         break;
1725     }
1726 
1727 #endif /* OPENSSL_VERSION_NUMBER>=0x10002000L */
1728 
1729     /* connect */
1730     switch(cmd) {
1731     case CMD_SET_DEFAULTS:
1732         addrlist_clear(&section->connect_addr, 0);
1733         section->connect_session=NULL;
1734         break;
1735     case CMD_SET_COPY:
1736         addrlist_clear(&section->connect_addr, 0);
1737         section->connect_session=NULL;
1738         name_list_dup(&section->connect_addr.names,
1739             new_service_options.connect_addr.names);
1740         break;
1741     case CMD_FREE:
1742         name_list_free(section->connect_addr.names);
1743         str_free(section->connect_addr.addr);
1744         str_free(section->connect_session);
1745         break;
1746     case CMD_SET_VALUE:
1747         if(strcasecmp(opt, "connect"))
1748             break;
1749         name_list_append(&section->connect_addr.names, arg);
1750         return NULL; /* OK */
1751     case CMD_INITIALIZE:
1752         if(section->connect_addr.names) {
1753             if(!section->option.delayed_lookup &&
1754                     !addrlist_resolve(&section->connect_addr)) {
1755                 s_log(LOG_INFO,
1756                     "Cannot resolve connect target - delaying DNS lookup");
1757                 section->connect_addr.num=0;
1758                 section->redirect_addr.num=0;
1759                 section->option.delayed_lookup=1;
1760             }
1761             if(section->option.client)
1762                 section->connect_session=
1763                     str_alloc_detached(section->connect_addr.num*sizeof(SSL_SESSION *));
1764             ++endpoints;
1765         }
1766         break;
1767     case CMD_PRINT_DEFAULTS:
1768         break;
1769     case CMD_PRINT_HELP:
1770         s_log(LOG_NOTICE, "%-22s = [host:]port to connect",
1771             "connect");
1772         break;
1773     }
1774 
1775     /* CRLpath */
1776     switch(cmd) {
1777     case CMD_SET_DEFAULTS:
1778         section->crl_dir=NULL;
1779         break;
1780     case CMD_SET_COPY:
1781         section->crl_dir=str_dup_detached(new_service_options.crl_dir);
1782         break;
1783     case CMD_FREE:
1784         str_free(section->crl_dir);
1785         break;
1786     case CMD_SET_VALUE:
1787         if(strcasecmp(opt, "CRLpath"))
1788             break;
1789         str_free(section->crl_dir);
1790         if(arg[0]) /* not empty */
1791             section->crl_dir=str_dup_detached(arg);
1792         else
1793             section->crl_dir=NULL;
1794         return NULL; /* OK */
1795     case CMD_INITIALIZE:
1796         break;
1797     case CMD_PRINT_DEFAULTS:
1798         break;
1799     case CMD_PRINT_HELP:
1800         s_log(LOG_NOTICE, "%-22s = CRL directory", "CRLpath");
1801         break;
1802     }
1803 
1804     /* CRLfile */
1805     switch(cmd) {
1806     case CMD_SET_DEFAULTS:
1807         section->crl_file=NULL;
1808         break;
1809     case CMD_SET_COPY:
1810         section->crl_file=str_dup_detached(new_service_options.crl_file);
1811         break;
1812     case CMD_FREE:
1813         str_free(section->crl_file);
1814         break;
1815     case CMD_SET_VALUE:
1816         if(strcasecmp(opt, "CRLfile"))
1817             break;
1818         str_free(section->crl_file);
1819         if(arg[0]) /* not empty */
1820             section->crl_file=str_dup_detached(arg);
1821         else
1822             section->crl_file=NULL;
1823         return NULL; /* OK */
1824     case CMD_INITIALIZE:
1825         break;
1826     case CMD_PRINT_DEFAULTS:
1827         break;
1828     case CMD_PRINT_HELP:
1829         s_log(LOG_NOTICE, "%-22s = CRL file", "CRLfile");
1830         break;
1831     }
1832 
1833 #ifndef OPENSSL_NO_ECDH
1834 
1835     /* curves */
1836     switch(cmd) {
1837     case CMD_SET_DEFAULTS:
1838         section->curves=str_dup_detached(DEFAULT_CURVES);
1839         break;
1840     case CMD_SET_COPY:
1841         section->curves=str_dup_detached(new_service_options.curves);
1842         break;
1843     case CMD_FREE:
1844         str_free(section->curves);
1845         break;
1846     case CMD_SET_VALUE:
1847         if(strcasecmp(opt, "curves") && strcasecmp(opt, "curve"))
1848             break;
1849         str_free(section->curves);
1850         section->curves=str_dup_detached(arg);
1851         return NULL; /* OK */
1852     case CMD_INITIALIZE:
1853         break;
1854     case CMD_PRINT_DEFAULTS:
1855         s_log(LOG_NOTICE, "%-22s = %s", "curves", DEFAULT_CURVES);
1856         break;
1857     case CMD_PRINT_HELP:
1858         s_log(LOG_NOTICE, "%-22s = ECDH curve names", "curves");
1859         break;
1860     }
1861 
1862 #endif /* !defined(OPENSSL_NO_ECDH) */
1863 
1864     /* debug */
1865     switch(cmd) {
1866     case CMD_SET_DEFAULTS:
1867         section->log_level=LOG_NOTICE;
1868 #if !defined (USE_WIN32) && !defined (__vms)
1869         new_global_options.log_facility=LOG_DAEMON;
1870 #endif
1871         break;
1872     case CMD_SET_COPY:
1873         section->log_level=new_service_options.log_level;
1874         break;
1875     case CMD_FREE:
1876         break;
1877     case CMD_SET_VALUE:
1878         if(strcasecmp(opt, "debug"))
1879             break;
1880         return parse_debug_level(arg, section);
1881     case CMD_INITIALIZE:
1882         break;
1883     case CMD_PRINT_DEFAULTS:
1884 #if !defined (USE_WIN32) && !defined (__vms)
1885         s_log(LOG_NOTICE, "%-22s = %s", "debug", "daemon.notice");
1886 #else
1887         s_log(LOG_NOTICE, "%-22s = %s", "debug", "notice");
1888 #endif
1889         break;
1890     case CMD_PRINT_HELP:
1891 #if !defined (USE_WIN32) && !defined (__vms)
1892         s_log(LOG_NOTICE, "%-22s = [facility].level (e.g. daemon.info)", "debug");
1893 #else
1894         s_log(LOG_NOTICE, "%-22s = level (e.g. info)", "debug");
1895 #endif
1896         break;
1897     }
1898 
1899     /* delay */
1900     switch(cmd) {
1901     case CMD_SET_DEFAULTS:
1902         section->option.delayed_lookup=0;
1903         break;
1904     case CMD_SET_COPY:
1905         section->option.delayed_lookup=new_service_options.option.delayed_lookup;
1906         break;
1907     case CMD_FREE:
1908         break;
1909     case CMD_SET_VALUE:
1910         if(strcasecmp(opt, "delay"))
1911             break;
1912         if(!strcasecmp(arg, "yes"))
1913             section->option.delayed_lookup=1;
1914         else if(!strcasecmp(arg, "no"))
1915             section->option.delayed_lookup=0;
1916         else
1917             return "The argument needs to be either 'yes' or 'no'";
1918         return NULL; /* OK */
1919     case CMD_INITIALIZE:
1920         break;
1921     case CMD_PRINT_DEFAULTS:
1922         break;
1923     case CMD_PRINT_HELP:
1924         s_log(LOG_NOTICE,
1925             "%-22s = yes|no delay DNS lookup for 'connect' option",
1926             "delay");
1927         break;
1928     }
1929 
1930 #ifndef OPENSSL_NO_ENGINE
1931 
1932     /* engineId */
1933     switch(cmd) {
1934     case CMD_SET_DEFAULTS:
1935         break;
1936     case CMD_SET_COPY:
1937         section->engine=new_service_options.engine;
1938         break;
1939     case CMD_FREE:
1940         break;
1941     case CMD_SET_VALUE:
1942         if(strcasecmp(opt, "engineId"))
1943             break;
1944         section->engine=engine_get_by_id(arg);
1945         if(!section->engine)
1946             return "Engine ID not found";
1947         return NULL; /* OK */
1948     case CMD_INITIALIZE:
1949         break;
1950     case CMD_PRINT_DEFAULTS:
1951         break;
1952     case CMD_PRINT_HELP:
1953         s_log(LOG_NOTICE, "%-22s = ID of engine to read the key from",
1954             "engineId");
1955         break;
1956     }
1957 
1958     /* engineNum */
1959     switch(cmd) {
1960     case CMD_SET_DEFAULTS:
1961         break;
1962     case CMD_SET_COPY:
1963         section->engine=new_service_options.engine;
1964         break;
1965     case CMD_FREE:
1966         break;
1967     case CMD_SET_VALUE:
1968         if(strcasecmp(opt, "engineNum"))
1969             break;
1970         {
1971             char *tmp_str;
1972             int tmp_int=(int)strtol(arg, &tmp_str, 10);
1973             if(tmp_str==arg || *tmp_str) /* not a number */
1974                 return "Illegal engine number";
1975             section->engine=engine_get_by_num(tmp_int-1);
1976         }
1977         if(!section->engine)
1978             return "Illegal engine number";
1979         return NULL; /* OK */
1980     case CMD_INITIALIZE:
1981         break;
1982     case CMD_PRINT_DEFAULTS:
1983         break;
1984     case CMD_PRINT_HELP:
1985         s_log(LOG_NOTICE, "%-22s = number of engine to read the key from",
1986             "engineNum");
1987         break;
1988     }
1989 
1990 #endif /* !defined(OPENSSL_NO_ENGINE) */
1991 
1992     /* exec */
1993     switch(cmd) {
1994     case CMD_SET_DEFAULTS:
1995         section->exec_name=NULL;
1996         break;
1997     case CMD_SET_COPY:
1998         section->exec_name=str_dup_detached(new_service_options.exec_name);
1999         break;
2000     case CMD_FREE:
2001         str_free(section->exec_name);
2002         break;
2003     case CMD_SET_VALUE:
2004         if(strcasecmp(opt, "exec"))
2005             break;
2006         str_free(section->exec_name);
2007         section->exec_name=str_dup_detached(arg);
2008 #ifdef USE_WIN32
2009         section->exec_args=str_dup_detached(arg);
2010 #else
2011         if(!section->exec_args) {
2012             section->exec_args=str_alloc_detached(2*sizeof(char *));
2013             section->exec_args[0]=str_dup_detached(section->exec_name);
2014             section->exec_args[1]=NULL; /* null-terminate */
2015         }
2016 #endif
2017         return NULL; /* OK */
2018     case CMD_INITIALIZE:
2019         if(section->exec_name)
2020             ++endpoints;
2021         break;
2022     case CMD_PRINT_DEFAULTS:
2023         break;
2024     case CMD_PRINT_HELP:
2025         s_log(LOG_NOTICE, "%-22s = file execute local inetd-type program",
2026             "exec");
2027         break;
2028     }
2029 
2030     /* execArgs */
2031     switch(cmd) {
2032     case CMD_SET_DEFAULTS:
2033         section->exec_args=NULL;
2034         break;
2035     case CMD_SET_COPY:
2036 #ifdef USE_WIN32
2037         section->exec_args=str_dup_detached(new_service_options.exec_args);
2038 #else
2039         section->exec_args=arg_dup(new_service_options.exec_args);
2040 #endif
2041         break;
2042     case CMD_FREE:
2043 #ifdef USE_WIN32
2044         str_free(section->exec_args);
2045 #else
2046         arg_free(section->exec_args);
2047 #endif
2048         break;
2049     case CMD_SET_VALUE:
2050         if(strcasecmp(opt, "execArgs"))
2051             break;
2052 #ifdef USE_WIN32
2053         str_free(section->exec_args);
2054         section->exec_args=str_dup_detached(arg);
2055 #else
2056         arg_free(section->exec_args);
2057         section->exec_args=arg_alloc(arg);
2058 #endif
2059         return NULL; /* OK */
2060     case CMD_INITIALIZE:
2061         break;
2062     case CMD_PRINT_DEFAULTS:
2063         break;
2064     case CMD_PRINT_HELP:
2065         s_log(LOG_NOTICE, "%-22s = arguments for 'exec' (including $0)",
2066             "execArgs");
2067         break;
2068     }
2069 
2070     /* failover */
2071     switch(cmd) {
2072     case CMD_SET_DEFAULTS:
2073         section->failover=FAILOVER_PRIO;
2074         section->rr=0;
2075         break;
2076     case CMD_SET_COPY:
2077         section->failover=new_service_options.failover;
2078         section->rr=new_service_options.rr;
2079         break;
2080     case CMD_FREE:
2081         break;
2082     case CMD_SET_VALUE:
2083         if(strcasecmp(opt, "failover"))
2084             break;
2085         if(!strcasecmp(arg, "rr"))
2086             section->failover=FAILOVER_RR;
2087         else if(!strcasecmp(arg, "prio"))
2088             section->failover=FAILOVER_PRIO;
2089         else
2090             return "The argument needs to be either 'rr' or 'prio'";
2091         return NULL; /* OK */
2092     case CMD_INITIALIZE:
2093         if(section->option.delayed_lookup)
2094             section->failover=FAILOVER_PRIO;
2095         break;
2096     case CMD_PRINT_DEFAULTS:
2097         break;
2098     case CMD_PRINT_HELP:
2099         s_log(LOG_NOTICE, "%-22s = rr|prio failover strategy",
2100             "failover");
2101         break;
2102     }
2103 
2104     /* ident */
2105     switch(cmd) {
2106     case CMD_SET_DEFAULTS:
2107         section->username=NULL;
2108         break;
2109     case CMD_SET_COPY:
2110         section->username=str_dup_detached(new_service_options.username);
2111         break;
2112     case CMD_FREE:
2113         str_free(section->username);
2114         break;
2115     case CMD_SET_VALUE:
2116         if(strcasecmp(opt, "ident"))
2117             break;
2118         str_free(section->username);
2119         section->username=str_dup_detached(arg);
2120         return NULL; /* OK */
2121     case CMD_INITIALIZE:
2122         break;
2123     case CMD_PRINT_DEFAULTS:
2124         break;
2125     case CMD_PRINT_HELP:
2126         s_log(LOG_NOTICE, "%-22s = username for IDENT (RFC 1413) checking", "ident");
2127         break;
2128     }
2129 
2130     /* include */
2131     switch(cmd) {
2132     case CMD_SET_DEFAULTS:
2133         break;
2134     case CMD_SET_COPY:
2135         break;
2136     case CMD_FREE:
2137         break;
2138     case CMD_SET_VALUE:
2139         if(strcasecmp(opt, "include"))
2140             break;
2141         return include_config(arg, section_ptr);
2142     case CMD_INITIALIZE:
2143         break;
2144     case CMD_PRINT_DEFAULTS:
2145         break;
2146     case CMD_PRINT_HELP:
2147         s_log(LOG_NOTICE, "%-22s = directory with configuration file snippets",
2148             "include");
2149         break;
2150     }
2151 
2152     /* key */
2153     switch(cmd) {
2154     case CMD_SET_DEFAULTS:
2155         section->key=NULL;
2156         break;
2157     case CMD_SET_COPY:
2158         section->key=str_dup_detached(new_service_options.key);
2159         break;
2160     case CMD_FREE:
2161         str_free(section->key);
2162         break;
2163     case CMD_SET_VALUE:
2164         if(strcasecmp(opt, "key"))
2165             break;
2166         str_free(section->key);
2167         section->key=str_dup_detached(arg);
2168         return NULL; /* OK */
2169     case CMD_INITIALIZE:
2170         if(section->cert && !section->key)
2171             section->key=str_dup_detached(section->cert);
2172         break;
2173     case CMD_PRINT_DEFAULTS:
2174         break;
2175     case CMD_PRINT_HELP:
2176         s_log(LOG_NOTICE, "%-22s = certificate private key", "key");
2177         break;
2178     }
2179 
2180     /* libwrap */
2181 #ifdef USE_LIBWRAP
2182     switch(cmd) {
2183     case CMD_SET_DEFAULTS:
2184         section->option.libwrap=0; /* disable libwrap by default */
2185         break;
2186     case CMD_SET_COPY:
2187         section->option.libwrap=new_service_options.option.libwrap;
2188         break;
2189     case CMD_FREE:
2190         break;
2191     case CMD_SET_VALUE:
2192         if(strcasecmp(opt, "libwrap"))
2193             break;
2194         if(!strcasecmp(arg, "yes"))
2195             section->option.libwrap=1;
2196         else if(!strcasecmp(arg, "no"))
2197             section->option.libwrap=0;
2198         else
2199             return "The argument needs to be either 'yes' or 'no'";
2200         return NULL; /* OK */
2201     case CMD_INITIALIZE:
2202         break;
2203     case CMD_PRINT_DEFAULTS:
2204         break;
2205     case CMD_PRINT_HELP:
2206         s_log(LOG_NOTICE, "%-22s = yes|no use /etc/hosts.allow and /etc/hosts.deny",
2207             "libwrap");
2208         break;
2209     }
2210 #endif /* USE_LIBWRAP */
2211 
2212     /* local */
2213     switch(cmd) {
2214     case CMD_SET_DEFAULTS:
2215         section->option.local=0;
2216         break;
2217     case CMD_SET_COPY:
2218         section->option.local=new_service_options.option.local;
2219         memcpy(&section->source_addr, &new_service_options.source_addr,
2220             sizeof(SOCKADDR_UNION));
2221         break;
2222     case CMD_FREE:
2223         break;
2224     case CMD_SET_VALUE:
2225         if(strcasecmp(opt, "local"))
2226             break;
2227         if(!hostport2addr(&section->source_addr, arg, "0", 1))
2228             return "Failed to resolve local address";
2229         section->option.local=1;
2230         return NULL; /* OK */
2231     case CMD_INITIALIZE:
2232         break;
2233     case CMD_PRINT_DEFAULTS:
2234         break;
2235     case CMD_PRINT_HELP:
2236         s_log(LOG_NOTICE, "%-22s = IP address to be used as source for remote"
2237             " connections", "local");
2238         break;
2239     }
2240 
2241     /* logId */
2242     switch(cmd) {
2243     case CMD_SET_DEFAULTS:
2244         section->log_id=LOG_ID_SEQUENTIAL;
2245         break;
2246     case CMD_SET_COPY:
2247         section->log_id=new_service_options.log_id;
2248         break;
2249     case CMD_FREE:
2250         break;
2251     case CMD_SET_VALUE:
2252         if(strcasecmp(opt, "logId"))
2253             break;
2254         if(!strcasecmp(arg, "sequential"))
2255             section->log_id=LOG_ID_SEQUENTIAL;
2256         else if(!strcasecmp(arg, "unique"))
2257             section->log_id=LOG_ID_UNIQUE;
2258         else if(!strcasecmp(arg, "thread"))
2259             section->log_id=LOG_ID_THREAD;
2260         else if(!strcasecmp(arg, "process"))
2261             section->log_id=LOG_ID_PROCESS;
2262         else
2263             return "Invalid connection identifier type";
2264         return NULL; /* OK */
2265     case CMD_INITIALIZE:
2266         break;
2267     case CMD_PRINT_DEFAULTS:
2268         s_log(LOG_NOTICE, "%-22s = %s", "logId", "sequential");
2269         break;
2270     case CMD_PRINT_HELP:
2271         s_log(LOG_NOTICE, "%-22s = connection identifier type",
2272             "logId");
2273         break;
2274     }
2275 
2276 #ifndef OPENSSL_NO_OCSP
2277 
2278     /* OCSP */
2279     switch(cmd) {
2280     case CMD_SET_DEFAULTS:
2281         section->ocsp_url=NULL;
2282         break;
2283     case CMD_SET_COPY:
2284         section->ocsp_url=str_dup_detached(new_service_options.ocsp_url);
2285         break;
2286     case CMD_FREE:
2287         str_free(section->ocsp_url);
2288         break;
2289     case CMD_SET_VALUE:
2290         if(strcasecmp(opt, "ocsp"))
2291             break;
2292         str_free(section->ocsp_url);
2293         section->ocsp_url=str_dup_detached(arg);
2294         return NULL; /* OK */
2295     case CMD_INITIALIZE:
2296         break;
2297     case CMD_PRINT_DEFAULTS:
2298         break;
2299     case CMD_PRINT_HELP:
2300         s_log(LOG_NOTICE, "%-22s = OCSP responder URL", "OCSP");
2301         break;
2302     }
2303 
2304     /* OCSPaia */
2305     switch(cmd) {
2306     case CMD_SET_DEFAULTS:
2307         section->option.aia=0; /* disable AIA by default */
2308         break;
2309     case CMD_SET_COPY:
2310         section->option.aia=new_service_options.option.aia;
2311         break;
2312     case CMD_FREE:
2313         break;
2314     case CMD_SET_VALUE:
2315         if(strcasecmp(opt, "OCSPaia"))
2316             break;
2317         if(!strcasecmp(arg, "yes"))
2318             section->option.aia=1;
2319         else if(!strcasecmp(arg, "no"))
2320             section->option.aia=0;
2321         else
2322             return "The argument needs to be either 'yes' or 'no'";
2323         return NULL; /* OK */
2324     case CMD_INITIALIZE:
2325         break;
2326     case CMD_PRINT_DEFAULTS:
2327         break;
2328     case CMD_PRINT_HELP:
2329         s_log(LOG_NOTICE,
2330             "%-22s = yes|no check the AIA responders from certificates",
2331             "OCSPaia");
2332         break;
2333     }
2334 
2335     /* OCSPflag */
2336     switch(cmd) {
2337     case CMD_SET_DEFAULTS:
2338         section->ocsp_flags=0;
2339         break;
2340     case CMD_SET_COPY:
2341         section->ocsp_flags=new_service_options.ocsp_flags;
2342         break;
2343     case CMD_FREE:
2344         break;
2345     case CMD_SET_VALUE:
2346         if(strcasecmp(opt, "OCSPflag"))
2347             break;
2348         {
2349             unsigned long tmp_ulong=parse_ocsp_flag(arg);
2350             if(!tmp_ulong)
2351                 return "Illegal OCSP flag";
2352             section->ocsp_flags|=tmp_ulong;
2353         }
2354         return NULL;
2355     case CMD_INITIALIZE:
2356         break;
2357     case CMD_PRINT_DEFAULTS:
2358         break;
2359     case CMD_PRINT_HELP:
2360         s_log(LOG_NOTICE, "%-22s = OCSP responder flags", "OCSPflag");
2361         break;
2362     }
2363 
2364     /* OCSPnonce */
2365     switch(cmd) {
2366     case CMD_SET_DEFAULTS:
2367         section->option.nonce=0; /* disable OCSP nonce by default */
2368         break;
2369     case CMD_SET_COPY:
2370         section->option.nonce=new_service_options.option.nonce;
2371         break;
2372     case CMD_FREE:
2373         break;
2374     case CMD_SET_VALUE:
2375         if(strcasecmp(opt, "OCSPnonce"))
2376             break;
2377         if(!strcasecmp(arg, "yes"))
2378             section->option.nonce=1;
2379         else if(!strcasecmp(arg, "no"))
2380             section->option.nonce=0;
2381         else
2382             return "The argument needs to be either 'yes' or 'no'";
2383         return NULL; /* OK */
2384     case CMD_INITIALIZE:
2385         break;
2386     case CMD_PRINT_DEFAULTS:
2387         break;
2388     case CMD_PRINT_HELP:
2389         s_log(LOG_NOTICE,
2390             "%-22s = yes|no send and verify the OCSP nonce extension",
2391             "OCSPnonce");
2392         break;
2393     }
2394 
2395 #endif /* !defined(OPENSSL_NO_OCSP) */
2396 
2397     /* options */
2398     switch(cmd) {
2399     case CMD_SET_DEFAULTS:
2400         section->ssl_options_set=0;
2401 #if OPENSSL_VERSION_NUMBER>=0x009080dfL
2402         section->ssl_options_clear=0;
2403 #endif /* OpenSSL 0.9.8m or later */
2404         break;
2405     case CMD_SET_COPY:
2406         section->ssl_options_set=new_service_options.ssl_options_set;
2407 #if OPENSSL_VERSION_NUMBER>=0x009080dfL
2408         section->ssl_options_clear=new_service_options.ssl_options_clear;
2409 #endif /* OpenSSL 0.9.8m or later */
2410         break;
2411     case CMD_FREE:
2412         break;
2413     case CMD_SET_VALUE:
2414         if(strcasecmp(opt, "options"))
2415             break;
2416 #if OPENSSL_VERSION_NUMBER>=0x009080dfL
2417         if(*arg=='-') {
2418             long unsigned tmp=parse_ssl_option(arg+1);
2419             if(tmp==INVALID_SSL_OPTION)
2420                 return "Illegal TLS option";
2421             section->ssl_options_clear|=tmp;
2422             return NULL; /* OK */
2423         }
2424 #endif /* OpenSSL 0.9.8m or later */
2425         {
2426             long unsigned tmp=parse_ssl_option(arg);
2427             if(tmp==INVALID_SSL_OPTION)
2428                 return "Illegal TLS option";
2429             section->ssl_options_set|=tmp;
2430         }
2431         return NULL; /* OK */
2432     case CMD_INITIALIZE:
2433         break;
2434     case CMD_PRINT_DEFAULTS:
2435         s_log(LOG_NOTICE, "%-22s = %s", "options", "NO_SSLv2");
2436         s_log(LOG_NOTICE, "%-22s = %s", "options", "NO_SSLv3");
2437         break;
2438     case CMD_PRINT_HELP:
2439         s_log(LOG_NOTICE, "%-22s = TLS option to set/reset", "options");
2440         break;
2441     }
2442 
2443     /* protocol */
2444     switch(cmd) {
2445     case CMD_SET_DEFAULTS:
2446         section->protocol=NULL;
2447         break;
2448     case CMD_SET_COPY:
2449         section->protocol=str_dup_detached(new_service_options.protocol);
2450         break;
2451     case CMD_FREE:
2452         str_free(section->protocol);
2453         break;
2454     case CMD_SET_VALUE:
2455         if(strcasecmp(opt, "protocol"))
2456             break;
2457         str_free(section->protocol);
2458         section->protocol=str_dup_detached(arg);
2459         return NULL; /* OK */
2460     case CMD_INITIALIZE:
2461         /* PROTOCOL_CHECK also initializes:
2462            section->option.connect_before_ssl
2463            section->option.protocol_endpoint */
2464         {
2465             char *tmp_str=protocol(NULL, section, PROTOCOL_CHECK);
2466             if(tmp_str)
2467                 return tmp_str;
2468         }
2469         endpoints+=section->option.protocol_endpoint;
2470         break;
2471     case CMD_PRINT_DEFAULTS:
2472         break;
2473     case CMD_PRINT_HELP:
2474         s_log(LOG_NOTICE, "%-22s = protocol to negotiate before TLS initialization",
2475             "protocol");
2476         s_log(LOG_NOTICE, "%25scurrently supported: cifs, connect, imap,", "");
2477         s_log(LOG_NOTICE, "%25s    nntp, pgsql, pop3, proxy, smtp, socks", "");
2478         break;
2479     }
2480 
2481     /* protocolAuthentication */
2482     switch(cmd) {
2483     case CMD_SET_DEFAULTS:
2484         section->protocol_authentication=str_dup_detached("basic");
2485         break;
2486     case CMD_SET_COPY:
2487         section->protocol_authentication=
2488             str_dup_detached(new_service_options.protocol_authentication);
2489         break;
2490     case CMD_FREE:
2491         str_free(section->protocol_authentication);
2492         break;
2493     case CMD_SET_VALUE:
2494         if(strcasecmp(opt, "protocolAuthentication"))
2495             break;
2496         str_free(section->protocol_authentication);
2497         section->protocol_authentication=str_dup_detached(arg);
2498         return NULL; /* OK */
2499     case CMD_INITIALIZE:
2500         break;
2501     case CMD_PRINT_DEFAULTS:
2502         break;
2503     case CMD_PRINT_HELP:
2504         s_log(LOG_NOTICE, "%-22s = authentication type for protocol negotiations",
2505             "protocolAuthentication");
2506         break;
2507     }
2508 
2509     /* protocolDomain */
2510     switch(cmd) {
2511     case CMD_SET_DEFAULTS:
2512         section->protocol_domain=NULL;
2513         break;
2514     case CMD_SET_COPY:
2515         section->protocol_domain=
2516             str_dup_detached(new_service_options.protocol_domain);
2517         break;
2518     case CMD_FREE:
2519         str_free(section->protocol_domain);
2520         break;
2521     case CMD_SET_VALUE:
2522         if(strcasecmp(opt, "protocolDomain"))
2523             break;
2524         str_free(section->protocol_domain);
2525         section->protocol_domain=str_dup_detached(arg);
2526         return NULL; /* OK */
2527     case CMD_INITIALIZE:
2528         break;
2529     case CMD_PRINT_DEFAULTS:
2530         break;
2531     case CMD_PRINT_HELP:
2532         s_log(LOG_NOTICE, "%-22s = domain for protocol negotiations",
2533             "protocolDomain");
2534         break;
2535     }
2536 
2537     /* protocolHeader */
2538     switch(cmd) {
2539     case CMD_SET_DEFAULTS:
2540         section->protocol_header=NULL;
2541         break;
2542     case CMD_SET_COPY:
2543         name_list_dup(&section->protocol_header,
2544             new_service_options.protocol_header);
2545         break;
2546     case CMD_FREE:
2547         name_list_free(section->protocol_header);
2548         break;
2549     case CMD_SET_VALUE:
2550         if(strcasecmp(opt, "protocolHeader"))
2551             break;
2552         name_list_append(&section->protocol_header, arg);
2553         return NULL; /* OK */
2554     case CMD_INITIALIZE:
2555         break;
2556     case CMD_PRINT_DEFAULTS:
2557         break;
2558     case CMD_PRINT_HELP:
2559         s_log(LOG_NOTICE, "%-22s = custom header for protocol negotiations",
2560             "protocolHeader");
2561         break;
2562     }
2563 
2564     /* protocolHost */
2565     switch(cmd) {
2566     case CMD_SET_DEFAULTS:
2567         section->protocol_host=NULL;
2568         break;
2569     case CMD_SET_COPY:
2570         section->protocol_host=
2571             str_dup_detached(new_service_options.protocol_host);
2572         break;
2573     case CMD_FREE:
2574         str_free(section->protocol_host);
2575         break;
2576     case CMD_SET_VALUE:
2577         if(strcasecmp(opt, "protocolHost"))
2578             break;
2579         str_free(section->protocol_host);
2580         section->protocol_host=str_dup_detached(arg);
2581         return NULL; /* OK */
2582     case CMD_INITIALIZE:
2583         break;
2584     case CMD_PRINT_DEFAULTS:
2585         break;
2586     case CMD_PRINT_HELP:
2587         s_log(LOG_NOTICE, "%-22s = host:port for protocol negotiations",
2588             "protocolHost");
2589         break;
2590     }
2591 
2592     /* protocolPassword */
2593     switch(cmd) {
2594     case CMD_SET_DEFAULTS:
2595         section->protocol_password=NULL;
2596         break;
2597     case CMD_SET_COPY:
2598         section->protocol_password=
2599             str_dup_detached(new_service_options.protocol_password);
2600         break;
2601     case CMD_FREE:
2602         str_free(section->protocol_password);
2603         break;
2604     case CMD_SET_VALUE:
2605         if(strcasecmp(opt, "protocolPassword"))
2606             break;
2607         str_free(section->protocol_password);
2608         section->protocol_password=str_dup_detached(arg);
2609         return NULL; /* OK */
2610     case CMD_INITIALIZE:
2611         break;
2612     case CMD_PRINT_DEFAULTS:
2613         break;
2614     case CMD_PRINT_HELP:
2615         s_log(LOG_NOTICE, "%-22s = password for protocol negotiations",
2616             "protocolPassword");
2617         break;
2618     }
2619 
2620     /* protocolUsername */
2621     switch(cmd) {
2622     case CMD_SET_DEFAULTS:
2623         section->protocol_username=NULL;
2624         break;
2625     case CMD_SET_COPY:
2626         section->protocol_username=
2627             str_dup_detached(new_service_options.protocol_username);
2628         break;
2629     case CMD_FREE:
2630         str_free(section->protocol_username);
2631         break;
2632     case CMD_SET_VALUE:
2633         if(strcasecmp(opt, "protocolUsername"))
2634             break;
2635         str_free(section->protocol_username);
2636         section->protocol_username=str_dup_detached(arg);
2637         return NULL; /* OK */
2638     case CMD_INITIALIZE:
2639         break;
2640     case CMD_PRINT_DEFAULTS:
2641         break;
2642     case CMD_PRINT_HELP:
2643         s_log(LOG_NOTICE, "%-22s = username for protocol negotiations",
2644             "protocolUsername");
2645         break;
2646     }
2647 
2648 #ifndef OPENSSL_NO_PSK
2649 
2650     /* PSKidentity */
2651     switch(cmd) {
2652     case CMD_SET_DEFAULTS:
2653         section->psk_identity=NULL;
2654         section->psk_selected=NULL;
2655         section->psk_sorted.val=NULL;
2656         section->psk_sorted.num=0;
2657         break;
2658     case CMD_SET_COPY:
2659         section->psk_identity=
2660             str_dup_detached(new_service_options.psk_identity);
2661         break;
2662     case CMD_FREE:
2663         str_free(section->psk_identity);
2664         str_free(section->psk_sorted.val);
2665         break;
2666     case CMD_SET_VALUE:
2667         if(strcasecmp(opt, "PSKidentity"))
2668             break;
2669         str_free(section->psk_identity);
2670         section->psk_identity=str_dup_detached(arg);
2671         return NULL; /* OK */
2672     case CMD_INITIALIZE:
2673         if(!section->psk_keys) /* PSK not configured */
2674             break;
2675         psk_sort(&section->psk_sorted, section->psk_keys);
2676         if(section->option.client) {
2677             if(section->psk_identity) {
2678                 section->psk_selected=
2679                     psk_find(&section->psk_sorted, section->psk_identity);
2680                 if(!section->psk_selected)
2681                     return "No key found for the specified PSK identity";
2682             } else { /* take the first specified identity as default */
2683                 section->psk_selected=section->psk_keys;
2684             }
2685         } else {
2686             if(section->psk_identity)
2687                 s_log(LOG_NOTICE,
2688                     "PSK identity is ignored in the server mode");
2689         }
2690         break;
2691     case CMD_PRINT_DEFAULTS:
2692         break;
2693     case CMD_PRINT_HELP:
2694         s_log(LOG_NOTICE, "%-22s = identity for PSK authentication",
2695             "PSKidentity");
2696         break;
2697     }
2698 
2699     /* PSKsecrets */
2700     switch(cmd) {
2701     case CMD_SET_DEFAULTS:
2702         section->psk_keys=NULL;
2703         break;
2704     case CMD_SET_COPY:
2705         section->psk_keys=psk_dup(new_service_options.psk_keys);
2706         break;
2707     case CMD_FREE:
2708         psk_free(section->psk_keys);
2709         break;
2710     case CMD_SET_VALUE:
2711         if(strcasecmp(opt, "PSKsecrets"))
2712             break;
2713         section->psk_keys=psk_read(arg);
2714         if(!section->psk_keys)
2715             return "Failed to read PSK secrets";
2716         return NULL; /* OK */
2717     case CMD_INITIALIZE:
2718         break;
2719     case CMD_PRINT_DEFAULTS:
2720         break;
2721     case CMD_PRINT_HELP:
2722         s_log(LOG_NOTICE, "%-22s = secrets for PSK authentication",
2723             "PSKsecrets");
2724         break;
2725     }
2726 
2727 #endif /* !defined(OPENSSL_NO_PSK) */
2728 
2729     /* pty */
2730 #ifndef USE_WIN32
2731     switch(cmd) {
2732     case CMD_SET_DEFAULTS:
2733         section->option.pty=0;
2734         break;
2735     case CMD_SET_COPY:
2736         section->option.pty=new_service_options.option.pty;
2737         break;
2738     case CMD_FREE:
2739         break;
2740     case CMD_SET_VALUE:
2741         if(strcasecmp(opt, "pty"))
2742             break;
2743         if(!strcasecmp(arg, "yes"))
2744             section->option.pty=1;
2745         else if(!strcasecmp(arg, "no"))
2746             section->option.pty=0;
2747         else
2748             return "The argument needs to be either 'yes' or 'no'";
2749         return NULL; /* OK */
2750     case CMD_INITIALIZE:
2751         break;
2752     case CMD_PRINT_DEFAULTS:
2753         break;
2754     case CMD_PRINT_HELP:
2755         s_log(LOG_NOTICE, "%-22s = yes|no allocate pseudo terminal for 'exec' option",
2756             "pty");
2757         break;
2758     }
2759 #endif
2760 
2761     /* redirect */
2762     switch(cmd) {
2763     case CMD_SET_DEFAULTS:
2764         addrlist_clear(&section->redirect_addr, 0);
2765         break;
2766     case CMD_SET_COPY:
2767         addrlist_clear(&section->redirect_addr, 0);
2768         name_list_dup(&section->redirect_addr.names,
2769             new_service_options.redirect_addr.names);
2770         break;
2771     case CMD_FREE:
2772         name_list_free(section->redirect_addr.names);
2773         str_free(section->redirect_addr.addr);
2774         break;
2775     case CMD_SET_VALUE:
2776         if(strcasecmp(opt, "redirect"))
2777             break;
2778         name_list_append(&section->redirect_addr.names, arg);
2779         return NULL; /* OK */
2780     case CMD_INITIALIZE:
2781         if(section->redirect_addr.names) {
2782             if(section->option.client)
2783                 return "\"redirect\" is unsupported in client sections";
2784             if(section->option.connect_before_ssl)
2785                 return "\"redirect\" is incompatible with the specified protocol negotiation";
2786             if(!section->option.delayed_lookup &&
2787                     !addrlist_resolve(&section->redirect_addr)) {
2788                 s_log(LOG_INFO,
2789                     "Cannot resolve redirect target - delaying DNS lookup");
2790                 section->connect_addr.num=0;
2791                 section->redirect_addr.num=0;
2792                 section->option.delayed_lookup=1;
2793             }
2794             if(!section->option.verify_chain && !section->option.verify_peer)
2795                 return "Either \"verifyChain\" or \"verifyPeer\" has to be enabled for \"redirect\" to work";
2796         }
2797         break;
2798     case CMD_PRINT_DEFAULTS:
2799         break;
2800     case CMD_PRINT_HELP:
2801         s_log(LOG_NOTICE,
2802             "%-22s = [host:]port to redirect on authentication failures",
2803             "redirect");
2804         break;
2805     }
2806 
2807     /* renegotiation */
2808     switch(cmd) {
2809     case CMD_SET_DEFAULTS:
2810         section->option.renegotiation=1;
2811         break;
2812     case CMD_SET_COPY:
2813         section->option.renegotiation=new_service_options.option.renegotiation;
2814         break;
2815     case CMD_FREE:
2816         break;
2817     case CMD_SET_VALUE:
2818         if(strcasecmp(opt, "renegotiation"))
2819             break;
2820         if(!strcasecmp(arg, "yes"))
2821             section->option.renegotiation=1;
2822         else if(!strcasecmp(arg, "no"))
2823             section->option.renegotiation=0;
2824         else
2825             return "The argument needs to be either 'yes' or 'no'";
2826         return NULL; /* OK */
2827     case CMD_INITIALIZE:
2828         break;
2829     case CMD_PRINT_DEFAULTS:
2830         break;
2831     case CMD_PRINT_HELP:
2832         s_log(LOG_NOTICE, "%-22s = yes|no support renegotiation",
2833               "renegotiation");
2834         break;
2835     }
2836 
2837     /* requireCert */
2838     switch(cmd) {
2839     case CMD_SET_DEFAULTS:
2840         section->option.require_cert=0;
2841         break;
2842     case CMD_SET_COPY:
2843         section->option.require_cert=new_service_options.option.require_cert;
2844         break;
2845     case CMD_FREE:
2846         break;
2847     case CMD_SET_VALUE:
2848         if(strcasecmp(opt, "requireCert"))
2849             break;
2850         if(!strcasecmp(arg, "yes")) {
2851             section->option.request_cert=1;
2852             section->option.require_cert=1;
2853         } else if(!strcasecmp(arg, "no")) {
2854             section->option.require_cert=0;
2855         } else {
2856             return "The argument needs to be either 'yes' or 'no'";
2857         }
2858         return NULL; /* OK */
2859     case CMD_INITIALIZE:
2860         break;
2861     case CMD_PRINT_DEFAULTS:
2862         break;
2863     case CMD_PRINT_HELP:
2864         s_log(LOG_NOTICE, "%-22s = yes|no require client certificate",
2865             "requireCert");
2866         break;
2867     }
2868 
2869     /* reset */
2870     switch(cmd) {
2871     case CMD_SET_DEFAULTS:
2872         section->option.reset=1; /* enabled by default */
2873         break;
2874     case CMD_SET_COPY:
2875         section->option.reset=new_service_options.option.reset;
2876         break;
2877     case CMD_FREE:
2878         break;
2879     case CMD_SET_VALUE:
2880         if(strcasecmp(opt, "reset"))
2881             break;
2882         if(!strcasecmp(arg, "yes"))
2883             section->option.reset=1;
2884         else if(!strcasecmp(arg, "no"))
2885             section->option.reset=0;
2886         else
2887             return "The argument needs to be either 'yes' or 'no'";
2888         return NULL; /* OK */
2889     case CMD_INITIALIZE:
2890         break;
2891     case CMD_PRINT_DEFAULTS:
2892         break;
2893     case CMD_PRINT_HELP:
2894         s_log(LOG_NOTICE, "%-22s = yes|no send TCP RST on error",
2895             "reset");
2896         break;
2897     }
2898 
2899     /* retry */
2900     switch(cmd) {
2901     case CMD_SET_DEFAULTS:
2902         section->option.retry=0;
2903         break;
2904     case CMD_SET_COPY:
2905         section->option.retry=new_service_options.option.retry;
2906         break;
2907     case CMD_FREE:
2908         break;
2909     case CMD_SET_VALUE:
2910         if(strcasecmp(opt, "retry"))
2911             break;
2912         if(!strcasecmp(arg, "yes"))
2913             section->option.retry=1;
2914         else if(!strcasecmp(arg, "no"))
2915             section->option.retry=0;
2916         else
2917             return "The argument needs to be either 'yes' or 'no'";
2918         return NULL; /* OK */
2919     case CMD_INITIALIZE:
2920         break;
2921     case CMD_PRINT_DEFAULTS:
2922         break;
2923     case CMD_PRINT_HELP:
2924         s_log(LOG_NOTICE, "%-22s = yes|no retry connect+exec section",
2925             "retry");
2926         break;
2927     }
2928 
2929 #if OPENSSL_VERSION_NUMBER>=0x10100000L
2930     /* securityLevel */
2931     switch(cmd) {
2932     case CMD_SET_DEFAULTS:
2933         section->security_level=-1;
2934         break;
2935     case CMD_SET_COPY:
2936         section->security_level=new_service_options.security_level;
2937         break;
2938     case CMD_FREE:
2939         break;
2940     case CMD_SET_VALUE:
2941         if(strcasecmp(opt, "securityLevel"))
2942             break;
2943         {
2944             char *tmp_str;
2945             int tmp_int =(int)strtol(arg, &tmp_str, 10);
2946             if(tmp_str==arg || *tmp_str || tmp_int<0 || tmp_int>5) /* not a correct number */
2947                 return "Illegal security level";
2948             section->security_level = tmp_int;
2949         }
2950         return NULL; /* OK */
2951     case CMD_INITIALIZE:
2952         break;
2953     case CMD_PRINT_DEFAULTS:
2954         s_log(LOG_NOTICE, "%-22s = %d", "securityLevel", DEFAULT_SECURITY_LEVEL);
2955         break;
2956     case CMD_PRINT_HELP:
2957         s_log(LOG_NOTICE, "%-22s = set the security level", "securityLevel");
2958         break;
2959     }
2960 #endif /* OpenSSL 1.1.0 or later */
2961 
2962 #ifndef USE_WIN32
2963     /* service */
2964     switch(cmd) {
2965     case CMD_SET_DEFAULTS:
2966         section->servname=str_dup_detached("stunnel");
2967         break;
2968     case CMD_SET_COPY:
2969         /* servname is *not* copied from the global section */
2970         break;
2971     case CMD_FREE:
2972         /* deallocation is performed at the end CMD_FREE */
2973         break;
2974     case CMD_SET_VALUE:
2975         if(strcasecmp(opt, "service"))
2976             break;
2977         str_free(section->servname);
2978         section->servname=str_dup_detached(arg);
2979         return NULL; /* OK */
2980     case CMD_INITIALIZE:
2981         break;
2982     case CMD_PRINT_DEFAULTS:
2983         break;
2984     case CMD_PRINT_HELP:
2985         s_log(LOG_NOTICE, "%-22s = service name", "service");
2986         break;
2987     }
2988 #endif
2989 
2990 #ifndef USE_WIN32
2991     /* setgid */
2992     switch(cmd) {
2993     case CMD_SET_DEFAULTS:
2994         section->gid=0;
2995         break;
2996     case CMD_SET_COPY:
2997         section->gid=new_service_options.gid;
2998         break;
2999     case CMD_FREE:
3000         break;
3001     case CMD_SET_VALUE:
3002         if(strcasecmp(opt, "setgid"))
3003             break;
3004         gr=getgrnam(arg);
3005         if(gr) {
3006             section->gid=gr->gr_gid;
3007             return NULL; /* OK */
3008         }
3009         {
3010             char *tmp_str;
3011             section->gid=(gid_t)strtol(arg, &tmp_str, 10);
3012             if(tmp_str==arg || *tmp_str) /* not a number */
3013                 return "Illegal GID";
3014         }
3015         return NULL; /* OK */
3016     case CMD_INITIALIZE:
3017         break;
3018     case CMD_PRINT_DEFAULTS:
3019         break;
3020     case CMD_PRINT_HELP:
3021         s_log(LOG_NOTICE, "%-22s = groupname for setgid()", "setgid");
3022         break;
3023     }
3024 #endif
3025 
3026 #ifndef USE_WIN32
3027     /* setuid */
3028     switch(cmd) {
3029     case CMD_SET_DEFAULTS:
3030         section->uid=0;
3031         break;
3032     case CMD_SET_COPY:
3033         section->uid=new_service_options.uid;
3034         break;
3035     case CMD_FREE:
3036         break;
3037     case CMD_SET_VALUE:
3038         if(strcasecmp(opt, "setuid"))
3039             break;
3040         pw=getpwnam(arg);
3041         if(pw) {
3042             section->uid=pw->pw_uid;
3043             return NULL; /* OK */
3044         }
3045         {
3046             char *tmp_str;
3047             section->uid=(uid_t)strtol(arg, &tmp_str, 10);
3048             if(tmp_str==arg || *tmp_str) /* not a number */
3049                 return "Illegal UID";
3050         }
3051         return NULL; /* OK */
3052     case CMD_INITIALIZE:
3053         break;
3054     case CMD_PRINT_DEFAULTS:
3055         break;
3056     case CMD_PRINT_HELP:
3057         s_log(LOG_NOTICE, "%-22s = username for setuid()", "setuid");
3058         break;
3059     }
3060 #endif
3061 
3062     /* sessionCacheSize */
3063     switch(cmd) {
3064     case CMD_SET_DEFAULTS:
3065         section->session_size=1000L;
3066         break;
3067     case CMD_SET_COPY:
3068         section->session_size=new_service_options.session_size;
3069         break;
3070     case CMD_FREE:
3071         break;
3072     case CMD_SET_VALUE:
3073         if(strcasecmp(opt, "sessionCacheSize"))
3074             break;
3075         {
3076             char *tmp_str;
3077             section->session_size=strtol(arg, &tmp_str, 10);
3078             if(tmp_str==arg || *tmp_str) /* not a number */
3079                 return "Illegal session cache size";
3080         }
3081         return NULL; /* OK */
3082     case CMD_INITIALIZE:
3083         break;
3084     case CMD_PRINT_DEFAULTS:
3085         s_log(LOG_NOTICE, "%-22s = %ld", "sessionCacheSize", 1000L);
3086         break;
3087     case CMD_PRINT_HELP:
3088         s_log(LOG_NOTICE, "%-22s = session cache size", "sessionCacheSize");
3089         break;
3090     }
3091 
3092     /* sessionCacheTimeout */
3093     switch(cmd) {
3094     case CMD_SET_DEFAULTS:
3095         section->session_timeout=300L;
3096         break;
3097     case CMD_SET_COPY:
3098         section->session_timeout=new_service_options.session_timeout;
3099         break;
3100     case CMD_FREE:
3101         break;
3102     case CMD_SET_VALUE:
3103         if(strcasecmp(opt, "sessionCacheTimeout") && strcasecmp(opt, "session"))
3104             break;
3105         {
3106             char *tmp_str;
3107             section->session_timeout=strtol(arg, &tmp_str, 10);
3108             if(tmp_str==arg || *tmp_str) /* not a number */
3109                 return "Illegal session cache timeout";
3110         }
3111         return NULL; /* OK */
3112     case CMD_INITIALIZE:
3113         break;
3114     case CMD_PRINT_DEFAULTS:
3115         s_log(LOG_NOTICE, "%-22s = %ld seconds", "sessionCacheTimeout", 300L);
3116         break;
3117     case CMD_PRINT_HELP:
3118         s_log(LOG_NOTICE, "%-22s = session cache timeout (in seconds)",
3119             "sessionCacheTimeout");
3120         break;
3121     }
3122 
3123     /* sessionResume */
3124     switch(cmd) {
3125     case CMD_SET_DEFAULTS:
3126         section->option.session_resume=1; /* enabled by default */
3127         break;
3128     case CMD_SET_COPY:
3129         section->option.session_resume=new_service_options.option.session_resume;
3130         break;
3131     case CMD_FREE:
3132         break;
3133     case CMD_SET_VALUE:
3134         if(strcasecmp(opt, "sessionResume"))
3135             break;
3136         if(!strcasecmp(arg, "yes"))
3137             section->option.session_resume=1;
3138         else if(!strcasecmp(arg, "no"))
3139             section->option.session_resume=0;
3140         else
3141             return "The argument needs to be either 'yes' or 'no'";
3142         return NULL; /* OK */
3143     case CMD_INITIALIZE:
3144         break;
3145     case CMD_PRINT_DEFAULTS:
3146         break;
3147     case CMD_PRINT_HELP:
3148         s_log(LOG_NOTICE, "%-22s = yes|no enable session resumption",
3149             "sessionResume");
3150         break;
3151     }
3152 
3153     /* sessiond */
3154     switch(cmd) {
3155     case CMD_SET_DEFAULTS:
3156         section->option.sessiond=0;
3157         memset(&section->sessiond_addr, 0, sizeof(SOCKADDR_UNION));
3158         section->sessiond_addr.in.sin_family=AF_INET;
3159         break;
3160     case CMD_SET_COPY:
3161         section->option.sessiond=new_service_options.option.sessiond;
3162         memcpy(&section->sessiond_addr, &new_service_options.sessiond_addr,
3163             sizeof(SOCKADDR_UNION));
3164         break;
3165     case CMD_FREE:
3166         break;
3167     case CMD_SET_VALUE:
3168         if(strcasecmp(opt, "sessiond"))
3169             break;
3170         section->option.sessiond=1;
3171 #ifdef SSL_OP_NO_TICKET
3172         /* disable RFC4507 support introduced in OpenSSL 0.9.8f */
3173         /* this prevents session callbacks from being executed */
3174         section->ssl_options_set|=SSL_OP_NO_TICKET;
3175 #endif
3176         if(!name2addr(&section->sessiond_addr, arg, 0))
3177             return "Failed to resolve sessiond server address";
3178         return NULL; /* OK */
3179     case CMD_INITIALIZE:
3180         break;
3181     case CMD_PRINT_DEFAULTS:
3182         break;
3183     case CMD_PRINT_HELP:
3184         s_log(LOG_NOTICE, "%-22s = [host:]port use sessiond at host:port",
3185             "sessiond");
3186         break;
3187     }
3188 
3189 #ifndef OPENSSL_NO_TLSEXT
3190     /* sni */
3191     switch(cmd) {
3192     case CMD_SET_DEFAULTS:
3193         section->servername_list_head=NULL;
3194         section->servername_list_tail=NULL;
3195         break;
3196     case CMD_SET_COPY:
3197         section->sni=
3198             str_dup_detached(new_service_options.sni);
3199         break;
3200     case CMD_FREE:
3201         str_free(section->sni);
3202         sni_free(section);
3203         break;
3204     case CMD_SET_VALUE:
3205         if(strcasecmp(opt, "sni"))
3206             break;
3207         str_free(section->sni);
3208         section->sni=str_dup_detached(arg);
3209         return NULL; /* OK */
3210     case CMD_INITIALIZE:
3211         {
3212             char *tmp_str=sni_init(section);
3213             if(tmp_str)
3214                 return tmp_str;
3215         }
3216         if(!section->option.client && section->sni)
3217             ++endpoints;
3218         break;
3219     case CMD_PRINT_DEFAULTS:
3220         break;
3221     case CMD_PRINT_HELP:
3222         s_log(LOG_NOTICE, "%-22s = master_service:host_name for an SNI virtual service",
3223             "sni");
3224         break;
3225     }
3226 #endif /* !defined(OPENSSL_NO_TLSEXT) */
3227 
3228     /* socket */
3229     switch(cmd) {
3230     case CMD_SET_DEFAULTS:
3231         section->sock_opts=socket_options_init();
3232         break;
3233     case CMD_SET_COPY:
3234         section->sock_opts=socket_options_dup(new_service_options.sock_opts);
3235         break;
3236     case CMD_FREE:
3237         socket_options_free(section->sock_opts);
3238         break;
3239     case CMD_SET_VALUE:
3240         if(strcasecmp(opt, "socket"))
3241             break;
3242         if(socket_option_parse(section->sock_opts, arg))
3243             return "Illegal socket option";
3244         return NULL; /* OK */
3245     case CMD_INITIALIZE:
3246         break;
3247     case CMD_PRINT_DEFAULTS:
3248         break;
3249     case CMD_PRINT_HELP:
3250         s_log(LOG_NOTICE, "%-22s = a|l|r:option=value[:value]", "socket");
3251         s_log(LOG_NOTICE, "%25sset an option on accept/local/remote socket", "");
3252         break;
3253     }
3254 
3255 #if OPENSSL_VERSION_NUMBER>=0x10100000L
3256 
3257     /* sslVersion */
3258     switch(cmd) {
3259     case CMD_SET_DEFAULTS:
3260         /* handled in sslVersionMax and sslVersionMin */
3261         break;
3262     case CMD_SET_COPY:
3263         /* handled in sslVersionMax and sslVersionMin */
3264         break;
3265     case CMD_FREE:
3266         break;
3267     case CMD_SET_VALUE:
3268         if(strcasecmp(opt, "sslVersion"))
3269             break;
3270         section->max_proto_version=
3271             section->min_proto_version=str_to_proto_version(arg);
3272         if(section->max_proto_version==-1)
3273             return "Invalid protocol version";
3274         return NULL; /* OK */
3275     case CMD_INITIALIZE:
3276         if(section->max_proto_version && section->min_proto_version &&
3277                 section->max_proto_version<section->min_proto_version)
3278             return "Invalid protocol version range";
3279         break;
3280     case CMD_PRINT_DEFAULTS:
3281         break;
3282     case CMD_PRINT_HELP:
3283         s_log(LOG_NOTICE, "%-22s = all"
3284             "|SSLv3|TLSv1|TLSv1.1|TLSv1.2"
3285 #ifdef TLS1_3_VERSION
3286             "|TLSv1.3"
3287 #endif
3288             " TLS version", "sslVersion");
3289         break;
3290     }
3291 
3292     /* sslVersionMax */
3293     switch(cmd) {
3294     case CMD_SET_DEFAULTS:
3295         section->max_proto_version=0; /* highest supported */
3296         break;
3297     case CMD_SET_COPY:
3298         section->max_proto_version=new_service_options.max_proto_version;
3299         break;
3300     case CMD_FREE:
3301         break;
3302     case CMD_SET_VALUE:
3303         if(strcasecmp(opt, "sslVersionMax"))
3304             break;
3305         section->max_proto_version=str_to_proto_version(arg);
3306         if(section->max_proto_version==-1)
3307             return "Invalid protocol version";
3308         return NULL; /* OK */
3309     case CMD_INITIALIZE:
3310         break;
3311     case CMD_PRINT_DEFAULTS:
3312         break;
3313     case CMD_PRINT_HELP:
3314         s_log(LOG_NOTICE, "%-22s = all"
3315             "|SSLv3|TLSv1|TLSv1.1|TLSv1.2"
3316 #ifdef TLS1_3_VERSION
3317             "|TLSv1.3"
3318 #endif
3319             " TLS version", "sslVersionMax");
3320         break;
3321     }
3322 
3323     /* sslVersionMin */
3324     switch(cmd) {
3325     case CMD_SET_DEFAULTS:
3326         section->min_proto_version=TLS1_VERSION;
3327         break;
3328     case CMD_SET_COPY:
3329         section->min_proto_version=new_service_options.min_proto_version;
3330         break;
3331     case CMD_FREE:
3332         break;
3333     case CMD_SET_VALUE:
3334         if(strcasecmp(opt, "sslVersionMin"))
3335             break;
3336         section->min_proto_version=str_to_proto_version(arg);
3337         if(section->min_proto_version==-1)
3338             return "Invalid protocol version";
3339         return NULL; /* OK */
3340     case CMD_INITIALIZE:
3341         break;
3342     case CMD_PRINT_DEFAULTS:
3343         break;
3344     case CMD_PRINT_HELP:
3345         s_log(LOG_NOTICE, "%-22s = all"
3346             "|SSLv3|TLSv1|TLSv1.1|TLSv1.2"
3347 #ifdef TLS1_3_VERSION
3348             "|TLSv1.3"
3349 #endif
3350             " TLS version", "sslVersionMin");
3351         break;
3352     }
3353 
3354 #else /* OPENSSL_VERSION_NUMBER<0x10100000L */
3355 
3356     /* sslVersion */
3357     switch(cmd) {
3358     case CMD_SET_DEFAULTS:
3359         tls_methods_set(section, NULL);
3360         break;
3361     case CMD_SET_COPY:
3362         section->client_method=new_service_options.client_method;
3363         section->server_method=new_service_options.server_method;
3364         break;
3365     case CMD_FREE:
3366         break;
3367     case CMD_SET_VALUE:
3368         if(strcasecmp(opt, "sslVersion"))
3369             break;
3370         return tls_methods_set(section, arg);
3371     case CMD_INITIALIZE:
3372         {
3373             char *tmp_str=tls_methods_check(section);
3374             if(tmp_str)
3375                 return tmp_str;
3376         }
3377         break;
3378     case CMD_PRINT_DEFAULTS:
3379         break;
3380     case CMD_PRINT_HELP:
3381         s_log(LOG_NOTICE, "%-22s = all"
3382             "|SSLv2|SSLv3|TLSv1"
3383 #if OPENSSL_VERSION_NUMBER>=0x10001000L
3384             "|TLSv1.1|TLSv1.2"
3385 #endif /* OPENSSL_VERSION_NUMBER>=0x10001000L */
3386             " TLS method", "sslVersion");
3387         break;
3388     }
3389 
3390 #endif /* OPENSSL_VERSION_NUMBER<0x10100000L */
3391 
3392 #ifndef USE_FORK
3393     /* stack */
3394     switch(cmd) {
3395     case CMD_SET_DEFAULTS:
3396         section->stack_size=DEFAULT_STACK_SIZE;
3397         break;
3398     case CMD_SET_COPY:
3399         section->stack_size=new_service_options.stack_size;
3400         break;
3401     case CMD_FREE:
3402         break;
3403     case CMD_SET_VALUE:
3404         if(strcasecmp(opt, "stack"))
3405             break;
3406         {
3407             char *tmp_str;
3408             section->stack_size=(size_t)strtol(arg, &tmp_str, 10);
3409             if(tmp_str==arg || *tmp_str) /* not a number */
3410                 return "Illegal thread stack size";
3411         }
3412         return NULL; /* OK */
3413     case CMD_INITIALIZE:
3414         break;
3415     case CMD_PRINT_DEFAULTS:
3416         s_log(LOG_NOTICE, "%-22s = %d bytes", "stack", DEFAULT_STACK_SIZE);
3417         break;
3418     case CMD_PRINT_HELP:
3419         s_log(LOG_NOTICE, "%-22s = thread stack size (in bytes)", "stack");
3420         break;
3421     }
3422 #endif
3423 
3424 #if OPENSSL_VERSION_NUMBER>=0x10000000L
3425 
3426     /* ticketKeySecret */
3427     switch(cmd) {
3428     case CMD_SET_DEFAULTS:
3429         section->ticket_key=NULL;
3430         break;
3431     case CMD_SET_COPY:
3432         section->ticket_key=key_dup(new_service_options.ticket_key);
3433         break;
3434     case CMD_FREE:
3435         key_free(section->ticket_key);
3436         break;
3437     case CMD_SET_VALUE:
3438         if(strcasecmp(opt, "ticketKeySecret"))
3439             break;
3440         section->ticket_key=key_read(arg, "ticketKeySecret");
3441         if(!section->ticket_key)
3442             return "Failed to read ticketKeySecret";
3443         return NULL; /* OK */
3444     case CMD_INITIALIZE:
3445         if(!section->ticket_key)          /* ticketKeySecret not configured */
3446             break;
3447         if(section->option.client){
3448             s_log(LOG_NOTICE,
3449                     "ticketKeySecret is ignored in the client mode");
3450             break;
3451         }
3452         if(section->ticket_key && !section->ticket_mac)
3453             return "\"ticketKeySecret\" and \"ticketMacSecret\" must be set together";
3454         break;
3455     case CMD_PRINT_DEFAULTS:
3456         break;
3457     case CMD_PRINT_HELP:
3458         s_log(LOG_NOTICE, "%-22s = secret key for encryption/decryption TLSv1.3 tickets",
3459             "ticketKeySecret");
3460         break;
3461     }
3462 
3463     /* ticketMacSecret */
3464     switch(cmd) {
3465     case CMD_SET_DEFAULTS:
3466         section->ticket_mac=NULL;
3467         break;
3468     case CMD_SET_COPY:
3469         section->ticket_mac=key_dup(new_service_options.ticket_mac);
3470         break;
3471     case CMD_FREE:
3472         key_free(section->ticket_mac);
3473         break;
3474     case CMD_SET_VALUE:
3475         if(strcasecmp(opt, "ticketMacSecret"))
3476             break;
3477         section->ticket_mac=key_read(arg, "ticketMacSecret");
3478         if(!section->ticket_mac)
3479             return "Failed to read ticketMacSecret";
3480         return NULL; /* OK */
3481     case CMD_INITIALIZE:
3482         if(!section->ticket_mac)            /* ticketMacSecret not configured */
3483             break;
3484         if(section->option.client){
3485             s_log(LOG_NOTICE,
3486                     "ticketMacSecret is ignored in the client mode");
3487             break;
3488         }
3489         if(section->ticket_mac && !section->ticket_key)
3490             return "\"ticketKeySecret\" and \"ticketMacSecret\" must be set together";
3491         break;
3492     case CMD_PRINT_DEFAULTS:
3493         break;
3494     case CMD_PRINT_HELP:
3495         s_log(LOG_NOTICE, "%-22s = key for HMAC operations on TLSv1.3 tickets",
3496             "ticketMacSecret");
3497         break;
3498     }
3499 
3500 #endif /* OpenSSL 1.0.0 or later */
3501 
3502     /* TIMEOUTbusy */
3503     switch(cmd) {
3504     case CMD_SET_DEFAULTS:
3505         section->timeout_busy=300; /* 5 minutes */
3506         break;
3507     case CMD_SET_COPY:
3508         section->timeout_busy=new_service_options.timeout_busy;
3509         break;
3510     case CMD_FREE:
3511         break;
3512     case CMD_SET_VALUE:
3513         if(strcasecmp(opt, "TIMEOUTbusy"))
3514             break;
3515         {
3516             char *tmp_str;
3517             section->timeout_busy=(int)strtol(arg, &tmp_str, 10);
3518             if(tmp_str==arg || *tmp_str) /* not a number */
3519                 return "Illegal busy timeout";
3520         }
3521         return NULL; /* OK */
3522     case CMD_INITIALIZE:
3523         break;
3524     case CMD_PRINT_DEFAULTS:
3525         s_log(LOG_NOTICE, "%-22s = %d seconds", "TIMEOUTbusy", 300);
3526         break;
3527     case CMD_PRINT_HELP:
3528         s_log(LOG_NOTICE, "%-22s = seconds to wait for expected data", "TIMEOUTbusy");
3529         break;
3530     }
3531 
3532     /* TIMEOUTclose */
3533     switch(cmd) {
3534     case CMD_SET_DEFAULTS:
3535         section->timeout_close=60; /* 1 minute */
3536         break;
3537     case CMD_SET_COPY:
3538         section->timeout_close=new_service_options.timeout_close;
3539         break;
3540     case CMD_FREE:
3541         break;
3542     case CMD_SET_VALUE:
3543         if(strcasecmp(opt, "TIMEOUTclose"))
3544             break;
3545         {
3546             char *tmp_str;
3547             section->timeout_close=(int)strtol(arg, &tmp_str, 10);
3548             if(tmp_str==arg || *tmp_str) /* not a number */
3549                 return "Illegal close timeout";
3550         }
3551         return NULL; /* OK */
3552     case CMD_INITIALIZE:
3553         break;
3554     case CMD_PRINT_DEFAULTS:
3555         s_log(LOG_NOTICE, "%-22s = %d seconds", "TIMEOUTclose", 60);
3556         break;
3557     case CMD_PRINT_HELP:
3558         s_log(LOG_NOTICE, "%-22s = seconds to wait for close_notify",
3559             "TIMEOUTclose");
3560         break;
3561     }
3562 
3563     /* TIMEOUTconnect */
3564     switch(cmd) {
3565     case CMD_SET_DEFAULTS:
3566         section->timeout_connect=10; /* 10 seconds */
3567         break;
3568     case CMD_SET_COPY:
3569         section->timeout_connect=new_service_options.timeout_connect;
3570         break;
3571     case CMD_FREE:
3572         break;
3573     case CMD_SET_VALUE:
3574         if(strcasecmp(opt, "TIMEOUTconnect"))
3575             break;
3576         {
3577             char *tmp_str;
3578             section->timeout_connect=(int)strtol(arg, &tmp_str, 10);
3579             if(tmp_str==arg || *tmp_str) /* not a number */
3580                 return "Illegal connect timeout";
3581         }
3582         return NULL; /* OK */
3583     case CMD_INITIALIZE:
3584         break;
3585     case CMD_PRINT_DEFAULTS:
3586         s_log(LOG_NOTICE, "%-22s = %d seconds", "TIMEOUTconnect", 10);
3587         break;
3588     case CMD_PRINT_HELP:
3589         s_log(LOG_NOTICE, "%-22s = seconds to connect remote host", "TIMEOUTconnect");
3590         break;
3591     }
3592 
3593     /* TIMEOUTidle */
3594     switch(cmd) {
3595     case CMD_SET_DEFAULTS:
3596         section->timeout_idle=43200; /* 12 hours */
3597         break;
3598     case CMD_SET_COPY:
3599         section->timeout_idle=new_service_options.timeout_idle;
3600         break;
3601     case CMD_FREE:
3602         break;
3603     case CMD_SET_VALUE:
3604         if(strcasecmp(opt, "TIMEOUTidle"))
3605             break;
3606         {
3607             char *tmp_str;
3608             section->timeout_idle=(int)strtol(arg, &tmp_str, 10);
3609             if(tmp_str==arg || *tmp_str) /* not a number */
3610                 return "Illegal idle timeout";
3611             return NULL; /* OK */
3612         }
3613     case CMD_INITIALIZE:
3614         break;
3615     case CMD_PRINT_DEFAULTS:
3616         s_log(LOG_NOTICE, "%-22s = %d seconds", "TIMEOUTidle", 43200);
3617         break;
3618     case CMD_PRINT_HELP:
3619         s_log(LOG_NOTICE, "%-22s = seconds to keep an idle connection", "TIMEOUTidle");
3620         break;
3621     }
3622 
3623     /* transparent */
3624 #ifndef USE_WIN32
3625     switch(cmd) {
3626     case CMD_SET_DEFAULTS:
3627         section->option.transparent_src=0;
3628         section->option.transparent_dst=0;
3629         break;
3630     case CMD_SET_COPY:
3631         section->option.transparent_src=new_service_options.option.transparent_src;
3632         section->option.transparent_dst=new_service_options.option.transparent_dst;
3633         break;
3634     case CMD_FREE:
3635         break;
3636     case CMD_SET_VALUE:
3637         if(strcasecmp(opt, "transparent"))
3638             break;
3639         if(!strcasecmp(arg, "none") || !strcasecmp(arg, "no")) {
3640             section->option.transparent_src=0;
3641             section->option.transparent_dst=0;
3642         } else if(!strcasecmp(arg, "source") || !strcasecmp(arg, "yes")) {
3643             section->option.transparent_src=1;
3644             section->option.transparent_dst=0;
3645         } else if(!strcasecmp(arg, "destination")) {
3646             section->option.transparent_src=0;
3647             section->option.transparent_dst=1;
3648         } else if(!strcasecmp(arg, "both")) {
3649             section->option.transparent_src=1;
3650             section->option.transparent_dst=1;
3651         } else
3652             return "Selected transparent proxy mode is not available";
3653         return NULL; /* OK */
3654     case CMD_INITIALIZE:
3655         if(section->option.transparent_dst)
3656             ++endpoints;
3657         break;
3658     case CMD_PRINT_DEFAULTS:
3659         break;
3660     case CMD_PRINT_HELP:
3661         s_log(LOG_NOTICE,
3662             "%-22s = none|source|destination|both transparent proxy mode",
3663             "transparent");
3664         break;
3665     }
3666 #endif
3667 
3668     /* verify */
3669     switch(cmd) {
3670     case CMD_SET_DEFAULTS:
3671         section->option.request_cert=0;
3672         break;
3673     case CMD_SET_COPY:
3674         section->option.request_cert=new_service_options.option.request_cert;
3675         break;
3676     case CMD_FREE:
3677         break;
3678     case CMD_SET_VALUE:
3679         if(strcasecmp(opt, "verify"))
3680             break;
3681         {
3682             char *tmp_str;
3683             int tmp_int=(int)strtol(arg, &tmp_str, 10);
3684             if(tmp_str==arg || *tmp_str || tmp_int<0 || tmp_int>4)
3685                 return "Bad verify level";
3686             section->option.request_cert=1;
3687             section->option.require_cert=(tmp_int>=2);
3688             section->option.verify_chain=(tmp_int>=1 && tmp_int<=3);
3689             section->option.verify_peer=(tmp_int>=3);
3690         }
3691         return NULL; /* OK */
3692     case CMD_INITIALIZE:
3693         if((section->option.verify_chain || section->option.verify_peer) &&
3694                 !section->ca_file && !section->ca_dir)
3695             return "Either \"CAfile\" or \"CApath\" has to be configured";
3696         break;
3697     case CMD_PRINT_DEFAULTS:
3698         s_log(LOG_NOTICE, "%-22s = none", "verify");
3699         break;
3700     case CMD_PRINT_HELP:
3701         s_log(LOG_NOTICE,
3702             "%-22s = level of peer certificate verification", "verify");
3703         break;
3704     }
3705 
3706     /* verifyChain */
3707     switch(cmd) {
3708     case CMD_SET_DEFAULTS:
3709         section->option.verify_chain=0;
3710         break;
3711     case CMD_SET_COPY:
3712         section->option.verify_chain=new_service_options.option.verify_chain;
3713         break;
3714     case CMD_FREE:
3715         break;
3716     case CMD_SET_VALUE:
3717         if(strcasecmp(opt, "verifyChain"))
3718             break;
3719         if(!strcasecmp(arg, "yes")) {
3720             section->option.request_cert=1;
3721             section->option.require_cert=1;
3722             section->option.verify_chain=1;
3723         } else if(!strcasecmp(arg, "no")) {
3724             section->option.verify_chain=0;
3725         } else {
3726             return "The argument needs to be either 'yes' or 'no'";
3727         }
3728         return NULL; /* OK */
3729     case CMD_INITIALIZE:
3730         break;
3731     case CMD_PRINT_DEFAULTS:
3732         break;
3733     case CMD_PRINT_HELP:
3734         s_log(LOG_NOTICE, "%-22s = yes|no verify certificate chain",
3735             "verifyChain");
3736         break;
3737     }
3738 
3739     /* verifyPeer */
3740     switch(cmd) {
3741     case CMD_SET_DEFAULTS:
3742         section->option.verify_peer=0;
3743         break;
3744     case CMD_SET_COPY:
3745         section->option.verify_peer=new_service_options.option.verify_peer;
3746         break;
3747     case CMD_FREE:
3748         break;
3749     case CMD_SET_VALUE:
3750         if(strcasecmp(opt, "verifyPeer"))
3751             break;
3752         if(!strcasecmp(arg, "yes")) {
3753             section->option.request_cert=1;
3754             section->option.require_cert=1;
3755             section->option.verify_peer=1;
3756         } else if(!strcasecmp(arg, "no")) {
3757             section->option.verify_peer=0;
3758         } else {
3759             return "The argument needs to be either 'yes' or 'no'";
3760         }
3761         return NULL; /* OK */
3762     case CMD_INITIALIZE:
3763         break;
3764     case CMD_PRINT_DEFAULTS:
3765         break;
3766     case CMD_PRINT_HELP:
3767         s_log(LOG_NOTICE, "%-22s = yes|no verify peer certificate",
3768             "verifyPeer");
3769         break;
3770     }
3771 
3772     /* final checks */
3773     switch(cmd) {
3774     case CMD_SET_DEFAULTS:
3775         break;
3776     case CMD_SET_COPY:
3777         break;
3778     case CMD_FREE:
3779         str_free(section->chain);
3780         if(section->session)
3781             SSL_SESSION_free(section->session);
3782         if(section->ctx)
3783             SSL_CTX_free(section->ctx);
3784         str_free(section->servname);
3785         if(section==&service_options || section==&new_service_options)
3786             memset(section, 0, sizeof(SERVICE_OPTIONS));
3787         else
3788             str_free(section);
3789         break;
3790     case CMD_SET_VALUE:
3791         return option_not_found;
3792     case CMD_INITIALIZE:
3793         if(section!=&new_service_options) { /* daemon mode checks */
3794             if(endpoints!=2)
3795                 return "Each service must define two endpoints";
3796         } else { /* inetd mode checks */
3797             if(section->option.accept)
3798                 return "'accept' option is only allowed in a [section]";
3799             /* no need to check for section->sni in inetd mode,
3800                as it requires valid sections to be set */
3801             if(endpoints!=1)
3802                 return "Inetd mode must define one endpoint";
3803         }
3804 #ifdef SSL_OP_NO_TICKET
3805         /* disable RFC4507 support introduced in OpenSSL 0.9.8f */
3806         /* OpenSSL 1.1.1 is required to serialize application data
3807          * into session tickets */
3808         /* server mode sections need it for the "redirect" option
3809          * and connect address session persistence */
3810         if(OpenSSL_version_num()<0x10101000L &&
3811                 !section->option.client &&
3812                 !section->option.connect_before_ssl)
3813             section->ssl_options_set|=SSL_OP_NO_TICKET;
3814 #endif /* SSL_OP_NO_TICKET */
3815         if(context_init(section)) /* initialize TLS context */
3816             return "Failed to initialize TLS context";
3817         break;
3818     case CMD_PRINT_DEFAULTS:
3819         break;
3820     case CMD_PRINT_HELP:
3821         break;
3822     }
3823 
3824     return NULL; /* OK */
3825 }
3826 
3827 /**************************************** validate and initialize configuration */
3828 
3829 #ifndef OPENSSL_NO_TLSEXT
3830 
sni_init(SERVICE_OPTIONS * section)3831 NOEXPORT char *sni_init(SERVICE_OPTIONS *section) {
3832     char *tmp_str;
3833     SERVICE_OPTIONS *tmpsrv;
3834 
3835     /* server mode: update servername_list based on the SNI option */
3836     if(!section->option.client && section->sni) {
3837         tmp_str=strchr(section->sni, ':');
3838         if(!tmp_str)
3839             return "Invalid SNI parameter format";
3840         *tmp_str++='\0';
3841         for(tmpsrv=new_service_options.next; tmpsrv; tmpsrv=tmpsrv->next)
3842             if(!strcmp(tmpsrv->servname, section->sni))
3843                 break;
3844         if(!tmpsrv)
3845             return "SNI section name not found";
3846         if(tmpsrv->option.client)
3847             return "SNI master service is a TLS client";
3848         if(tmpsrv->servername_list_tail) {
3849             tmpsrv->servername_list_tail->next=str_alloc_detached(sizeof(SERVERNAME_LIST));
3850             tmpsrv->servername_list_tail=tmpsrv->servername_list_tail->next;
3851         } else { /* first virtual service */
3852             tmpsrv->servername_list_head=
3853                 tmpsrv->servername_list_tail=
3854                 str_alloc_detached(sizeof(SERVERNAME_LIST));
3855             tmpsrv->ssl_options_set|=
3856                 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
3857         }
3858         /* a slave section reference is needed to prevent a race condition
3859            while switching to a section after configuration file reload */
3860         service_up_ref(section);
3861         tmpsrv->servername_list_tail->servername=str_dup_detached(tmp_str);
3862         tmpsrv->servername_list_tail->opt=section;
3863         tmpsrv->servername_list_tail->next=NULL;
3864         /* always negotiate a new session on renegotiation, as the TLS
3865          * context settings (including access control) may be different */
3866         section->ssl_options_set|=
3867             SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
3868     }
3869 
3870     /* client mode: setup SNI default based on 'protocolHost' and 'connect' options */
3871     if(section->option.client && !section->sni) {
3872         /* setup host_name for SNI, prefer SNI and protocolHost if specified */
3873         if(section->protocol_host) /* 'protocolHost' option */
3874             section->sni=str_dup_detached(section->protocol_host);
3875         else if(section->connect_addr.names) /* 'connect' option */
3876             section->sni=str_dup_detached(section->connect_addr.names->name); /* first hostname */
3877         if(section->sni) { /* either 'protocolHost' or 'connect' specified */
3878             tmp_str=strrchr(section->sni, ':');
3879             if(tmp_str) { /* 'host:port' -> drop ':port' */
3880                 *tmp_str='\0';
3881             } else { /* 'port' -> default to 'localhost' */
3882                 str_free(section->sni);
3883                 section->sni=str_dup_detached("localhost");
3884             }
3885         }
3886     }
3887     return NULL;
3888 }
3889 
sni_free(SERVICE_OPTIONS * section)3890 NOEXPORT void sni_free(SERVICE_OPTIONS *section) {
3891     SERVERNAME_LIST *curr=section->servername_list_head;
3892     while(curr) {
3893         SERVERNAME_LIST *next=curr->next;
3894         str_free(curr->servername);
3895         service_free(curr->opt); /* free the slave section */
3896         str_free(curr);
3897         curr=next;
3898     }
3899     section->servername_list_head=NULL;
3900     section->servername_list_tail=NULL;
3901 }
3902 
3903 #endif /* !defined(OPENSSL_NO_TLSEXT) */
3904 
3905 /**************************************** modern TLS version handling */
3906 
3907 #if OPENSSL_VERSION_NUMBER>=0x10100000L
3908 
str_to_proto_version(const char * name)3909 NOEXPORT int str_to_proto_version(const char *name) {
3910     if(!strcasecmp(name, "all"))
3911         return 0;
3912     if(!strcasecmp(name, "SSLv3"))
3913         return SSL3_VERSION;
3914     if(!strcasecmp(name, "TLSv1"))
3915         return TLS1_VERSION;
3916     if(!strcasecmp(name, "TLSv1.1"))
3917         return TLS1_1_VERSION;
3918     if(!strcasecmp(name, "TLSv1.2"))
3919         return TLS1_2_VERSION;
3920 #ifdef TLS1_3_VERSION
3921     if(!strcasecmp(name, "TLSv1.3"))
3922         return TLS1_3_VERSION;
3923 #endif
3924     return -1;
3925 }
3926 
3927 /**************************************** deprecated TLS version handling */
3928 
3929 #else /* OPENSSL_VERSION_NUMBER<0x10100000L */
3930 
3931 #ifdef __GNUC__
3932 #pragma GCC diagnostic push
3933 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
3934 #endif /* __GNUC__ */
3935 
tls_methods_set(SERVICE_OPTIONS * section,const char * arg)3936 NOEXPORT char *tls_methods_set(SERVICE_OPTIONS *section, const char *arg) {
3937     if(!arg) { /* defaults */
3938         section->client_method=(SSL_METHOD *)SSLv23_client_method();
3939         section->server_method=(SSL_METHOD *)SSLv23_server_method();
3940     } else if(!strcasecmp(arg, "all")) {
3941         section->client_method=(SSL_METHOD *)SSLv23_client_method();
3942         section->server_method=(SSL_METHOD *)SSLv23_server_method();
3943     } else if(!strcasecmp(arg, "SSLv2")) {
3944 #ifndef OPENSSL_NO_SSL2
3945         section->client_method=(SSL_METHOD *)SSLv2_client_method();
3946         section->server_method=(SSL_METHOD *)SSLv2_server_method();
3947 #else /* OPENSSL_NO_SSL2 */
3948         return "SSLv2 not supported";
3949 #endif /* !OPENSSL_NO_SSL2 */
3950     } else if(!strcasecmp(arg, "SSLv3")) {
3951 #ifndef OPENSSL_NO_SSL3
3952         section->client_method=(SSL_METHOD *)SSLv3_client_method();
3953         section->server_method=(SSL_METHOD *)SSLv3_server_method();
3954 #else /* OPENSSL_NO_SSL3 */
3955         return "SSLv3 not supported";
3956 #endif /* !OPENSSL_NO_SSL3 */
3957     } else if(!strcasecmp(arg, "TLSv1")) {
3958 #ifndef OPENSSL_NO_TLS1
3959         section->client_method=(SSL_METHOD *)TLSv1_client_method();
3960         section->server_method=(SSL_METHOD *)TLSv1_server_method();
3961 #else /* OPENSSL_NO_TLS1 */
3962         return "TLSv1 not supported";
3963 #endif /* !OPENSSL_NO_TLS1 */
3964     } else if(!strcasecmp(arg, "TLSv1.1")) {
3965 #ifndef OPENSSL_NO_TLS1_1
3966         section->client_method=(SSL_METHOD *)TLSv1_1_client_method();
3967         section->server_method=(SSL_METHOD *)TLSv1_1_server_method();
3968 #else /* OPENSSL_NO_TLS1_1 */
3969         return "TLSv1.1 not supported";
3970 #endif /* !OPENSSL_NO_TLS1_1 */
3971     } else if(!strcasecmp(arg, "TLSv1.2")) {
3972 #ifndef OPENSSL_NO_TLS1_2
3973         section->client_method=(SSL_METHOD *)TLSv1_2_client_method();
3974         section->server_method=(SSL_METHOD *)TLSv1_2_server_method();
3975 #else /* OPENSSL_NO_TLS1_2 */
3976         return "TLSv1.2 not supported";
3977 #endif /* !OPENSSL_NO_TLS1_2 */
3978     } else
3979         return "Incorrect version of TLS protocol";
3980     return NULL; /* OK */
3981 }
3982 
tls_methods_check(SERVICE_OPTIONS * section)3983 NOEXPORT char *tls_methods_check(SERVICE_OPTIONS *section) {
3984 #ifdef USE_FIPS
3985     if(new_global_options.option.fips) {
3986 #ifndef OPENSSL_NO_SSL2
3987         if(section->option.client ?
3988                 section->client_method==(SSL_METHOD *)SSLv2_client_method() :
3989                 section->server_method==(SSL_METHOD *)SSLv2_server_method())
3990             return "\"sslVersion = SSLv2\" not supported in FIPS mode";
3991 #endif /* !OPENSSL_NO_SSL2 */
3992 #ifndef OPENSSL_NO_SSL3
3993         if(section->option.client ?
3994                 section->client_method==(SSL_METHOD *)SSLv3_client_method() :
3995                 section->server_method==(SSL_METHOD *)SSLv3_server_method())
3996             return "\"sslVersion = SSLv3\" not supported in FIPS mode";
3997 #endif /* !OPENSSL_NO_SSL3 */
3998     }
3999 #else /* USE_FIPS */
4000     (void)section; /* squash the unused parameter warning */
4001 #endif /* USE_FIPS */
4002     return NULL;
4003 }
4004 
4005 #ifdef __GNUC__
4006 #pragma GCC diagnostic pop
4007 #endif /* __GNUC__ */
4008 
4009 #endif /* OPENSSL_VERSION_NUMBER<0x10100000L */
4010 
4011 /**************************************** facility/debug level */
4012 
4013 typedef struct {
4014     char *name;
4015     int value;
4016 } facilitylevel;
4017 
parse_debug_level(char * arg,SERVICE_OPTIONS * section)4018 NOEXPORT char *parse_debug_level(char *arg, SERVICE_OPTIONS *section) {
4019     facilitylevel *fl;
4020 
4021 /* facilities only make sense on unix */
4022 #if !defined (USE_WIN32) && !defined (__vms)
4023     facilitylevel facilities[] = {
4024         {"auth", LOG_AUTH},     {"cron", LOG_CRON},     {"daemon", LOG_DAEMON},
4025         {"kern", LOG_KERN},     {"lpr", LOG_LPR},       {"mail", LOG_MAIL},
4026         {"news", LOG_NEWS},     {"syslog", LOG_SYSLOG}, {"user", LOG_USER},
4027         {"uucp", LOG_UUCP},     {"local0", LOG_LOCAL0}, {"local1", LOG_LOCAL1},
4028         {"local2", LOG_LOCAL2}, {"local3", LOG_LOCAL3}, {"local4", LOG_LOCAL4},
4029         {"local5", LOG_LOCAL5}, {"local6", LOG_LOCAL6}, {"local7", LOG_LOCAL7},
4030 
4031         /* some facilities are not defined on all Unices */
4032 #ifdef LOG_AUTHPRIV
4033         {"authpriv", LOG_AUTHPRIV},
4034 #endif
4035 #ifdef LOG_FTP
4036         {"ftp", LOG_FTP},
4037 #endif
4038 #ifdef LOG_NTP
4039         {"ntp", LOG_NTP},
4040 #endif
4041         {NULL, 0}
4042     };
4043 #endif /* USE_WIN32, __vms */
4044 
4045     facilitylevel levels[] = {
4046         {"emerg", LOG_EMERG},     {"alert", LOG_ALERT},
4047         {"crit", LOG_CRIT},       {"err", LOG_ERR},
4048         {"warning", LOG_WARNING}, {"notice", LOG_NOTICE},
4049         {"info", LOG_INFO},       {"debug", LOG_DEBUG},
4050         {NULL, -1}
4051     };
4052 
4053 /* facilities only make sense on Unix */
4054 #if !defined (USE_WIN32) && !defined (__vms)
4055     if(section==&new_service_options && strchr(arg, '.')) {
4056         /* a facility was specified in the global options */
4057         new_global_options.log_facility=-1;
4058         arg=strtok(arg, "."); /* break it up */
4059 
4060         for(fl=facilities; fl->name; ++fl) {
4061             if(!strcasecmp(fl->name, arg)) {
4062                 new_global_options.log_facility=fl->value;
4063                 break;
4064             }
4065         }
4066         if(new_global_options.log_facility==-1)
4067             return "Illegal syslog facility";
4068         arg=strtok(NULL, ".");    /* set to the remainder */
4069     }
4070 #endif /* USE_WIN32, __vms */
4071 
4072     /* time to check the syslog level */
4073     if(arg && strlen(arg)==1 && *arg>='0' && *arg<='7') {
4074         section->log_level=*arg-'0';
4075         return NULL; /* OK */
4076     }
4077     section->log_level=8;    /* illegal level */
4078     for(fl=levels; fl->name; ++fl) {
4079         if(!strcasecmp(fl->name, arg)) {
4080             section->log_level=fl->value;
4081             break;
4082         }
4083     }
4084     if(section->log_level==8)
4085         return "Illegal debug level"; /* FAILED */
4086     return NULL; /* OK */
4087 }
4088 
4089 /**************************************** TLS options */
4090 
parse_ssl_option(char * arg)4091 NOEXPORT long unsigned parse_ssl_option(char *arg) {
4092     SSL_OPTION *option;
4093 
4094     for(option=(SSL_OPTION *)ssl_opts; option->name; ++option)
4095         if(!strcasecmp(option->name, arg))
4096             return option->value;
4097     return INVALID_SSL_OPTION; /* FAILED */
4098 }
4099 
print_ssl_options(void)4100 NOEXPORT void print_ssl_options(void) {
4101     SSL_OPTION *option;
4102 
4103     s_log(LOG_NOTICE, " ");
4104     s_log(LOG_NOTICE, "Supported TLS options:");
4105     for(option=(SSL_OPTION *)ssl_opts; option->name; ++option)
4106         s_log(LOG_NOTICE, "options = %s", option->name);
4107 }
4108 
4109 /**************************************** read PSK file */
4110 
4111 #ifndef OPENSSL_NO_PSK
4112 
psk_read(char * key_file)4113 NOEXPORT PSK_KEYS *psk_read(char *key_file) {
4114     DISK_FILE *df;
4115     char line[CONFLINELEN], *key_str;
4116     unsigned char *key_buf;
4117     long key_len;
4118     PSK_KEYS *head=NULL, *tail=NULL, *curr;
4119     int line_number=0;
4120 
4121     if(file_permissions(key_file))
4122         return NULL;
4123     df=file_open(key_file, FILE_MODE_READ);
4124     if(!df) {
4125         s_log(LOG_ERR, "Cannot open PSKsecrets file");
4126         return NULL;
4127     }
4128     while(file_getline(df, line, CONFLINELEN)>=0) {
4129         ++line_number;
4130         if(!line[0]) /* empty line */
4131             continue;
4132         key_str=strchr(line, ':');
4133         if(!key_str) {
4134             s_log(LOG_ERR,
4135                 "PSKsecrets line %d: Not in identity:key format",
4136                 line_number);
4137             file_close(df);
4138             psk_free(head);
4139             return NULL;
4140         }
4141         *key_str++='\0';
4142         if(strlen(line)+1>PSK_MAX_IDENTITY_LEN) { /* with the trailing '\0' */
4143             s_log(LOG_ERR,
4144                 "PSKsecrets line %d: Identity longer than %d characters",
4145                 line_number, PSK_MAX_IDENTITY_LEN);
4146             file_close(df);
4147             psk_free(head);
4148             return NULL;
4149         }
4150         key_buf=OPENSSL_hexstr2buf(key_str, &key_len);
4151         if(key_buf) { /* a valid hexadecimal value */
4152             s_log(LOG_INFO, "PSKsecrets line %d: "
4153                 "%ld-byte hexadecimal key configured for identity \"%s\"",
4154                 line_number, key_len, line);
4155         } else { /* not a valid hexadecimal value -> copy as a string */
4156             key_len=(long)strlen(key_str);
4157             key_buf=OPENSSL_malloc((size_t)key_len);
4158             memcpy(key_buf, key_str, (size_t)key_len);
4159             s_log(LOG_INFO, "PSKsecrets line %d: "
4160                 "%ld-byte ASCII key configured for identity \"%s\"",
4161                 line_number, key_len, line);
4162         }
4163         if(key_len>PSK_MAX_PSK_LEN) {
4164             s_log(LOG_ERR,
4165                 "PSKsecrets line %d: Key longer than %d bytes",
4166                 line_number, PSK_MAX_PSK_LEN);
4167             OPENSSL_free(key_buf);
4168             file_close(df);
4169             psk_free(head);
4170             return NULL;
4171         }
4172         if(key_len<16) {
4173             /* shorter keys are unlikely to have sufficient entropy */
4174             s_log(LOG_ERR,
4175                 "PSKsecrets line %d: Key shorter than 16 bytes",
4176                 line_number);
4177             OPENSSL_free(key_buf);
4178             file_close(df);
4179             psk_free(head);
4180             return NULL;
4181         }
4182         curr=str_alloc_detached(sizeof(PSK_KEYS));
4183         curr->identity=str_dup_detached(line);
4184         curr->key_val=str_alloc_detached((size_t)key_len);
4185         memcpy(curr->key_val, key_buf, (size_t)key_len);
4186         OPENSSL_free(key_buf);
4187         curr->key_len=(unsigned)key_len;
4188         curr->next=NULL;
4189         if(head)
4190             tail->next=curr;
4191         else
4192             head=curr;
4193         tail=curr;
4194     }
4195     file_close(df);
4196     return head;
4197 }
4198 
psk_dup(PSK_KEYS * src)4199 NOEXPORT PSK_KEYS *psk_dup(PSK_KEYS *src) {
4200     PSK_KEYS *head=NULL, *tail=NULL, *curr;
4201 
4202     for(; src; src=src->next) {
4203         curr=str_alloc_detached(sizeof(PSK_KEYS));
4204         curr->identity=str_dup_detached(src->identity);
4205         curr->key_val=str_alloc_detached(src->key_len);
4206         memcpy(curr->key_val, src->key_val, src->key_len);
4207         curr->key_len=src->key_len;
4208         curr->next=NULL;
4209         if(head)
4210             tail->next=curr;
4211         else
4212             head=curr;
4213         tail=curr;
4214     }
4215     return head;
4216 }
4217 
psk_free(PSK_KEYS * head)4218 NOEXPORT void psk_free(PSK_KEYS *head) {
4219     while(head) {
4220         PSK_KEYS *next=head->next;
4221         str_free(head->identity);
4222         str_free(head->key_val);
4223         str_free(head);
4224         head=next;
4225     }
4226 }
4227 
4228 #endif
4229 
4230 /**************************************** read ticket key */
4231 
4232 #if OPENSSL_VERSION_NUMBER>=0x10000000L
4233 
key_read(char * arg,char * option)4234 NOEXPORT TICKET_KEY *key_read(char *arg, char *option) {
4235     char *key_str;
4236     unsigned char *key_buf;
4237     long key_len;
4238     TICKET_KEY *head=NULL;
4239 
4240     key_str=str_dup_detached(arg);
4241     key_buf=OPENSSL_hexstr2buf(key_str, &key_len);
4242     if(key_buf)
4243         if((key_len == 16) || (key_len == 32)) /* a valid 16 or 32 byte hexadecimal value */
4244             s_log(LOG_INFO, "%s configured", option);
4245         else { /* not a valid length */
4246             s_log(LOG_ERR, "%s value has %ld bytes instead of required 16 or 32 bytes",
4247                 option, key_len);
4248             OPENSSL_free(key_buf);
4249             key_free(head);
4250             return NULL;
4251         }
4252     else { /* not a valid hexadecimal form */
4253         s_log(LOG_ERR, "Required %s is 16 or 32 byte hexadecimal key", option);
4254         key_free(head);
4255         return NULL;
4256     }
4257     head=str_alloc_detached(sizeof(TICKET_KEY));
4258     head->key_val=str_alloc_detached((size_t)key_len);
4259     memcpy(head->key_val, key_buf, (size_t)key_len);
4260     OPENSSL_free(key_buf);
4261     head->key_len=(int)key_len;
4262     return head;
4263 }
4264 
key_dup(TICKET_KEY * src)4265 NOEXPORT TICKET_KEY *key_dup(TICKET_KEY *src) {
4266     TICKET_KEY *head=NULL;
4267 
4268     if (src) {
4269         head=str_alloc_detached(sizeof(TICKET_KEY));
4270         head->key_val=(unsigned char *)str_dup_detached((char *)src->key_val);
4271         head->key_len=src->key_len;
4272     }
4273     return head;
4274 }
4275 
key_free(TICKET_KEY * head)4276 NOEXPORT void key_free(TICKET_KEY *head) {
4277     if (head) {
4278         str_free(head->key_val);
4279         str_free(head);
4280     }
4281 }
4282 
4283 #endif /* OpenSSL 1.0.0 or later */
4284 
4285 /**************************************** socket options */
4286 
4287 #define VAL_TAB {NULL, NULL, NULL}
4288 
4289 SOCK_OPT sock_opts_def[]={
4290     {"SO_DEBUG",        SOL_SOCKET,     SO_DEBUG,        TYPE_FLAG,     VAL_TAB},
4291     {"SO_DONTROUTE",    SOL_SOCKET,     SO_DONTROUTE,    TYPE_FLAG,     VAL_TAB},
4292     {"SO_KEEPALIVE",    SOL_SOCKET,     SO_KEEPALIVE,    TYPE_FLAG,     VAL_TAB},
4293     {"SO_LINGER",       SOL_SOCKET,     SO_LINGER,       TYPE_LINGER,   VAL_TAB},
4294     {"SO_OOBINLINE",    SOL_SOCKET,     SO_OOBINLINE,    TYPE_FLAG,     VAL_TAB},
4295     {"SO_RCVBUF",       SOL_SOCKET,     SO_RCVBUF,       TYPE_INT,      VAL_TAB},
4296     {"SO_SNDBUF",       SOL_SOCKET,     SO_SNDBUF,       TYPE_INT,      VAL_TAB},
4297 #ifdef SO_RCVLOWAT
4298     {"SO_RCVLOWAT",     SOL_SOCKET,     SO_RCVLOWAT,     TYPE_INT,      VAL_TAB},
4299 #endif
4300 #ifdef SO_SNDLOWAT
4301     {"SO_SNDLOWAT",     SOL_SOCKET,     SO_SNDLOWAT,     TYPE_INT,      VAL_TAB},
4302 #endif
4303 #ifdef SO_RCVTIMEO
4304     {"SO_RCVTIMEO",     SOL_SOCKET,     SO_RCVTIMEO,     TYPE_TIMEVAL,  VAL_TAB},
4305 #endif
4306 #ifdef SO_SNDTIMEO
4307     {"SO_SNDTIMEO",     SOL_SOCKET,     SO_SNDTIMEO,     TYPE_TIMEVAL,  VAL_TAB},
4308 #endif
4309 #ifdef USE_WIN32
4310     {"SO_EXCLUSIVEADDRUSE", SOL_SOCKET, SO_EXCLUSIVEADDRUSE, TYPE_FLAG, VAL_TAB},
4311 #endif
4312     {"SO_REUSEADDR",    SOL_SOCKET,     SO_REUSEADDR,    TYPE_FLAG,     VAL_TAB},
4313 #ifdef SO_BINDTODEVICE
4314     {"SO_BINDTODEVICE", SOL_SOCKET,     SO_BINDTODEVICE, TYPE_STRING,   VAL_TAB},
4315 #endif
4316 #ifdef SOL_TCP
4317 #ifdef TCP_KEEPCNT
4318     {"TCP_KEEPCNT",     SOL_TCP,        TCP_KEEPCNT,     TYPE_INT,      VAL_TAB},
4319 #endif
4320 #ifdef TCP_KEEPIDLE
4321     {"TCP_KEEPIDLE",    SOL_TCP,        TCP_KEEPIDLE,    TYPE_INT,      VAL_TAB},
4322 #endif
4323 #ifdef TCP_KEEPINTVL
4324     {"TCP_KEEPINTVL",   SOL_TCP,        TCP_KEEPINTVL,   TYPE_INT,      VAL_TAB},
4325 #endif
4326 #endif /* SOL_TCP */
4327 #ifdef IP_TOS
4328     {"IP_TOS",          IPPROTO_IP,     IP_TOS,          TYPE_INT,      VAL_TAB},
4329 #endif
4330 #ifdef IP_TTL
4331     {"IP_TTL",          IPPROTO_IP,     IP_TTL,          TYPE_INT,      VAL_TAB},
4332 #endif
4333 #ifdef IP_MAXSEG
4334     {"TCP_MAXSEG",      IPPROTO_TCP,    TCP_MAXSEG,      TYPE_INT,      VAL_TAB},
4335 #endif
4336     {"TCP_NODELAY",     IPPROTO_TCP,    TCP_NODELAY,     TYPE_FLAG,     VAL_TAB},
4337 #ifdef IP_FREEBIND
4338     {"IP_FREEBIND",     IPPROTO_IP,     IP_FREEBIND,     TYPE_FLAG,     VAL_TAB},
4339 #endif
4340 #ifdef IP_BINDANY
4341     {"IP_BINDANY",      IPPROTO_IP,     IP_BINDANY,      TYPE_FLAG,     VAL_TAB},
4342 #endif
4343 #ifdef IPV6_BINDANY
4344     {"IPV6_BINDANY",    IPPROTO_IPV6,   IPV6_BINDANY,    TYPE_FLAG,     VAL_TAB},
4345 #endif
4346 #ifdef IPV6_V6ONLY
4347     {"IPV6_V6ONLY",     IPPROTO_IPV6,   IPV6_V6ONLY,     TYPE_FLAG,     VAL_TAB},
4348 #endif
4349     {NULL,              0,              0,               TYPE_NONE,     VAL_TAB}
4350 };
4351 
socket_options_init(void)4352 NOEXPORT SOCK_OPT *socket_options_init(void) {
4353 #ifdef USE_WIN32
4354     DWORD version;
4355     int major, minor;
4356 #endif
4357 
4358     SOCK_OPT *opt=str_alloc_detached(sizeof sock_opts_def);
4359     memcpy(opt, sock_opts_def, sizeof sock_opts_def);
4360 
4361 #ifdef USE_WIN32
4362     version=GetVersion();
4363     major=LOBYTE(LOWORD(version));
4364     minor=HIBYTE(LOWORD(version));
4365     s_log(LOG_DEBUG, "Running on Windows %d.%d", major, minor);
4366 
4367     if(major>5) /* Vista or later */
4368         socket_option_set_int(opt, "SO_EXCLUSIVEADDRUSE", 0, 1); /* accepting socket */
4369 #else
4370     socket_option_set_int(opt, "SO_REUSEADDR", 0, 1); /* accepting socket */
4371 #endif
4372     socket_option_set_int(opt, "TCP_NODELAY", 1, 1); /* local socket */
4373     socket_option_set_int(opt, "TCP_NODELAY", 2, 1); /* remote socket */
4374     return opt;
4375 }
4376 
socket_option_set_int(SOCK_OPT * opt,char * name,int type,int value)4377 NOEXPORT void socket_option_set_int(SOCK_OPT *opt, char *name, int type, int value) {
4378     for(; opt->opt_str; ++opt) {
4379         if(!strcmp(name, opt->opt_str)) {
4380             opt->opt_val[type]=str_alloc_detached(sizeof(OPT_UNION));
4381             opt->opt_val[type]->i_val=value;
4382         }
4383     }
4384 }
4385 
socket_options_dup(SOCK_OPT * src)4386 NOEXPORT SOCK_OPT *socket_options_dup(SOCK_OPT *src) {
4387     SOCK_OPT *dst=str_alloc_detached(sizeof sock_opts_def);
4388     SOCK_OPT *ptr;
4389 
4390     memcpy(dst, sock_opts_def, sizeof sock_opts_def);
4391     for(ptr=dst; src->opt_str; ++src, ++ptr) {
4392         int type;
4393         for(type=0; type<3; ++type) {
4394             if(src->opt_val[type]) {
4395                 ptr->opt_val[type]=str_alloc_detached(sizeof(OPT_UNION));
4396                 memcpy(ptr->opt_val[type],
4397                     src->opt_val[type], sizeof(OPT_UNION));
4398             }
4399         }
4400     }
4401     return dst;
4402 }
4403 
socket_options_free(SOCK_OPT * opt)4404 NOEXPORT void socket_options_free(SOCK_OPT *opt) {
4405     SOCK_OPT *ptr;
4406     if(!opt) {
4407         s_log(LOG_ERR, "INTERNAL ERROR: Socket options not initialized");
4408         return;
4409     }
4410     for(ptr=opt; ptr->opt_str; ++ptr) {
4411         int type;
4412         for(type=0; type<3; ++type)
4413             str_free(ptr->opt_val[type]);
4414     }
4415     str_free(opt);
4416 }
4417 
socket_options_print(void)4418 NOEXPORT int socket_options_print(void) {
4419     SOCK_OPT *opt, *ptr;
4420     SOCKET fd;
4421     socklen_t optlen;
4422     OPT_UNION val;
4423     char *ta, *tl, *tr, *td;
4424 
4425     fd=socket(AF_INET, SOCK_STREAM, 0);
4426     opt=socket_options_init();
4427 
4428     s_log(LOG_NOTICE, " ");
4429     s_log(LOG_NOTICE, "Socket option defaults:");
4430     s_log(LOG_NOTICE,
4431         "    Option Name         |  Accept  |   Local  |  Remote  |OS default");
4432     s_log(LOG_NOTICE,
4433         "    --------------------+----------+----------+----------+----------");
4434     for(ptr=opt; ptr->opt_str; ++ptr) {
4435         /* get OS default value */
4436         optlen=sizeof val;
4437         if(getsockopt(fd, ptr->opt_level,
4438                 ptr->opt_name, (void *)&val, &optlen)) {
4439             switch(get_last_socket_error()) {
4440             case S_ENOPROTOOPT:
4441             case S_EOPNOTSUPP:
4442                 td=str_dup("write-only");
4443                 break;
4444             default:
4445                 s_log(LOG_ERR, "Failed to get %s OS default", ptr->opt_str);
4446                 sockerror("getsockopt");
4447                 closesocket(fd);
4448                 return 1; /* FAILED */
4449             }
4450         } else
4451             td=socket_option_text(ptr->opt_type, &val);
4452         /* get stunnel default values */
4453         ta=socket_option_text(ptr->opt_type, ptr->opt_val[0]);
4454         tl=socket_option_text(ptr->opt_type, ptr->opt_val[1]);
4455         tr=socket_option_text(ptr->opt_type, ptr->opt_val[2]);
4456         /* print collected data and fee the memory */
4457         s_log(LOG_NOTICE, "    %-20s|%10s|%10s|%10s|%10s",
4458             ptr->opt_str, ta, tl, tr, td);
4459         str_free(ta); str_free(tl); str_free(tr); str_free(td);
4460     }
4461     socket_options_free(opt);
4462     closesocket(fd);
4463     return 0; /* OK */
4464 }
4465 
socket_option_text(VAL_TYPE type,OPT_UNION * val)4466 NOEXPORT char *socket_option_text(VAL_TYPE type, OPT_UNION *val) {
4467     if(!val)
4468         return str_dup("    --    ");
4469     switch(type) {
4470     case TYPE_FLAG:
4471         return str_printf("%s", val->i_val ? "yes" : "no");
4472     case TYPE_INT:
4473         return str_printf("%d", val->i_val);
4474     case TYPE_LINGER:
4475         return str_printf("%d:%d",
4476             val->linger_val.l_onoff, val->linger_val.l_linger);
4477     case TYPE_TIMEVAL:
4478         return str_printf("%d:%d",
4479             (int)val->timeval_val.tv_sec, (int)val->timeval_val.tv_usec);
4480     case TYPE_STRING:
4481         return str_printf("%s", val->c_val);
4482     case TYPE_NONE:
4483         return str_dup("   none   "); /* internal error? */
4484     }
4485     return str_dup("  Ooops?  "); /* internal error? */
4486 }
4487 
socket_option_parse(SOCK_OPT * opt,char * arg)4488 NOEXPORT int socket_option_parse(SOCK_OPT *opt, char *arg) {
4489     int socket_type; /* 0-accept, 1-local, 2-remote */
4490     char *opt_val_str, *opt_val2_str, *tmp_str;
4491     OPT_UNION opt_val;
4492 
4493     if(arg[1]!=':')
4494         return 1; /* FAILED */
4495     switch(arg[0]) {
4496     case 'a':
4497         socket_type=0; break;
4498     case 'l':
4499         socket_type=1; break;
4500     case 'r':
4501         socket_type=2; break;
4502     default:
4503         return 1; /* FAILED */
4504     }
4505     arg+=2;
4506     opt_val_str=strchr(arg, '=');
4507     if(!opt_val_str) /* no '='? */
4508         return 1; /* FAILED */
4509     *opt_val_str++='\0';
4510 
4511     for(; opt->opt_str && strcmp(arg, opt->opt_str); ++opt)
4512         ;
4513     if(!opt->opt_str)
4514         return 1; /* FAILED */
4515 
4516     switch(opt->opt_type) {
4517     case TYPE_FLAG:
4518         if(!strcasecmp(opt_val_str, "yes") || !strcmp(opt_val_str, "1")) {
4519             opt_val.i_val=1;
4520             break; /* OK */
4521         }
4522         if(!strcasecmp(opt_val_str, "no") || !strcmp(opt_val_str, "0")) {
4523             opt_val.i_val=0;
4524             break; /* OK */
4525         }
4526         return 1; /* FAILED */
4527     case TYPE_INT:
4528         opt_val.i_val=(int)strtol(opt_val_str, &tmp_str, 10);
4529         if(tmp_str==arg || *tmp_str) /* not a number */
4530             return 1; /* FAILED */
4531         break; /* OK */
4532     case TYPE_LINGER:
4533         opt_val2_str=strchr(opt_val_str, ':');
4534         if(opt_val2_str) {
4535             *opt_val2_str++='\0';
4536             opt_val.linger_val.l_linger=
4537                 (u_short)strtol(opt_val2_str, &tmp_str, 10);
4538             if(tmp_str==arg || *tmp_str) /* not a number */
4539                 return 1; /* FAILED */
4540         } else {
4541             opt_val.linger_val.l_linger=0;
4542         }
4543         opt_val.linger_val.l_onoff=
4544             (u_short)strtol(opt_val_str, &tmp_str, 10);
4545         if(tmp_str==arg || *tmp_str) /* not a number */
4546             return 1; /* FAILED */
4547         break; /* OK */
4548     case TYPE_TIMEVAL:
4549         opt_val2_str=strchr(opt_val_str, ':');
4550         if(opt_val2_str) {
4551             *opt_val2_str++='\0';
4552             opt_val.timeval_val.tv_usec=
4553                 (int)strtol(opt_val2_str, &tmp_str, 10);
4554             if(tmp_str==arg || *tmp_str) /* not a number */
4555                 return 1; /* FAILED */
4556         } else {
4557             opt_val.timeval_val.tv_usec=0;
4558         }
4559         opt_val.timeval_val.tv_sec=
4560             (int)strtol(opt_val_str, &tmp_str, 10);
4561         if(tmp_str==arg || *tmp_str) /* not a number */
4562             return 1; /* FAILED */
4563         break; /* OK */
4564     case TYPE_STRING:
4565         if(strlen(opt_val_str)+1>sizeof(OPT_UNION))
4566             return 1; /* FAILED */
4567         strcpy(opt_val.c_val, opt_val_str);
4568         break; /* OK */
4569     default:
4570         return 1; /* FAILED */
4571     }
4572     str_free(opt->opt_val[socket_type]);
4573     opt->opt_val[socket_type]=str_alloc_detached(sizeof(OPT_UNION));
4574     memcpy(opt->opt_val[socket_type], &opt_val, sizeof(OPT_UNION));
4575     return 0;
4576 }
4577 
4578 /**************************************** OCSP */
4579 
4580 #ifndef OPENSSL_NO_OCSP
4581 
parse_ocsp_flag(char * arg)4582 NOEXPORT unsigned long parse_ocsp_flag(char *arg) {
4583     struct {
4584         char *name;
4585         unsigned long value;
4586     } ocsp_opts[] = {
4587         {"NOCERTS", OCSP_NOCERTS},
4588         {"NOINTERN", OCSP_NOINTERN},
4589         {"NOSIGS", OCSP_NOSIGS},
4590         {"NOCHAIN", OCSP_NOCHAIN},
4591         {"NOVERIFY", OCSP_NOVERIFY},
4592         {"NOEXPLICIT", OCSP_NOEXPLICIT},
4593         {"NOCASIGN", OCSP_NOCASIGN},
4594         {"NODELEGATED", OCSP_NODELEGATED},
4595         {"NOCHECKS", OCSP_NOCHECKS},
4596         {"TRUSTOTHER", OCSP_TRUSTOTHER},
4597         {"RESPID_KEY", OCSP_RESPID_KEY},
4598         {"NOTIME", OCSP_NOTIME},
4599         {NULL, 0}
4600     }, *option;
4601 
4602     for(option=ocsp_opts; option->name; ++option)
4603         if(!strcasecmp(option->name, arg))
4604             return option->value;
4605     return 0; /* FAILED */
4606 }
4607 
4608 #endif /* !defined(OPENSSL_NO_OCSP) */
4609 
4610 /**************************************** engine */
4611 
4612 #ifndef OPENSSL_NO_ENGINE
4613 
4614 #define MAX_ENGINES 256
4615 static ENGINE *engines[MAX_ENGINES]; /* table of engines for config parser */
4616 static int current_engine;
4617 static int engine_initialized;
4618 
engine_reset_list(void)4619 NOEXPORT void engine_reset_list(void) {
4620     current_engine=-1;
4621     engine_initialized=1;
4622 }
4623 
engine_auto(void)4624 NOEXPORT char *engine_auto(void) {
4625     ENGINE *e;
4626 
4627     s_log(LOG_INFO, "Enabling automatic engine support");
4628     ENGINE_register_all_complete();
4629     /* rebuild the internal list of engines */
4630     engine_reset_list();
4631     for(e=ENGINE_get_first(); e; e=ENGINE_get_next(e)) {
4632         if(++current_engine>=MAX_ENGINES)
4633             return "Too many open engines";
4634         engines[current_engine]=e;
4635         s_log(LOG_INFO, "Engine #%d (%s) registered",
4636             current_engine+1, ENGINE_get_id(e));
4637     }
4638     s_log(LOG_INFO, "Automatic engine support enabled");
4639     return NULL; /* OK */
4640 }
4641 
engine_open(const char * name)4642 NOEXPORT char *engine_open(const char *name) {
4643     engine_init(); /* initialize the previous engine (if any) */
4644     if(++current_engine>=MAX_ENGINES)
4645         return "Too many open engines";
4646     s_log(LOG_DEBUG, "Enabling support for engine \"%s\"", name);
4647     engines[current_engine]=ENGINE_by_id(name);
4648     if(!engines[current_engine]) {
4649         sslerror("ENGINE_by_id");
4650         return "Failed to open the engine";
4651     }
4652     engine_initialized=0;
4653     if(ENGINE_ctrl(engines[current_engine], ENGINE_CTRL_SET_USER_INTERFACE,
4654             0, ui_stunnel(), NULL)) {
4655         s_log(LOG_NOTICE, "UI set for engine #%d (%s)",
4656             current_engine+1, ENGINE_get_id(engines[current_engine]));
4657     } else {
4658         ERR_clear_error();
4659         s_log(LOG_INFO, "UI not supported by engine #%d (%s)",
4660             current_engine+1, ENGINE_get_id(engines[current_engine]));
4661     }
4662     return NULL; /* OK */
4663 }
4664 
engine_ctrl(const char * cmd,const char * arg)4665 NOEXPORT char *engine_ctrl(const char *cmd, const char *arg) {
4666     if(current_engine<0)
4667         return "No engine was defined";
4668     if(!strcasecmp(cmd, "INIT")) /* special control command */
4669         return engine_init();
4670     if(arg)
4671         s_log(LOG_DEBUG, "Executing engine control command %s:%s", cmd, arg);
4672     else
4673         s_log(LOG_DEBUG, "Executing engine control command %s", cmd);
4674     if(!ENGINE_ctrl_cmd_string(engines[current_engine], cmd, arg, 0)) {
4675         sslerror("ENGINE_ctrl_cmd_string");
4676         return "Failed to execute the engine control command";
4677     }
4678     return NULL; /* OK */
4679 }
4680 
engine_default(const char * list)4681 NOEXPORT char *engine_default(const char *list) {
4682     if(current_engine<0)
4683         return "No engine was defined";
4684     if(!ENGINE_set_default_string(engines[current_engine], list)) {
4685         sslerror("ENGINE_set_default_string");
4686         return "Failed to set engine as default";
4687     }
4688     s_log(LOG_INFO, "Engine #%d (%s) set as default for %s",
4689         current_engine+1, ENGINE_get_id(engines[current_engine]), list);
4690     return NULL;
4691 }
4692 
engine_init(void)4693 NOEXPORT char *engine_init(void) {
4694     if(engine_initialized) /* either first or already initialized */
4695         return NULL; /* OK */
4696     s_log(LOG_DEBUG, "Initializing engine #%d (%s)",
4697         current_engine+1, ENGINE_get_id(engines[current_engine]));
4698     if(!ENGINE_init(engines[current_engine])) {
4699         if(ERR_peek_last_error()) /* really an error */
4700             sslerror("ENGINE_init");
4701         else
4702             s_log(LOG_ERR, "Engine #%d (%s) not initialized",
4703                 current_engine+1, ENGINE_get_id(engines[current_engine]));
4704         return "Engine initialization failed";
4705     }
4706 #if 0
4707     /* it is a bad idea to set the engine as default for all sections */
4708     /* the "engine=auto" or "engineDefault" options should be used instead */
4709     if(!ENGINE_set_default(engines[current_engine], ENGINE_METHOD_ALL)) {
4710         sslerror("ENGINE_set_default");
4711         return "Selecting default engine failed";
4712     }
4713 #endif
4714 
4715     s_log(LOG_INFO, "Engine #%d (%s) initialized",
4716         current_engine+1, ENGINE_get_id(engines[current_engine]));
4717     engine_initialized=1;
4718     return NULL; /* OK */
4719 }
4720 
engine_get_by_id(const char * id)4721 NOEXPORT ENGINE *engine_get_by_id(const char *id) {
4722     int i;
4723 
4724     for(i=0; i<=current_engine; ++i)
4725         if(!strcmp(id, ENGINE_get_id(engines[i])))
4726             return engines[i];
4727     return NULL;
4728 }
4729 
engine_get_by_num(const int i)4730 NOEXPORT ENGINE *engine_get_by_num(const int i) {
4731     if(i<0 || i>current_engine)
4732         return NULL;
4733     return engines[i];
4734 }
4735 
4736 #endif /* !defined(OPENSSL_NO_ENGINE) */
4737 
4738 /**************************************** include config directory */
4739 
include_config(char * directory,SERVICE_OPTIONS ** section_ptr)4740 NOEXPORT char *include_config(char *directory, SERVICE_OPTIONS **section_ptr) {
4741     struct dirent **namelist;
4742     int i, num, err=0;
4743 
4744     num=scandir(directory, &namelist, NULL, alphasort);
4745     if(num<0) {
4746         ioerror("scandir");
4747         return "Failed to include directory";
4748     }
4749     for(i=0; i<num; ++i) {
4750         if(!err) {
4751             struct stat sb;
4752             char *name=str_printf(
4753 #ifdef USE_WIN32
4754                 "%s\\%s",
4755 #else
4756                 "%s/%s",
4757 #endif
4758                 directory, namelist[i]->d_name);
4759             if(!stat(name, &sb) && S_ISREG(sb.st_mode))
4760                 err=options_file(name, CONF_FILE, section_ptr);
4761             else
4762                 s_log(LOG_DEBUG, "\"%s\" is not a file", name);
4763             str_free(name);
4764         }
4765         free(namelist[i]);
4766     }
4767     free(namelist);
4768     if(err)
4769         return "Failed to include a file";
4770     return NULL;
4771 }
4772 
4773 /**************************************** fatal error */
4774 
print_syntax(void)4775 NOEXPORT void print_syntax(void) {
4776     s_log(LOG_NOTICE, " ");
4777     s_log(LOG_NOTICE, "Syntax:");
4778     s_log(LOG_NOTICE, "stunnel "
4779 #ifdef USE_WIN32
4780 #ifndef _WIN32_WCE
4781         "[ [-install | -uninstall | -start | -stop | -reload | -reopen | -exit] "
4782 #endif
4783         "[-quiet] "
4784 #endif
4785         "[<filename>] ] "
4786 #ifndef USE_WIN32
4787         "-fd <n> "
4788 #endif
4789         "| -help | -version | -sockets | -options");
4790     s_log(LOG_NOTICE, "    <filename>  - use specified config file");
4791 #ifdef USE_WIN32
4792 #ifndef _WIN32_WCE
4793     s_log(LOG_NOTICE, "    -install    - install NT service");
4794     s_log(LOG_NOTICE, "    -uninstall  - uninstall NT service");
4795     s_log(LOG_NOTICE, "    -start      - start NT service");
4796     s_log(LOG_NOTICE, "    -stop       - stop NT service");
4797     s_log(LOG_NOTICE, "    -reload     - reload configuration for NT service");
4798     s_log(LOG_NOTICE, "    -reopen     - reopen log file for NT service");
4799     s_log(LOG_NOTICE, "    -exit       - exit an already started stunnel");
4800 #endif
4801     s_log(LOG_NOTICE, "    -quiet      - don't display message boxes");
4802 #else
4803     s_log(LOG_NOTICE, "    -fd <n>     - read the config file from a file descriptor");
4804 #endif
4805     s_log(LOG_NOTICE, "    -help       - get config file help");
4806     s_log(LOG_NOTICE, "    -version    - display version and defaults");
4807     s_log(LOG_NOTICE, "    -sockets    - display default socket options");
4808     s_log(LOG_NOTICE, "    -options    - display supported TLS options");
4809 }
4810 
4811 /**************************************** various supporting functions */
4812 
name_list_append(NAME_LIST ** ptr,char * name)4813 NOEXPORT void name_list_append(NAME_LIST **ptr, char *name) {
4814     while(*ptr) /* find the null pointer */
4815         ptr=&(*ptr)->next;
4816     *ptr=str_alloc_detached(sizeof(NAME_LIST));
4817     (*ptr)->name=str_dup_detached(name);
4818     (*ptr)->next=NULL;
4819 }
4820 
name_list_dup(NAME_LIST ** dst,NAME_LIST * src)4821 NOEXPORT void name_list_dup(NAME_LIST **dst, NAME_LIST *src) {
4822     for(; src; src=src->next)
4823         name_list_append(dst, src->name);
4824 }
4825 
name_list_free(NAME_LIST * ptr)4826 NOEXPORT void name_list_free(NAME_LIST *ptr) {
4827     while(ptr) {
4828         NAME_LIST *next=ptr->next;
4829         str_free(ptr->name);
4830         str_free(ptr);
4831         ptr=next;
4832     }
4833 }
4834 
4835 #ifndef USE_WIN32
4836 
4837 /* allocate 'exec' arguments */
4838 /* TODO: support quotes */
arg_alloc(char * str)4839 NOEXPORT char **arg_alloc(char *str) {
4840     size_t max_arg, i;
4841     char **tmp, **retval;
4842 
4843     max_arg=strlen(str)/2+1;
4844     tmp=str_alloc((max_arg+1)*sizeof(char *));
4845 
4846     i=0;
4847     while(*str && i<max_arg) {
4848         tmp[i++]=str;
4849         while(*str && !isspace((unsigned char)*str))
4850             ++str;
4851         while(*str && isspace((unsigned char)*str))
4852             *str++='\0';
4853     }
4854     tmp[i]=NULL; /* null-terminate the table */
4855 
4856     retval=arg_dup(tmp);
4857     str_free(tmp);
4858     return retval;
4859 }
4860 
arg_dup(char ** src)4861 NOEXPORT char **arg_dup(char **src) {
4862     size_t i, n;
4863     char **dst;
4864 
4865     if(!src)
4866         return NULL;
4867     for(n=0; src[n]; ++n)
4868         ;
4869     dst=str_alloc_detached((n+1)*sizeof(char *));
4870     for(i=0; i<n; ++i)
4871         dst[i]=str_dup_detached(src[i]);
4872     dst[n]=NULL;
4873     return dst;
4874 }
4875 
arg_free(char ** arg)4876 NOEXPORT void arg_free(char **arg) {
4877     size_t i;
4878 
4879     if(arg) {
4880         for(i=0; arg[i]; ++i)
4881             str_free(arg[i]);
4882         str_free(arg);
4883     }
4884 }
4885 
4886 #endif
4887 
4888 /* end of options.c */
4889