2 ** _ __ ___ ___ __| | ___ ___| | mod_ssl
3 ** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
4 ** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org
5 ** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org
8 ** Apache Configuration Directives
11 /* ====================================================================
12 * The Apache Software License, Version 1.1
14 * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
29 * 3. The end-user documentation included with the redistribution,
30 * if any, must include the following acknowledgment:
31 * "This product includes software developed by the
32 * Apache Software Foundation (http://www.apache.org/)."
33 * Alternately, this acknowledgment may appear in the software itself,
34 * if and wherever such third-party acknowledgments normally appear.
36 * 4. The names "Apache" and "Apache Software Foundation" must
37 * not be used to endorse or promote products derived from this
38 * software without prior written permission. For written
39 * permission, please contact apache@apache.org.
41 * 5. Products derived from this software may not be called "Apache",
42 * nor may "Apache" appear in their name, without prior written
43 * permission of the Apache Software Foundation.
45 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
49 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * ====================================================================
60 /* ``Damned if you do,
61 damned if you don't.''
65 /* _________________________________________________________________
67 ** Support for Global Configuration
68 ** _________________________________________________________________
71 #define SSL_MOD_CONFIG_KEY "ssl_module"
73 SSLModConfigRec *ssl_config_global_create(server_rec *s)
75 apr_pool_t *pool = s->process->pool;
78 apr_pool_userdata_get((void **)&mc, SSL_MOD_CONFIG_KEY,
82 return mc; /* reused for lifetime of the server */
86 * allocate an own subpool which survives server restarts
88 mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc));
93 * initialize per-module configuration
95 mc->nSessionCacheMode = SSL_SCMODE_UNSET;
96 mc->szSessionCacheDataFile = NULL;
97 mc->nSessionCacheDataSize = 0;
99 mc->pSessionCacheDataMM = NULL;
101 mc->tSessionCacheDataTable = NULL;
102 mc->nMutexMode = SSL_MUTEXMODE_UNSET;
103 mc->szMutexFile = NULL;
105 mc->aRandSeed = apr_array_make(pool, 4,
106 sizeof(ssl_randseed_t));
107 mc->tVHostKeys = apr_hash_make(pool);
108 mc->tPrivateKey = apr_hash_make(pool);
109 mc->tPublicCert = apr_hash_make(pool);
110 mc->tTmpKeys = apr_hash_make(pool);
111 #ifdef SSL_EXPERIMENTAL_ENGINE
112 mc->szCryptoDevice = NULL;
115 memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
117 apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
118 apr_pool_cleanup_null,
124 void ssl_config_global_fix(SSLModConfigRec *mc)
129 BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
134 /* _________________________________________________________________
136 ** Configuration handling
137 ** _________________________________________________________________
141 * Create per-server SSL configuration
143 void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
145 SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
147 sc->mc = ssl_config_global_create(s);
148 sc->bEnabled = UNSET;
149 sc->szCACertificatePath = NULL;
150 sc->szCACertificateFile = NULL;
151 sc->szCertificateChain = NULL;
152 sc->szLogFile = NULL;
153 sc->szCipherSuite = NULL;
154 sc->nLogLevel = SSL_LOG_NONE;
155 sc->nVerifyDepth = UNSET;
156 sc->nVerifyClient = SSL_CVERIFY_UNSET;
157 sc->nSessionCacheTimeout = UNSET;
158 sc->nPassPhraseDialogType = SSL_PPTYPE_UNSET;
159 sc->szPassPhraseDialogPath = NULL;
160 sc->nProtocol = SSL_PROTOCOL_ALL;
161 sc->fileLogFile = NULL;
163 sc->szCARevocationPath = NULL;
164 sc->szCARevocationFile = NULL;
165 sc->pRevocationStore = NULL;
167 #ifdef SSL_EXPERIMENTAL_PROXY
168 sc->nProxyVerifyDepth = UNSET;
169 sc->szProxyCACertificatePath = NULL;
170 sc->szProxyCACertificateFile = NULL;
171 sc->szProxyClientCertificateFile = NULL;
172 sc->szProxyClientCertificatePath = NULL;
173 sc->szProxyCipherSuite = NULL;
174 sc->nProxyProtocol = SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_TLSV1;
175 sc->bProxyVerify = UNSET;
176 sc->pSSLProxyCtx = NULL;
179 memset(sc->szPublicCertFile, 0, sizeof(sc->szPublicCertFile));
180 memset(sc->szPrivateKeyFile, 0, sizeof(sc->szPrivateKeyFile));
181 memset(sc->pPublicCert, 0, sizeof(sc->pPublicCert));
182 memset(sc->pPrivateKey, 0, sizeof(sc->pPrivateKey));
188 * Merge per-server SSL configurations
190 void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
193 SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
194 SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv;
195 SSLSrvConfigRec *new = (SSLSrvConfigRec *)apr_palloc(p, sizeof(*new));
198 cfgMergeString(szVHostID);
199 cfgMergeBool(bEnabled);
200 cfgMergeString(szCACertificatePath);
201 cfgMergeString(szCACertificateFile);
202 cfgMergeString(szCertificateChain);
203 cfgMergeString(szLogFile);
204 cfgMergeString(szCipherSuite);
205 cfgMerge(nLogLevel, SSL_LOG_NONE);
206 cfgMergeInt(nVerifyDepth);
207 cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
208 cfgMergeInt(nSessionCacheTimeout);
209 cfgMerge(nPassPhraseDialogType, SSL_PPTYPE_UNSET);
210 cfgMergeString(szPassPhraseDialogPath);
211 cfgMerge(nProtocol, SSL_PROTOCOL_ALL);
212 cfgMerge(fileLogFile, NULL);
213 cfgMerge(pSSLCtx, NULL);
214 cfgMerge(szCARevocationPath, NULL);
215 cfgMerge(szCARevocationFile, NULL);
216 cfgMerge(pRevocationStore, NULL);
218 for (i = 0; i < SSL_AIDX_MAX; i++) {
219 cfgMergeString(szPublicCertFile[i]);
220 cfgMergeString(szPrivateKeyFile[i]);
221 cfgMerge(pPublicCert[i], NULL);
222 cfgMerge(pPrivateKey[i], NULL);
225 #ifdef SSL_EXPERIMENTAL_PROXY
226 cfgMergeInt(nProxyVerifyDepth);
227 cfgMergeString(szProxyCACertificatePath);
228 cfgMergeString(szProxyCACertificateFile);
229 cfgMergeString(szProxyClientCertificateFile);
230 cfgMergeString(szProxyClientCertificatePath);
231 cfgMergeString(szProxyCipherSuite);
232 cfgMerge(nProxyProtocol, (SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_TLSV1));
233 cfgMergeBool(bProxyVerify);
234 cfgMerge(pSSLProxyCtx, NULL);
241 * Create per-directory SSL configuration
243 void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
245 SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
247 dc->bSSLRequired = FALSE;
248 dc->aRequirement = apr_array_make(p, 4, sizeof(ssl_require_t));
249 dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET;
250 dc->nOptionsAdd = SSL_OPT_NONE;
251 dc->nOptionsDel = SSL_OPT_NONE;
253 dc->szCipherSuite = NULL;
254 dc->nVerifyClient = SSL_CVERIFY_UNSET;
255 dc->nVerifyDepth = UNSET;
257 #ifdef SSL_EXPERIMENTAL_PERDIRCA
258 dc->szCACertificatePath = NULL;
259 dc->szCACertificateFile = NULL;
266 * Merge per-directory SSL configurations
268 void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
270 SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
271 SSLDirConfigRec *add = (SSLDirConfigRec *)addv;
272 SSLDirConfigRec *new = (SSLDirConfigRec *)apr_palloc(p, sizeof(*new));
274 cfgMerge(bSSLRequired, FALSE);
275 cfgMergeArray(aRequirement);
277 if (add->nOptions & SSL_OPT_RELSET) {
279 (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
281 (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
283 (base->nOptions & ~(new->nOptionsDel)) | new->nOptionsAdd;
286 new->nOptions = add->nOptions;
287 new->nOptionsAdd = add->nOptionsAdd;
288 new->nOptionsDel = add->nOptionsDel;
291 cfgMergeString(szCipherSuite);
292 cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
293 cfgMergeInt(nVerifyDepth);
295 #ifdef SSL_EXPERIMENTAL_PERDIRCA
296 cfgMergeString(szCACertificatePath);
297 cfgMergeString(szCACertificateFile);
304 * Configuration functions for particular directives
307 const char *ssl_cmd_SSLMutex(cmd_parms *cmd, void *ctx,
311 SSLModConfigRec *mc = myModConfig(cmd->server);
313 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
317 if (ssl_config_global_isfixed(mc)) {
321 if (strcEQ(arg, "none") || strcEQ(arg, "no")) {
322 mc->nMutexMode = SSL_MUTEXMODE_NONE;
324 else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) {
325 mc->nMutexMode = SSL_MUTEXMODE_USED;
327 (char *)apr_psprintf(mc->pPool, "%s.%lu",
328 ap_server_root_relative(cmd->pool, arg+5),
329 (unsigned long)getpid());
331 else if (strcEQ(arg, "sem") || strcEQ(arg, "yes")) {
332 mc->nMutexMode = SSL_MUTEXMODE_USED;
333 mc->szMutexFile = NULL; /* APR determines temporary filename */
336 return "SSLMutex: Invalid argument";
342 const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd, void *ctx,
345 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
347 int arglen = strlen(arg);
349 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
353 if (strcEQ(arg, "builtin")) {
354 sc->nPassPhraseDialogType = SSL_PPTYPE_BUILTIN;
355 sc->szPassPhraseDialogPath = NULL;
357 else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
358 sc->nPassPhraseDialogType = SSL_PPTYPE_FILTER;
359 /* XXX This is broken, exec: may contain args! */
360 sc->szPassPhraseDialogPath =
361 ap_server_root_relative(cmd->pool, arg+5);
363 if (!ssl_util_path_check(SSL_PCM_EXISTS,
364 sc->szPassPhraseDialogPath,
367 return apr_pstrcat(cmd->pool,
368 "SSLPassPhraseDialog: file '",
369 sc->szPassPhraseDialogPath,
370 "' does not exist", NULL);
374 else if ((arglen > 1) && (arg[0] == '|')) {
375 sc->nPassPhraseDialogType = SSL_PPTYPE_PIPE;
376 sc->szPassPhraseDialogPath = arg + 1;
379 return "SSLPassPhraseDialog: Invalid argument";
385 #ifdef SSL_EXPERIMENTAL_ENGINE
386 const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd, void *ctx,
389 SSLModConfigRec *mc = myModConfig(cmd->server);
392 #if SSL_LIBRARY_VERSION >= 0x00907000
393 static int loaded_engines = FALSE;
395 /* early loading to make sure the engines are already
396 available for ENGINE_by_id() above... */
397 if (!loaded_engines) {
398 ENGINE_load_builtin_engines();
399 loaded_engines = TRUE;
402 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
406 if (strcEQ(arg, "builtin")) {
407 mc->szCryptoDevice = NULL;
409 else if ((e = ENGINE_by_id(arg))) {
410 mc->szCryptoDevice = arg;
414 return "SSLCryptoDevice: Invalid argument";
421 const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd, void *ctx,
426 SSLModConfigRec *mc = myModConfig(cmd->server);
428 ssl_randseed_t *seed;
429 int arg2len = strlen(arg2);
431 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
435 if (ssl_config_global_isfixed(mc)) {
439 seed = apr_array_push(mc->aRandSeed);
441 if (strcEQ(arg1, "startup")) {
442 seed->nCtx = SSL_RSCTX_STARTUP;
444 else if (strcEQ(arg1, "connect")) {
445 seed->nCtx = SSL_RSCTX_CONNECT;
448 return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
449 "invalid context: `", arg1, "'",
453 if ((arg2len > 5) && strEQn(arg2, "file:", 5)) {
454 seed->nSrc = SSL_RSSRC_FILE;
455 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
457 else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) {
458 seed->nSrc = SSL_RSSRC_EXEC;
459 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
461 else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
462 seed->nSrc = SSL_RSSRC_EGD;
463 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
465 else if (strcEQ(arg2, "builtin")) {
466 seed->nSrc = SSL_RSSRC_BUILTIN;
470 seed->nSrc = SSL_RSSRC_FILE;
471 seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
474 if (seed->nSrc != SSL_RSSRC_BUILTIN) {
475 if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) {
476 return apr_pstrcat(cmd->pool,
477 "SSLRandomSeed: source path '",
478 seed->cpPath, "' does not exist", NULL);
483 seed->nBytes = 0; /* read whole file */
486 if (seed->nSrc == SSL_RSSRC_BUILTIN) {
487 return "SSLRandomSeed: byte specification not "
488 "allowed for builtin seed source";
491 seed->nBytes = atoi(arg3);
493 if (seed->nBytes < 0) {
494 return "SSLRandomSeed: invalid number of bytes specified";
501 const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *ctx, int flag)
503 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
505 sc->bEnabled = flag ? TRUE : FALSE;
510 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd, void *ctx,
513 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
514 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
516 if (!(cmd->path || dc)) {
517 sc->szCipherSuite = arg;
520 dc->szCipherSuite = (char *)arg;
526 #define SSL_FLAGS_CHECK_FILE \
527 (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
529 #define SSL_FLAGS_CHECK_DIR \
530 (SSL_PCM_EXISTS|SSL_PCM_ISDIR)
532 static const char *ssl_cmd_check_file(cmd_parms *parms,
535 *file = ap_server_root_relative(parms->pool, *file);
537 if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
541 return apr_pstrcat(parms->pool, parms->cmd->name,
543 "' does not exist or is empty", NULL);
547 static const char *ssl_cmd_check_dir(cmd_parms *parms,
550 *dir = ap_server_root_relative(parms->pool, *dir);
552 if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
556 return apr_pstrcat(parms->pool, parms->cmd->name,
557 ": directory '", *dir,
558 "' does not exist", NULL);
562 #define SSL_AIDX_CERTS 1
563 #define SSL_AIDX_KEYS 2
565 static const char *ssl_cmd_check_aidx_max(cmd_parms *parms,
569 SSLSrvConfigRec *sc = mySrvConfig(parms->server);
570 const char *err, *desc, **files;
573 if ((err = ssl_cmd_check_file(parms, &arg))) {
579 desc = "certificates";
580 files = sc->szPublicCertFile;
583 desc = "private keys";
584 files = sc->szPrivateKeyFile;
588 for (i = 0; i < SSL_AIDX_MAX; i++) {
595 return apr_psprintf(parms->pool,
597 "different %s per virtual host allowed",
598 parms->cmd->name, SSL_AIDX_MAX, desc);
601 const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd, void *ctx,
607 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) {
614 const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd, void *ctx,
619 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) {
626 const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd, void *ctx,
629 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
632 if ((err = ssl_cmd_check_file(cmd, &arg))) {
636 sc->szCertificateChain = arg;
641 const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, void *ctx,
644 #ifdef SSL_EXPERIMENTAL_PERDIRCA
645 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
647 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
650 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
654 #ifdef SSL_EXPERIMENTAL_PERDIRCA
655 if (!(cmd->path || dc)) {
656 sc->szCACertificatePath = arg;
659 dc->szCACertificatePath = arg;
662 sc->szCACertificatePath = arg;
668 const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd, void *ctx,
671 #ifdef SSL_EXPERIMENTAL_PERDIRCA
672 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
674 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
677 if ((err = ssl_cmd_check_file(cmd, &arg))) {
681 #ifdef SSL_EXPERIMENTAL_PERDIRCA
682 if (!(cmd->path || dc)) {
683 sc->szCACertificateFile = arg;
686 dc->szCACertificateFile = arg;
689 sc->szCACertificateFile = arg;
695 const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd, void *ctx,
698 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
701 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
705 sc->szCARevocationPath = arg;
710 const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd, void *ctx,
713 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
716 if ((err = ssl_cmd_check_file(cmd, &arg))) {
720 sc->szCARevocationFile = arg;
725 static const char *ssl_cmd_verify_parse(cmd_parms *parms,
729 if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
730 *id = SSL_CVERIFY_NONE;
732 else if (strcEQ(arg, "optional")) {
733 *id = SSL_CVERIFY_OPTIONAL;
735 else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
736 *id = SSL_CVERIFY_REQUIRE;
738 else if (strcEQ(arg, "optional_no_ca")) {
739 *id = SSL_CVERIFY_OPTIONAL_NO_CA;
742 return apr_pstrcat(parms->temp_pool, parms->cmd->name,
743 ": Invalid argument '", arg, "'",
750 const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd, void *ctx,
753 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
754 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
758 if ((err = ssl_cmd_verify_parse(cmd, arg, &id))) {
762 if (!(cmd->path || dc)) {
763 sc->nVerifyClient = id;
766 dc->nVerifyClient = id;
772 static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
776 if ((*depth = atoi(arg)) >= 0) {
780 return apr_pstrcat(parms->temp_pool, parms->cmd->name,
781 ": Invalid argument '", arg, "'",
785 const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd, void *ctx,
788 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
789 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
793 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
797 if (!(cmd->path || dc)) {
798 sc->nVerifyDepth = depth;
801 dc->nVerifyDepth = depth;
807 const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd, void *ctx,
810 SSLModConfigRec *mc = myModConfig(cmd->server);
811 const char *err, *colon;
814 int arglen = strlen(arg);
816 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
820 if (ssl_config_global_isfixed(mc)) {
824 if (strcEQ(arg, "none")) {
825 mc->nSessionCacheMode = SSL_SCMODE_NONE;
826 mc->szSessionCacheDataFile = NULL;
828 else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) {
829 mc->nSessionCacheMode = SSL_SCMODE_DBM;
830 mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4);
832 else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) ||
833 ((arglen > 6) && strcEQn(arg, "shmht:", 6)))
836 if (!ap_mm_useable()) {
837 return "SSLSessionCache: shared memory cache "
838 "not useable on this platform";
842 mc->nSessionCacheMode = SSL_SCMODE_SHMHT;
843 colon = ap_strchr_c(arg, ':');
844 mc->szSessionCacheDataFile =
845 ap_server_root_relative(mc->pPool, colon+1);
846 mc->tSessionCacheDataTable = NULL;
847 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
849 if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
852 if (!(cp2 = strchr(cp, ')'))) {
853 return "SSLSessionCache: Invalid argument: "
854 "no closing parenthesis";
859 mc->nSessionCacheDataSize = atoi(cp);
861 if (mc->nSessionCacheDataSize <= 8192) {
862 return "SSLSessionCache: Invalid argument: "
863 "size has to be >= 8192 bytes";
867 maxsize = ap_mm_core_maxsegsize();
869 maxsize = 1024 * 512;
872 if (mc->nSessionCacheDataSize >= maxsize) {
873 return apr_psprintf(cmd->pool,
874 "SSLSessionCache: Invalid argument: "
875 "size has to be < %d bytes on this "
876 "platform", maxsize);
880 else if ((arglen > 6) && strcEQn(arg, "shmcb:", 6)) {
882 if (!ap_mm_useable()) {
883 return "SSLSessionCache: shared memory cache "
884 "not useable on this platform";
887 mc->nSessionCacheMode = SSL_SCMODE_SHMCB;
888 mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+6);
889 mc->tSessionCacheDataTable = NULL;
890 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
892 if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
895 if ((cp2 = strchr(cp, ')'))) {
896 return "SSLSessionCache: Invalid argument: "
897 "no closing parenthesis";
902 mc->nSessionCacheDataSize = atoi(cp);
904 if (mc->nSessionCacheDataSize <= 8192) {
905 return "SSLSessionCache: Invalid argument: "
906 "size has to be >= 8192 bytes";
911 maxsize = ap_mm_core_maxsegsize();
913 maxsize = 1024 * 512;
916 if (mc->nSessionCacheDataSize >= maxsize) {
917 return apr_psprintf(cmd->pool,
918 "SSLSessionCache: Invalid argument: "
919 "size has to be < %d bytes on this "
920 "platform", maxsize);
925 return "SSLSessionCache: Invalid argument";
932 const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd, void *ctx,
935 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
937 sc->nSessionCacheTimeout = atoi(arg);
939 if (sc->nSessionCacheTimeout < 0) {
940 return "SSLSessionCacheTimeout: Invalid argument";
946 #define SSL_FLAGS_LOG_CONTEXT \
947 (NOT_IN_LIMIT|NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
949 const char *ssl_cmd_SSLLog(cmd_parms *cmd, void *ctx,
952 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
955 if ((err = ap_check_cmd_context(cmd, SSL_FLAGS_LOG_CONTEXT))) {
964 const char *ssl_cmd_SSLLogLevel(cmd_parms *cmd, void *ctx,
967 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
970 if ((err = ap_check_cmd_context(cmd, SSL_FLAGS_LOG_CONTEXT))) {
974 if (strcEQ(level, "none")) {
975 sc->nLogLevel = SSL_LOG_NONE;
977 else if (strcEQ(level, "error")) {
978 sc->nLogLevel = SSL_LOG_ERROR;
980 else if (strcEQ(level, "warn")) {
981 sc->nLogLevel = SSL_LOG_WARN;
983 else if (strcEQ(level, "info")) {
984 sc->nLogLevel = SSL_LOG_INFO;
986 else if (strcEQ(level, "trace")) {
987 sc->nLogLevel = SSL_LOG_TRACE;
989 else if (strcEQ(level, "debug")) {
990 sc->nLogLevel = SSL_LOG_DEBUG;
993 return "SSLLogLevel: Invalid argument";
999 const char *ssl_cmd_SSLOptions(cmd_parms *cmd, void *ctx,
1002 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
1008 w = ap_getword_conf(cmd->pool, &arg);
1011 if ((*w == '+') || (*w == '-')) {
1015 dc->nOptions = SSL_OPT_NONE;
1019 if (strcEQ(w, "StdEnvVars")) {
1020 opt = SSL_OPT_STDENVVARS;
1022 else if (strcEQ(w, "CompatEnvVars")) {
1023 opt = SSL_OPT_COMPATENVVARS;
1025 else if (strcEQ(w, "ExportCertData")) {
1026 opt = SSL_OPT_EXPORTCERTDATA;
1028 else if (strcEQ(w, "FakeBasicAuth")) {
1029 opt = SSL_OPT_FAKEBASICAUTH;
1031 else if (strcEQ(w, "StrictRequire")) {
1032 opt = SSL_OPT_STRICTREQUIRE;
1034 else if (strcEQ(w, "OptRenegotiate")) {
1035 opt = SSL_OPT_OPTRENEGOTIATE;
1038 return apr_pstrcat(cmd->pool,
1039 "SSLOptions: Illegal option '", w, "'",
1043 if (action == '-') {
1044 dc->nOptionsAdd &= ~opt;
1045 dc->nOptionsDel |= opt;
1046 dc->nOptions &= ~opt;
1048 else if (action == '+') {
1049 dc->nOptionsAdd |= opt;
1050 dc->nOptionsDel &= ~opt;
1051 dc->nOptions |= opt;
1055 dc->nOptionsAdd = opt;
1056 dc->nOptionsDel = SSL_OPT_NONE;
1063 const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *ctx)
1065 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
1067 dc->bSSLRequired = TRUE;
1072 const char *ssl_cmd_SSLRequire(cmd_parms *cmd, void *ctx,
1075 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
1077 ssl_require_t *require;
1079 if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) {
1080 return apr_pstrcat(cmd->pool, "SSLRequire: ",
1081 ssl_expr_get_error(), NULL);
1084 require = apr_array_push(dc->aRequirement);
1085 require->cpExpr = apr_pstrdup(cmd->pool, arg);
1086 require->mpExpr = expr;
1091 static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
1093 ssl_proto_t *options)
1095 ssl_proto_t thisopt;
1097 *options = SSL_PROTOCOL_NONE;
1100 char *w = ap_getword_conf(parms->temp_pool, &arg);
1103 if ((*w == '+') || (*w == '-')) {
1107 if (strcEQ(w, "SSLv2")) {
1108 thisopt = SSL_PROTOCOL_SSLV2;
1110 else if (strcEQ(w, "SSLv3")) {
1111 thisopt = SSL_PROTOCOL_SSLV3;
1113 else if (strcEQ(w, "TLSv1")) {
1114 thisopt = SSL_PROTOCOL_TLSV1;
1116 else if (strcEQ(w, "all")) {
1117 thisopt = SSL_PROTOCOL_ALL;
1120 return apr_pstrcat(parms->temp_pool,
1122 ": Illegal protocol '",
1126 if (action == '-') {
1127 *options &= ~thisopt;
1129 else if (action == '+') {
1130 *options |= thisopt;
1140 const char *ssl_cmd_SSLProtocol(cmd_parms *cmd, void *ctx,
1143 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1145 return ssl_cmd_protocol_parse(cmd, opt, &sc->nProtocol);
1148 #ifdef SSL_EXPERIMENTAL_PROXY
1150 const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd, char *struct_ptr,
1153 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1155 return ssl_cmd_protocol_parse(cmd, opt, &sc->nProxyProtocol);
1158 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd, char *struct_ptr,
1161 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1163 sc->szProxyCipherSuite = arg;
1168 const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd, char *struct_ptr,
1171 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1173 sc->bProxyVerify = flag ? TRUE : FALSE;
1178 const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd, char *struct_ptr,
1181 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1185 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1189 sc->nProxyVerifyDepth = depth;
1194 const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
1198 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1201 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1205 sc->szProxyCACertificateFile = arg;
1210 const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
1214 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1217 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1221 sc->szProxyCACertificatePath = arg;
1226 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
1230 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1233 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1237 sc->szProxyClientCertificateFile = arg;
1242 const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
1246 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1249 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1253 sc->szProxyClientCertificatePath = arg;
1258 #endif /* SSL_EXPERIMENTAL_PROXY */