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 const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd, void *ctx,
565 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
569 if ((err = ssl_cmd_check_file(cmd, &arg))) {
573 for (i = 0; i < SSL_AIDX_MAX; i++) {
574 if (!sc->szPublicCertFile[i]) {
575 sc->szPublicCertFile[i] = arg;
580 return apr_psprintf(cmd->pool,
581 "SSLCertificateFile: only up to %d "
582 "different certificates per virtual host allowed",
586 const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd, void *ctx,
589 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
593 if ((err = ssl_cmd_check_file(cmd, &arg))) {
597 for (i = 0; i < SSL_AIDX_MAX; i++) {
598 if (!sc->szPrivateKeyFile[i]) {
599 sc->szPrivateKeyFile[i] = arg;
604 return apr_psprintf(cmd->pool,
605 "SSLCertificateKeyFile: only up to %d "
606 "different private keys per virtual host allowed",
610 const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd, void *ctx,
613 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
616 if ((err = ssl_cmd_check_file(cmd, &arg))) {
620 sc->szCertificateChain = arg;
625 const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, void *ctx,
628 #ifdef SSL_EXPERIMENTAL_PERDIRCA
629 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
631 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
634 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
638 #ifdef SSL_EXPERIMENTAL_PERDIRCA
639 if (!(cmd->path || dc)) {
640 sc->szCACertificatePath = arg;
643 dc->szCACertificatePath = arg;
646 sc->szCACertificatePath = arg;
652 const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd, void *ctx,
655 #ifdef SSL_EXPERIMENTAL_PERDIRCA
656 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
658 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
661 if ((err = ssl_cmd_check_file(cmd, &arg))) {
665 #ifdef SSL_EXPERIMENTAL_PERDIRCA
666 if (!(cmd->path || dc)) {
667 sc->szCACertificateFile = arg;
670 dc->szCACertificateFile = arg;
673 sc->szCACertificateFile = arg;
679 const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd, void *ctx,
682 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
685 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
689 sc->szCARevocationPath = arg;
694 const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd, void *ctx,
697 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
700 if ((err = ssl_cmd_check_file(cmd, &arg))) {
704 sc->szCARevocationFile = arg;
709 const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd, void *ctx,
712 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
713 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
716 if (strEQ(level, "0") || strcEQ(level, "none")) {
717 id = SSL_CVERIFY_NONE;
719 else if (strEQ(level, "1") || strcEQ(level, "optional")) {
720 id = SSL_CVERIFY_OPTIONAL;
722 else if (strEQ(level, "2") || strcEQ(level, "require")) {
723 id = SSL_CVERIFY_REQUIRE;
725 else if (strEQ(level, "3") || strcEQ(level, "optional_no_ca")) {
726 id = SSL_CVERIFY_OPTIONAL_NO_CA;
729 return "SSLVerifyClient: Invalid argument";
732 if (!(cmd->path || dc)) {
733 sc->nVerifyClient = id;
736 dc->nVerifyClient = id;
742 const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd, void *ctx,
745 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
746 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
750 return "SSLVerifyDepth: Invalid argument";
753 if (!(cmd->path || dc)) {
754 sc->nVerifyDepth = d;
757 dc->nVerifyDepth = d;
763 const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd, void *ctx,
766 SSLModConfigRec *mc = myModConfig(cmd->server);
767 const char *err, *colon;
770 int arglen = strlen(arg);
772 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
776 if (ssl_config_global_isfixed(mc)) {
780 if (strcEQ(arg, "none")) {
781 mc->nSessionCacheMode = SSL_SCMODE_NONE;
782 mc->szSessionCacheDataFile = NULL;
784 else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) {
785 mc->nSessionCacheMode = SSL_SCMODE_DBM;
786 mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4);
788 else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) ||
789 ((arglen > 6) && strcEQn(arg, "shmht:", 6)))
792 if (!ap_mm_useable()) {
793 return "SSLSessionCache: shared memory cache "
794 "not useable on this platform";
798 mc->nSessionCacheMode = SSL_SCMODE_SHMHT;
799 colon = ap_strchr_c(arg, ':');
800 mc->szSessionCacheDataFile =
801 ap_server_root_relative(mc->pPool, colon+1);
802 mc->tSessionCacheDataTable = NULL;
803 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
805 if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
808 if (!(cp2 = strchr(cp, ')'))) {
809 return "SSLSessionCache: Invalid argument: "
810 "no closing parenthesis";
815 mc->nSessionCacheDataSize = atoi(cp);
817 if (mc->nSessionCacheDataSize <= 8192) {
818 return "SSLSessionCache: Invalid argument: "
819 "size has to be >= 8192 bytes";
823 maxsize = ap_mm_core_maxsegsize();
825 maxsize = 1024 * 512;
828 if (mc->nSessionCacheDataSize >= maxsize) {
829 return apr_psprintf(cmd->pool,
830 "SSLSessionCache: Invalid argument: "
831 "size has to be < %d bytes on this "
832 "platform", maxsize);
836 else if ((arglen > 6) && strcEQn(arg, "shmcb:", 6)) {
838 if (!ap_mm_useable()) {
839 return "SSLSessionCache: shared memory cache "
840 "not useable on this platform";
843 mc->nSessionCacheMode = SSL_SCMODE_SHMCB;
844 mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+6);
845 mc->tSessionCacheDataTable = NULL;
846 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
848 if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
851 if ((cp2 = strchr(cp, ')'))) {
852 return "SSLSessionCache: Invalid argument: "
853 "no closing parenthesis";
858 mc->nSessionCacheDataSize = atoi(cp);
860 if (mc->nSessionCacheDataSize <= 8192) {
861 return "SSLSessionCache: Invalid argument: "
862 "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);
881 return "SSLSessionCache: Invalid argument";
888 const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd, void *ctx,
891 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
893 sc->nSessionCacheTimeout = atoi(arg);
895 if (sc->nSessionCacheTimeout < 0) {
896 return "SSLSessionCacheTimeout: Invalid argument";
902 #define SSL_FLAGS_LOG_CONTEXT \
903 (NOT_IN_LIMIT|NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
905 const char *ssl_cmd_SSLLog(cmd_parms *cmd, void *ctx,
908 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
911 if ((err = ap_check_cmd_context(cmd, SSL_FLAGS_LOG_CONTEXT))) {
920 const char *ssl_cmd_SSLLogLevel(cmd_parms *cmd, void *ctx,
923 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
926 if ((err = ap_check_cmd_context(cmd, SSL_FLAGS_LOG_CONTEXT))) {
930 if (strcEQ(level, "none")) {
931 sc->nLogLevel = SSL_LOG_NONE;
933 else if (strcEQ(level, "error")) {
934 sc->nLogLevel = SSL_LOG_ERROR;
936 else if (strcEQ(level, "warn")) {
937 sc->nLogLevel = SSL_LOG_WARN;
939 else if (strcEQ(level, "info")) {
940 sc->nLogLevel = SSL_LOG_INFO;
942 else if (strcEQ(level, "trace")) {
943 sc->nLogLevel = SSL_LOG_TRACE;
945 else if (strcEQ(level, "debug")) {
946 sc->nLogLevel = SSL_LOG_DEBUG;
949 return "SSLLogLevel: Invalid argument";
955 const char *ssl_cmd_SSLOptions(cmd_parms *cmd, void *ctx,
958 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
964 w = ap_getword_conf(cmd->pool, &arg);
967 if ((*w == '+') || (*w == '-')) {
971 dc->nOptions = SSL_OPT_NONE;
975 if (strcEQ(w, "StdEnvVars")) {
976 opt = SSL_OPT_STDENVVARS;
978 else if (strcEQ(w, "CompatEnvVars")) {
979 opt = SSL_OPT_COMPATENVVARS;
981 else if (strcEQ(w, "ExportCertData")) {
982 opt = SSL_OPT_EXPORTCERTDATA;
984 else if (strcEQ(w, "FakeBasicAuth")) {
985 opt = SSL_OPT_FAKEBASICAUTH;
987 else if (strcEQ(w, "StrictRequire")) {
988 opt = SSL_OPT_STRICTREQUIRE;
990 else if (strcEQ(w, "OptRenegotiate")) {
991 opt = SSL_OPT_OPTRENEGOTIATE;
994 return apr_pstrcat(cmd->pool,
995 "SSLOptions: Illegal option '", w, "'",
1000 dc->nOptionsAdd &= ~opt;
1001 dc->nOptionsDel |= opt;
1002 dc->nOptions &= ~opt;
1004 else if (action == '+') {
1005 dc->nOptionsAdd |= opt;
1006 dc->nOptionsDel &= ~opt;
1007 dc->nOptions |= opt;
1011 dc->nOptionsAdd = opt;
1012 dc->nOptionsDel = SSL_OPT_NONE;
1019 const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *ctx)
1021 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
1023 dc->bSSLRequired = TRUE;
1028 const char *ssl_cmd_SSLRequire(cmd_parms *cmd, void *ctx,
1031 SSLDirConfigRec *dc = (SSLDirConfigRec *)ctx;
1033 ssl_require_t *require;
1035 if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) {
1036 return apr_pstrcat(cmd->pool, "SSLRequire: ",
1037 ssl_expr_get_error(), NULL);
1040 require = apr_array_push(dc->aRequirement);
1041 require->cpExpr = apr_pstrdup(cmd->pool, arg);
1042 require->mpExpr = expr;
1047 const char *ssl_cmd_SSLProtocol(cmd_parms *cmd, void *ctx,
1050 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1051 ssl_proto_t thisopt, options = SSL_PROTOCOL_NONE;
1054 char *w = ap_getword_conf(cmd->pool, &opt);
1057 if ((*w == '+') || (*w == '-')) {
1061 if (strcEQ(w, "SSLv2")) {
1062 thisopt = SSL_PROTOCOL_SSLV2;
1064 else if (strcEQ(w, "SSLv3")) {
1065 thisopt = SSL_PROTOCOL_SSLV3;
1067 else if (strcEQ(w, "TLSv1")) {
1068 thisopt = SSL_PROTOCOL_TLSV1;
1070 else if (strcEQ(w, "all")) {
1071 thisopt = SSL_PROTOCOL_ALL;
1074 return apr_pstrcat(cmd->pool,
1075 "SSLProtocol: Illegal protocol '",
1079 if (action == '-') {
1080 options &= ~thisopt;
1082 else if (action == '+') {
1090 sc->nProtocol = options;
1095 #ifdef SSL_EXPERIMENTAL_PROXY
1097 const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd, char *struct_ptr,
1100 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1101 ssl_proto_t thisopt, options = SSL_PROTOCOL_NONE;
1104 char *w = ap_getword_conf(cmd->pool, &opt);
1107 if ((*w == '+') || (*w == '-')) {
1111 if (strcEQ(w, "SSLv2")) {
1112 thisopt = SSL_PROTOCOL_SSLV2;
1114 else if (strcEQ(w, "SSLv3")) {
1115 thisopt = SSL_PROTOCOL_SSLV3;
1117 else if (strcEQ(w, "TLSv1")) {
1118 thisopt = SSL_PROTOCOL_TLSV1;
1120 else if (strcEQ(w, "all")) {
1121 thisopt = SSL_PROTOCOL_ALL;
1124 return apr_pstrcat(cmd->pool,
1125 "SSLProxyProtocol: Illegal protocol '",
1129 if (action == '-') {
1130 options &= ~thisopt;
1132 else if (action == '+') {
1140 sc->nProxyProtocol = options;
1145 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd, char *struct_ptr,
1148 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1150 sc->szProxyCipherSuite = arg;
1155 const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd, char *struct_ptr,
1158 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1160 sc->bProxyVerify = flag ? TRUE : FALSE;
1165 const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd, char *struct_ptr,
1168 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1172 return "SSLProxyVerifyDepth: Invalid argument";
1175 sc->nProxyVerifyDepth = d;
1180 const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
1184 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1187 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1191 sc->szProxyCACertificateFile = arg;
1196 const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
1200 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1203 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1207 sc->szProxyCACertificatePath = arg;
1212 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
1216 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1219 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1223 sc->szProxyClientCertificateFile = arg;
1228 const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
1232 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1235 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1239 sc->szProxyClientCertificatePath = arg;
1244 #endif /* SSL_EXPERIMENTAL_PROXY */