Update from Debian version 2.7-1.2.
[pound.git] / config.c
1 /*
2  * Pound - the reverse-proxy load-balancer
3  * Copyright (C) 2002-2010 Apsis GmbH
4  *
5  * This file is part of Pound.
6  *
7  * Pound is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  * 
12  * Pound is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  * 
20  * Contact information:
21  * Apsis GmbH
22  * P.O.Box
23  * 8707 Uetikon am See
24  * Switzerland
25  * EMail: roseg@apsis.ch
26  */
27
28 #ifndef MISS_FACILITYNAMES
29 #define SYSLOG_NAMES    1
30 #endif
31
32 #include    "pound.h"
33
34 #include    <openssl/x509v3.h>
35
36 #ifdef MISS_FACILITYNAMES
37
38 /* This is lifted verbatim from the Linux sys/syslog.h */
39
40 typedef struct _code {
41     char    *c_name;
42     int     c_val;
43 } CODE;
44
45 static CODE facilitynames[] = {
46     { "auth", LOG_AUTH },
47 #ifdef  LOG_AUTHPRIV
48     { "authpriv", LOG_AUTHPRIV },
49 #endif
50     { "cron", LOG_CRON },
51     { "daemon", LOG_DAEMON },
52 #ifdef  LOG_FTP
53     { "ftp", LOG_FTP },
54 #endif
55     { "kern", LOG_KERN },
56     { "lpr", LOG_LPR },
57     { "mail", LOG_MAIL },
58     { "mark", 0 },                  /* never used! */
59     { "news", LOG_NEWS },
60     { "security", LOG_AUTH },       /* DEPRECATED */
61     { "syslog", LOG_SYSLOG },
62     { "user", LOG_USER },
63     { "uucp", LOG_UUCP },
64     { "local0", LOG_LOCAL0 },
65     { "local1", LOG_LOCAL1 },
66     { "local2", LOG_LOCAL2 },
67     { "local3", LOG_LOCAL3 },
68     { "local4", LOG_LOCAL4 },
69     { "local5", LOG_LOCAL5 },
70     { "local6", LOG_LOCAL6 },
71     { "local7", LOG_LOCAL7 },
72     { NULL, -1 }
73 };
74 #endif
75
76 static regex_t  Empty, Comment, User, Group, RootJail, Daemon, LogFacility, LogLevel, Alive, SSLEngine, Control;
77 static regex_t  ListenHTTP, ListenHTTPS, End, Address, Port, Cert, xHTTP, Client, CheckURL;
78 static regex_t  Err414, Err500, Err501, Err503, MaxRequest, HeadRemove, RewriteLocation, RewriteDestination;
79 static regex_t  Service, ServiceName, URL, HeadRequire, HeadDeny, BackEnd, Emergency, Priority, HAport, HAportAddr;
80 static regex_t  Redirect, RedirectN, TimeOut, Session, Type, TTL, ID, DynScale;
81 static regex_t  ClientCert, AddHeader, DisableProto, SSLAllowClientRenegotiation, SSLHonorCipherOrder, Ciphers;
82 static regex_t  CAlist, VerifyList, CRLlist, NoHTTPS11, Grace, Include, ConnTO, IgnoreCase, HTTPS;
83 static regex_t  Disabled, Threads, CNName, Anonymise, ECDHCurve;
84
85 static regmatch_t   matches[5];
86
87 static char *xhttp[] = {
88     "^(GET|POST|HEAD) ([^ ]+) HTTP/1.[01]$",
89     "^(GET|POST|HEAD|PUT|PATCH|DELETE) ([^ ]+) HTTP/1.[01]$",
90     "^(GET|POST|HEAD|PUT|PATCH|DELETE|LOCK|UNLOCK|PROPFIND|PROPPATCH|SEARCH|MKCOL|MOVE|COPY|OPTIONS|TRACE|MKACTIVITY|CHECKOUT|MERGE|REPORT) ([^ ]+) HTTP/1.[01]$",
91     "^(GET|POST|HEAD|PUT|PATCH|DELETE|LOCK|UNLOCK|PROPFIND|PROPPATCH|SEARCH|MKCOL|MOVE|COPY|OPTIONS|TRACE|MKACTIVITY|CHECKOUT|MERGE|REPORT|SUBSCRIBE|UNSUBSCRIBE|BPROPPATCH|POLL|BMOVE|BCOPY|BDELETE|BPROPFIND|NOTIFY|CONNECT) ([^ ]+) HTTP/1.[01]$",
92     "^(GET|POST|HEAD|PUT|PATCH|DELETE|LOCK|UNLOCK|PROPFIND|PROPPATCH|SEARCH|MKCOL|MOVE|COPY|OPTIONS|TRACE|MKACTIVITY|CHECKOUT|MERGE|REPORT|SUBSCRIBE|UNSUBSCRIBE|BPROPPATCH|POLL|BMOVE|BCOPY|BDELETE|BPROPFIND|NOTIFY|CONNECT|RPC_IN_DATA|RPC_OUT_DATA) ([^ ]+) HTTP/1.[01]$",
93 };
94
95 static int  log_level = 1;
96 static int  def_facility = LOG_DAEMON;
97 static int  clnt_to = 10;
98 static int  be_to = 15;
99 static int  be_connto = 15;
100 static int  dynscale = 0;
101 static int  ignore_case = 0;
102 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
103 #ifndef OPENSSL_NO_ECDH
104 static int  EC_nid = NID_X9_62_prime256v1;
105 #endif
106 #endif
107
108 #define MAX_FIN 8
109
110 static FILE *f_in[MAX_FIN];
111 static char *f_name[MAX_FIN];
112 static int  n_lin[MAX_FIN];
113 static int  cur_fin;
114
115 static int
116 conf_init(const char *name)
117 {
118     if((f_name[0] = strdup(name)) == NULL) {
119         logmsg(LOG_ERR, "open %s: out of memory", name);
120         exit(1);
121     }
122     if((f_in[0] = fopen(name, "rt")) == NULL) {
123         logmsg(LOG_ERR, "can't open open %s", name);
124         exit(1);
125     }
126     n_lin[0] = 0;
127     cur_fin = 0;
128     return 0;
129 }
130
131 void
132 conf_err(const char *msg)
133 {
134     logmsg(LOG_ERR, "%s line %d: %s", f_name[cur_fin], n_lin[cur_fin], msg);
135     exit(1);
136 }
137
138 static char *
139 conf_fgets(char *buf, const int max)
140 {
141     int i;
142
143     for(;;) {
144         if(fgets(buf, max, f_in[cur_fin]) == NULL) {
145             fclose(f_in[cur_fin]);
146             free(f_name[cur_fin]);
147             if(cur_fin > 0) {
148                 cur_fin--;
149                 continue;
150             } else
151                 return NULL;
152         }
153         n_lin[cur_fin]++;
154         for(i = 0; i < max; i++)
155             if(buf[i] == '\n' || buf[i] == '\r') {
156                 buf[i] = '\0';
157                 break;
158             }
159         if(!regexec(&Empty, buf, 4, matches, 0) || !regexec(&Comment, buf, 4, matches, 0))
160             /* comment or empty line */
161             continue;
162         if(!regexec(&Include, buf, 4, matches, 0)) {
163             buf[matches[1].rm_eo] = '\0';
164             if(cur_fin == (MAX_FIN - 1))
165                 conf_err("Include nesting too deep");
166             cur_fin++;
167             if((f_name[cur_fin] = strdup(&buf[matches[1].rm_so])) == NULL)
168                 conf_err("Include out of memory");
169             if((f_in[cur_fin] = fopen(&buf[matches[1].rm_so], "rt")) == NULL)
170                 conf_err("can't open included file");
171             n_lin[cur_fin] = 0;
172             continue;
173         }
174         return buf;
175     }
176 }
177
178 unsigned char **
179 get_subjectaltnames(X509 *x509, unsigned int *count)
180 {
181     unsigned int            local_count;
182     unsigned char           **result;
183     STACK_OF(GENERAL_NAME)  *san_stack = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);     
184     unsigned char           *temp[sk_GENERAL_NAME_num(san_stack)];
185     GENERAL_NAME            *name;
186     int                     i;
187
188     local_count = 0;
189     result = NULL;
190     name = NULL;
191     *count = 0;
192     if(san_stack == NULL)
193         return NULL;
194     while(sk_GENERAL_NAME_num(san_stack) > 0) {
195         name = sk_GENERAL_NAME_pop(san_stack);
196         switch(name->type) {
197             case GEN_DNS:
198                 temp[local_count] = strndup(ASN1_STRING_data(name->d.dNSName), ASN1_STRING_length(name->d.dNSName)
199                                     + 1);
200                 if(temp[local_count] == NULL)
201                     conf_err("out of memory");
202                 local_count++;
203                 break;
204             default:
205               logmsg(LOG_INFO, "unsupported subjectAltName type encountered: %i", name->type);
206         }
207         GENERAL_NAME_free(name);
208     }
209
210     result = (unsigned char**)malloc(sizeof(unsigned char*)*local_count);
211     if(result == NULL)
212         conf_err("out of memory");
213     for(i = 0;i < local_count; i++) {
214         result[i] = strndup(temp[i], strlen(temp[i])+1);
215         if(result[i] == NULL)
216             conf_err("out of memory");
217         free(temp[i]);
218     }
219     *count = local_count;
220
221     sk_GENERAL_NAME_pop_free(san_stack, GENERAL_NAME_free);
222
223     return result;
224 }
225
226 /*
227  * parse a back-end
228  */
229 static BACKEND *
230 parse_be(const int is_emergency)
231 {
232     char        lin[MAXBUF];
233     BACKEND     *res;
234     int         has_addr, has_port;
235     struct hostent      *host;
236     struct sockaddr_in  in;
237     struct sockaddr_in6 in6;
238
239     if((res = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
240         conf_err("BackEnd config: out of memory - aborted");
241     memset(res, 0, sizeof(BACKEND));
242     res->be_type = 0;
243     res->addr.ai_socktype = SOCK_STREAM;
244     res->to = is_emergency? 120: be_to;
245     res->conn_to = is_emergency? 120: be_connto;
246     res->alive = 1;
247     memset(&res->addr, 0, sizeof(res->addr));
248     res->priority = 5;
249     memset(&res->ha_addr, 0, sizeof(res->ha_addr));
250     res->url = NULL;
251     res->next = NULL;
252     has_addr = has_port = 0;
253     pthread_mutex_init(&res->mut, NULL);
254     while(conf_fgets(lin, MAXBUF)) {
255         if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
256             lin[strlen(lin) - 1] = '\0';
257         if(!regexec(&Address, lin, 4, matches, 0)) {
258             lin[matches[1].rm_eo] = '\0';
259             if(get_host(lin + matches[1].rm_so, &res->addr, PF_UNSPEC)) {
260                 /* if we can't resolve it assume this is a UNIX domain socket */
261                 res->addr.ai_socktype = SOCK_STREAM;
262                 res->addr.ai_family = AF_UNIX;
263                 res->addr.ai_protocol = 0;
264                 if((res->addr.ai_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_un))) == NULL)
265                     conf_err("out of memory");
266                 if((strlen(lin + matches[1].rm_so) + 1) > UNIX_PATH_MAX)
267                     conf_err("UNIX path name too long");
268                 res->addr.ai_addrlen = strlen(lin + matches[1].rm_so) + 1;
269                 res->addr.ai_addr->sa_family = AF_UNIX;
270                 strcpy(res->addr.ai_addr->sa_data, lin + matches[1].rm_so);
271                 res->addr.ai_addrlen = sizeof( struct sockaddr_un );
272             }
273             has_addr = 1;
274         } else if(!regexec(&Port, lin, 4, matches, 0)) {
275             switch(res->addr.ai_family) {
276             case AF_INET:
277                 memcpy(&in, res->addr.ai_addr, sizeof(in));
278                 in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
279                 memcpy(res->addr.ai_addr, &in, sizeof(in));
280                 break;
281             case AF_INET6:
282                 memcpy(&in6, res->addr.ai_addr, sizeof(in6));
283                 in6.sin6_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
284                 memcpy(res->addr.ai_addr, &in6, sizeof(in6));
285                 break;
286             default:
287                 conf_err("Port is supported only for INET/INET6 back-ends");
288             }
289             has_port = 1;
290         } else if(!regexec(&Priority, lin, 4, matches, 0)) {
291             if(is_emergency)
292                 conf_err("Priority is not supported for Emergency back-ends");
293             res->priority = atoi(lin + matches[1].rm_so);
294         } else if(!regexec(&TimeOut, lin, 4, matches, 0)) {
295             res->to = atoi(lin + matches[1].rm_so);
296         } else if(!regexec(&ConnTO, lin, 4, matches, 0)) {
297             res->conn_to = atoi(lin + matches[1].rm_so);
298         } else if(!regexec(&HAport, lin, 4, matches, 0)) {
299             if(is_emergency)
300                 conf_err("HAport is not supported for Emergency back-ends");
301             res->ha_addr = res->addr;
302             if((res->ha_addr.ai_addr = (struct sockaddr *)malloc(res->addr.ai_addrlen)) == NULL)
303                 conf_err("out of memory");
304             memcpy(res->ha_addr.ai_addr, res->addr.ai_addr, res->addr.ai_addrlen);
305             switch(res->addr.ai_family) {
306             case AF_INET:
307                 memcpy(&in, res->ha_addr.ai_addr, sizeof(in));
308                 in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
309                 memcpy(res->ha_addr.ai_addr, &in, sizeof(in));
310                 break;
311             case AF_INET6:
312                 memcpy(&in6, res->addr.ai_addr, sizeof(in6));
313                 in6.sin6_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
314                 memcpy(res->addr.ai_addr, &in6, sizeof(in6));
315                 break;
316             default:
317                 conf_err("HAport is supported only for INET/INET6 back-ends");
318             }
319         } else if(!regexec(&HAportAddr, lin, 4, matches, 0)) {
320             if(is_emergency)
321                 conf_err("HAportAddr is not supported for Emergency back-ends");
322             lin[matches[1].rm_eo] = '\0';
323             if(get_host(lin + matches[1].rm_so, &res->ha_addr, PF_UNSPEC)) {
324                 /* if we can't resolve it assume this is a UNIX domain socket */
325                 res->addr.ai_socktype = SOCK_STREAM;
326                 res->ha_addr.ai_family = AF_UNIX;
327                 res->ha_addr.ai_protocol = 0;
328                 if((res->ha_addr.ai_addr = (struct sockaddr *)strdup(lin + matches[1].rm_so)) == NULL)
329                     conf_err("out of memory");
330                 res->addr.ai_addrlen = strlen(lin + matches[1].rm_so) + 1;
331             } else switch(res->ha_addr.ai_family) {
332             case AF_INET:
333                 memcpy(&in, res->ha_addr.ai_addr, sizeof(in));
334                 in.sin_port = (in_port_t)htons(atoi(lin + matches[2].rm_so));
335                 memcpy(res->ha_addr.ai_addr, &in, sizeof(in));
336                 break;
337             case AF_INET6:
338                 memcpy(&in6, res->ha_addr.ai_addr, sizeof(in6));
339                 in6.sin6_port = (in_port_t)htons(atoi(lin + matches[2].rm_so));
340                 memcpy(res->ha_addr.ai_addr, &in6, sizeof(in6));
341                 break;
342             default:
343                 conf_err("Unknown HA address type");
344             }
345         } else if(!regexec(&HTTPS, lin, 4, matches, 0)) {
346             if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
347                 conf_err("SSL_CTX_new failed - aborted");
348             SSL_CTX_set_app_data(res->ctx, res);
349             SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL);
350             SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY);
351 #ifdef SSL_MODE_SEND_FALLBACK_SCSV
352             SSL_CTX_set_mode(res->ctx, SSL_MODE_SEND_FALLBACK_SCSV);
353 #endif
354             SSL_CTX_set_options(res->ctx, SSL_OP_ALL);
355 #ifdef  SSL_OP_NO_COMPRESSION
356             SSL_CTX_set_options(res->ctx, SSL_OP_NO_COMPRESSION);
357 #endif
358             SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
359             SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT);
360             sprintf(lin, "%d-Pound-%ld", getpid(), random());
361             SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin));
362             SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback);
363             SSL_CTX_set_tmp_dh_callback(res->ctx, DH_tmp_callback);
364 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
365 #ifndef OPENSSL_NO_ECDH
366             /* This generates a EC_KEY structure with no key, but a group defined */
367             EC_KEY *ecdh;
368             if((ecdh = EC_KEY_new_by_curve_name(EC_nid)) == NULL)
369                 conf_err("Unable to generate temp ECDH key");
370             SSL_CTX_set_tmp_ecdh(res->ctx, ecdh);
371             SSL_CTX_set_options(res->ctx, SSL_OP_SINGLE_ECDH_USE);
372             EC_KEY_free(ecdh);
373 #endif
374 #endif
375         } else if(!regexec(&Cert, lin, 4, matches, 0)) {
376             if(res->ctx == NULL)
377                 conf_err("BackEnd Cert can only be used after HTTPS - aborted");
378             lin[matches[1].rm_eo] = '\0';
379             if(SSL_CTX_use_certificate_chain_file(res->ctx, lin + matches[1].rm_so) != 1)
380                 conf_err("SSL_CTX_use_certificate_chain_file failed - aborted");
381             if(SSL_CTX_use_PrivateKey_file(res->ctx, lin + matches[1].rm_so, SSL_FILETYPE_PEM) != 1)
382                 conf_err("SSL_CTX_use_PrivateKey_file failed - aborted");
383             if(SSL_CTX_check_private_key(res->ctx) != 1)
384                 conf_err("SSL_CTX_check_private_key failed - aborted");
385         } else if(!regexec(&Ciphers, lin, 4, matches, 0)) {
386             if(res->ctx == NULL)
387                 conf_err("BackEnd Ciphers can only be used after HTTPS - aborted");
388             lin[matches[1].rm_eo] = '\0';
389             SSL_CTX_set_cipher_list(res->ctx, lin + matches[1].rm_so);
390         } else if(!regexec(&DisableProto, lin, 4, matches, 0)) {
391             if(res->ctx == NULL)
392                 conf_err("BackEnd Disable can only be used after HTTPS - aborted");
393             lin[matches[1].rm_eo] = '\0';
394             if(strcasecmp(lin + matches[1].rm_so, "SSLv2") == 0)
395                 SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2);
396             else if(strcasecmp(lin + matches[1].rm_so, "SSLv3") == 0)
397                 SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
398 #ifdef SSL_OP_NO_TLSv1
399             else if(strcasecmp(lin + matches[1].rm_so, "TLSv1") == 0)
400                 SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
401 #endif
402 #ifdef SSL_OP_NO_TLSv1_1
403             else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_1") == 0)
404                 SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
405 #endif
406 #ifdef SSL_OP_NO_TLSv1_2
407             else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_2") == 0)
408                 SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
409 #endif
410         } else if(!regexec(&Disabled, lin, 4, matches, 0)) {
411             res->disabled = atoi(lin + matches[1].rm_so);
412         } else if(!regexec(&End, lin, 4, matches, 0)) {
413             if(!has_addr)
414                 conf_err("BackEnd missing Address - aborted");
415             if((res->addr.ai_family == AF_INET || res->addr.ai_family == AF_INET6) && !has_port)
416                 conf_err("BackEnd missing Port - aborted");
417             return res;
418         } else {
419             conf_err("unknown directive");
420         }
421     }
422
423     conf_err("BackEnd premature EOF");
424     return NULL;
425 }
426
427 /*
428  * parse a session
429  */
430 static void
431 parse_sess(SERVICE *const svc)
432 {
433     char        lin[MAXBUF], *cp, *parm;
434
435     parm = NULL;
436     while(conf_fgets(lin, MAXBUF)) {
437         if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
438             lin[strlen(lin) - 1] = '\0';
439         if(!regexec(&Type, lin, 4, matches, 0)) {
440             if(svc->sess_type != SESS_NONE)
441                 conf_err("Multiple Session types in one Service - aborted");
442             lin[matches[1].rm_eo] = '\0';
443             cp = lin + matches[1].rm_so;
444             if(!strcasecmp(cp, "IP"))
445                 svc->sess_type = SESS_IP;
446             else if(!strcasecmp(cp, "COOKIE"))
447                 svc->sess_type = SESS_COOKIE;
448             else if(!strcasecmp(cp, "URL"))
449                 svc->sess_type = SESS_URL;
450             else if(!strcasecmp(cp, "PARM"))
451                 svc->sess_type = SESS_PARM;
452             else if(!strcasecmp(cp, "BASIC"))
453                 svc->sess_type = SESS_BASIC;
454             else if(!strcasecmp(cp, "HEADER"))
455                 svc->sess_type = SESS_HEADER;
456             else
457                 conf_err("Unknown Session type");
458         } else if(!regexec(&TTL, lin, 4, matches, 0)) {
459             svc->sess_ttl = atoi(lin + matches[1].rm_so);
460         } else if(!regexec(&ID, lin, 4, matches, 0)) {
461             if(svc->sess_type != SESS_COOKIE && svc->sess_type != SESS_URL && svc->sess_type != SESS_HEADER)
462                 conf_err("no ID permitted unless COOKIE/URL/HEADER Session - aborted");
463             lin[matches[1].rm_eo] = '\0';
464             if((parm = strdup(lin + matches[1].rm_so)) == NULL)
465                 conf_err("ID config: out of memory - aborted");
466         } else if(!regexec(&End, lin, 4, matches, 0)) {
467             if(svc->sess_type == SESS_NONE)
468                 conf_err("Session type not defined - aborted");
469             if(svc->sess_ttl == 0)
470                 conf_err("Session TTL not defined - aborted");
471             if((svc->sess_type == SESS_COOKIE || svc->sess_type == SESS_URL || svc->sess_type == SESS_HEADER)
472             && parm == NULL)
473                 conf_err("Session ID not defined - aborted");
474             if(svc->sess_type == SESS_COOKIE) {
475                 snprintf(lin, MAXBUF - 1, "Cookie[^:]*:.*[ \t]%s=", parm);
476                 if(regcomp(&svc->sess_start, lin, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
477                     conf_err("COOKIE pattern failed - aborted");
478                 if(regcomp(&svc->sess_pat, "([^;]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
479                     conf_err("COOKIE pattern failed - aborted");
480             } else if(svc->sess_type == SESS_URL) {
481                 snprintf(lin, MAXBUF - 1, "[?&]%s=", parm);
482                 if(regcomp(&svc->sess_start, lin, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
483                     conf_err("URL pattern failed - aborted");
484                 if(regcomp(&svc->sess_pat, "([^&;#]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
485                     conf_err("URL pattern failed - aborted");
486             } else if(svc->sess_type == SESS_PARM) {
487                 if(regcomp(&svc->sess_start, ";", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
488                     conf_err("PARM pattern failed - aborted");
489                 if(regcomp(&svc->sess_pat, "([^?]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
490                     conf_err("PARM pattern failed - aborted");
491             } else if(svc->sess_type == SESS_BASIC) {
492                 if(regcomp(&svc->sess_start, "Authorization:[ \t]*Basic[ \t]*", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
493                     conf_err("BASIC pattern failed - aborted");
494                 if(regcomp(&svc->sess_pat, "([^ \t]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
495                     conf_err("BASIC pattern failed - aborted");
496             } else if(svc->sess_type == SESS_HEADER) {
497                 snprintf(lin, MAXBUF - 1, "%s:[ \t]*", parm);
498                 if(regcomp(&svc->sess_start, lin, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
499                     conf_err("HEADER pattern failed - aborted");
500                 if(regcomp(&svc->sess_pat, "([^ \t]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
501                     conf_err("HEADER pattern failed - aborted");
502             }
503             if(parm != NULL)
504                 free(parm);
505             return;
506         } else {
507             conf_err("unknown directive");
508         }
509     }
510
511     conf_err("Session premature EOF");
512     return;
513 }
514
515 /*
516  * basic hashing function, based on fmv
517  */
518 static unsigned long
519 t_hash(const TABNODE *e)
520 {
521     unsigned long   res;
522     char            *k;
523
524     k = e->key;
525     res = 2166136261;
526     while(*k)
527         res = ((res ^ *k++) * 16777619) & 0xFFFFFFFF;
528     return res;
529 }
530
531 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
532 static IMPLEMENT_LHASH_HASH_FN(t, TABNODE)
533 #else
534 static IMPLEMENT_LHASH_HASH_FN(t_hash, const TABNODE *)
535 #endif
536  
537 static int
538 t_cmp(const TABNODE *d1, const TABNODE *d2)
539 {
540     return strcmp(d1->key, d2->key);
541 }
542
543 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
544 static IMPLEMENT_LHASH_COMP_FN(t, TABNODE)
545 #else
546 static IMPLEMENT_LHASH_COMP_FN(t_cmp, const TABNODE *)
547 #endif
548
549
550 /*
551  * parse a service
552  */
553 static SERVICE *
554 parse_service(const char *svc_name)
555 {
556     char        lin[MAXBUF];
557     SERVICE     *res;
558     BACKEND     *be;
559     MATCHER     *m;
560     int         ign_case;
561
562     if((res = (SERVICE *)malloc(sizeof(SERVICE))) == NULL)
563         conf_err("Service config: out of memory - aborted");
564     memset(res, 0, sizeof(SERVICE));
565     res->sess_type = SESS_NONE;
566     res->dynscale = dynscale;
567     pthread_mutex_init(&res->mut, NULL);
568     if(svc_name)
569         strncpy(res->name, svc_name, KEY_SIZE);
570 #if OPENSSL_VERSION_NUMBER >= 0x10000000L
571     if((res->sessions = LHM_lh_new(TABNODE, t)) == NULL)
572 #else
573     if((res->sessions = lh_new(LHASH_HASH_FN(t_hash), LHASH_COMP_FN(t_cmp))) == NULL)
574 #endif
575         conf_err("lh_new failed - aborted");
576     ign_case = ignore_case;
577     while(conf_fgets(lin, MAXBUF)) {
578         if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
579             lin[strlen(lin) - 1] = '\0';
580         if(!regexec(&URL, lin, 4, matches, 0)) {
581             if(res->url) {
582                 for(m = res->url; m->next; m = m->next)
583                     ;
584                 if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
585                     conf_err("URL config: out of memory - aborted");
586                 m = m->next;
587             } else {
588                 if((res->url = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
589                     conf_err("URL config: out of memory - aborted");
590                 m = res->url;
591             }
592             memset(m, 0, sizeof(MATCHER));
593             lin[matches[1].rm_eo] = '\0';
594             if(regcomp(&m->pat, lin + matches[1].rm_so, REG_NEWLINE | REG_EXTENDED | (ign_case? REG_ICASE: 0)))
595                 conf_err("URL bad pattern - aborted");
596         } else if(!regexec(&HeadRequire, lin, 4, matches, 0)) {
597             if(res->req_head) {
598                 for(m = res->req_head; m->next; m = m->next)
599                     ;
600                 if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
601                     conf_err("HeadRequire config: out of memory - aborted");
602                 m = m->next;
603             } else {
604                 if((res->req_head = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
605                     conf_err("HeadRequire config: out of memory - aborted");
606                 m = res->req_head;
607             }
608             memset(m, 0, sizeof(MATCHER));
609             lin[matches[1].rm_eo] = '\0';
610             if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
611                 conf_err("HeadRequire bad pattern - aborted");
612         } else if(!regexec(&HeadDeny, lin, 4, matches, 0)) {
613             if(res->deny_head) {
614                 for(m = res->deny_head; m->next; m = m->next)
615                     ;
616                 if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
617                     conf_err("HeadDeny config: out of memory - aborted");
618                 m = m->next;
619             } else {
620                 if((res->deny_head = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
621                     conf_err("HeadDeny config: out of memory - aborted");
622                 m = res->deny_head;
623             }
624             memset(m, 0, sizeof(MATCHER));
625             lin[matches[1].rm_eo] = '\0';
626             if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
627                 conf_err("HeadDeny bad pattern - aborted");
628         } else if(!regexec(&Redirect, lin, 4, matches, 0)) {
629             if(res->backends) {
630                 for(be = res->backends; be->next; be = be->next)
631                     ;
632                 if((be->next = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
633                     conf_err("Redirect config: out of memory - aborted");
634                 be = be->next;
635             } else {
636                 if((res->backends = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
637                     conf_err("Redirect config: out of memory - aborted");
638                 be = res->backends;
639             }
640             memset(be, 0, sizeof(BACKEND));
641             be->be_type = 302;
642             be->priority = 1;
643             be->alive = 1;
644             pthread_mutex_init(& be->mut, NULL);
645             lin[matches[1].rm_eo] = '\0';
646             if((be->url = strdup(lin + matches[1].rm_so)) == NULL)
647                 conf_err("Redirector config: out of memory - aborted");
648             /* split the URL into its fields */
649             if(regexec(&LOCATION, be->url, 4, matches, 0))
650                 conf_err("Redirect bad URL - aborted");
651             if((be->redir_req = matches[3].rm_eo - matches[3].rm_so) == 1)
652                 /* the path is a single '/', so remove it */
653                 be->url[matches[3].rm_so] = '\0';
654         } else if(!regexec(&RedirectN, lin, 4, matches, 0)) {
655             if(res->backends) {
656                 for(be = res->backends; be->next; be = be->next)
657                     ;
658                 if((be->next = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
659                     conf_err("Redirect config: out of memory - aborted");
660                 be = be->next;
661             } else {
662                 if((res->backends = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
663                     conf_err("Redirect config: out of memory - aborted");
664                 be = res->backends;
665             }
666             memset(be, 0, sizeof(BACKEND));
667             be->be_type = atoi(lin + matches[1].rm_so);
668             be->priority = 1;
669             be->alive = 1;
670             pthread_mutex_init(& be->mut, NULL);
671             lin[matches[2].rm_eo] = '\0';
672             if((be->url = strdup(lin + matches[2].rm_so)) == NULL)
673                 conf_err("Redirector config: out of memory - aborted");
674             /* split the URL into its fields */
675             if(regexec(&LOCATION, be->url, 4, matches, 0))
676                 conf_err("Redirect bad URL - aborted");
677             if((be->redir_req = matches[3].rm_eo - matches[3].rm_so) == 1)
678                 /* the path is a single '/', so remove it */
679                 be->url[matches[3].rm_so] = '\0';
680         } else if(!regexec(&BackEnd, lin, 4, matches, 0)) {
681             if(res->backends) {
682                 for(be = res->backends; be->next; be = be->next)
683                     ;
684                 be->next = parse_be(0);
685             } else
686                 res->backends = parse_be(0);
687         } else if(!regexec(&Emergency, lin, 4, matches, 0)) {
688             res->emergency = parse_be(1);
689         } else if(!regexec(&Session, lin, 4, matches, 0)) {
690             parse_sess(res);
691         } else if(!regexec(&DynScale, lin, 4, matches, 0)) {
692             res->dynscale = atoi(lin + matches[1].rm_so);
693         } else if(!regexec(&IgnoreCase, lin, 4, matches, 0)) {
694             ign_case = atoi(lin + matches[1].rm_so);
695         } else if(!regexec(&Disabled, lin, 4, matches, 0)) {
696             res->disabled = atoi(lin + matches[1].rm_so);
697         } else if(!regexec(&End, lin, 4, matches, 0)) {
698             for(be = res->backends; be; be = be->next) {
699                 if(!be->disabled)
700                     res->tot_pri += be->priority;
701                 res->abs_pri += be->priority;
702             }
703             return res;
704         } else {
705             conf_err("unknown directive");
706         }
707     }
708
709     conf_err("Service premature EOF");
710     return NULL;
711 }
712
713 /*
714  * return the file contents as a string
715  */
716 static char *
717 file2str(const char *fname)
718 {
719     char    *res;
720     struct stat st;
721     int     fin;
722
723     if(stat(fname, &st))
724         conf_err("can't stat Err file - aborted");
725     if((fin = open(fname, O_RDONLY)) < 0)
726         conf_err("can't open Err file - aborted");
727     if((res = malloc(st.st_size + 1)) == NULL)
728         conf_err("can't alloc Err file (out of memory) - aborted");
729     if(read(fin, res, st.st_size) != st.st_size)
730         conf_err("can't read Err file - aborted");
731     res[st.st_size] = '\0';
732     close(fin);
733     return res;
734 }
735
736 /*
737  * parse an HTTP listener
738  */
739 static LISTENER *
740 parse_HTTP(void)
741 {
742     char        lin[MAXBUF];
743     LISTENER    *res;
744     SERVICE     *svc;
745     MATCHER     *m;
746     int         has_addr, has_port;
747     struct sockaddr_in  in;
748     struct sockaddr_in6 in6;
749
750     if((res = (LISTENER *)malloc(sizeof(LISTENER))) == NULL)
751         conf_err("ListenHTTP config: out of memory - aborted");
752     memset(res, 0, sizeof(LISTENER));
753     res->to = clnt_to;
754     res->rewr_loc = 1;
755     res->err414 = "Request URI is too long";
756     res->err500 = "An internal server error occurred. Please try again later.";
757     res->err501 = "This method may not be used.";
758     res->err503 = "The service is not available. Please try again later.";
759     res->log_level = log_level;
760     if(regcomp(&res->verb, xhttp[0], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
761         conf_err("xHTTP bad default pattern - aborted");
762     has_addr = has_port = 0;
763     while(conf_fgets(lin, MAXBUF)) {
764         if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
765             lin[strlen(lin) - 1] = '\0';
766         if(!regexec(&Address, lin, 4, matches, 0)) {
767             lin[matches[1].rm_eo] = '\0';
768             if(get_host(lin + matches[1].rm_so, &res->addr, PF_UNSPEC))
769                 conf_err("Unknown Listener address");
770             if(res->addr.ai_family != AF_INET && res->addr.ai_family != AF_INET6)
771                 conf_err("Unknown Listener address family");
772             has_addr = 1;
773         } else if(!regexec(&Port, lin, 4, matches, 0)) {
774             switch(res->addr.ai_family) {
775             case AF_INET:
776                 memcpy(&in, res->addr.ai_addr, sizeof(in));
777                 in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
778                 memcpy(res->addr.ai_addr, &in, sizeof(in));
779                 break;
780             case AF_INET6:
781                 memcpy(&in6, res->addr.ai_addr, sizeof(in6));
782                 in6.sin6_port = htons(atoi(lin + matches[1].rm_so));
783                 memcpy(res->addr.ai_addr, &in6, sizeof(in6));
784                 break;
785             default:
786                 conf_err("Unknown Listener address family");
787             }
788             has_port = 1;
789         } else if(!regexec(&xHTTP, lin, 4, matches, 0)) {
790             int n;
791
792             n = atoi(lin + matches[1].rm_so);
793             regfree(&res->verb);
794             if(regcomp(&res->verb, xhttp[n], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
795                 conf_err("xHTTP bad pattern - aborted");
796         } else if(!regexec(&Client, lin, 4, matches, 0)) {
797             res->to = atoi(lin + matches[1].rm_so);
798         } else if(!regexec(&CheckURL, lin, 4, matches, 0)) {
799             if(res->has_pat)
800                 conf_err("CheckURL multiple pattern - aborted");
801             lin[matches[1].rm_eo] = '\0';
802             if(regcomp(&res->url_pat, lin + matches[1].rm_so, REG_NEWLINE | REG_EXTENDED | (ignore_case? REG_ICASE: 0)))
803                 conf_err("CheckURL bad pattern - aborted");
804             res->has_pat = 1;
805         } else if(!regexec(&Err414, lin, 4, matches, 0)) {
806             lin[matches[1].rm_eo] = '\0';
807             res->err414 = file2str(lin + matches[1].rm_so);
808         } else if(!regexec(&Err500, lin, 4, matches, 0)) {
809             lin[matches[1].rm_eo] = '\0';
810             res->err500 = file2str(lin + matches[1].rm_so);
811         } else if(!regexec(&Err501, lin, 4, matches, 0)) {
812             lin[matches[1].rm_eo] = '\0';
813             res->err501 = file2str(lin + matches[1].rm_so);
814         } else if(!regexec(&Err503, lin, 4, matches, 0)) {
815             lin[matches[1].rm_eo] = '\0';
816             res->err503 = file2str(lin + matches[1].rm_so);
817         } else if(!regexec(&MaxRequest, lin, 4, matches, 0)) {
818             res->max_req = ATOL(lin + matches[1].rm_so);
819         } else if(!regexec(&HeadRemove, lin, 4, matches, 0)) {
820             if(res->head_off) {
821                 for(m = res->head_off; m->next; m = m->next)
822                     ;
823                 if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
824                     conf_err("HeadRemove config: out of memory - aborted");
825                 m = m->next;
826             } else {
827                 if((res->head_off = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
828                     conf_err("HeadRemove config: out of memory - aborted");
829                 m = res->head_off;
830             }
831             memset(m, 0, sizeof(MATCHER));
832             lin[matches[1].rm_eo] = '\0';
833             if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
834                 conf_err("HeadRemove bad pattern - aborted");
835         } else if(!regexec(&AddHeader, lin, 4, matches, 0)) {
836             lin[matches[1].rm_eo] = '\0';
837             if(res->add_head == NULL) {
838                 if((res->add_head = strdup(lin + matches[1].rm_so)) == NULL)
839                     conf_err("AddHeader config: out of memory - aborted");
840             } else {
841                 if((res->add_head = realloc(res->add_head, strlen(res->add_head) + strlen(lin + matches[1].rm_so) + 3))
842                 == NULL)
843                     conf_err("AddHeader config: out of memory - aborted");
844                 strcat(res->add_head, "\r\n");
845                 strcat(res->add_head, lin + matches[1].rm_so);
846             }
847         } else if(!regexec(&RewriteLocation, lin, 4, matches, 0)) {
848             res->rewr_loc = atoi(lin + matches[1].rm_so);
849         } else if(!regexec(&RewriteDestination, lin, 4, matches, 0)) {
850             res->rewr_dest = atoi(lin + matches[1].rm_so);
851         } else if(!regexec(&LogLevel, lin, 4, matches, 0)) {
852             res->log_level = atoi(lin + matches[1].rm_so);
853         } else if(!regexec(&Service, lin, 4, matches, 0)) {
854             if(res->services == NULL)
855                 res->services = parse_service(NULL);
856             else {
857                 for(svc = res->services; svc->next; svc = svc->next)
858                     ;
859                 svc->next = parse_service(NULL);
860             }
861         } else if(!regexec(&ServiceName, lin, 4, matches, 0)) {
862             lin[matches[1].rm_eo] = '\0';
863             if(res->services == NULL)
864                 res->services = parse_service(lin + matches[1].rm_so);
865             else {
866                 for(svc = res->services; svc->next; svc = svc->next)
867                     ;
868                 svc->next = parse_service(lin + matches[1].rm_so);
869             }
870         } else if(!regexec(&End, lin, 4, matches, 0)) {
871             if(!has_addr || !has_port)
872                 conf_err("ListenHTTP missing Address or Port - aborted");
873             return res;
874         } else {
875             conf_err("unknown directive - aborted");
876         }
877     }
878
879     conf_err("ListenHTTP premature EOF");
880     return NULL;
881 }
882 /*
883  * Dummy certificate verification - always OK
884  */
885 static int
886 verify_OK(int pre_ok, X509_STORE_CTX *ctx)
887 {
888     return 1;
889 }
890
891 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
892 static int
893 SNI_server_name(SSL *ssl, int *dummy, POUND_CTX *ctx)
894 {
895     const char  *server_name;
896     POUND_CTX   *pc;
897
898     if((server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) == NULL)
899         return SSL_TLSEXT_ERR_NOACK;
900
901     /* logmsg(LOG_DEBUG, "Received SSL SNI Header for servername %s", servername); */
902
903     SSL_set_SSL_CTX(ssl, NULL);
904     for(pc = ctx; pc; pc = pc->next) {
905         if(fnmatch(pc->server_name, server_name, 0) == 0) {
906             /* logmsg(LOG_DEBUG, "Found cert for %s", servername); */
907             SSL_set_SSL_CTX(ssl, pc->ctx);
908             return SSL_TLSEXT_ERR_OK;
909         }
910         else if(pc->subjectAltNameCount > 0 && pc->subjectAltNames != NULL) {
911             int i;
912
913             for(i = 0; i < pc->subjectAltNameCount; i++) {
914                 if(fnmatch(pc->subjectAltNames[i], server_name, 0) == 0) {
915                     SSL_set_SSL_CTX(ssl, pc->ctx);
916                     return SSL_TLSEXT_ERR_OK;
917                 }
918             }
919         }
920     }
921     
922     /* logmsg(LOG_DEBUG, "No match for %s, default used", server_name); */
923     SSL_set_SSL_CTX(ssl, ctx->ctx);
924     return SSL_TLSEXT_ERR_OK;
925 }
926 #endif
927
928 /*
929  * parse an HTTPS listener
930  */
931 static LISTENER *
932 parse_HTTPS(void)
933 {
934     char                lin[MAXBUF];
935     LISTENER            *res;
936     SERVICE             *svc;
937     MATCHER             *m;
938     int                 has_addr, has_port, has_other;
939     long                ssl_op_enable, ssl_op_disable;
940     struct hostent      *host;
941     struct sockaddr_in  in;
942     struct sockaddr_in6 in6;
943     POUND_CTX           *pc;
944
945     ssl_op_enable = SSL_OP_ALL;
946 #ifdef  SSL_OP_NO_COMPRESSION
947     ssl_op_enable |= SSL_OP_NO_COMPRESSION;
948 #endif
949     ssl_op_disable = SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | SSL_OP_LEGACY_SERVER_CONNECT
950                     | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
951
952     if((res = (LISTENER *)malloc(sizeof(LISTENER))) == NULL)
953         conf_err("ListenHTTPS config: out of memory - aborted");
954     memset(res, 0, sizeof(LISTENER));
955
956     res->to = clnt_to;
957     res->rewr_loc = 1;
958     res->err414 = "Request URI is too long";
959     res->err500 = "An internal server error occurred. Please try again later.";
960     res->err501 = "This method may not be used.";
961     res->err503 = "The service is not available. Please try again later.";
962     res->allow_client_reneg = 0;
963     res->log_level = log_level;
964     if(regcomp(&res->verb, xhttp[0], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
965         conf_err("xHTTP bad default pattern - aborted");
966     has_addr = has_port = has_other = 0;
967     while(conf_fgets(lin, MAXBUF)) {
968         if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
969             lin[strlen(lin) - 1] = '\0';
970         if(!regexec(&Address, lin, 4, matches, 0)) {
971             lin[matches[1].rm_eo] = '\0';
972             if(get_host(lin + matches[1].rm_so, &res->addr, PF_UNSPEC))
973                 conf_err("Unknown Listener address");
974             if(res->addr.ai_family != AF_INET && res->addr.ai_family != AF_INET6)
975                 conf_err("Unknown Listener address family");
976             has_addr = 1;
977         } else if(!regexec(&Port, lin, 4, matches, 0)) {
978             if(res->addr.ai_family == AF_INET) {
979                 memcpy(&in, res->addr.ai_addr, sizeof(in));
980                 in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
981                 memcpy(res->addr.ai_addr, &in, sizeof(in));
982             } else {
983                 memcpy(&in6, res->addr.ai_addr, sizeof(in6));
984                 in6.sin6_port = htons(atoi(lin + matches[1].rm_so));
985                 memcpy(res->addr.ai_addr, &in6, sizeof(in6));
986             }
987             has_port = 1;
988         } else if(!regexec(&xHTTP, lin, 4, matches, 0)) {
989             int n;
990
991             n = atoi(lin + matches[1].rm_so);
992             regfree(&res->verb);
993             if(regcomp(&res->verb, xhttp[n], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
994                 conf_err("xHTTP bad pattern - aborted");
995         } else if(!regexec(&Client, lin, 4, matches, 0)) {
996             res->to = atoi(lin + matches[1].rm_so);
997         } else if(!regexec(&CheckURL, lin, 4, matches, 0)) {
998             if(res->has_pat)
999                 conf_err("CheckURL multiple pattern - aborted");
1000             lin[matches[1].rm_eo] = '\0';
1001             if(regcomp(&res->url_pat, lin + matches[1].rm_so, REG_NEWLINE | REG_EXTENDED | (ignore_case? REG_ICASE: 0)))
1002                 conf_err("CheckURL bad pattern - aborted");
1003             res->has_pat = 1;
1004         } else if(!regexec(&Err414, lin, 4, matches, 0)) {
1005             lin[matches[1].rm_eo] = '\0';
1006             res->err414 = file2str(lin + matches[1].rm_so);
1007         } else if(!regexec(&Err500, lin, 4, matches, 0)) {
1008             lin[matches[1].rm_eo] = '\0';
1009             res->err500 = file2str(lin + matches[1].rm_so);
1010         } else if(!regexec(&Err501, lin, 4, matches, 0)) {
1011             lin[matches[1].rm_eo] = '\0';
1012             res->err501 = file2str(lin + matches[1].rm_so);
1013         } else if(!regexec(&Err503, lin, 4, matches, 0)) {
1014             lin[matches[1].rm_eo] = '\0';
1015             res->err503 = file2str(lin + matches[1].rm_so);
1016         } else if(!regexec(&MaxRequest, lin, 4, matches, 0)) {
1017             res->max_req = ATOL(lin + matches[1].rm_so);
1018         } else if(!regexec(&HeadRemove, lin, 4, matches, 0)) {
1019             if(res->head_off) {
1020                 for(m = res->head_off; m->next; m = m->next)
1021                     ;
1022                 if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
1023                     conf_err("HeadRemove config: out of memory - aborted");
1024                 m = m->next;
1025             } else {
1026                 if((res->head_off = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
1027                     conf_err("HeadRemove config: out of memory - aborted");
1028                 m = res->head_off;
1029             }
1030             memset(m, 0, sizeof(MATCHER));
1031             lin[matches[1].rm_eo] = '\0';
1032             if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
1033                 conf_err("HeadRemove bad pattern - aborted");
1034         } else if(!regexec(&RewriteLocation, lin, 4, matches, 0)) {
1035             res->rewr_loc = atoi(lin + matches[1].rm_so);
1036         } else if(!regexec(&RewriteDestination, lin, 4, matches, 0)) {
1037             res->rewr_dest = atoi(lin + matches[1].rm_so);
1038         } else if(!regexec(&LogLevel, lin, 4, matches, 0)) {
1039             res->log_level = atoi(lin + matches[1].rm_so);
1040         } else if(!regexec(&Cert, lin, 4, matches, 0)) {
1041 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1042             /* we have support for SNI */
1043             FILE        *fcert;
1044             char        server_name[MAXBUF], *cp;
1045             X509        *x509;
1046
1047             if(has_other)
1048                 conf_err("Cert directives MUST precede other SSL-specific directives - aborted");
1049             if(res->ctx) {
1050                 for(pc = res->ctx; pc->next; pc = pc->next)
1051                     ;
1052                 if((pc->next = malloc(sizeof(POUND_CTX))) == NULL)
1053                     conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
1054                 pc = pc->next;
1055             } else {
1056                 if((res->ctx = malloc(sizeof(POUND_CTX))) == NULL)
1057                     conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
1058                 pc = res->ctx;
1059             }
1060             if((pc->ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
1061                 conf_err("SSL_CTX_new failed - aborted");
1062             pc->server_name = NULL;
1063             pc->next = NULL;
1064             lin[matches[1].rm_eo] = '\0';
1065             if(SSL_CTX_use_certificate_chain_file(pc->ctx, lin + matches[1].rm_so) != 1)
1066                 conf_err("SSL_CTX_use_certificate_chain_file failed - aborted");
1067             if(SSL_CTX_use_PrivateKey_file(pc->ctx, lin + matches[1].rm_so, SSL_FILETYPE_PEM) != 1)
1068                 conf_err("SSL_CTX_use_PrivateKey_file failed - aborted");
1069             if(SSL_CTX_check_private_key(pc->ctx) != 1)
1070                 conf_err("SSL_CTX_check_private_key failed - aborted");
1071             if((fcert = fopen(lin + matches[1].rm_so, "r")) == NULL)
1072                 conf_err("ListenHTTPS: could not open certificate file");
1073             if((x509 = PEM_read_X509(fcert, NULL, NULL, NULL)) == NULL)
1074                 conf_err("ListenHTTPS: could not get certificate subject");
1075             fclose(fcert);
1076             memset(server_name, '\0', MAXBUF);
1077             X509_NAME_oneline(X509_get_subject_name(x509), server_name, MAXBUF - 1);
1078             pc->subjectAltNameCount = 0;
1079             pc->subjectAltNames = NULL;
1080             pc->subjectAltNames = get_subjectaltnames(x509, &(pc->subjectAltNameCount));
1081             X509_free(x509);
1082             if(!regexec(&CNName, server_name, 4, matches, 0)) {
1083                 server_name[matches[1].rm_eo] = '\0';
1084                 if((pc->server_name = strdup(server_name + matches[1].rm_so)) == NULL)
1085                     conf_err("ListenHTTPS: could not set certificate subject");
1086             } else
1087                 conf_err("ListenHTTPS: could not get certificate CN");
1088 #else
1089             /* no SNI support */
1090             if(has_other)
1091                 conf_err("Cert directives MUST precede other SSL-specific directives - aborted");
1092             if(res->ctx)
1093                 conf_err("ListenHTTPS: multiple certificates not supported - aborted");
1094             if((res->ctx = malloc(sizeof(POUND_CTX))) == NULL)
1095                 conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
1096             res->ctx->server_name = NULL;
1097             res->ctx->next = NULL;
1098             if((res->ctx->ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
1099                 conf_err("SSL_CTX_new failed - aborted");
1100             lin[matches[1].rm_eo] = '\0';
1101             if(SSL_CTX_use_certificate_chain_file(res->ctx->ctx, lin + matches[1].rm_so) != 1)
1102                 conf_err("SSL_CTX_use_certificate_chain_file failed - aborted");
1103             if(SSL_CTX_use_PrivateKey_file(res->ctx->ctx, lin + matches[1].rm_so, SSL_FILETYPE_PEM) != 1)
1104                 conf_err("SSL_CTX_use_PrivateKey_file failed - aborted");
1105             if(SSL_CTX_check_private_key(res->ctx->ctx) != 1)
1106                 conf_err("SSL_CTX_check_private_key failed - aborted");
1107 #endif
1108         } else if(!regexec(&ClientCert, lin, 4, matches, 0)) {
1109             has_other = 1;
1110             if(res->ctx == NULL)
1111                 conf_err("ClientCert may only be used after Cert - aborted");
1112             switch(res->clnt_check = atoi(lin + matches[1].rm_so)) {
1113             case 0:
1114                 /* don't ask */
1115                 for(pc = res->ctx; pc; pc = pc->next)
1116                     SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_NONE, NULL);
1117                 break;
1118             case 1:
1119                 /* ask but OK if no client certificate */
1120                 for(pc = res->ctx; pc; pc = pc->next) {
1121                     SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
1122                     SSL_CTX_set_verify_depth(pc->ctx, atoi(lin + matches[2].rm_so));
1123                 }
1124                 break;
1125             case 2:
1126                 /* ask and fail if no client certificate */
1127                 for(pc = res->ctx; pc; pc = pc->next) {
1128                     SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
1129                     SSL_CTX_set_verify_depth(pc->ctx, atoi(lin + matches[2].rm_so));
1130                 }
1131                 break;
1132             case 3:
1133                 /* ask but do not verify client certificate */
1134                 for(pc = res->ctx; pc; pc = pc->next) {
1135                     SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_OK);
1136                     SSL_CTX_set_verify_depth(pc->ctx, atoi(lin + matches[2].rm_so));
1137                 }
1138                 break;
1139             }
1140         } else if(!regexec(&AddHeader, lin, 4, matches, 0)) {
1141             lin[matches[1].rm_eo] = '\0';
1142             if(res->add_head == NULL) {
1143                 if((res->add_head = strdup(lin + matches[1].rm_so)) == NULL)
1144                     conf_err("AddHeader config: out of memory - aborted");
1145             } else {
1146                 if((res->add_head = realloc(res->add_head, strlen(res->add_head) + strlen(lin + matches[1].rm_so) + 3)) == NULL)
1147                     conf_err("AddHeader config: out of memory - aborted");
1148                 strcat(res->add_head, "\r\n");
1149                 strcat(res->add_head, lin + matches[1].rm_so);
1150             }
1151         } else if(!regexec(&DisableProto, lin, 4, matches, 0)) {
1152             lin[matches[1].rm_eo] = '\0';
1153             if(strcasecmp(lin + matches[1].rm_so, "SSLv2") == 0)
1154                 ssl_op_enable |= SSL_OP_NO_SSLv2;
1155             else if(strcasecmp(lin + matches[1].rm_so, "SSLv3") == 0)
1156                 ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
1157 #ifdef SSL_OP_NO_TLSv1
1158             else if(strcasecmp(lin + matches[1].rm_so, "TLSv1") == 0)
1159                 ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
1160 #endif
1161 #ifdef SSL_OP_NO_TLSv1_1
1162             else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_1") == 0)
1163                 ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
1164 #endif
1165 #ifdef SSL_OP_NO_TLSv1_2
1166             else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_2") == 0)
1167                 ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
1168 #endif
1169         } else if(!regexec(&SSLAllowClientRenegotiation, lin, 4, matches, 0)) {
1170             res->allow_client_reneg = atoi(lin + matches[1].rm_so);
1171             if (res->allow_client_reneg == 2) {
1172                 ssl_op_enable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
1173                 ssl_op_disable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
1174             } else {
1175                 ssl_op_disable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
1176                 ssl_op_enable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
1177             }
1178         } else if(!regexec(&SSLHonorCipherOrder, lin, 4, matches, 0)) {
1179             if (atoi(lin + matches[1].rm_so)) {
1180                 ssl_op_enable |= SSL_OP_CIPHER_SERVER_PREFERENCE;
1181                 ssl_op_disable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
1182             } else {
1183                 ssl_op_disable |= SSL_OP_CIPHER_SERVER_PREFERENCE;
1184                 ssl_op_enable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
1185             }
1186         } else if(!regexec(&Ciphers, lin, 4, matches, 0)) {
1187             has_other = 1;
1188             if(res->ctx == NULL)
1189                 conf_err("Ciphers may only be used after Cert - aborted");
1190             lin[matches[1].rm_eo] = '\0';
1191             for(pc = res->ctx; pc; pc = pc->next)
1192                 SSL_CTX_set_cipher_list(pc->ctx, lin + matches[1].rm_so);
1193         } else if(!regexec(&CAlist, lin, 4, matches, 0)) {
1194             STACK_OF(X509_NAME) *cert_names;
1195
1196             has_other = 1;
1197             if(res->ctx == NULL)
1198                 conf_err("CAList may only be used after Cert - aborted");
1199             lin[matches[1].rm_eo] = '\0';
1200             if((cert_names = SSL_load_client_CA_file(lin + matches[1].rm_so)) == NULL)
1201                 conf_err("SSL_load_client_CA_file failed - aborted");
1202             for(pc = res->ctx; pc; pc = pc->next)
1203                 SSL_CTX_set_client_CA_list(pc->ctx, cert_names);
1204         } else if(!regexec(&VerifyList, lin, 4, matches, 0)) {
1205             has_other = 1;
1206             if(res->ctx == NULL)
1207                 conf_err("VerifyList may only be used after Cert - aborted");
1208             lin[matches[1].rm_eo] = '\0';
1209             for(pc = res->ctx; pc; pc = pc->next)
1210                 if(SSL_CTX_load_verify_locations(pc->ctx, lin + matches[1].rm_so, NULL) != 1)
1211                     conf_err("SSL_CTX_load_verify_locations failed - aborted");
1212         } else if(!regexec(&CRLlist, lin, 4, matches, 0)) {
1213 #if HAVE_X509_STORE_SET_FLAGS
1214             X509_STORE *store;
1215             X509_LOOKUP *lookup;
1216
1217             has_other = 1;
1218             if(res->ctx == NULL)
1219                 conf_err("CRLlist may only be used after Cert - aborted");
1220             lin[matches[1].rm_eo] = '\0';
1221             for(pc = res->ctx; pc; pc = pc->next) {
1222                 store = SSL_CTX_get_cert_store(pc->ctx);
1223                 if((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) == NULL)
1224                     conf_err("X509_STORE_add_lookup failed - aborted");
1225                 if(X509_load_crl_file(lookup, lin + matches[1].rm_so, X509_FILETYPE_PEM) != 1)
1226                     conf_err("X509_load_crl_file failed - aborted");
1227                 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1228             }
1229 #else
1230             conf_err("your version of OpenSSL does not support CRL checking");
1231 #endif
1232         } else if(!regexec(&NoHTTPS11, lin, 4, matches, 0)) {
1233             res->noHTTPS11 = atoi(lin + matches[1].rm_so);
1234         } else if(!regexec(&Service, lin, 4, matches, 0)) {
1235             if(res->services == NULL)
1236                 res->services = parse_service(NULL);
1237             else {
1238                 for(svc = res->services; svc->next; svc = svc->next)
1239                     ;
1240                 svc->next = parse_service(NULL);
1241             }
1242         } else if(!regexec(&ServiceName, lin, 4, matches, 0)) {
1243             lin[matches[1].rm_eo] = '\0';
1244             if(res->services == NULL)
1245                 res->services = parse_service(lin + matches[1].rm_so);
1246             else {
1247                 for(svc = res->services; svc->next; svc = svc->next)
1248                     ;
1249                 svc->next = parse_service(lin + matches[1].rm_so);
1250             }
1251         } else if(!regexec(&End, lin, 4, matches, 0)) {
1252             X509_STORE  *store;
1253
1254             if(!has_addr || !has_port || res->ctx == NULL)
1255                 conf_err("ListenHTTPS missing Address, Port or Certificate - aborted");
1256 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
1257             if(res->ctx->next)
1258                 if(!SSL_CTX_set_tlsext_servername_callback(res->ctx->ctx, SNI_server_name)
1259                 || !SSL_CTX_set_tlsext_servername_arg(res->ctx->ctx, res->ctx))
1260                     conf_err("ListenHTTPS: can't set SNI callback");
1261 #endif
1262             for(pc = res->ctx; pc; pc = pc->next) {
1263                 SSL_CTX_set_app_data(pc->ctx, res);
1264                 SSL_CTX_set_mode(pc->ctx, SSL_MODE_AUTO_RETRY);
1265                 SSL_CTX_set_options(pc->ctx, ssl_op_enable);
1266                 SSL_CTX_clear_options(pc->ctx, ssl_op_disable);
1267                 sprintf(lin, "%d-Pound-%ld", getpid(), random());
1268                 SSL_CTX_set_session_id_context(pc->ctx, (unsigned char *)lin, strlen(lin));
1269                 SSL_CTX_set_tmp_rsa_callback(pc->ctx, RSA_tmp_callback);
1270                 SSL_CTX_set_tmp_dh_callback(pc->ctx, DH_tmp_callback);
1271                 SSL_CTX_set_info_callback(pc->ctx, SSLINFO_callback);
1272 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
1273 #ifndef OPENSSL_NO_ECDH
1274                 /* This generates a EC_KEY structure with no key, but a group defined */
1275                 EC_KEY *ecdh;
1276                 if((ecdh = EC_KEY_new_by_curve_name(EC_nid)) == NULL)
1277                     conf_err("Unable to generate temp ECDH key");
1278                 SSL_CTX_set_tmp_ecdh(pc->ctx, ecdh);
1279                 SSL_CTX_set_options(pc->ctx, SSL_OP_SINGLE_ECDH_USE);
1280                 EC_KEY_free(ecdh);
1281 #endif
1282 #endif
1283             }
1284             return res;
1285         } else {
1286             conf_err("unknown directive");
1287         }
1288     }
1289
1290     conf_err("ListenHTTPS premature EOF");
1291     return NULL;
1292 }
1293
1294 /*
1295  * parse the config file
1296  */
1297 static void
1298 parse_file(void)
1299 {
1300     char        lin[MAXBUF];
1301     SERVICE     *svc;
1302     LISTENER    *lstn;
1303     int         i;
1304 #if HAVE_OPENSSL_ENGINE_H
1305     ENGINE      *e;
1306 #endif
1307
1308     while(conf_fgets(lin, MAXBUF)) {
1309         if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
1310             lin[strlen(lin) - 1] = '\0';
1311         if(!regexec(&User, lin, 4, matches, 0)) {
1312             lin[matches[1].rm_eo] = '\0';
1313             if((user = strdup(lin + matches[1].rm_so)) == NULL)
1314                 conf_err("User config: out of memory - aborted");
1315         } else if(!regexec(&Group, lin, 4, matches, 0)) {
1316             lin[matches[1].rm_eo] = '\0';
1317             if((group = strdup(lin + matches[1].rm_so)) == NULL)
1318                 conf_err("Group config: out of memory - aborted");
1319         } else if(!regexec(&RootJail, lin, 4, matches, 0)) {
1320             lin[matches[1].rm_eo] = '\0';
1321             if((root_jail = strdup(lin + matches[1].rm_so)) == NULL)
1322                 conf_err("RootJail config: out of memory - aborted");
1323         } else if(!regexec(&Daemon, lin, 4, matches, 0)) {
1324             daemonize = atoi(lin + matches[1].rm_so);
1325         } else if(!regexec(&Threads, lin, 4, matches, 0)) {
1326             numthreads = atoi(lin + matches[1].rm_so);
1327         } else if(!regexec(&LogFacility, lin, 4, matches, 0)) {
1328             lin[matches[1].rm_eo] = '\0';
1329             if(lin[matches[1].rm_so] == '-')
1330                 def_facility = -1;
1331             else
1332                 for(i = 0; facilitynames[i].c_name; i++)
1333                     if(!strcmp(facilitynames[i].c_name, lin + matches[1].rm_so)) {
1334                         def_facility = facilitynames[i].c_val;
1335                         break;
1336                     }
1337         } else if(!regexec(&Grace, lin, 4, matches, 0)) {
1338             grace = atoi(lin + matches[1].rm_so);
1339         } else if(!regexec(&LogLevel, lin, 4, matches, 0)) {
1340             log_level = atoi(lin + matches[1].rm_so);
1341         } else if(!regexec(&Client, lin, 4, matches, 0)) {
1342             clnt_to = atoi(lin + matches[1].rm_so);
1343         } else if(!regexec(&Alive, lin, 4, matches, 0)) {
1344             alive_to = atoi(lin + matches[1].rm_so);
1345         } else if(!regexec(&DynScale, lin, 4, matches, 0)) {
1346             dynscale = atoi(lin + matches[1].rm_so);
1347         } else if(!regexec(&TimeOut, lin, 4, matches, 0)) {
1348             be_to = atoi(lin + matches[1].rm_so);
1349         } else if(!regexec(&ConnTO, lin, 4, matches, 0)) {
1350             be_connto = atoi(lin + matches[1].rm_so);
1351         } else if(!regexec(&IgnoreCase, lin, 4, matches, 0)) {
1352             ignore_case = atoi(lin + matches[1].rm_so);
1353 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
1354 #ifndef OPENSSL_NO_ECDH
1355         } else if(!regexec(&ECDHCurve, lin, 4, matches, 0)) {
1356             lin[matches[1].rm_eo] = '\0';
1357             if((EC_nid = OBJ_sn2nid(lin + matches[1].rm_so)) == 0)
1358                 conf_err("ECDHCurve config: invalid curve name");
1359 #endif
1360 #endif
1361 #if HAVE_OPENSSL_ENGINE_H
1362         } else if(!regexec(&SSLEngine, lin, 4, matches, 0)) {
1363             lin[matches[1].rm_eo] = '\0';
1364 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
1365             ENGINE_load_builtin_engines();
1366 #endif
1367             if (!(e = ENGINE_by_id(lin + matches[1].rm_so)))
1368                 conf_err("could not find engine");
1369             if(!ENGINE_init(e)) {
1370                 ENGINE_free(e);
1371                 conf_err("could not init engine");
1372             }
1373             if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
1374                 ENGINE_free(e);
1375                 conf_err("could not set all defaults");
1376             }
1377             ENGINE_finish(e);
1378             ENGINE_free(e);
1379 #endif
1380         } else if(!regexec(&Control, lin, 4, matches, 0)) {
1381             if(ctrl_name != NULL)
1382                 conf_err("Control multiply defined - aborted");
1383             lin[matches[1].rm_eo] = '\0';
1384             ctrl_name = strdup(lin + matches[1].rm_so);
1385         } else if(!regexec(&ListenHTTP, lin, 4, matches, 0)) {
1386             if(listeners == NULL)
1387                 listeners = parse_HTTP();
1388             else {
1389                 for(lstn = listeners; lstn->next; lstn = lstn->next)
1390                     ;
1391                 lstn->next = parse_HTTP();
1392             }
1393         } else if(!regexec(&ListenHTTPS, lin, 4, matches, 0)) {
1394             if(listeners == NULL)
1395                 listeners = parse_HTTPS();
1396             else {
1397                 for(lstn = listeners; lstn->next; lstn = lstn->next)
1398                     ;
1399                 lstn->next = parse_HTTPS();
1400             }
1401         } else if(!regexec(&Service, lin, 4, matches, 0)) {
1402             if(services == NULL)
1403                 services = parse_service(NULL);
1404             else {
1405                 for(svc = services; svc->next; svc = svc->next)
1406                     ;
1407                 svc->next = parse_service(NULL);
1408             }
1409         } else if(!regexec(&ServiceName, lin, 4, matches, 0)) {
1410             lin[matches[1].rm_eo] = '\0';
1411             if(services == NULL)
1412                 services = parse_service(lin + matches[1].rm_so);
1413             else {
1414                 for(svc = services; svc->next; svc = svc->next)
1415                     ;
1416                 svc->next = parse_service(lin + matches[1].rm_so);
1417             }
1418         } else if(!regexec(&Anonymise, lin, 4, matches, 0)) {
1419             anonymise = 1;
1420         } else {
1421             conf_err("unknown directive - aborted");
1422         }
1423     }
1424     return;
1425 }
1426
1427 /*
1428  * prepare to parse the arguments/config file
1429  */
1430 void
1431 config_parse(const int argc, char **const argv)
1432 {
1433     char    *conf_name;
1434     FILE    *f_conf;
1435     int     c_opt, check_only;
1436
1437     if(regcomp(&Empty, "^[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1438     || regcomp(&Comment, "^[ \t]*#.*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1439     || regcomp(&User, "^[ \t]*User[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1440     || regcomp(&Group, "^[ \t]*Group[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1441     || regcomp(&RootJail, "^[ \t]*RootJail[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1442     || regcomp(&Daemon, "^[ \t]*Daemon[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1443     || regcomp(&Threads, "^[ \t]*Threads[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1444     || regcomp(&LogFacility, "^[ \t]*LogFacility[ \t]+([a-z0-9-]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1445     || regcomp(&LogLevel, "^[ \t]*LogLevel[ \t]+([0-5])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1446     || regcomp(&Grace, "^[ \t]*Grace[ \t]+([0-9]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1447     || regcomp(&Alive, "^[ \t]*Alive[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1448     || regcomp(&SSLEngine, "^[ \t]*SSLEngine[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1449     || regcomp(&Control, "^[ \t]*Control[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1450     || regcomp(&ListenHTTP, "^[ \t]*ListenHTTP[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1451     || regcomp(&ListenHTTPS, "^[ \t]*ListenHTTPS[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1452     || regcomp(&End, "^[ \t]*End[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1453     || regcomp(&Address, "^[ \t]*Address[ \t]+([^ \t]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1454     || regcomp(&Port, "^[ \t]*Port[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1455     || regcomp(&Cert, "^[ \t]*Cert[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1456     || regcomp(&xHTTP, "^[ \t]*xHTTP[ \t]+([01234])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1457     || regcomp(&Client, "^[ \t]*Client[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1458     || regcomp(&CheckURL, "^[ \t]*CheckURL[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1459     || regcomp(&Err414, "^[ \t]*Err414[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1460     || regcomp(&Err500, "^[ \t]*Err500[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1461     || regcomp(&Err501, "^[ \t]*Err501[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1462     || regcomp(&Err503, "^[ \t]*Err503[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1463     || regcomp(&MaxRequest, "^[ \t]*MaxRequest[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1464     || regcomp(&HeadRemove, "^[ \t]*HeadRemove[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1465     || regcomp(&RewriteLocation, "^[ \t]*RewriteLocation[ \t]+([012])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1466     || regcomp(&RewriteDestination, "^[ \t]*RewriteDestination[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1467     || regcomp(&Service, "^[ \t]*Service[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1468     || regcomp(&ServiceName, "^[ \t]*Service[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1469     || regcomp(&URL, "^[ \t]*URL[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1470     || regcomp(&HeadRequire, "^[ \t]*HeadRequire[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1471     || regcomp(&HeadDeny, "^[ \t]*HeadDeny[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1472     || regcomp(&BackEnd, "^[ \t]*BackEnd[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1473     || regcomp(&Emergency, "^[ \t]*Emergency[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1474     || regcomp(&Priority, "^[ \t]*Priority[ \t]+([1-9])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1475     || regcomp(&TimeOut, "^[ \t]*TimeOut[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1476     || regcomp(&HAport, "^[ \t]*HAport[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1477     || regcomp(&HAportAddr, "^[ \t]*HAport[ \t]+([^ \t]+)[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1478     || regcomp(&Redirect, "^[ \t]*Redirect[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1479     || regcomp(&RedirectN, "^[ \t]*Redirect[ \t]+(30[127])[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1480     || regcomp(&Session, "^[ \t]*Session[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1481     || regcomp(&Type, "^[ \t]*Type[ \t]+([^ \t]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1482     || regcomp(&TTL, "^[ \t]*TTL[ \t]+([1-9-][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1483     || regcomp(&ID, "^[ \t]*ID[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1484     || regcomp(&DynScale, "^[ \t]*DynScale[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1485     || regcomp(&ClientCert, "^[ \t]*ClientCert[ \t]+([0-3])[ \t]+([1-9])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1486     || regcomp(&AddHeader, "^[ \t]*AddHeader[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1487     || regcomp(&SSLAllowClientRenegotiation, "^[ \t]*SSLAllowClientRenegotiation[ \t]+([012])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1488     || regcomp(&DisableProto, "^[ \t]*Disable[ \t]+(SSLv2|SSLv3|TLSv1|TLSv1_1|TLSv1_2)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1489     || regcomp(&SSLHonorCipherOrder, "^[ \t]*SSLHonorCipherOrder[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1490     || regcomp(&Ciphers, "^[ \t]*Ciphers[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1491     || regcomp(&CAlist, "^[ \t]*CAlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1492     || regcomp(&VerifyList, "^[ \t]*VerifyList[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1493     || regcomp(&CRLlist, "^[ \t]*CRLlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1494     || regcomp(&NoHTTPS11, "^[ \t]*NoHTTPS11[ \t]+([0-2])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1495     || regcomp(&Include, "^[ \t]*Include[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1496     || regcomp(&ConnTO, "^[ \t]*ConnTO[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1497     || regcomp(&IgnoreCase, "^[ \t]*IgnoreCase[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1498     || regcomp(&HTTPS, "^[ \t]*HTTPS[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1499     || regcomp(&Disabled, "^[ \t]*Disabled[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1500     || regcomp(&CNName, ".*[Cc][Nn]=([-*.A-Za-z0-9]+).*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1501     || regcomp(&Anonymise, "^[ \t]*Anonymise[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1502 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
1503 #ifndef OPENSSL_NO_ECDH
1504     || regcomp(&ECDHCurve, "^[ \t]*ECDHCurve[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
1505 #endif
1506 #endif
1507     ) {
1508         logmsg(LOG_ERR, "bad config Regex - aborted");
1509         exit(1);
1510     }
1511
1512     opterr = 0;
1513     check_only = 0;
1514     conf_name = F_CONF;
1515     pid_name = F_PID;
1516
1517     while((c_opt = getopt(argc, argv, "f:cvVp:")) > 0)
1518         switch(c_opt) {
1519         case 'f':
1520             conf_name = optarg;
1521             break;
1522         case 'p':
1523             pid_name = optarg;
1524             break;
1525         case 'c':
1526             check_only = 1;
1527             break;
1528         case 'v':
1529             print_log = 1;
1530             break;
1531         case 'V':
1532             print_log = 1;
1533             logmsg(LOG_DEBUG, "Version %s", VERSION);
1534             logmsg(LOG_DEBUG, "  Configuration switches:");
1535 #ifdef  C_SUPER
1536             if(strcmp(C_SUPER, "0"))
1537                 logmsg(LOG_DEBUG, "    --disable-super");
1538 #endif
1539 #ifdef  C_CERT1L
1540             if(strcmp(C_CERT1L, "1"))
1541                 logmsg(LOG_DEBUG, "    --enable-cert1l");
1542 #endif
1543 #ifdef  C_SSL
1544             if(strcmp(C_SSL, ""))
1545                 logmsg(LOG_DEBUG, "    --with-ssl=%s", C_SSL);
1546 #endif
1547 #ifdef  C_T_RSA
1548             if(strcmp(C_T_RSA, "0"))
1549                 logmsg(LOG_DEBUG, "    --with-t_rsa=%s", C_T_RSA);
1550 #endif
1551 #ifdef  C_MAXBUF
1552             if(strcmp(C_MAXBUF, "0"))
1553                 logmsg(LOG_DEBUG, "    --with-maxbuf=%s", C_MAXBUF);
1554 #endif
1555 #ifdef  C_OWNER
1556             if(strcmp(C_OWNER, ""))
1557                 logmsg(LOG_DEBUG, "    --with-owner=%s", C_OWNER);
1558 #endif
1559 #ifdef  C_GROUP
1560             if(strcmp(C_GROUP, ""))
1561                 logmsg(LOG_DEBUG, "    --with-group=%s", C_GROUP);
1562 #endif
1563 #ifdef  C_DH_LEN
1564             if(strcmp(C_DH_LEN, "0"))
1565                 logmsg(LOG_DEBUG, "    --with-dh=%s", C_DH_LEN);
1566 #endif
1567             logmsg(LOG_DEBUG, "Exiting...");
1568             exit(0);
1569             break;
1570         default:
1571             logmsg(LOG_ERR, "bad flag -%c", optopt);
1572             exit(1);
1573             break;
1574         }
1575     if(optind < argc) {
1576         logmsg(LOG_ERR, "unknown extra arguments (%s...)", argv[optind]);
1577         exit(1);
1578     }
1579
1580     conf_init(conf_name);
1581
1582     user = NULL;
1583     group = NULL;
1584     root_jail = NULL;
1585     ctrl_name = NULL;
1586
1587     numthreads = 128;
1588     alive_to = 30;
1589     daemonize = 1;
1590     grace = 30;
1591
1592     services = NULL;
1593     listeners = NULL;
1594
1595     parse_file();
1596
1597     if(check_only) {
1598         logmsg(LOG_INFO, "Config file %s is OK", conf_name);
1599         exit(0);
1600     }
1601
1602     if(listeners == NULL) {
1603         logmsg(LOG_ERR, "no listeners defined - aborted");
1604         exit(1);
1605     }
1606
1607     regfree(&Empty);
1608     regfree(&Comment);
1609     regfree(&User);
1610     regfree(&Group);
1611     regfree(&RootJail);
1612     regfree(&Daemon);
1613     regfree(&Threads);
1614     regfree(&LogFacility);
1615     regfree(&LogLevel);
1616     regfree(&Grace);
1617     regfree(&Alive);
1618     regfree(&SSLEngine);
1619     regfree(&Control);
1620     regfree(&ListenHTTP);
1621     regfree(&ListenHTTPS);
1622     regfree(&End);
1623     regfree(&Address);
1624     regfree(&Port);
1625     regfree(&Cert);
1626     regfree(&xHTTP);
1627     regfree(&Client);
1628     regfree(&CheckURL);
1629     regfree(&Err414);
1630     regfree(&Err500);
1631     regfree(&Err501);
1632     regfree(&Err503);
1633     regfree(&MaxRequest);
1634     regfree(&HeadRemove);
1635     regfree(&RewriteLocation);
1636     regfree(&RewriteDestination);
1637     regfree(&Service);
1638     regfree(&ServiceName);
1639     regfree(&URL);
1640     regfree(&HeadRequire);
1641     regfree(&HeadDeny);
1642     regfree(&BackEnd);
1643     regfree(&Emergency);
1644     regfree(&Priority);
1645     regfree(&TimeOut);
1646     regfree(&HAport);
1647     regfree(&HAportAddr);
1648     regfree(&Redirect);
1649     regfree(&RedirectN);
1650     regfree(&Session);
1651     regfree(&Type);
1652     regfree(&TTL);
1653     regfree(&ID);
1654     regfree(&DynScale);
1655     regfree(&ClientCert);
1656     regfree(&AddHeader);
1657     regfree(&SSLAllowClientRenegotiation);
1658     regfree(&DisableProto);
1659     regfree(&SSLHonorCipherOrder);
1660     regfree(&Ciphers);
1661     regfree(&CAlist);
1662     regfree(&VerifyList);
1663     regfree(&CRLlist);
1664     regfree(&NoHTTPS11);
1665     regfree(&Include);
1666     regfree(&ConnTO);
1667     regfree(&IgnoreCase);
1668     regfree(&HTTPS);
1669     regfree(&Disabled);
1670     regfree(&CNName);
1671     regfree(&Anonymise);
1672 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
1673 #ifndef OPENSSL_NO_ECDH
1674     regfree(&ECDHCurve);
1675 #endif
1676 #endif
1677
1678     /* set the facility only here to ensure the syslog gets opened if necessary */
1679     log_facility = def_facility;
1680
1681     return;
1682 }