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.''
66 /* _________________________________________________________________
68 ** Support for Global Configuration
69 ** _________________________________________________________________
72 void ssl_hook_AddModule(module *m)
74 if (m == &ssl_module) {
76 * Announce us for the configuration files
78 ap_add_config_define("MOD_SSL");
81 * Link ourself into the Apache kernel
86 #if defined(SSL_VENDOR) && defined(SSL_VENDOR_OBJS)
87 ssl_vendor_register();
93 void ssl_hook_RemoveModule(module *m)
95 if (m == &ssl_module) {
97 * Unlink ourself from the Apache kernel
100 ssl_ext_unregister();
102 #if defined(SSL_VENDOR) && defined(SSL_VENDOR_OBJS)
103 ssl_vendor_unregister();
109 void ssl_config_global_create(void)
114 mc = ap_ctx_get(ap_global_ctx, "ssl_module");
117 * allocate an own subpool which survives server restarts
119 pPool = ap_make_sub_pool(NULL);
120 mc = (SSLModConfigRec *)ap_palloc(pPool, sizeof(SSLModConfigRec));
125 * initialize per-module configuration
128 mc->nSessionCacheMode = SSL_SCMODE_UNSET;
129 mc->szSessionCacheDataFile = NULL;
130 mc->nSessionCacheDataSize = 0;
131 mc->pSessionCacheDataMM = NULL;
132 mc->tSessionCacheDataTable = NULL;
133 mc->nMutexMode = SSL_MUTEXMODE_UNSET;
134 mc->szMutexFile = NULL;
136 mc->nMutexSEMID = -1;
137 mc->aRandSeed = ap_make_array(pPool, 4, sizeof(ssl_randseed_t));
138 mc->tPrivateKey = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
139 mc->tPublicCert = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
140 mc->tTmpKeys = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
141 #ifdef SSL_EXPERIMENTAL_ENGINE
142 mc->szCryptoDevice = NULL;
145 (void)memset(mc->pTmpKeys, 0, SSL_TKPIDX_MAX*sizeof(void *));
148 mc->ctx = ap_ctx_new(pPool);
149 ap_hook_use("ap::mod_ssl::vendor::config_global_create",
150 AP_HOOK_SIG2(void,ptr), AP_HOOK_MODE_ALL, mc);
154 * And push it into Apache's global context
156 ap_ctx_set(ap_global_ctx, "ssl_module", mc);
161 void ssl_config_global_fix(void)
163 SSLModConfigRec *mc = myModConfig();
168 BOOL ssl_config_global_isfixed(void)
170 SSLModConfigRec *mc = myModConfig();
175 /* _________________________________________________________________
177 ** Configuration handling
178 ** _________________________________________________________________
182 * Create per-server SSL configuration
184 void *ssl_config_server_create(pool *p, server_rec *s)
188 ssl_config_global_create();
190 sc = ap_palloc(p, sizeof(SSLSrvConfigRec));
191 sc->bEnabled = UNSET;
192 sc->szCACertificatePath = NULL;
193 sc->szCACertificateFile = NULL;
194 sc->szCertificateChain = NULL;
195 sc->szLogFile = NULL;
196 sc->szCipherSuite = NULL;
197 sc->nLogLevel = SSL_LOG_NONE;
198 sc->nVerifyDepth = UNSET;
199 sc->nVerifyClient = SSL_CVERIFY_UNSET;
200 sc->nSessionCacheTimeout = UNSET;
201 sc->nPassPhraseDialogType = SSL_PPTYPE_UNSET;
202 sc->szPassPhraseDialogPath = NULL;
203 sc->nProtocol = SSL_PROTOCOL_ALL;
204 sc->fileLogFile = NULL;
206 sc->szCARevocationPath = NULL;
207 sc->szCARevocationFile = NULL;
208 sc->pRevocationStore = NULL;
210 #ifdef SSL_EXPERIMENTAL_PROXY
211 sc->nProxyVerifyDepth = UNSET;
212 sc->szProxyCACertificatePath = NULL;
213 sc->szProxyCACertificateFile = NULL;
214 sc->szProxyClientCertificateFile = NULL;
215 sc->szProxyClientCertificatePath = NULL;
216 sc->szProxyCipherSuite = NULL;
217 sc->nProxyProtocol = SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_TLSV1;
218 sc->bProxyVerify = UNSET;
219 sc->pSSLProxyCtx = NULL;
222 (void)memset(sc->szPublicCertFile, 0, SSL_AIDX_MAX*sizeof(char *));
223 (void)memset(sc->szPrivateKeyFile, 0, SSL_AIDX_MAX*sizeof(char *));
224 (void)memset(sc->pPublicCert, 0, SSL_AIDX_MAX*sizeof(X509 *));
225 (void)memset(sc->pPrivateKey, 0, SSL_AIDX_MAX*sizeof(EVP_PKEY *));
228 sc->ctx = ap_ctx_new(p);
229 ap_hook_use("ap::mod_ssl::vendor::config_server_create",
230 AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
238 * Merge per-server SSL configurations
240 void *ssl_config_server_merge(pool *p, void *basev, void *addv)
242 SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
243 SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv;
244 SSLSrvConfigRec *new = (SSLSrvConfigRec *)ap_palloc(p, sizeof(SSLSrvConfigRec));
247 cfgMergeBool(bEnabled);
248 cfgMergeString(szCACertificatePath);
249 cfgMergeString(szCACertificateFile);
250 cfgMergeString(szCertificateChain);
251 cfgMergeString(szLogFile);
252 cfgMergeString(szCipherSuite);
253 cfgMerge(nLogLevel, SSL_LOG_NONE);
254 cfgMergeInt(nVerifyDepth);
255 cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
256 cfgMergeInt(nSessionCacheTimeout);
257 cfgMerge(nPassPhraseDialogType, SSL_PPTYPE_UNSET);
258 cfgMergeString(szPassPhraseDialogPath);
259 cfgMerge(nProtocol, SSL_PROTOCOL_ALL);
260 cfgMerge(fileLogFile, NULL);
261 cfgMerge(pSSLCtx, NULL);
262 cfgMerge(szCARevocationPath, NULL);
263 cfgMerge(szCARevocationFile, NULL);
264 cfgMerge(pRevocationStore, NULL);
266 for (i = 0; i < SSL_AIDX_MAX; i++) {
267 cfgMergeString(szPublicCertFile[i]);
268 cfgMergeString(szPrivateKeyFile[i]);
269 cfgMerge(pPublicCert[i], NULL);
270 cfgMerge(pPrivateKey[i], NULL);
275 ap_hook_use("ap::mod_ssl::vendor::config_server_merge",
276 AP_HOOK_SIG5(void,ptr,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
280 #ifdef SSL_EXPERIMENTAL_PROXY
281 cfgMergeInt(nProxyVerifyDepth);
282 cfgMergeString(szProxyCACertificatePath);
283 cfgMergeString(szProxyCACertificateFile);
284 cfgMergeString(szProxyClientCertificateFile);
285 cfgMergeString(szProxyClientCertificatePath);
286 cfgMergeString(szProxyCipherSuite);
287 cfgMerge(nProxyProtocol, (SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_TLSV1));
288 cfgMergeBool(bProxyVerify);
289 cfgMerge(pSSLProxyCtx, NULL);
296 * Create per-directory SSL configuration
298 void *ssl_config_perdir_create(pool *p, char *dir)
300 SSLDirConfigRec *dc = ap_palloc(p, sizeof(SSLDirConfigRec));
302 dc->bSSLRequired = FALSE;
303 dc->aRequirement = ap_make_array(p, 4, sizeof(ssl_require_t));
304 dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET;
305 dc->nOptionsAdd = SSL_OPT_NONE;
306 dc->nOptionsDel = SSL_OPT_NONE;
308 dc->szCipherSuite = NULL;
309 dc->nVerifyClient = SSL_CVERIFY_UNSET;
310 dc->nVerifyDepth = UNSET;
311 #ifdef SSL_EXPERIMENTAL_PERDIRCA
312 dc->szCACertificatePath = NULL;
313 dc->szCACertificateFile = NULL;
317 dc->ctx = ap_ctx_new(p);
318 ap_hook_use("ap::mod_ssl::vendor::config_perdir_create",
319 AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
327 * Merge per-directory SSL configurations
329 void *ssl_config_perdir_merge(pool *p, void *basev, void *addv)
331 SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
332 SSLDirConfigRec *add = (SSLDirConfigRec *)addv;
333 SSLDirConfigRec *new = (SSLDirConfigRec *)ap_palloc(p,
334 sizeof(SSLDirConfigRec));
336 cfgMerge(bSSLRequired, FALSE);
337 cfgMergeArray(aRequirement);
339 if (add->nOptions & SSL_OPT_RELSET) {
340 new->nOptionsAdd = (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
341 new->nOptionsDel = (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
342 new->nOptions = (base->nOptions & ~(new->nOptionsDel)) | new->nOptionsAdd;
345 new->nOptions = add->nOptions;
346 new->nOptionsAdd = add->nOptionsAdd;
347 new->nOptionsDel = add->nOptionsDel;
350 cfgMergeString(szCipherSuite);
351 cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
352 cfgMergeInt(nVerifyDepth);
353 #ifdef SSL_EXPERIMENTAL_PERDIRCA
354 cfgMergeString(szCACertificatePath);
355 cfgMergeString(szCACertificateFile);
360 ap_hook_use("ap::mod_ssl::vendor::config_perdir_merge",
361 AP_HOOK_SIG5(void,ptr,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
369 * Directive Rewriting
372 char *ssl_hook_RewriteCommand(cmd_parms *cmd, void *config, const char *cmd_line)
375 return ssl_compat_directive(cmd->server, cmd->pool, cmd_line);
382 * Configuration functions for particular directives
385 const char *ssl_cmd_SSLMutex(
386 cmd_parms *cmd, char *struct_ptr, char *arg)
389 SSLModConfigRec *mc = myModConfig();
391 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
393 if (ssl_config_global_isfixed())
395 if (strcEQ(arg, "none")) {
396 mc->nMutexMode = SSL_MUTEXMODE_NONE;
398 else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) {
400 mc->nMutexMode = SSL_MUTEXMODE_FILE;
401 mc->szMutexFile = ap_psprintf(mc->pPool, "%s.%lu",
402 ssl_util_server_root_relative(cmd->pool, "mutex", arg+5),
403 (unsigned long)getpid());
405 return "SSLMutex: Lockfiles not available on this platform";
408 else if (strcEQ(arg, "sem")) {
409 #ifdef SSL_CAN_USE_SEM
410 mc->nMutexMode = SSL_MUTEXMODE_SEM;
412 return "SSLMutex: Semaphores not available on this platform";
416 return "SSLMutex: Invalid argument";
420 const char *ssl_cmd_SSLPassPhraseDialog(
421 cmd_parms *cmd, char *struct_ptr, char *arg)
423 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
426 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
428 if (strcEQ(arg, "builtin")) {
429 sc->nPassPhraseDialogType = SSL_PPTYPE_BUILTIN;
430 sc->szPassPhraseDialogPath = NULL;
432 else if (strlen(arg) > 5 && strEQn(arg, "exec:", 5)) {
433 sc->nPassPhraseDialogType = SSL_PPTYPE_FILTER;
434 sc->szPassPhraseDialogPath = ssl_util_server_root_relative(cmd->pool, "dialog", arg+5);
435 if (!ssl_util_path_check(SSL_PCM_EXISTS, sc->szPassPhraseDialogPath))
436 return ap_pstrcat(cmd->pool, "SSLPassPhraseDialog: file '",
437 sc->szPassPhraseDialogPath, "' not exists", NULL);
440 return "SSLPassPhraseDialog: Invalid argument";
444 #ifdef SSL_EXPERIMENTAL_ENGINE
445 const char *ssl_cmd_SSLCryptoDevice(
446 cmd_parms *cmd, char *struct_ptr, char *arg)
448 SSLModConfigRec *mc = myModConfig();
451 #if SSL_LIBRARY_VERSION >= 0x00907000
452 static int loaded_engines = FALSE;
454 /* early loading to make sure the engines are already
455 available for ENGINE_by_id() above... */
456 if (!loaded_engines) {
457 ENGINE_load_builtin_engines();
458 loaded_engines = TRUE;
461 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
463 if (strcEQ(arg, "builtin")) {
464 mc->szCryptoDevice = NULL;
466 else if ((e = ENGINE_by_id(arg)) != NULL) {
467 mc->szCryptoDevice = arg;
471 return "SSLCryptoDevice: Invalid argument";
476 const char *ssl_cmd_SSLRandomSeed(
477 cmd_parms *cmd, char *struct_ptr, char *arg1, char *arg2, char *arg3)
479 SSLModConfigRec *mc = myModConfig();
483 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
485 if (ssl_config_global_isfixed())
487 pRS = ap_push_array(mc->aRandSeed);
488 if (strcEQ(arg1, "startup"))
489 pRS->nCtx = SSL_RSCTX_STARTUP;
490 else if (strcEQ(arg1, "connect"))
491 pRS->nCtx = SSL_RSCTX_CONNECT;
493 return ap_pstrcat(cmd->pool, "SSLRandomSeed: "
494 "invalid context: `", arg1, "'");
495 if (strlen(arg2) > 5 && strEQn(arg2, "file:", 5)) {
496 pRS->nSrc = SSL_RSSRC_FILE;
497 pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2+5));
499 else if (strlen(arg2) > 5 && strEQn(arg2, "exec:", 5)) {
500 pRS->nSrc = SSL_RSSRC_EXEC;
501 pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2+5));
503 #if SSL_LIBRARY_VERSION >= 0x00905100
504 else if (strlen(arg2) > 4 && strEQn(arg2, "egd:", 4)) {
505 pRS->nSrc = SSL_RSSRC_EGD;
506 pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2+4));
509 else if (strcEQ(arg2, "builtin")) {
510 pRS->nSrc = SSL_RSSRC_BUILTIN;
514 pRS->nSrc = SSL_RSSRC_FILE;
515 pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2));
517 if (pRS->nSrc != SSL_RSSRC_BUILTIN)
518 if (!ssl_util_path_check(SSL_PCM_EXISTS, pRS->cpPath))
519 return ap_pstrcat(cmd->pool, "SSLRandomSeed: source path '",
520 pRS->cpPath, "' not exists", NULL);
522 pRS->nBytes = 0; /* read whole file */
524 if (pRS->nSrc == SSL_RSSRC_BUILTIN)
525 return "SSLRandomSeed: byte specification not "
526 "allowed for builtin seed source";
527 pRS->nBytes = atoi(arg3);
529 return "SSLRandomSeed: invalid number of bytes specified";
534 const char *ssl_cmd_SSLEngine(
535 cmd_parms *cmd, char *struct_ptr, int flag)
537 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
539 sc->bEnabled = (flag ? TRUE : FALSE);
543 const char *ssl_cmd_SSLCipherSuite(
544 cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
546 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
548 if (cmd->path == NULL || dc == NULL)
549 sc->szCipherSuite = arg;
551 dc->szCipherSuite = arg;
555 const char *ssl_cmd_SSLCertificateFile(
556 cmd_parms *cmd, char *struct_ptr, char *arg)
558 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
562 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
563 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
564 return ap_pstrcat(cmd->pool, "SSLCertificateFile: file '",
565 cpPath, "' not exists or empty", NULL);
566 for (i = 0; i < SSL_AIDX_MAX && sc->szPublicCertFile[i] != NULL; i++)
568 if (i == SSL_AIDX_MAX)
569 return ap_psprintf(cmd->pool, "SSLCertificateFile: only up to %d "
570 "different certificates per virtual host allowed",
572 sc->szPublicCertFile[i] = cpPath;
576 const char *ssl_cmd_SSLCertificateKeyFile(
577 cmd_parms *cmd, char *struct_ptr, char *arg)
579 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
583 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
584 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
585 return ap_pstrcat(cmd->pool, "SSLCertificateKeyFile: file '",
586 cpPath, "' not exists or empty", NULL);
587 for (i = 0; i < SSL_AIDX_MAX && sc->szPrivateKeyFile[i] != NULL; i++)
589 if (i == SSL_AIDX_MAX)
590 return ap_psprintf(cmd->pool, "SSLCertificateKeyFile: only up to %d "
591 "different private keys per virtual host allowed",
593 sc->szPrivateKeyFile[i] = cpPath;
597 const char *ssl_cmd_SSLCertificateChainFile(
598 cmd_parms *cmd, char *struct_ptr, char *arg)
600 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
603 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
604 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
605 return ap_pstrcat(cmd->pool, "SSLCertificateChainFile: file '",
606 cpPath, "' not exists or empty", NULL);
607 sc->szCertificateChain = cpPath;
611 const char *ssl_cmd_SSLCACertificatePath(
612 cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
614 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
617 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
618 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
619 return ap_pstrcat(cmd->pool, "SSLCACertificatePath: directory '",
620 cpPath, "' not exists", NULL);
621 #ifdef SSL_EXPERIMENTAL_PERDIRCA
622 if (cmd->path == NULL || dc == NULL)
623 sc->szCACertificatePath = cpPath;
625 dc->szCACertificatePath = cpPath;
627 sc->szCACertificatePath = cpPath;
632 const char *ssl_cmd_SSLCACertificateFile(
633 cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
635 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
638 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
639 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
640 return ap_pstrcat(cmd->pool, "SSLCACertificateFile: file '",
641 cpPath, "' not exists or empty", NULL);
642 #ifdef SSL_EXPERIMENTAL_PERDIRCA
643 if (cmd->path == NULL || dc == NULL)
644 sc->szCACertificateFile = cpPath;
646 dc->szCACertificateFile = cpPath;
648 sc->szCACertificateFile = cpPath;
653 const char *ssl_cmd_SSLCARevocationPath(
654 cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
656 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
659 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
660 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
661 return ap_pstrcat(cmd->pool, "SSLCARecocationPath: directory '",
662 cpPath, "' not exists", NULL);
663 sc->szCARevocationPath = cpPath;
667 const char *ssl_cmd_SSLCARevocationFile(
668 cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
670 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
673 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
674 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
675 return ap_pstrcat(cmd->pool, "SSLCARevocationFile: file '",
676 cpPath, "' not exists or empty", NULL);
677 sc->szCARevocationFile = cpPath;
681 const char *ssl_cmd_SSLVerifyClient(
682 cmd_parms *cmd, SSLDirConfigRec *dc, char *level)
684 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
687 if (strEQ(level, "0") || strcEQ(level, "none"))
688 id = SSL_CVERIFY_NONE;
689 else if (strEQ(level, "1") || strcEQ(level, "optional"))
690 id = SSL_CVERIFY_OPTIONAL;
691 else if (strEQ(level, "2") || strcEQ(level, "require"))
692 id = SSL_CVERIFY_REQUIRE;
693 else if (strEQ(level, "3") || strcEQ(level, "optional_no_ca"))
694 id = SSL_CVERIFY_OPTIONAL_NO_CA;
696 return "SSLVerifyClient: Invalid argument";
697 if (cmd->path == NULL || dc == NULL)
698 sc->nVerifyClient = id;
700 dc->nVerifyClient = id;
704 const char *ssl_cmd_SSLVerifyDepth(
705 cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
707 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
712 return "SSLVerifyDepth: Invalid argument";
713 if (cmd->path == NULL || dc == NULL)
714 sc->nVerifyDepth = d;
716 dc->nVerifyDepth = d;
720 const char *ssl_cmd_SSLSessionCache(
721 cmd_parms *cmd, char *struct_ptr, char *arg)
724 SSLModConfigRec *mc = myModConfig();
728 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
730 if (ssl_config_global_isfixed())
732 if (strcEQ(arg, "none")) {
733 mc->nSessionCacheMode = SSL_SCMODE_NONE;
734 mc->szSessionCacheDataFile = NULL;
736 else if (strlen(arg) > 4 && strcEQn(arg, "dbm:", 4)) {
737 mc->nSessionCacheMode = SSL_SCMODE_DBM;
738 mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool,
739 ssl_util_server_root_relative(cmd->pool, "scache", arg+4));
741 else if ( (strlen(arg) > 4 && strcEQn(arg, "shm:", 4))
742 || (strlen(arg) > 6 && strcEQn(arg, "shmht:", 6))) {
743 if (!ap_mm_useable())
744 return "SSLSessionCache: shared memory cache not useable on this platform";
745 mc->nSessionCacheMode = SSL_SCMODE_SHMHT;
746 cp = strchr(arg, ':');
747 mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool,
748 ssl_util_server_root_relative(cmd->pool, "scache", cp+1));
749 mc->tSessionCacheDataTable = NULL;
750 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
751 if ((cp = strchr(mc->szSessionCacheDataFile, '(')) != NULL) {
753 if ((cp2 = strchr(cp, ')')) == NULL)
754 return "SSLSessionCache: Invalid argument: no closing parenthesis";
756 mc->nSessionCacheDataSize = atoi(cp);
757 if (mc->nSessionCacheDataSize <= 8192)
758 return "SSLSessionCache: Invalid argument: size has to be >= 8192 bytes";
759 maxsize = ap_mm_core_maxsegsize();
760 if (mc->nSessionCacheDataSize >= maxsize)
761 return ap_psprintf(cmd->pool, "SSLSessionCache: Invalid argument: "
762 "size has to be < %d bytes on this platform", maxsize);
765 else if (strlen(arg) > 6 && strcEQn(arg, "shmcb:", 6)) {
766 if (!ap_mm_useable())
767 return "SSLSessionCache: shared memory cache not useable on this platform";
768 mc->nSessionCacheMode = SSL_SCMODE_SHMCB;
769 mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool,
770 ap_server_root_relative(cmd->pool, arg+6));
771 mc->tSessionCacheDataTable = NULL;
772 mc->nSessionCacheDataSize = 1024*512; /* 512KB */
773 if ((cp = strchr(mc->szSessionCacheDataFile, '(')) != NULL) {
775 if ((cp2 = strchr(cp, ')')) == NULL)
776 return "SSLSessionCache: Invalid argument: no closing parenthesis";
778 mc->nSessionCacheDataSize = atoi(cp);
779 if (mc->nSessionCacheDataSize <= 8192)
780 return "SSLSessionCache: Invalid argument: size has to be >= 8192 bytes";
781 maxsize = ap_mm_core_maxsegsize();
782 if (mc->nSessionCacheDataSize >= maxsize)
783 return ap_psprintf(cmd->pool, "SSLSessionCache: Invalid argument: "
784 "size has to be < %d bytes on this platform", maxsize);
789 if (!ap_hook_use("ap::mod_ssl::vendor::cmd_sslsessioncache",
790 AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
793 return "SSLSessionCache: Invalid argument";
797 const char *ssl_cmd_SSLSessionCacheTimeout(
798 cmd_parms *cmd, char *struct_ptr, char *arg)
800 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
802 sc->nSessionCacheTimeout = atoi(arg);
803 if (sc->nSessionCacheTimeout < 0)
804 return "SSLSessionCacheTimeout: Invalid argument";
808 const char *ssl_cmd_SSLLog(
809 cmd_parms *cmd, char *struct_ptr, char *arg)
811 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
814 if ((err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_DIRECTORY
815 |NOT_IN_LOCATION|NOT_IN_FILES )) != NULL)
821 const char *ssl_cmd_SSLLogLevel(
822 cmd_parms *cmd, char *struct_ptr, char *level)
824 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
827 if ((err = ap_check_cmd_context(cmd, NOT_IN_LIMIT|NOT_IN_DIRECTORY
828 |NOT_IN_LOCATION|NOT_IN_FILES )) != NULL)
830 if (strcEQ(level, "none"))
831 sc->nLogLevel = SSL_LOG_NONE;
832 else if (strcEQ(level, "error"))
833 sc->nLogLevel = SSL_LOG_ERROR;
834 else if (strcEQ(level, "warn"))
835 sc->nLogLevel = SSL_LOG_WARN;
836 else if (strcEQ(level, "info"))
837 sc->nLogLevel = SSL_LOG_INFO;
838 else if (strcEQ(level, "trace"))
839 sc->nLogLevel = SSL_LOG_TRACE;
840 else if (strcEQ(level, "debug"))
841 sc->nLogLevel = SSL_LOG_DEBUG;
843 return "SSLLogLevel: Invalid argument";
847 const char *ssl_cmd_SSLOptions(
848 cmd_parms *cmd, SSLDirConfigRec *dc, const char *cpLine)
856 while (cpLine[0] != NUL) {
857 w = ap_getword_conf(cmd->pool, &cpLine);
860 if (*w == '+' || *w == '-') {
864 dc->nOptions = SSL_OPT_NONE;
868 if (strcEQ(w, "StdEnvVars"))
869 opt = SSL_OPT_STDENVVARS;
870 else if (strcEQ(w, "CompatEnvVars"))
871 opt = SSL_OPT_COMPATENVVARS;
872 else if (strcEQ(w, "ExportCertData"))
873 opt = SSL_OPT_EXPORTCERTDATA;
874 else if (strcEQ(w, "FakeBasicAuth"))
875 opt = SSL_OPT_FAKEBASICAUTH;
876 else if (strcEQ(w, "StrictRequire"))
877 opt = SSL_OPT_STRICTREQUIRE;
878 else if (strcEQ(w, "OptRenegotiate"))
879 opt = SSL_OPT_OPTRENEGOTIATE;
881 return ap_pstrcat(cmd->pool, "SSLOptions: Illegal option '", w, "'", NULL);
884 dc->nOptionsAdd &= ~opt;
885 dc->nOptionsDel |= opt;
886 dc->nOptions &= ~opt;
888 else if (action == '+') {
889 dc->nOptionsAdd |= opt;
890 dc->nOptionsDel &= ~opt;
895 dc->nOptionsAdd = opt;
896 dc->nOptionsDel = SSL_OPT_NONE;
902 const char *ssl_cmd_SSLRequireSSL(
903 cmd_parms *cmd, SSLDirConfigRec *dc, char *cipher)
905 dc->bSSLRequired = TRUE;
909 const char *ssl_cmd_SSLRequire(
910 cmd_parms *cmd, SSLDirConfigRec *dc, char *cpExpr)
913 ssl_require_t *pReqRec;
915 if ((mpExpr = ssl_expr_comp(cmd->pool, cpExpr)) == NULL)
916 return ap_pstrcat(cmd->pool, "SSLRequire: ", ssl_expr_get_error(), NULL);
917 pReqRec = ap_push_array(dc->aRequirement);
918 pReqRec->cpExpr = ap_pstrdup(cmd->pool, cpExpr);
919 pReqRec->mpExpr = mpExpr;
923 const char *ssl_cmd_SSLProtocol(
924 cmd_parms *cmd, char *struct_ptr, const char *opt)
927 ssl_proto_t options, thisopt;
931 sc = mySrvConfig(cmd->server);
932 options = SSL_PROTOCOL_NONE;
933 while (opt[0] != NUL) {
934 w = ap_getword_conf(cmd->pool, &opt);
937 if (*w == '+' || *w == '-')
940 if (strcEQ(w, "SSLv2"))
941 thisopt = SSL_PROTOCOL_SSLV2;
942 else if (strcEQ(w, "SSLv3"))
943 thisopt = SSL_PROTOCOL_SSLV3;
944 else if (strcEQ(w, "TLSv1"))
945 thisopt = SSL_PROTOCOL_TLSV1;
946 else if (strcEQ(w, "all"))
947 thisopt = SSL_PROTOCOL_ALL;
949 return ap_pstrcat(cmd->pool, "SSLProtocol: Illegal protocol '", w, "'", NULL);
953 else if (action == '+')
958 sc->nProtocol = options;
962 #ifdef SSL_EXPERIMENTAL_PROXY
964 const char *ssl_cmd_SSLProxyProtocol(
965 cmd_parms *cmd, char *struct_ptr, const char *opt)
968 ssl_proto_t options, thisopt;
972 sc = mySrvConfig(cmd->server);
973 options = SSL_PROTOCOL_NONE;
974 while (opt[0] != NUL) {
975 w = ap_getword_conf(cmd->pool, &opt);
978 if (*w == '+' || *w == '-')
981 if (strcEQ(w, "SSLv2"))
982 thisopt = SSL_PROTOCOL_SSLV2;
983 else if (strcEQ(w, "SSLv3"))
984 thisopt = SSL_PROTOCOL_SSLV3;
985 else if (strcEQ(w, "TLSv1"))
986 thisopt = SSL_PROTOCOL_TLSV1;
987 else if (strcEQ(w, "all"))
988 thisopt = SSL_PROTOCOL_ALL;
990 return ap_pstrcat(cmd->pool, "SSLProxyProtocol: "
991 "Illegal protocol '", w, "'", NULL);
994 else if (action == '+')
999 sc->nProxyProtocol = options;
1003 const char *ssl_cmd_SSLProxyCipherSuite(
1004 cmd_parms *cmd, char *struct_ptr, char *arg)
1006 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1008 sc->szProxyCipherSuite = arg;
1012 const char *ssl_cmd_SSLProxyVerify(
1013 cmd_parms *cmd, char *struct_ptr, int flag)
1015 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1017 sc->bProxyVerify = (flag ? TRUE : FALSE);
1021 const char *ssl_cmd_SSLProxyVerifyDepth(
1022 cmd_parms *cmd, char *struct_ptr, char *arg)
1024 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1029 return "SSLProxyVerifyDepth: Invalid argument";
1030 sc->nProxyVerifyDepth = d;
1034 const char *ssl_cmd_SSLProxyCACertificateFile(
1035 cmd_parms *cmd, char *struct_ptr, char *arg)
1037 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1040 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1041 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
1042 return ap_pstrcat(cmd->pool, "SSLProxyCACertificateFile: file '",
1043 cpPath, "' not exists or empty", NULL);
1044 sc->szProxyCACertificateFile = cpPath;
1048 const char *ssl_cmd_SSLProxyCACertificatePath(
1049 cmd_parms *cmd, char *struct_ptr, char *arg)
1051 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1054 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1055 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
1056 return ap_pstrcat(cmd->pool, "SSLProxyCACertificatePath: directory '",
1057 cpPath, "' does not exists", NULL);
1058 sc->szProxyCACertificatePath = cpPath;
1062 const char *ssl_cmd_SSLProxyMachineCertificateFile(
1063 cmd_parms *cmd, char *struct_ptr, char *arg)
1065 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1068 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1069 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
1070 return ap_pstrcat(cmd->pool, "SSLProxyMachineCertFile: file '",
1071 cpPath, "' not exists or empty", NULL);
1072 sc->szProxyClientCertificateFile = cpPath;
1076 const char *ssl_cmd_SSLProxyMachineCertificatePath(
1077 cmd_parms *cmd, char *struct_ptr, char *arg)
1079 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1082 cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1083 if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
1084 return ap_pstrcat(cmd->pool, "SSLProxyMachineCertPath: directory '",
1085 cpPath, "' does not exists", NULL);
1086 sc->szProxyClientCertificatePath = cpPath;
1090 #endif /* SSL_EXPERIMENTAL_PROXY */