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