]> granicus.if.org Git - apache/blob - modules/ssl/ssl_engine_config.c
drop SSLv2 support (set SSL_OP_NO_SSLv2 for any new SSL_CTX)
[apache] / modules / ssl / ssl_engine_config.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*                      _             _
18  *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
19  * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
20  * | | | | | | (_) | (_| |   \__ \__ \ |
21  * |_| |_| |_|\___/ \__,_|___|___/___/_|
22  *                      |_____|
23  *  ssl_engine_config.c
24  *  Apache Configuration Directives
25  */
26                                       /* ``Damned if you do,
27                                            damned if you don't.''
28                                                -- Unknown        */
29 #include "ssl_private.h"
30 #include "util_mutex.h"
31 #include "ap_provider.h"
32
33 /*  _________________________________________________________________
34 **
35 **  Support for Global Configuration
36 **  _________________________________________________________________
37 */
38
39 #define SSL_MOD_CONFIG_KEY "ssl_module"
40
41 SSLModConfigRec *ssl_config_global_create(server_rec *s)
42 {
43     apr_pool_t *pool = s->process->pool;
44     SSLModConfigRec *mc;
45     void *vmc;
46
47     apr_pool_userdata_get(&vmc, SSL_MOD_CONFIG_KEY, pool);
48     if (vmc) {
49         return vmc; /* reused for lifetime of the server */
50     }
51
52     /*
53      * allocate an own subpool which survives server restarts
54      */
55     mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc));
56     mc->pPool = pool;
57     mc->bFixed = FALSE;
58
59     /*
60      * initialize per-module configuration
61      */
62     mc->sesscache_mode         = SSL_SESS_CACHE_OFF;
63     mc->sesscache              = NULL;
64     mc->pMutex                 = NULL;
65     mc->aRandSeed              = apr_array_make(pool, 4,
66                                                 sizeof(ssl_randseed_t));
67     mc->tVHostKeys             = apr_hash_make(pool);
68     mc->tPrivateKey            = apr_hash_make(pool);
69     mc->tPublicCert            = apr_hash_make(pool);
70 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
71     mc->szCryptoDevice         = NULL;
72 #endif
73 #ifdef HAVE_OCSP_STAPLING
74     mc->stapling_cache         = NULL;
75     mc->stapling_mutex         = NULL;
76 #endif
77
78     memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
79
80     apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
81                           apr_pool_cleanup_null,
82                           pool);
83
84     return mc;
85 }
86
87 void ssl_config_global_fix(SSLModConfigRec *mc)
88 {
89     mc->bFixed = TRUE;
90 }
91
92 BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
93 {
94     return mc->bFixed;
95 }
96
97 /*  _________________________________________________________________
98 **
99 **  Configuration handling
100 **  _________________________________________________________________
101 */
102
103 static void modssl_ctx_init(modssl_ctx_t *mctx)
104 {
105     mctx->sc                  = NULL; /* set during module init */
106
107     mctx->ssl_ctx             = NULL; /* set during module init */
108
109     mctx->pks                 = NULL;
110     mctx->pkp                 = NULL;
111
112     mctx->protocol            = SSL_PROTOCOL_ALL;
113
114     mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
115     mctx->pphrase_dialog_path = NULL;
116
117     mctx->pkcs7               = NULL;
118     mctx->cert_chain          = NULL;
119
120     mctx->crl_path            = NULL;
121     mctx->crl_file            = NULL;
122     mctx->crl_check_mode      = SSL_CRLCHECK_UNSET;
123
124     mctx->auth.ca_cert_path   = NULL;
125     mctx->auth.ca_cert_file   = NULL;
126     mctx->auth.cipher_suite   = NULL;
127     mctx->auth.verify_depth   = UNSET;
128     mctx->auth.verify_mode    = SSL_CVERIFY_UNSET;
129
130     mctx->ocsp_enabled        = FALSE;
131     mctx->ocsp_force_default  = FALSE;
132     mctx->ocsp_responder      = NULL;
133     mctx->ocsp_resptime_skew  = UNSET;
134     mctx->ocsp_resp_maxage    = UNSET;
135     mctx->ocsp_responder_timeout = UNSET;
136
137 #ifdef HAVE_OCSP_STAPLING
138     mctx->stapling_enabled           = UNSET;
139     mctx->stapling_resptime_skew     = UNSET;
140     mctx->stapling_resp_maxage       = UNSET;
141     mctx->stapling_cache_timeout     = UNSET;
142     mctx->stapling_return_errors     = UNSET;
143     mctx->stapling_fake_trylater     = UNSET;
144     mctx->stapling_errcache_timeout  = UNSET;
145     mctx->stapling_responder_timeout = UNSET;
146     mctx->stapling_force_url         = NULL;
147 #endif
148 }
149
150 static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
151                                   apr_pool_t *p)
152 {
153     modssl_ctx_t *mctx;
154
155     mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy));
156
157     modssl_ctx_init(mctx);
158
159     mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
160
161     mctx->pkp->cert_file = NULL;
162     mctx->pkp->cert_path = NULL;
163     mctx->pkp->ca_cert_file = NULL;
164     mctx->pkp->certs     = NULL;
165     mctx->pkp->ca_certs  = NULL;
166 }
167
168 static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
169                                    apr_pool_t *p)
170 {
171     modssl_ctx_t *mctx;
172
173     mctx = sc->server = apr_palloc(p, sizeof(*sc->server));
174
175     modssl_ctx_init(mctx);
176
177     mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks));
178
179     /* mctx->pks->... certs/keys are set during module init */
180 }
181
182 static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
183 {
184     SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
185
186     sc->mc                     = NULL;
187     sc->enabled                = SSL_ENABLED_FALSE;
188     sc->proxy_enabled          = UNSET;
189     sc->vhost_id               = NULL;  /* set during module init */
190     sc->vhost_id_len           = 0;     /* set during module init */
191     sc->session_cache_timeout  = UNSET;
192     sc->cipher_server_pref     = UNSET;
193     sc->insecure_reneg         = UNSET;
194     sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET;
195     sc->proxy_ssl_check_peer_cn     = SSL_ENABLED_UNSET;
196 #ifndef OPENSSL_NO_TLSEXT
197     sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
198 #endif
199 #ifdef HAVE_FIPS
200     sc->fips                   = UNSET;
201 #endif
202
203 #ifdef HAVE_TLSEXT_TICKETS
204     sc->default_ticket_name = NULL;
205     sc->default_ticket = NULL;
206     sc->tickets = apr_array_make(p, 4, sizeof(modssl_ticket_t*));
207 #endif
208
209     modssl_ctx_init_proxy(sc, p);
210
211     modssl_ctx_init_server(sc, p);
212
213     return sc;
214 }
215
216 /*
217  *  Create per-server SSL configuration
218  */
219 void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
220 {
221     SSLSrvConfigRec *sc = ssl_config_server_new(p);
222
223     sc->mc = ssl_config_global_create(s);
224
225     return sc;
226 }
227
228 #define cfgMerge(el,unset)  mrg->el = (add->el == (unset)) ? base->el : add->el
229 #define cfgMergeArray(el)   mrg->el = apr_array_append(p, add->el, base->el)
230 #define cfgMergeString(el)  cfgMerge(el, NULL)
231 #define cfgMergeBool(el)    cfgMerge(el, UNSET)
232 #define cfgMergeInt(el)     cfgMerge(el, UNSET)
233
234 static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
235                                  modssl_ctx_t *add,
236                                  modssl_ctx_t *mrg)
237 {
238     cfgMerge(protocol, SSL_PROTOCOL_ALL);
239
240     cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
241     cfgMergeString(pphrase_dialog_path);
242
243     cfgMergeString(cert_chain);
244
245     cfgMerge(crl_path, NULL);
246     cfgMerge(crl_file, NULL);
247     cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET);
248
249     cfgMergeString(auth.ca_cert_path);
250     cfgMergeString(auth.ca_cert_file);
251     cfgMergeString(auth.cipher_suite);
252     cfgMergeInt(auth.verify_depth);
253     cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
254
255     cfgMergeBool(ocsp_enabled);
256     cfgMergeBool(ocsp_force_default);
257     cfgMerge(ocsp_responder, NULL);
258     cfgMergeInt(ocsp_resptime_skew);
259     cfgMergeInt(ocsp_resp_maxage);
260     cfgMergeInt(ocsp_responder_timeout);
261 #ifdef HAVE_OCSP_STAPLING
262     cfgMergeBool(stapling_enabled);
263     cfgMergeInt(stapling_resptime_skew);
264     cfgMergeInt(stapling_resp_maxage);
265     cfgMergeInt(stapling_cache_timeout);
266     cfgMergeBool(stapling_return_errors);
267     cfgMergeBool(stapling_fake_trylater);
268     cfgMergeInt(stapling_errcache_timeout);
269     cfgMergeInt(stapling_responder_timeout);
270     cfgMerge(stapling_force_url, NULL);
271 #endif
272 }
273
274 static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
275                                        modssl_ctx_t *add,
276                                        modssl_ctx_t *mrg)
277 {
278     modssl_ctx_cfg_merge(base, add, mrg);
279
280     cfgMergeString(pkp->cert_file);
281     cfgMergeString(pkp->cert_path);
282     cfgMergeString(pkp->ca_cert_file);
283 }
284
285 static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
286                                         modssl_ctx_t *add,
287                                         modssl_ctx_t *mrg)
288 {
289     int i;
290
291     modssl_ctx_cfg_merge(base, add, mrg);
292
293     for (i = 0; i < SSL_AIDX_MAX; i++) {
294         cfgMergeString(pks->cert_files[i]);
295         cfgMergeString(pks->key_files[i]);
296     }
297
298     cfgMergeString(pks->ca_name_path);
299     cfgMergeString(pks->ca_name_file);
300 }
301
302 /*
303  *  Merge per-server SSL configurations
304  */
305 void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
306 {
307     SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
308     SSLSrvConfigRec *add  = (SSLSrvConfigRec *)addv;
309     SSLSrvConfigRec *mrg  = ssl_config_server_new(p);
310
311     cfgMerge(mc, NULL);
312     cfgMerge(enabled, SSL_ENABLED_UNSET);
313 #ifdef HAVE_TLSEXT_TICKETS
314     cfgMergeString(default_ticket_name);
315     apr_array_cat(mrg->tickets, base->tickets);
316     apr_array_cat(mrg->tickets, add->tickets);
317 #endif
318     cfgMergeBool(proxy_enabled);
319     cfgMergeInt(session_cache_timeout);
320     cfgMergeBool(cipher_server_pref);
321     cfgMergeBool(insecure_reneg);
322     cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET);
323     cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET);
324 #ifndef OPENSSL_NO_TLSEXT
325     cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
326 #endif
327 #ifdef HAVE_FIPS
328     cfgMergeBool(fips);
329 #endif
330
331     modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
332
333     modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server);
334
335     return mrg;
336 }
337
338 /*
339  *  Create per-directory SSL configuration
340  */
341 void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
342 {
343     SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
344
345     dc->bSSLRequired  = FALSE;
346     dc->aRequirement  = apr_array_make(p, 4, sizeof(ssl_require_t));
347     dc->nOptions      = SSL_OPT_NONE|SSL_OPT_RELSET;
348     dc->nOptionsAdd   = SSL_OPT_NONE;
349     dc->nOptionsDel   = SSL_OPT_NONE;
350
351     dc->szCipherSuite          = NULL;
352     dc->nVerifyClient          = SSL_CVERIFY_UNSET;
353     dc->nVerifyDepth           = UNSET;
354
355     dc->szCACertificatePath    = NULL;
356     dc->szCACertificateFile    = NULL;
357     dc->szUserName             = NULL;
358
359     dc->nRenegBufferSize = UNSET;
360
361     return dc;
362 }
363
364 /*
365  *  Merge per-directory SSL configurations
366  */
367 void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
368 {
369     SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
370     SSLDirConfigRec *add  = (SSLDirConfigRec *)addv;
371     SSLDirConfigRec *mrg  = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
372
373     cfgMerge(bSSLRequired, FALSE);
374     cfgMergeArray(aRequirement);
375
376     if (add->nOptions & SSL_OPT_RELSET) {
377         mrg->nOptionsAdd =
378             (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
379         mrg->nOptionsDel =
380             (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
381         mrg->nOptions    =
382             (base->nOptions    & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd;
383     }
384     else {
385         mrg->nOptions    = add->nOptions;
386         mrg->nOptionsAdd = add->nOptionsAdd;
387         mrg->nOptionsDel = add->nOptionsDel;
388     }
389
390     cfgMergeString(szCipherSuite);
391     cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
392     cfgMergeInt(nVerifyDepth);
393
394     cfgMergeString(szCACertificatePath);
395     cfgMergeString(szCACertificateFile);
396     cfgMergeString(szUserName);
397
398     cfgMergeInt(nRenegBufferSize);
399
400     return mrg;
401 }
402
403 /*
404  *  Configuration functions for particular directives
405  */
406
407 const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
408                                         void *dcfg,
409                                         const char *arg)
410 {
411     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
412     const char *err;
413     int arglen = strlen(arg);
414
415     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
416         return err;
417     }
418
419     if (strcEQ(arg, "builtin")) {
420         sc->server->pphrase_dialog_type  = SSL_PPTYPE_BUILTIN;
421         sc->server->pphrase_dialog_path = NULL;
422     }
423     else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
424         sc->server->pphrase_dialog_type  = SSL_PPTYPE_FILTER;
425         sc->server->pphrase_dialog_path =
426             ap_server_root_relative(cmd->pool, arg+5);
427         if (!sc->server->pphrase_dialog_path) {
428             return apr_pstrcat(cmd->pool,
429                                "Invalid SSLPassPhraseDialog exec: path ",
430                                arg+5, NULL);
431         }
432         if (!ssl_util_path_check(SSL_PCM_EXISTS,
433                                  sc->server->pphrase_dialog_path,
434                                  cmd->pool))
435         {
436             return apr_pstrcat(cmd->pool,
437                                "SSLPassPhraseDialog: file '",
438                                sc->server->pphrase_dialog_path,
439                                "' does not exist", NULL);
440         }
441
442     }
443     else if ((arglen > 1) && (arg[0] == '|')) {
444         sc->server->pphrase_dialog_type  = SSL_PPTYPE_PIPE;
445         sc->server->pphrase_dialog_path = arg + 1;
446     }
447     else {
448         return "SSLPassPhraseDialog: Invalid argument";
449     }
450
451     return NULL;
452 }
453
454 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
455 const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
456                                     void *dcfg,
457                                     const char *arg)
458 {
459     SSLModConfigRec *mc = myModConfig(cmd->server);
460     const char *err;
461     ENGINE *e;
462
463     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
464         return err;
465     }
466
467     if (strcEQ(arg, "builtin")) {
468         mc->szCryptoDevice = NULL;
469     }
470     else if ((e = ENGINE_by_id(arg))) {
471         mc->szCryptoDevice = arg;
472         ENGINE_free(e);
473     }
474     else {
475         err = "SSLCryptoDevice: Invalid argument; must be one of: "
476               "'builtin' (none)";
477         e = ENGINE_get_first();
478         while (e) {
479             err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e),
480                                          "' (", ENGINE_get_name(e), ")", NULL);
481             /* Iterate; this call implicitly decrements the refcount
482              * on the 'old' e, per the docs in engine.h. */
483             e = ENGINE_get_next(e);
484         }
485         return err;
486     }
487
488     return NULL;
489 }
490 #endif
491
492 const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
493                                   void *dcfg,
494                                   const char *arg1,
495                                   const char *arg2,
496                                   const char *arg3)
497 {
498     SSLModConfigRec *mc = myModConfig(cmd->server);
499     const char *err;
500     ssl_randseed_t *seed;
501     int arg2len = strlen(arg2);
502
503     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
504         return err;
505     }
506
507     if (ssl_config_global_isfixed(mc)) {
508         return NULL;
509     }
510
511     seed = apr_array_push(mc->aRandSeed);
512
513     if (strcEQ(arg1, "startup")) {
514         seed->nCtx = SSL_RSCTX_STARTUP;
515     }
516     else if (strcEQ(arg1, "connect")) {
517         seed->nCtx = SSL_RSCTX_CONNECT;
518     }
519     else {
520         return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
521                            "invalid context: `", arg1, "'",
522                            NULL);
523     }
524
525     if ((arg2len > 5) && strEQn(arg2, "file:", 5)) {
526         seed->nSrc   = SSL_RSSRC_FILE;
527         seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
528     }
529     else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) {
530         seed->nSrc   = SSL_RSSRC_EXEC;
531         seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
532     }
533     else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
534         seed->nSrc   = SSL_RSSRC_EGD;
535         seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
536     }
537     else if (strcEQ(arg2, "builtin")) {
538         seed->nSrc   = SSL_RSSRC_BUILTIN;
539         seed->cpPath = NULL;
540     }
541     else {
542         seed->nSrc   = SSL_RSSRC_FILE;
543         seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
544     }
545
546     if (seed->nSrc != SSL_RSSRC_BUILTIN) {
547         if (!seed->cpPath) {
548             return apr_pstrcat(cmd->pool,
549                                "Invalid SSLRandomSeed path ",
550                                arg2, NULL);
551         }
552         if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) {
553             return apr_pstrcat(cmd->pool,
554                                "SSLRandomSeed: source path '",
555                                seed->cpPath, "' does not exist", NULL);
556         }
557     }
558
559     if (!arg3) {
560         seed->nBytes = 0; /* read whole file */
561     }
562     else {
563         if (seed->nSrc == SSL_RSSRC_BUILTIN) {
564             return "SSLRandomSeed: byte specification not "
565                    "allowed for builtin seed source";
566         }
567
568         seed->nBytes = atoi(arg3);
569
570         if (seed->nBytes < 0) {
571             return "SSLRandomSeed: invalid number of bytes specified";
572         }
573     }
574
575     return NULL;
576 }
577
578 const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
579 {
580     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
581
582     if (!strcasecmp(arg, "On")) {
583         sc->enabled = SSL_ENABLED_TRUE;
584     return NULL;
585     }
586     else if (!strcasecmp(arg, "Off")) {
587         sc->enabled = SSL_ENABLED_FALSE;
588         return NULL;
589     }
590     else if (!strcasecmp(arg, "Optional")) {
591         sc->enabled = SSL_ENABLED_OPTIONAL;
592         return NULL;
593     }
594
595     return "Argument must be On, Off, or Optional";
596 }
597
598 const char *ssl_cmd_SSLTicketKeyDefault(cmd_parms *cmd, void *dcfg, const char *name)
599 {
600 #ifdef HAVE_TLSEXT_TICKETS
601     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
602
603     sc->default_ticket_name = name;
604
605     return NULL;
606 #else
607     return "TLS Ticket keys are not supported.";
608 #endif
609 }
610
611 const char *ssl_cmd_SSLTicketKeyFile(cmd_parms *cmd, void *dcfg, const char *name, const char *path)
612 {
613 #ifdef HAVE_TLSEXT_TICKETS
614     apr_status_t rv;
615     apr_file_t *fp;
616     apr_size_t len;
617     char buf[TLSEXT_TICKET_KEYLEN];
618     modssl_ticket_t* ticket = NULL;
619     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
620
621     path = ap_server_root_relative(cmd->pool, path);
622
623     rv = apr_file_open(&fp, path, APR_READ|APR_BINARY,
624                        APR_OS_DEFAULT, cmd->temp_pool);
625
626     if (rv != APR_SUCCESS) {
627         return apr_psprintf(cmd->pool,
628                             "Failed to open %s: (%d) %pm",
629                             path, rv, &rv);
630     }
631
632     rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEYLEN, &len);
633
634     if (rv != APR_SUCCESS) {
635         return apr_psprintf(cmd->pool,
636                             "Failed to read at least 48 bytes from %s: (%d) %pm",
637                             path, rv, &rv);
638     }
639
640     ticket = apr_palloc(cmd->pool, sizeof(modssl_ticket_t));
641
642     ticket->conf_name = name;
643
644     memcpy(ticket->key_name, buf, 16);
645     memcpy(ticket->hmac_secret, buf + 16, 16);
646     memcpy(ticket->aes_key, buf + 32, 16);
647
648     APR_ARRAY_PUSH(sc->tickets, modssl_ticket_t*) = ticket;
649
650     return NULL;
651 #else
652     return "TLS Ticket keys are not supported.";
653 #endif
654 }
655
656 const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
657 {
658 #ifdef HAVE_FIPS
659     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
660 #endif
661     const char *err;
662
663     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
664         return err;
665     }
666
667 #ifdef HAVE_FIPS
668     if ((sc->fips != UNSET) && (sc->fips != (BOOL)(flag ? TRUE : FALSE)))
669         return "Conflicting SSLFIPS options, cannot be both On and Off";
670     sc->fips = flag ? TRUE : FALSE;
671 #else
672     if (flag)
673         return "SSLFIPS invalid, rebuild httpd and openssl compiled for FIPS";
674 #endif
675
676     return NULL;
677 }
678
679 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
680                                    void *dcfg,
681                                    const char *arg)
682 {
683     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
684     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
685
686     if (cmd->path) {
687         dc->szCipherSuite = arg;
688     }
689     else {
690         sc->server->auth.cipher_suite = arg;
691     }
692
693     return NULL;
694 }
695
696 #define SSL_FLAGS_CHECK_FILE \
697     (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
698
699 #define SSL_FLAGS_CHECK_DIR \
700     (SSL_PCM_EXISTS|SSL_PCM_ISDIR)
701
702 static const char *ssl_cmd_check_file(cmd_parms *parms,
703                                       const char **file)
704 {
705     const char *filepath = ap_server_root_relative(parms->pool, *file);
706
707     if (!filepath) {
708         return apr_pstrcat(parms->pool, parms->cmd->name,
709                            ": Invalid file path ", *file, NULL);
710     }
711     *file = filepath;
712
713     if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
714         return NULL;
715     }
716
717     return apr_pstrcat(parms->pool, parms->cmd->name,
718                        ": file '", *file,
719                        "' does not exist or is empty", NULL);
720
721 }
722
723 const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
724 {
725 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
726     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
727     sc->cipher_server_pref = flag?TRUE:FALSE;
728     return NULL;
729 #else
730     return "SSLHonorCiperOrder unsupported; not implemented by the SSL library";
731 #endif
732 }
733
734 const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag)
735 {
736 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
737     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
738     sc->insecure_reneg = flag?TRUE:FALSE;
739     return NULL;
740 #else
741     return "The SSLInsecureRenegotiation directive is not available "
742         "with this SSL library";
743 #endif
744 }
745
746
747 static const char *ssl_cmd_check_dir(cmd_parms *parms,
748                                      const char **dir)
749 {
750     const char *dirpath = ap_server_root_relative(parms->pool, *dir);
751
752     if (!dirpath) {
753         return apr_pstrcat(parms->pool, parms->cmd->name,
754                            ": Invalid dir path ", *dir, NULL);
755     }
756     *dir = dirpath;
757
758     if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
759         return NULL;
760     }
761
762     return apr_pstrcat(parms->pool, parms->cmd->name,
763                        ": directory '", *dir,
764                        "' does not exist", NULL);
765
766 }
767
768 #define SSL_AIDX_CERTS 1
769 #define SSL_AIDX_KEYS  2
770
771 static const char *ssl_cmd_check_aidx_max(cmd_parms *parms,
772                                           const char *arg,
773                                           int idx)
774 {
775     SSLSrvConfigRec *sc = mySrvConfig(parms->server);
776     const char *err, *desc=NULL, **files=NULL;
777     int i;
778
779     if ((err = ssl_cmd_check_file(parms, &arg))) {
780         return err;
781     }
782
783     switch (idx) {
784       case SSL_AIDX_CERTS:
785         desc = "certificates";
786         files = sc->server->pks->cert_files;
787         break;
788       case SSL_AIDX_KEYS:
789         desc = "private keys";
790         files = sc->server->pks->key_files;
791         break;
792     }
793
794     for (i = 0; i < SSL_AIDX_MAX; i++) {
795         if (!files[i]) {
796             files[i] = arg;
797             return NULL;
798         }
799     }
800
801     return apr_psprintf(parms->pool,
802                         "%s: only up to %d "
803                         "different %s per virtual host allowed",
804                          parms->cmd->name, SSL_AIDX_MAX, desc);
805 }
806
807 const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
808                                        void *dcfg,
809                                        const char *arg)
810 {
811
812     const char *err;
813
814     if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) {
815         return err;
816     }
817
818     return NULL;
819 }
820
821 const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
822                                           void *dcfg,
823                                           const char *arg)
824 {
825     const char *err;
826
827     if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) {
828         return err;
829     }
830
831     return NULL;
832 }
833
834 const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
835                                             void *dcfg,
836                                             const char *arg)
837 {
838     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
839     const char *err;
840
841     if ((err = ssl_cmd_check_file(cmd, &arg))) {
842         return err;
843     }
844
845     sc->server->cert_chain = arg;
846
847     return NULL;
848 }
849
850 const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *cmd,
851                                             void *dcfg,
852                                             const char *arg)
853 {
854     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
855     const char *err;
856
857     if ((err = ssl_cmd_check_file(cmd, &arg))) {
858         return err;
859     }
860
861     sc->server->pkcs7 = arg;
862
863     return NULL;
864 }
865
866 #define NO_PER_DIR_SSL_CA \
867     "Your SSL library does not have support for per-directory CA"
868
869 const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
870                                          void *dcfg,
871                                          const char *arg)
872 {
873     /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
874     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
875     const char *err;
876
877     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
878         return err;
879     }
880
881     if (cmd->path) {
882         return NO_PER_DIR_SSL_CA;
883     }
884
885     /* XXX: bring back per-dir */
886     sc->server->auth.ca_cert_path = arg;
887
888     return NULL;
889 }
890
891 const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
892                                          void *dcfg,
893                                          const char *arg)
894 {
895     /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
896     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
897     const char *err;
898
899     if ((err = ssl_cmd_check_file(cmd, &arg))) {
900         return err;
901     }
902
903     if (cmd->path) {
904         return NO_PER_DIR_SSL_CA;
905     }
906
907     /* XXX: bring back per-dir */
908     sc->server->auth.ca_cert_file = arg;
909
910     return NULL;
911 }
912
913 const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg,
914                                        const char *arg)
915 {
916     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
917     const char *err;
918
919     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
920         return err;
921     }
922
923     sc->server->pks->ca_name_path = arg;
924
925     return NULL;
926 }
927
928 const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg,
929                                        const char *arg)
930 {
931     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
932     const char *err;
933
934     if ((err = ssl_cmd_check_file(cmd, &arg))) {
935         return err;
936     }
937
938     sc->server->pks->ca_name_file = arg;
939
940     return NULL;
941 }
942
943 const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
944                                         void *dcfg,
945                                         const char *arg)
946 {
947     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
948     const char *err;
949
950     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
951         return err;
952     }
953
954     sc->server->crl_path = arg;
955
956     return NULL;
957 }
958
959 const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
960                                         void *dcfg,
961                                         const char *arg)
962 {
963     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
964     const char *err;
965
966     if ((err = ssl_cmd_check_file(cmd, &arg))) {
967         return err;
968     }
969
970     sc->server->crl_file = arg;
971
972     return NULL;
973 }
974
975 static const char *ssl_cmd_crlcheck_parse(cmd_parms *parms,
976                                           const char *arg,
977                                           ssl_crlcheck_t *mode)
978 {
979     if (strcEQ(arg, "none")) {
980         *mode = SSL_CRLCHECK_NONE;
981     }
982     else if (strcEQ(arg, "leaf")) {
983         *mode = SSL_CRLCHECK_LEAF;
984     }
985     else if (strcEQ(arg, "chain")) {
986         *mode = SSL_CRLCHECK_CHAIN;
987     }
988     else {
989         return apr_pstrcat(parms->temp_pool, parms->cmd->name,
990                            ": Invalid argument '", arg, "'",
991                            NULL);
992     }
993
994     return NULL;
995 }
996
997 const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd,
998                                          void *dcfg,
999                                          const char *arg)
1000 {
1001     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1002
1003     return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mode);
1004 }
1005
1006 static const char *ssl_cmd_verify_parse(cmd_parms *parms,
1007                                         const char *arg,
1008                                         ssl_verify_t *id)
1009 {
1010     if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
1011         *id = SSL_CVERIFY_NONE;
1012     }
1013     else if (strcEQ(arg, "optional")) {
1014         *id = SSL_CVERIFY_OPTIONAL;
1015     }
1016     else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
1017         *id = SSL_CVERIFY_REQUIRE;
1018     }
1019     else if (strcEQ(arg, "optional_no_ca")) {
1020         *id = SSL_CVERIFY_OPTIONAL_NO_CA;
1021     }
1022     else {
1023         return apr_pstrcat(parms->temp_pool, parms->cmd->name,
1024                            ": Invalid argument '", arg, "'",
1025                            NULL);
1026     }
1027
1028     return NULL;
1029 }
1030
1031 const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd,
1032                                     void *dcfg,
1033                                     const char *arg)
1034 {
1035     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1036     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1037     ssl_verify_t mode;
1038     const char *err;
1039
1040     if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
1041         return err;
1042     }
1043
1044     if (cmd->path) {
1045         dc->nVerifyClient = mode;
1046     }
1047     else {
1048         sc->server->auth.verify_mode = mode;
1049     }
1050
1051     return NULL;
1052 }
1053
1054 static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
1055                                               const char *arg,
1056                                               int *depth)
1057 {
1058     if ((*depth = atoi(arg)) >= 0) {
1059         return NULL;
1060     }
1061
1062     return apr_pstrcat(parms->temp_pool, parms->cmd->name,
1063                        ": Invalid argument '", arg, "'",
1064                        NULL);
1065 }
1066
1067 const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
1068                                    void *dcfg,
1069                                    const char *arg)
1070 {
1071     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1072     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1073     int depth;
1074     const char *err;
1075
1076     if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1077         return err;
1078     }
1079
1080     if (cmd->path) {
1081         dc->nVerifyDepth = depth;
1082     }
1083     else {
1084         sc->server->auth.verify_depth = depth;
1085     }
1086
1087     return NULL;
1088 }
1089
1090 const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
1091                                     void *dcfg,
1092                                     const char *arg)
1093 {
1094     SSLModConfigRec *mc = myModConfig(cmd->server);
1095     const char *err, *sep, *name;
1096     long enabled_flags;
1097
1098     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
1099         return err;
1100     }
1101
1102     /* The OpenSSL session cache mode must have both the flags
1103      * SSL_SESS_CACHE_SERVER and SSL_SESS_CACHE_NO_INTERNAL set if a
1104      * session cache is configured; NO_INTERNAL prevents the
1105      * OpenSSL-internal session cache being used in addition to the
1106      * "external" (mod_ssl-provided) cache, which otherwise causes
1107      * additional memory consumption. */
1108     enabled_flags = SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL;
1109
1110     if (strcEQ(arg, "none")) {
1111         /* Nothing to do; session cache will be off. */
1112     }
1113     else if (strcEQ(arg, "nonenotnull")) {
1114         /* ### Having a separate mode for this seems logically
1115          * unnecessary; the stated purpose of sending non-empty
1116          * session IDs would be better fixed in OpenSSL or simply
1117          * doing it by default if "none" is used. */
1118         mc->sesscache_mode = enabled_flags;
1119     }
1120     else {
1121         /* Argument is of form 'name:args' or just 'name'. */
1122         sep = ap_strchr_c(arg, ':');
1123         if (sep) {
1124             name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
1125             sep++;
1126         }
1127         else {
1128             name = arg;
1129         }
1130
1131         /* Find the provider of given name. */
1132         mc->sesscache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
1133                                            name,
1134                                            AP_SOCACHE_PROVIDER_VERSION);
1135         if (mc->sesscache) {
1136             /* Cache found; create it, passing anything beyond the colon. */
1137             mc->sesscache_mode = enabled_flags;
1138             err = mc->sesscache->create(&mc->sesscache_context, sep,
1139                                         cmd->temp_pool, cmd->pool);
1140         }
1141         else {
1142             apr_array_header_t *name_list;
1143             const char *all_names;
1144
1145             /* Build a comma-separated list of all registered provider
1146              * names: */
1147             name_list = ap_list_provider_names(cmd->pool,
1148                                                AP_SOCACHE_PROVIDER_GROUP,
1149                                                AP_SOCACHE_PROVIDER_VERSION);
1150             all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
1151
1152             err = apr_psprintf(cmd->pool, "'%s' session cache not supported "
1153                                "(known names: %s)", name, all_names);
1154         }
1155     }
1156
1157     if (err) {
1158         return apr_psprintf(cmd->pool, "SSLSessionCache: %s", err);
1159     }
1160
1161     return NULL;
1162 }
1163
1164 const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd,
1165                                            void *dcfg,
1166                                            const char *arg)
1167 {
1168     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1169
1170     sc->session_cache_timeout = atoi(arg);
1171
1172     if (sc->session_cache_timeout < 0) {
1173         return "SSLSessionCacheTimeout: Invalid argument";
1174     }
1175
1176     return NULL;
1177 }
1178
1179 const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
1180                                void *dcfg,
1181                                const char *arg)
1182 {
1183     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1184     ssl_opt_t opt;
1185     int first = TRUE;
1186     char action, *w;
1187
1188     while (*arg) {
1189         w = ap_getword_conf(cmd->temp_pool, &arg);
1190         action = NUL;
1191
1192         if ((*w == '+') || (*w == '-')) {
1193             action = *(w++);
1194         }
1195         else if (first) {
1196             dc->nOptions = SSL_OPT_NONE;
1197             first = FALSE;
1198         }
1199
1200         if (strcEQ(w, "StdEnvVars")) {
1201             opt = SSL_OPT_STDENVVARS;
1202         }
1203         else if (strcEQ(w, "ExportCertData")) {
1204             opt = SSL_OPT_EXPORTCERTDATA;
1205         }
1206         else if (strcEQ(w, "FakeBasicAuth")) {
1207             opt = SSL_OPT_FAKEBASICAUTH;
1208         }
1209         else if (strcEQ(w, "StrictRequire")) {
1210             opt = SSL_OPT_STRICTREQUIRE;
1211         }
1212         else if (strcEQ(w, "OptRenegotiate")) {
1213             opt = SSL_OPT_OPTRENEGOTIATE;
1214         }
1215         else if (strcEQ(w, "LegacyDNStringFormat")) {
1216             opt = SSL_OPT_LEGACYDNFORMAT;
1217         }
1218         else {
1219             return apr_pstrcat(cmd->pool,
1220                                "SSLOptions: Illegal option '", w, "'",
1221                                NULL);
1222         }
1223
1224         if (action == '-') {
1225             dc->nOptionsAdd &= ~opt;
1226             dc->nOptionsDel |=  opt;
1227             dc->nOptions    &= ~opt;
1228         }
1229         else if (action == '+') {
1230             dc->nOptionsAdd |=  opt;
1231             dc->nOptionsDel &= ~opt;
1232             dc->nOptions    |=  opt;
1233         }
1234         else {
1235             dc->nOptions    = opt;
1236             dc->nOptionsAdd = opt;
1237             dc->nOptionsDel = SSL_OPT_NONE;
1238         }
1239     }
1240
1241     return NULL;
1242 }
1243
1244 const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg)
1245 {
1246     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1247
1248     dc->bSSLRequired = TRUE;
1249
1250     return NULL;
1251 }
1252
1253 const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
1254                                void *dcfg,
1255                                const char *arg)
1256 {
1257     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1258     ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
1259     ssl_require_t *require;
1260     const char *errstring;
1261
1262     info->flags = AP_EXPR_FLAG_SSL_EXPR_COMPAT;
1263     info->filename = cmd->directive->filename;
1264     info->line_number = cmd->directive->line_num;
1265     info->module_index = APLOG_MODULE_INDEX;
1266     errstring = ap_expr_parse(cmd->pool, cmd->temp_pool, info, arg, NULL);
1267     if (errstring) {
1268         return apr_pstrcat(cmd->pool, "SSLRequire: ", errstring, NULL);
1269     }
1270
1271     require = apr_array_push(dc->aRequirement);
1272     require->cpExpr = apr_pstrdup(cmd->pool, arg);
1273     require->mpExpr = info;
1274
1275     return NULL;
1276 }
1277
1278 const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg)
1279 {
1280     SSLDirConfigRec *dc = dcfg;
1281     int val;
1282
1283     val = atoi(arg);
1284     if (val < 0) {
1285         return apr_pstrcat(cmd->pool, "Invalid size for SSLRenegBufferSize: ",
1286                            arg, NULL);
1287     }
1288     dc->nRenegBufferSize = val;
1289
1290     return NULL;
1291 }
1292
1293 static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
1294                                           const char *arg,
1295                                           ssl_proto_t *options)
1296 {
1297     ssl_proto_t thisopt;
1298
1299     *options = SSL_PROTOCOL_NONE;
1300
1301     while (*arg) {
1302         char *w = ap_getword_conf(parms->temp_pool, &arg);
1303         char action = '\0';
1304
1305         if ((*w == '+') || (*w == '-')) {
1306             action = *(w++);
1307         }
1308
1309         if (strcEQ(w, "SSLv2")) {
1310             if (action == '-') {
1311                 continue;
1312             }
1313             else {
1314                 return "SSLProtocol: SSLv2 is no longer supported";
1315             }
1316         }
1317         else if (strcEQ(w, "SSLv3")) {
1318             thisopt = SSL_PROTOCOL_SSLV3;
1319         }
1320         else if (strcEQ(w, "TLSv1")) {
1321             thisopt = SSL_PROTOCOL_TLSV1;
1322         }
1323         else if (strcEQ(w, "all")) {
1324             thisopt = SSL_PROTOCOL_ALL;
1325         }
1326         else {
1327             return apr_pstrcat(parms->temp_pool,
1328                                parms->cmd->name,
1329                                ": Illegal protocol '",
1330                                w, "'", NULL);
1331         }
1332
1333         if (action == '-') {
1334             *options &= ~thisopt;
1335         }
1336         else if (action == '+') {
1337             *options |= thisopt;
1338         }
1339         else {
1340             *options = thisopt;
1341         }
1342     }
1343
1344     return NULL;
1345 }
1346
1347 const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
1348                                 void *dcfg,
1349                                 const char *arg)
1350 {
1351     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1352
1353     return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
1354 }
1355
1356 const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
1357 {
1358     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1359
1360     sc->proxy_enabled = flag ? TRUE : FALSE;
1361
1362     return NULL;
1363 }
1364
1365 const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,
1366                                      void *dcfg,
1367                                      const char *arg)
1368 {
1369     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1370
1371     return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
1372 }
1373
1374 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
1375                                         void *dcfg,
1376                                         const char *arg)
1377 {
1378     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1379
1380     sc->proxy->auth.cipher_suite = arg;
1381
1382     return NULL;
1383 }
1384
1385 const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
1386                                    void *dcfg,
1387                                    const char *arg)
1388 {
1389     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1390     ssl_verify_t mode;
1391     const char *err;
1392
1393     if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
1394         return err;
1395     }
1396
1397     sc->proxy->auth.verify_mode = mode;
1398
1399     return NULL;
1400 }
1401
1402 const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
1403                                         void *dcfg,
1404                                         const char *arg)
1405 {
1406     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1407     int depth;
1408     const char *err;
1409
1410     if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1411         return err;
1412     }
1413
1414     sc->proxy->auth.verify_depth = depth;
1415
1416     return NULL;
1417 }
1418
1419 const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
1420                                               void *dcfg,
1421                                               const char *arg)
1422 {
1423     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1424     const char *err;
1425
1426     if ((err = ssl_cmd_check_file(cmd, &arg))) {
1427         return err;
1428     }
1429
1430     sc->proxy->auth.ca_cert_file = arg;
1431
1432     return NULL;
1433 }
1434
1435 const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
1436                                               void *dcfg,
1437                                               const char *arg)
1438 {
1439     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1440     const char *err;
1441
1442     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1443         return err;
1444     }
1445
1446     sc->proxy->auth.ca_cert_path = arg;
1447
1448     return NULL;
1449 }
1450
1451 const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
1452                                              void *dcfg,
1453                                              const char *arg)
1454 {
1455     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1456     const char *err;
1457
1458     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1459         return err;
1460     }
1461
1462     sc->proxy->crl_path = arg;
1463
1464     return NULL;
1465 }
1466
1467 const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
1468                                              void *dcfg,
1469                                              const char *arg)
1470 {
1471     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1472     const char *err;
1473
1474     if ((err = ssl_cmd_check_file(cmd, &arg))) {
1475         return err;
1476     }
1477
1478     sc->proxy->crl_file = arg;
1479
1480     return NULL;
1481 }
1482
1483 const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd,
1484                                               void *dcfg,
1485                                               const char *arg)
1486 {
1487     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1488
1489     return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mode);
1490 }
1491
1492 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
1493                                                    void *dcfg,
1494                                                    const char *arg)
1495 {
1496     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1497     const char *err;
1498
1499     if ((err = ssl_cmd_check_file(cmd, &arg))) {
1500         return err;
1501     }
1502
1503     sc->proxy->pkp->cert_file = arg;
1504
1505     return NULL;
1506 }
1507
1508 const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
1509                                                    void *dcfg,
1510                                                    const char *arg)
1511 {
1512     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1513     const char *err;
1514
1515     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1516         return err;
1517     }
1518
1519     sc->proxy->pkp->cert_path = arg;
1520
1521     return NULL;
1522 }
1523
1524 const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *cmd,
1525                                                    void *dcfg,
1526                                                    const char *arg)
1527 {
1528     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1529     const char *err;
1530
1531     if ((err = ssl_cmd_check_file(cmd, &arg))) {
1532         return err;
1533     }
1534
1535     sc->proxy->pkp->ca_cert_file = arg;
1536
1537     return NULL;
1538 }
1539
1540 const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
1541                                 const char *arg)
1542 {
1543     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1544     dc->szUserName = arg;
1545     return NULL;
1546 }
1547
1548 const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag)
1549 {
1550     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1551
1552     sc->server->ocsp_enabled = flag ? TRUE : FALSE;
1553
1554 #ifdef OPENSSL_NO_OCSP
1555     if (flag) {
1556         return "OCSP support disabled in SSL library; cannot enable "
1557             "OCSP validation";
1558     }
1559 #endif
1560
1561     return NULL;
1562 }
1563
1564 const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag)
1565 {
1566     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1567
1568     sc->server->ocsp_force_default = flag ? TRUE : FALSE;
1569
1570     return NULL;
1571 }
1572
1573 const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg)
1574 {
1575     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1576
1577     sc->server->ocsp_responder = arg;
1578
1579     return NULL;
1580 }
1581
1582 const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg)
1583 {
1584     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1585     sc->server->ocsp_resptime_skew = atoi(arg);
1586     if (sc->server->ocsp_resptime_skew < 0) {
1587         return "SSLOCSPResponseTimeSkew: invalid argument";
1588     }
1589     return NULL;
1590 }
1591
1592 const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg)
1593 {
1594     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1595     sc->server->ocsp_resp_maxage = atoi(arg);
1596     if (sc->server->ocsp_resp_maxage < 0) {
1597         return "SSLOCSPResponseMaxAge: invalid argument";
1598     }
1599     return NULL;
1600 }
1601
1602 const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg)
1603 {
1604     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1605     sc->server->ocsp_responder_timeout = apr_time_from_sec(atoi(arg));
1606     if (sc->server->ocsp_responder_timeout < 0) {
1607         return "SSLOCSPResponderTimeout: invalid argument";
1608     }
1609     return NULL;
1610 }
1611
1612 const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
1613 {
1614     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1615
1616     sc->proxy_ssl_check_peer_expire = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
1617
1618     return NULL;
1619 }
1620
1621 const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
1622 {
1623     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1624
1625     sc->proxy_ssl_check_peer_cn = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
1626
1627     return NULL;
1628 }
1629
1630 const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag)
1631 {
1632 #ifndef OPENSSL_NO_TLSEXT
1633     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1634
1635     sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
1636
1637     return NULL;
1638 #else
1639     return "SSLStrictSNIVHostCheck failed; OpenSSL is not built with support "
1640            "for TLS extensions and SNI indication. Refer to the "
1641            "documentation, and build a compatible version of OpenSSL.";
1642 #endif
1643 }
1644
1645 #ifdef HAVE_OCSP_STAPLING
1646
1647 const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd,
1648                                     void *dcfg,
1649                                     const char *arg)
1650 {
1651     SSLModConfigRec *mc = myModConfig(cmd->server);
1652     const char *err, *sep, *name;
1653
1654     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
1655         return err;
1656     }
1657
1658     /* Argument is of form 'name:args' or just 'name'. */
1659     sep = ap_strchr_c(arg, ':');
1660     if (sep) {
1661         name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
1662         sep++;
1663     }
1664     else {
1665         name = arg;
1666     }
1667
1668     /* Find the provider of given name. */
1669     mc->stapling_cache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
1670                                             name,
1671                                             AP_SOCACHE_PROVIDER_VERSION);
1672     if (mc->stapling_cache) {
1673         /* Cache found; create it, passing anything beyond the colon. */
1674         err = mc->stapling_cache->create(&mc->stapling_cache_context,
1675                                          sep, cmd->temp_pool,
1676                                          cmd->pool);
1677     }
1678     else {
1679         apr_array_header_t *name_list;
1680         const char *all_names;
1681
1682         /* Build a comma-separated list of all registered provider
1683          * names: */
1684         name_list = ap_list_provider_names(cmd->pool,
1685                                            AP_SOCACHE_PROVIDER_GROUP,
1686                                            AP_SOCACHE_PROVIDER_VERSION);
1687         all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
1688
1689         err = apr_psprintf(cmd->pool, "'%s' stapling cache not supported "
1690                            "(known names: %s)", name, all_names);
1691     }
1692
1693     if (err) {
1694         return apr_psprintf(cmd->pool, "SSLStaplingCache: %s", err);
1695     }
1696
1697     return NULL;
1698 }
1699
1700 const char *ssl_cmd_SSLUseStapling(cmd_parms *cmd, void *dcfg, int flag)
1701 {
1702     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1703     sc->server->stapling_enabled = flag ? TRUE : FALSE;
1704     return NULL;
1705 }
1706
1707 const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *cmd, void *dcfg,
1708                                                     const char *arg)
1709 {
1710     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1711     sc->server->stapling_resptime_skew = atoi(arg);
1712     if (sc->server->stapling_resptime_skew < 0) {
1713         return "SSLStaplingResponseTimeSkew: invalid argument";
1714     }
1715     return NULL;
1716 }
1717
1718 const char *ssl_cmd_SSLStaplingResponseMaxAge(cmd_parms *cmd, void *dcfg,
1719                                                     const char *arg)
1720 {
1721     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1722     sc->server->stapling_resp_maxage = atoi(arg);
1723     if (sc->server->stapling_resp_maxage < 0) {
1724         return "SSLStaplingResponseMaxAge: invalid argument";
1725     }
1726     return NULL;
1727 }
1728
1729 const char *ssl_cmd_SSLStaplingStandardCacheTimeout(cmd_parms *cmd, void *dcfg,
1730                                                     const char *arg)
1731 {
1732     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1733     sc->server->stapling_cache_timeout = atoi(arg);
1734     if (sc->server->stapling_cache_timeout < 0) {
1735         return "SSLStaplingStandardCacheTimeout: invalid argument";
1736     }
1737     return NULL;
1738 }
1739
1740 const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *cmd, void *dcfg,
1741                                                  const char *arg)
1742 {
1743     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1744     sc->server->stapling_errcache_timeout = atoi(arg);
1745     if (sc->server->stapling_errcache_timeout < 0) {
1746         return "SSLStaplingErrorCacheTimeout: invalid argument";
1747     }
1748     return NULL;
1749 }
1750
1751 const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *cmd,
1752                                                      void *dcfg, int flag)
1753 {
1754     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1755     sc->server->stapling_return_errors = flag ? TRUE : FALSE;
1756     return NULL;
1757 }
1758
1759 const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *cmd,
1760                                             void *dcfg, int flag)
1761 {
1762     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1763     sc->server->stapling_fake_trylater = flag ? TRUE : FALSE;
1764     return NULL;
1765 }
1766
1767 const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *cmd, void *dcfg,
1768                                                 const char *arg)
1769 {
1770     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1771     sc->server->stapling_responder_timeout = atoi(arg);
1772     sc->server->stapling_responder_timeout *= APR_USEC_PER_SEC;
1773     if (sc->server->stapling_responder_timeout < 0) {
1774         return "SSLStaplingResponderTimeout: invalid argument";
1775     }
1776     return NULL;
1777 }
1778
1779 const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg,
1780                                         const char *arg)
1781 {
1782     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1783     sc->server->stapling_force_url = arg;
1784     return NULL;
1785 }
1786
1787 #endif /* HAVE_OCSP_STAPLING */
1788
1789 void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
1790 {
1791     apr_file_t *out = NULL;
1792     if (!ap_exists_config_define("DUMP_CERTS")) {
1793         return;
1794     }
1795     apr_file_open_stdout(&out, pconf);
1796     apr_file_printf(out, "Server certificates:\n");
1797
1798     /* Dump the filenames of all configured server certificates to
1799      * stdout. */
1800     while (s) {
1801         SSLSrvConfigRec *sc = mySrvConfig(s);
1802
1803         if (sc && sc->server && sc->server->pks) {
1804             modssl_pk_server_t *const pks = sc->server->pks;
1805             int i;
1806
1807             for (i = 0; (i < SSL_AIDX_MAX) && pks->cert_files[i]; i++) {
1808                 apr_file_printf(out, "  %s\n", pks->cert_files[i]);
1809             }
1810         }
1811
1812         s = s->next;
1813     }
1814
1815 }