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