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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * _ __ ___ ___ __| | ___ ___| | mod_ssl
19 * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
20 * | | | | | | (_) | (_| | \__ \__ \ |
21 * |_| |_| |_|\___/ \__,_|___|___/___/_|
24 * Apache Configuration Directives
26 /* ``Damned if you do,
27 damned if you don't.''
31 /* _________________________________________________________________
33 ** Support for Global Configuration
34 ** _________________________________________________________________
37 #define SSL_MOD_CONFIG_KEY "ssl_module"
39 SSLModConfigRec *ssl_config_global_create(server_rec *s)
41 apr_pool_t *pool = s->process->pool;
45 apr_pool_userdata_get(&vmc, SSL_MOD_CONFIG_KEY, pool);
47 return vmc; /* reused for lifetime of the server */
51 * allocate an own subpool which survives server restarts
53 mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc));
58 * initialize per-module configuration
60 mc->nSessionCacheMode = SSL_SCMODE_UNSET;
61 mc->szSessionCacheDataFile = NULL;
62 mc->nSessionCacheDataSize = 0;
63 mc->pSessionCacheDataMM = NULL;
64 mc->pSessionCacheDataRMM = NULL;
65 mc->tSessionCacheDataTable = NULL;
66 mc->nMutexMode = SSL_MUTEXMODE_UNSET;
67 mc->nMutexMech = APR_LOCK_DEFAULT;
68 mc->szMutexFile = NULL;
70 mc->aRandSeed = apr_array_make(pool, 4,
71 sizeof(ssl_randseed_t));
72 mc->tVHostKeys = apr_hash_make(pool);
73 mc->tPrivateKey = apr_hash_make(pool);
74 mc->tPublicCert = apr_hash_make(pool);
75 #ifdef SSL_EXPERIMENTAL_ENGINE
76 mc->szCryptoDevice = NULL;
79 memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
81 apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
82 apr_pool_cleanup_null,
88 void ssl_config_global_fix(SSLModConfigRec *mc)
93 BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
98 /* _________________________________________________________________
100 ** Configuration handling
101 ** _________________________________________________________________
104 static void modssl_ctx_init(modssl_ctx_t *mctx)
106 mctx->sc = NULL; /* set during module init */
108 mctx->ssl_ctx = NULL; /* set during module init */
113 mctx->protocol = SSL_PROTOCOL_ALL;
115 mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
116 mctx->pphrase_dialog_path = NULL;
118 mctx->cert_chain = NULL;
120 mctx->crl_path = NULL;
121 mctx->crl_file = NULL;
122 mctx->crl = NULL; /* set during module init */
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;
131 static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
136 mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy));
138 modssl_ctx_init(mctx);
140 mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
142 mctx->pkp->cert_file = NULL;
143 mctx->pkp->cert_path = NULL;
144 mctx->pkp->certs = NULL;
147 static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
152 mctx = sc->server = apr_palloc(p, sizeof(*sc->server));
154 modssl_ctx_init(mctx);
156 mctx->pks = apr_palloc(p, sizeof(*mctx->pks));
158 memset((void*)mctx->pks->cert_files, 0, sizeof(mctx->pks->cert_files));
160 memset((void*)mctx->pks->key_files, 0, sizeof(mctx->pks->key_files));
162 /* certs/keys are set during module init */
164 memset(mctx->pks->certs, 0, sizeof(mctx->pks->certs));
166 memset(mctx->pks->keys, 0, sizeof(mctx->pks->keys));
169 static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
171 SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
175 sc->proxy_enabled = UNSET;
176 sc->vhost_id = NULL; /* set during module init */
177 sc->vhost_id_len = 0; /* set during module init */
178 sc->session_cache_timeout = UNSET;
179 sc->insecure_reneg = UNSET;
181 modssl_ctx_init_proxy(sc, p);
183 modssl_ctx_init_server(sc, p);
189 * Create per-server SSL configuration
191 void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
193 SSLSrvConfigRec *sc = ssl_config_server_new(p);
195 sc->mc = ssl_config_global_create(s);
200 #define cfgMerge(el,unset) mrg->el = (add->el == (unset)) ? base->el : add->el
201 #define cfgMergeArray(el) mrg->el = apr_array_append(p, add->el, base->el)
202 #define cfgMergeString(el) cfgMerge(el, NULL)
203 #define cfgMergeBool(el) cfgMerge(el, UNSET)
204 #define cfgMergeInt(el) cfgMerge(el, UNSET)
206 static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
210 cfgMerge(protocol, SSL_PROTOCOL_ALL);
212 cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
213 cfgMergeString(pphrase_dialog_path);
215 cfgMergeString(cert_chain);
217 cfgMerge(crl_path, NULL);
218 cfgMerge(crl_file, NULL);
220 cfgMergeString(auth.ca_cert_path);
221 cfgMergeString(auth.ca_cert_file);
222 cfgMergeString(auth.cipher_suite);
223 cfgMergeInt(auth.verify_depth);
224 cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
227 static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
231 modssl_ctx_cfg_merge(base, add, mrg);
233 cfgMergeString(pkp->cert_file);
234 cfgMergeString(pkp->cert_path);
237 static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
243 modssl_ctx_cfg_merge(base, add, mrg);
245 for (i = 0; i < SSL_AIDX_MAX; i++) {
246 cfgMergeString(pks->cert_files[i]);
247 cfgMergeString(pks->key_files[i]);
252 * Merge per-server SSL configurations
254 void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
256 SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
257 SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv;
258 SSLSrvConfigRec *mrg = ssl_config_server_new(p);
261 cfgMergeBool(enabled);
262 cfgMergeBool(proxy_enabled);
263 cfgMergeInt(session_cache_timeout);
264 cfgMergeBool(insecure_reneg);
266 modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
268 modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server);
274 * Create per-directory SSL configuration
276 void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
278 SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
280 dc->bSSLRequired = FALSE;
281 dc->aRequirement = apr_array_make(p, 4, sizeof(ssl_require_t));
282 dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET;
283 dc->nOptionsAdd = SSL_OPT_NONE;
284 dc->nOptionsDel = SSL_OPT_NONE;
286 dc->szCipherSuite = NULL;
287 dc->nVerifyClient = SSL_CVERIFY_UNSET;
288 dc->nVerifyDepth = UNSET;
290 dc->szCACertificatePath = NULL;
291 dc->szCACertificateFile = NULL;
292 dc->szUserName = NULL;
298 * Merge per-directory SSL configurations
300 void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
302 SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
303 SSLDirConfigRec *add = (SSLDirConfigRec *)addv;
304 SSLDirConfigRec *mrg = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
306 cfgMerge(bSSLRequired, FALSE);
307 cfgMergeArray(aRequirement);
309 if (add->nOptions & SSL_OPT_RELSET) {
311 (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
313 (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
315 (base->nOptions & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd;
318 mrg->nOptions = add->nOptions;
319 mrg->nOptionsAdd = add->nOptionsAdd;
320 mrg->nOptionsDel = add->nOptionsDel;
323 cfgMergeString(szCipherSuite);
324 cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
325 cfgMergeInt(nVerifyDepth);
327 cfgMergeString(szCACertificatePath);
328 cfgMergeString(szCACertificateFile);
329 cfgMergeString(szUserName);
335 * Configuration functions for particular directives
338 const char *ssl_cmd_SSLMutex(cmd_parms *cmd,
343 SSLModConfigRec *mc = myModConfig(cmd->server);
345 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
349 if (ssl_config_global_isfixed(mc)) {
353 if (strcEQ(arg, "none") || strcEQ(arg, "no")) {
354 mc->nMutexMode = SSL_MUTEXMODE_NONE;
356 /* NOTE: previously, 'yes' implied 'sem' */
357 else if (strcEQ(arg, "default") || strcEQ(arg, "yes")) {
358 mc->nMutexMode = SSL_MUTEXMODE_USED;
359 mc->nMutexMech = APR_LOCK_DEFAULT;
360 mc->szMutexFile = NULL; /* APR determines temporary filename */
362 #if APR_HAS_FLOCK_SERIALIZE
363 else if (strlen(arg) > 6 && strcEQn(arg, "flock:", 6)) {
364 const char *file = ap_server_root_relative(cmd->pool, arg+6);
366 return apr_pstrcat(cmd->pool, "Invalid SSLMutex flock: path ",
369 mc->nMutexMode = SSL_MUTEXMODE_USED;
370 mc->nMutexMech = APR_LOCK_FLOCK;
371 mc->szMutexFile = apr_psprintf(mc->pPool, "%s.%lu",
372 file, (unsigned long)getpid());
375 #if APR_HAS_FCNTL_SERIALIZE
376 else if (strlen(arg) > 6 && strcEQn(arg, "fcntl:", 6)) {
377 const char *file = ap_server_root_relative(cmd->pool, arg+6);
379 return apr_pstrcat(cmd->pool, "Invalid SSLMutex fcntl: path ",
382 mc->nMutexMode = SSL_MUTEXMODE_USED;
383 mc->nMutexMech = APR_LOCK_FCNTL;
384 mc->szMutexFile = apr_psprintf(mc->pPool, "%s.%lu",
385 file, (unsigned long)getpid());
388 #if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
389 else if (strcEQ(arg, "sysvsem")) {
390 mc->nMutexMode = SSL_MUTEXMODE_USED;
391 mc->nMutexMech = APR_LOCK_SYSVSEM;
392 mc->szMutexFile = NULL; /* APR determines temporary filename */
395 #if APR_HAS_POSIXSEM_SERIALIZE
396 else if (strcEQ(arg, "posixsem")) {
397 mc->nMutexMode = SSL_MUTEXMODE_USED;
398 mc->nMutexMech = APR_LOCK_POSIXSEM;
399 mc->szMutexFile = NULL; /* APR determines temporary filename */
402 #if APR_HAS_PROC_PTHREAD_SERIALIZE
403 else if (strcEQ(arg, "pthread")) {
404 mc->nMutexMode = SSL_MUTEXMODE_USED;
405 mc->nMutexMech = APR_LOCK_PROC_PTHREAD;
406 mc->szMutexFile = NULL; /* APR determines temporary filename */
409 #if APR_HAS_FLOCK_SERIALIZE || APR_HAS_FCNTL_SERIALIZE
410 else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) {
411 const char *file = ap_server_root_relative(cmd->pool, arg+5);
413 return apr_pstrcat(cmd->pool, "Invalid SSLMutex file: path ",
416 mc->nMutexMode = SSL_MUTEXMODE_USED;
417 #if APR_HAS_FLOCK_SERIALIZE
418 mc->nMutexMech = APR_LOCK_FLOCK;
420 #if APR_HAS_FCNTL_SERIALIZE
421 mc->nMutexMech = APR_LOCK_FCNTL;
424 apr_psprintf(mc->pPool, "%s.%lu",
425 file, (unsigned long)getpid());
428 #if (APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)) || APR_HAS_POSIXSEM_SERIALIZE
429 else if (strcEQ(arg, "sem")) {
430 mc->nMutexMode = SSL_MUTEXMODE_USED;
431 #if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
432 mc->nMutexMech = APR_LOCK_SYSVSEM;
434 #if APR_HAS_POSIXSEM_SERIALIZE
435 mc->nMutexMech = APR_LOCK_POSIXSEM;
437 mc->szMutexFile = NULL; /* APR determines temporary filename */
441 return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ",
442 arg, " (", ssl_valid_ssl_mutex_string, ")", NULL);
448 const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
452 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
454 int arglen = strlen(arg);
456 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
460 if (strcEQ(arg, "builtin")) {
461 sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
462 sc->server->pphrase_dialog_path = NULL;
464 else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
465 sc->server->pphrase_dialog_type = SSL_PPTYPE_FILTER;
466 /* ### This is broken, exec: may contain args, no? */
467 sc->server->pphrase_dialog_path =
468 ap_server_root_relative(cmd->pool, arg+5);
469 if (!sc->server->pphrase_dialog_path) {
470 return apr_pstrcat(cmd->pool,
471 "Invalid SSLPassPhraseDialog exec: path ",
474 if (!ssl_util_path_check(SSL_PCM_EXISTS,
475 sc->server->pphrase_dialog_path,
478 return apr_pstrcat(cmd->pool,
479 "SSLPassPhraseDialog: file '",
480 sc->server->pphrase_dialog_path,
481 "' does not exist", NULL);
485 else if ((arglen > 1) && (arg[0] == '|')) {
486 sc->server->pphrase_dialog_type = SSL_PPTYPE_PIPE;
487 sc->server->pphrase_dialog_path = arg + 1;
490 return "SSLPassPhraseDialog: Invalid argument";
496 #ifdef SSL_EXPERIMENTAL_ENGINE
497 const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
501 SSLModConfigRec *mc = myModConfig(cmd->server);
504 #if SSL_LIBRARY_VERSION >= 0x00907000
505 static int loaded_engines = FALSE;
507 /* early loading to make sure the engines are already
508 available for ENGINE_by_id() above... */
509 if (!loaded_engines) {
510 ENGINE_load_builtin_engines();
511 loaded_engines = TRUE;
514 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
518 if (strcEQ(arg, "builtin")) {
519 mc->szCryptoDevice = NULL;
521 else if ((e = ENGINE_by_id(arg))) {
522 mc->szCryptoDevice = arg;
526 return "SSLCryptoDevice: Invalid argument";
533 const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
539 SSLModConfigRec *mc = myModConfig(cmd->server);
541 ssl_randseed_t *seed;
542 int arg2len = strlen(arg2);
544 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
548 if (ssl_config_global_isfixed(mc)) {
552 seed = apr_array_push(mc->aRandSeed);
554 if (strcEQ(arg1, "startup")) {
555 seed->nCtx = SSL_RSCTX_STARTUP;
557 else if (strcEQ(arg1, "connect")) {
558 seed->nCtx = SSL_RSCTX_CONNECT;
561 return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
562 "invalid context: `", arg1, "'",
566 if ((arg2len > 5) && strEQn(arg2, "file:", 5)) {
567 seed->nSrc = SSL_RSSRC_FILE;
568 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
570 else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) {
571 seed->nSrc = SSL_RSSRC_EXEC;
572 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
574 else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
575 #ifdef HAVE_SSL_RAND_EGD
576 seed->nSrc = SSL_RSSRC_EGD;
577 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
579 return "egd not supported with this SSL toolkit";
582 else if (strcEQ(arg2, "builtin")) {
583 seed->nSrc = SSL_RSSRC_BUILTIN;
587 seed->nSrc = SSL_RSSRC_FILE;
588 seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
591 if (seed->nSrc != SSL_RSSRC_BUILTIN) {
593 return apr_pstrcat(cmd->pool,
594 "Invalid SSLRandomSeed path ",
597 if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) {
598 return apr_pstrcat(cmd->pool,
599 "SSLRandomSeed: source path '",
600 seed->cpPath, "' does not exist", NULL);
605 seed->nBytes = 0; /* read whole file */
608 if (seed->nSrc == SSL_RSSRC_BUILTIN) {
609 return "SSLRandomSeed: byte specification not "
610 "allowed for builtin seed source";
613 seed->nBytes = atoi(arg3);
615 if (seed->nBytes < 0) {
616 return "SSLRandomSeed: invalid number of bytes specified";
623 const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, int flag)
625 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
627 sc->enabled = flag ? TRUE : FALSE;
632 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
636 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
637 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
640 dc->szCipherSuite = arg;
643 sc->server->auth.cipher_suite = arg;
649 #define SSL_FLAGS_CHECK_FILE \
650 (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
652 #define SSL_FLAGS_CHECK_DIR \
653 (SSL_PCM_EXISTS|SSL_PCM_ISDIR)
655 static const char *ssl_cmd_check_file(cmd_parms *parms,
658 const char *filepath = ap_server_root_relative(parms->pool, *file);
661 return apr_pstrcat(parms->pool, parms->cmd->name,
662 ": Invalid file path ", *file, NULL);
666 if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
670 return apr_pstrcat(parms->pool, parms->cmd->name,
672 "' does not exist or is empty", NULL);
676 const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag)
678 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
679 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
680 sc->insecure_reneg = flag?TRUE:FALSE;
683 return "The SSLInsecureRenegotiation directive is not available "
684 "with this SSL library";
689 static const char *ssl_cmd_check_dir(cmd_parms *parms,
692 const char *dirpath = ap_server_root_relative(parms->pool, *dir);
695 return apr_pstrcat(parms->pool, parms->cmd->name,
696 ": Invalid dir path ", *dir, NULL);
700 if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
704 return apr_pstrcat(parms->pool, parms->cmd->name,
705 ": directory '", *dir,
706 "' does not exist", NULL);
710 #define SSL_AIDX_CERTS 1
711 #define SSL_AIDX_KEYS 2
713 static const char *ssl_cmd_check_aidx_max(cmd_parms *parms,
717 SSLSrvConfigRec *sc = mySrvConfig(parms->server);
718 const char *err, *desc=NULL, **files=NULL;
721 if ((err = ssl_cmd_check_file(parms, &arg))) {
727 desc = "certificates";
728 files = sc->server->pks->cert_files;
731 desc = "private keys";
732 files = sc->server->pks->key_files;
736 for (i = 0; i < SSL_AIDX_MAX; i++) {
743 return apr_psprintf(parms->pool,
745 "different %s per virtual host allowed",
746 parms->cmd->name, SSL_AIDX_MAX, desc);
749 const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
756 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) {
763 const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
769 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) {
776 const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
780 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
783 if ((err = ssl_cmd_check_file(cmd, &arg))) {
787 sc->server->cert_chain = arg;
792 #define NO_PER_DIR_SSL_CA \
793 "Your ssl library does not have support for per-directory CA"
795 #ifdef HAVE_SSL_SET_CERT_STORE
796 # define MODSSL_HAVE_SSL_SET_CERT_STORE 1
798 # define MODSSL_HAVE_SSL_SET_CERT_STORE 0
801 #define MODSSL_SET_CA(f) \
803 if (MODSSL_HAVE_SSL_SET_CERT_STORE) \
806 return NO_PER_DIR_SSL_CA; \
810 const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
814 /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
815 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
818 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
822 /* XXX: bring back per-dir */
823 sc->server->auth.ca_cert_path = arg;
828 const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
832 /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
833 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
836 if ((err = ssl_cmd_check_file(cmd, &arg))) {
840 /* XXX: bring back per-dir */
841 sc->server->auth.ca_cert_file = arg;
846 const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
850 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
853 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
857 sc->server->crl_path = arg;
862 const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
866 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
869 if ((err = ssl_cmd_check_file(cmd, &arg))) {
873 sc->server->crl_file = arg;
878 static const char *ssl_cmd_verify_parse(cmd_parms *parms,
882 if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
883 *id = SSL_CVERIFY_NONE;
885 else if (strcEQ(arg, "optional")) {
886 *id = SSL_CVERIFY_OPTIONAL;
888 else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
889 *id = SSL_CVERIFY_REQUIRE;
891 else if (strcEQ(arg, "optional_no_ca")) {
892 *id = SSL_CVERIFY_OPTIONAL_NO_CA;
895 return apr_pstrcat(parms->temp_pool, parms->cmd->name,
896 ": Invalid argument '", arg, "'",
903 const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd,
907 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
908 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
912 if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
917 dc->nVerifyClient = mode;
920 sc->server->auth.verify_mode = mode;
926 static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
930 if ((*depth = atoi(arg)) >= 0) {
934 return apr_pstrcat(parms->temp_pool, parms->cmd->name,
935 ": Invalid argument '", arg, "'",
939 const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
943 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
944 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
948 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
953 dc->nVerifyDepth = depth;
956 sc->server->auth.verify_depth = depth;
962 #define MODSSL_NO_SHARED_MEMORY_ERROR \
963 "SSLSessionCache: shared memory cache not useable on this platform"
965 const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
969 SSLModConfigRec *mc = myModConfig(cmd->server);
970 const char *err, *colon;
972 int arglen = strlen(arg);
974 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
978 if (ssl_config_global_isfixed(mc)) {
982 if (strcEQ(arg, "none")) {
983 mc->nSessionCacheMode = SSL_SCMODE_NONE;
984 mc->szSessionCacheDataFile = NULL;
986 else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) {
987 mc->nSessionCacheMode = SSL_SCMODE_DBM;
988 mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4);
989 if (!mc->szSessionCacheDataFile) {
990 return apr_psprintf(cmd->pool,
991 "SSLSessionCache: Invalid cache file path %s",
995 else if ((arglen > 6) && strcEQn(arg, "shmht:", 6)) {
996 #if !APR_HAS_SHARED_MEMORY
997 return MODSSL_NO_SHARED_MEMORY_ERROR;
999 mc->nSessionCacheMode = SSL_SCMODE_SHMHT;
1000 colon = ap_strchr_c(arg, ':');
1001 mc->szSessionCacheDataFile =
1002 ap_server_root_relative(mc->pPool, colon+1);
1003 if (!mc->szSessionCacheDataFile) {
1004 return apr_psprintf(cmd->pool,
1005 "SSLSessionCache: Invalid cache file path %s",
1008 mc->tSessionCacheDataTable = NULL;
1009 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
1011 if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
1014 if (!(cp2 = strchr(cp, ')'))) {
1015 return "SSLSessionCache: Invalid argument: "
1016 "no closing parenthesis";
1021 mc->nSessionCacheDataSize = atoi(cp);
1023 if (mc->nSessionCacheDataSize < 8192) {
1024 return "SSLSessionCache: Invalid argument: "
1025 "size has to be >= 8192 bytes";
1028 if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) {
1029 return apr_psprintf(cmd->pool,
1030 "SSLSessionCache: Invalid argument: "
1031 "size has to be < %d bytes on this "
1032 "platform", APR_SHM_MAXSIZE);
1036 else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) ||
1037 ((arglen > 6) && strcEQn(arg, "shmcb:", 6))) {
1038 #if !APR_HAS_SHARED_MEMORY
1039 return MODSSL_NO_SHARED_MEMORY_ERROR;
1041 mc->nSessionCacheMode = SSL_SCMODE_SHMCB;
1042 colon = ap_strchr_c(arg, ':');
1043 mc->szSessionCacheDataFile =
1044 ap_server_root_relative(mc->pPool, colon+1);
1045 if (!mc->szSessionCacheDataFile) {
1046 return apr_psprintf(cmd->pool,
1047 "SSLSessionCache: Invalid cache file path %s",
1050 mc->tSessionCacheDataTable = NULL;
1051 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
1053 if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
1056 if (!(cp2 = strchr(cp, ')'))) {
1057 return "SSLSessionCache: Invalid argument: "
1058 "no closing parenthesis";
1063 mc->nSessionCacheDataSize = atoi(cp);
1065 if (mc->nSessionCacheDataSize < 8192) {
1066 return "SSLSessionCache: Invalid argument: "
1067 "size has to be >= 8192 bytes";
1071 if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) {
1072 return apr_psprintf(cmd->pool,
1073 "SSLSessionCache: Invalid argument: "
1074 "size has to be < %d bytes on this "
1075 "platform", APR_SHM_MAXSIZE);
1081 return "SSLSessionCache: Invalid argument";
1087 const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd,
1091 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1093 sc->session_cache_timeout = atoi(arg);
1095 if (sc->session_cache_timeout < 0) {
1096 return "SSLSessionCacheTimeout: Invalid argument";
1102 const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
1106 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1112 w = ap_getword_conf(cmd->pool, &arg);
1115 if ((*w == '+') || (*w == '-')) {
1119 dc->nOptions = SSL_OPT_NONE;
1123 if (strcEQ(w, "StdEnvVars")) {
1124 opt = SSL_OPT_STDENVVARS;
1126 else if (strcEQ(w, "CompatEnvVars")) {
1127 opt = SSL_OPT_COMPATENVVARS;
1129 else if (strcEQ(w, "ExportCertData")) {
1130 opt = SSL_OPT_EXPORTCERTDATA;
1132 else if (strcEQ(w, "FakeBasicAuth")) {
1133 opt = SSL_OPT_FAKEBASICAUTH;
1135 else if (strcEQ(w, "StrictRequire")) {
1136 opt = SSL_OPT_STRICTREQUIRE;
1138 else if (strcEQ(w, "OptRenegotiate")) {
1139 opt = SSL_OPT_OPTRENEGOTIATE;
1142 return apr_pstrcat(cmd->pool,
1143 "SSLOptions: Illegal option '", w, "'",
1147 if (action == '-') {
1148 dc->nOptionsAdd &= ~opt;
1149 dc->nOptionsDel |= opt;
1150 dc->nOptions &= ~opt;
1152 else if (action == '+') {
1153 dc->nOptionsAdd |= opt;
1154 dc->nOptionsDel &= ~opt;
1155 dc->nOptions |= opt;
1159 dc->nOptionsAdd = opt;
1160 dc->nOptionsDel = SSL_OPT_NONE;
1167 const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg)
1169 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1171 dc->bSSLRequired = TRUE;
1176 const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
1180 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1182 ssl_require_t *require;
1184 if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) {
1185 return apr_pstrcat(cmd->pool, "SSLRequire: ",
1186 ssl_expr_get_error(), NULL);
1189 require = apr_array_push(dc->aRequirement);
1190 require->cpExpr = apr_pstrdup(cmd->pool, arg);
1191 require->mpExpr = expr;
1196 static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
1198 ssl_proto_t *options)
1200 ssl_proto_t thisopt;
1202 *options = SSL_PROTOCOL_NONE;
1205 char *w = ap_getword_conf(parms->temp_pool, &arg);
1208 if ((*w == '+') || (*w == '-')) {
1212 if (strcEQ(w, "SSLv2")) {
1213 thisopt = SSL_PROTOCOL_SSLV2;
1215 else if (strcEQ(w, "SSLv3")) {
1216 thisopt = SSL_PROTOCOL_SSLV3;
1218 else if (strcEQ(w, "TLSv1")) {
1219 thisopt = SSL_PROTOCOL_TLSV1;
1221 else if (strcEQ(w, "all")) {
1222 thisopt = SSL_PROTOCOL_ALL;
1225 return apr_pstrcat(parms->temp_pool,
1227 ": Illegal protocol '",
1231 if (action == '-') {
1232 *options &= ~thisopt;
1234 else if (action == '+') {
1235 *options |= thisopt;
1245 const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
1249 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1251 return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
1254 const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
1256 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1258 sc->proxy_enabled = flag ? TRUE : FALSE;
1263 const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,
1267 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1269 return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
1272 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
1276 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1278 sc->proxy->auth.cipher_suite = arg;
1283 const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
1287 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1291 if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
1295 sc->proxy->auth.verify_mode = mode;
1300 const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
1304 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1308 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1312 sc->proxy->auth.verify_depth = depth;
1317 const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
1321 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1324 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1328 sc->proxy->auth.ca_cert_file = arg;
1333 const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
1337 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1340 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1344 sc->proxy->auth.ca_cert_path = arg;
1349 const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
1353 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1356 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1360 sc->proxy->crl_path = arg;
1365 const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
1369 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1372 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1376 sc->proxy->crl_file = arg;
1381 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
1385 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1388 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1392 sc->proxy->pkp->cert_file = arg;
1397 const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
1401 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1404 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1408 sc->proxy->pkp->cert_path = arg;
1414 const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
1417 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1418 dc->szUserName = arg;