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.''
29
#include "ssl_private.h"
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
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
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_pcalloc(p, sizeof(*mctx->pks));
158
/* mctx->pks->... certs/keys are set during module init */
161
static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
163
SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
166
sc->enabled = SSL_ENABLED_FALSE;
167
sc->proxy_enabled = UNSET;
168
sc->vhost_id = NULL; /* set during module init */
169
sc->vhost_id_len = 0; /* set during module init */
170
sc->session_cache_timeout = UNSET;
171
sc->cipher_server_pref = UNSET;
173
modssl_ctx_init_proxy(sc, p);
175
modssl_ctx_init_server(sc, p);
181
* Create per-server SSL configuration
183
void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
185
SSLSrvConfigRec *sc = ssl_config_server_new(p);
187
sc->mc = ssl_config_global_create(s);
192
#define cfgMerge(el,unset) mrg->el = (add->el == (unset)) ? base->el : add->el
193
#define cfgMergeArray(el) mrg->el = apr_array_append(p, add->el, base->el)
194
#define cfgMergeString(el) cfgMerge(el, NULL)
195
#define cfgMergeBool(el) cfgMerge(el, UNSET)
196
#define cfgMergeInt(el) cfgMerge(el, UNSET)
198
static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
202
cfgMerge(protocol, SSL_PROTOCOL_ALL);
204
cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
205
cfgMergeString(pphrase_dialog_path);
207
cfgMergeString(cert_chain);
209
cfgMerge(crl_path, NULL);
210
cfgMerge(crl_file, NULL);
212
cfgMergeString(auth.ca_cert_path);
213
cfgMergeString(auth.ca_cert_file);
214
cfgMergeString(auth.cipher_suite);
215
cfgMergeInt(auth.verify_depth);
216
cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
219
static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
223
modssl_ctx_cfg_merge(base, add, mrg);
225
cfgMergeString(pkp->cert_file);
226
cfgMergeString(pkp->cert_path);
229
static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
235
modssl_ctx_cfg_merge(base, add, mrg);
237
for (i = 0; i < SSL_AIDX_MAX; i++) {
238
cfgMergeString(pks->cert_files[i]);
239
cfgMergeString(pks->key_files[i]);
242
cfgMergeString(pks->ca_name_path);
243
cfgMergeString(pks->ca_name_file);
247
* Merge per-server SSL configurations
249
void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
251
SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
252
SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv;
253
SSLSrvConfigRec *mrg = ssl_config_server_new(p);
256
cfgMerge(enabled, SSL_ENABLED_UNSET);
257
cfgMergeBool(proxy_enabled);
258
cfgMergeInt(session_cache_timeout);
259
cfgMergeBool(cipher_server_pref);
261
modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
263
modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server);
269
* Create per-directory SSL configuration
271
void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
273
SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
275
dc->bSSLRequired = FALSE;
276
dc->aRequirement = apr_array_make(p, 4, sizeof(ssl_require_t));
277
dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET;
278
dc->nOptionsAdd = SSL_OPT_NONE;
279
dc->nOptionsDel = SSL_OPT_NONE;
281
dc->szCipherSuite = NULL;
282
dc->nVerifyClient = SSL_CVERIFY_UNSET;
283
dc->nVerifyDepth = UNSET;
285
dc->szCACertificatePath = NULL;
286
dc->szCACertificateFile = NULL;
287
dc->szUserName = NULL;
293
* Merge per-directory SSL configurations
295
void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
297
SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
298
SSLDirConfigRec *add = (SSLDirConfigRec *)addv;
299
SSLDirConfigRec *mrg = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
301
cfgMerge(bSSLRequired, FALSE);
302
cfgMergeArray(aRequirement);
304
if (add->nOptions & SSL_OPT_RELSET) {
306
(base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
308
(base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
310
(base->nOptions & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd;
313
mrg->nOptions = add->nOptions;
314
mrg->nOptionsAdd = add->nOptionsAdd;
315
mrg->nOptionsDel = add->nOptionsDel;
318
cfgMergeString(szCipherSuite);
319
cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
320
cfgMergeInt(nVerifyDepth);
322
cfgMergeString(szCACertificatePath);
323
cfgMergeString(szCACertificateFile);
324
cfgMergeString(szUserName);
330
* Configuration functions for particular directives
333
const char *ssl_cmd_SSLMutex(cmd_parms *cmd,
338
SSLModConfigRec *mc = myModConfig(cmd->server);
339
/* Split arg_ into meth and file */
340
char *meth = apr_pstrdup(cmd->temp_pool, arg_);
341
char *file = strchr(meth, ':');
349
if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
353
if (ssl_config_global_isfixed(mc)) {
356
if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) {
357
mc->nMutexMode = SSL_MUTEXMODE_NONE;
361
/* APR determines temporary filename unless overridden below,
362
* we presume file indicates an szMutexFile is a file path
363
* unless the method sets szMutexFile=file and NULLs file
365
mc->nMutexMode = SSL_MUTEXMODE_USED;
366
mc->szMutexFile = NULL;
368
/* NOTE: previously, 'yes' implied 'sem' */
369
if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) {
370
mc->nMutexMech = APR_LOCK_DEFAULT;
372
#if APR_HAS_FCNTL_SERIALIZE
373
else if ((!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) && file) {
374
mc->nMutexMech = APR_LOCK_FCNTL;
377
#if APR_HAS_FLOCK_SERIALIZE
378
else if ((!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) && file) {
379
mc->nMutexMech = APR_LOCK_FLOCK;
382
#if APR_HAS_POSIXSEM_SERIALIZE
383
else if (!strcasecmp(meth, "posixsem") || !strcasecmp(meth, "sem")) {
384
mc->nMutexMech = APR_LOCK_POSIXSEM;
385
/* Posix/SysV semaphores aren't file based, use the literal name
386
* if provided and fall back on APR's default if not. Today, APR
387
* will ignore it, but once supported it has an absurdly short limit.
390
mc->szMutexFile = apr_pstrdup(cmd->server->process->pool, file);
396
#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
397
else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) {
398
mc->nMutexMech = APR_LOCK_SYSVSEM;
401
#if APR_HAS_PROC_PTHREAD_SERIALIZE
402
else if (!strcasecmp(meth, "pthread")) {
403
mc->nMutexMech = APR_LOCK_PROC_PTHREAD;
407
return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", arg_,
408
" (", ssl_valid_ssl_mutex_string, ")", NULL);
411
/* Unless the method above assumed responsibility for setting up
412
* mc->szMutexFile and NULLing out file, presume it is a file we
416
mc->szMutexFile = ap_server_root_relative(cmd->server->process->pool, file);
417
if (!mc->szMutexFile) {
418
return apr_pstrcat(cmd->pool, "Invalid SSLMutex ", meth,
419
": filepath ", file, NULL);
426
const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
430
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
432
int arglen = strlen(arg);
434
if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
438
if (strcEQ(arg, "builtin")) {
439
sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
440
sc->server->pphrase_dialog_path = NULL;
442
else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
443
sc->server->pphrase_dialog_type = SSL_PPTYPE_FILTER;
444
sc->server->pphrase_dialog_path =
445
ap_server_root_relative(cmd->pool, arg+5);
446
if (!sc->server->pphrase_dialog_path) {
447
return apr_pstrcat(cmd->pool,
448
"Invalid SSLPassPhraseDialog exec: path ",
451
if (!ssl_util_path_check(SSL_PCM_EXISTS,
452
sc->server->pphrase_dialog_path,
455
return apr_pstrcat(cmd->pool,
456
"SSLPassPhraseDialog: file '",
457
sc->server->pphrase_dialog_path,
458
"' does not exist", NULL);
462
else if ((arglen > 1) && (arg[0] == '|')) {
463
sc->server->pphrase_dialog_type = SSL_PPTYPE_PIPE;
464
sc->server->pphrase_dialog_path = arg + 1;
467
return "SSLPassPhraseDialog: Invalid argument";
473
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
474
const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
478
SSLModConfigRec *mc = myModConfig(cmd->server);
482
if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
486
if (strcEQ(arg, "builtin")) {
487
mc->szCryptoDevice = NULL;
489
else if ((e = ENGINE_by_id(arg))) {
490
mc->szCryptoDevice = arg;
494
err = "SSLCryptoDevice: Invalid argument; must be one of: "
496
e = ENGINE_get_first();
499
err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e),
500
"' (", ENGINE_get_name(e), ")", NULL);
501
en = ENGINE_get_next(e);
512
const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
518
SSLModConfigRec *mc = myModConfig(cmd->server);
520
ssl_randseed_t *seed;
521
int arg2len = strlen(arg2);
523
if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
527
if (ssl_config_global_isfixed(mc)) {
531
seed = apr_array_push(mc->aRandSeed);
533
if (strcEQ(arg1, "startup")) {
534
seed->nCtx = SSL_RSCTX_STARTUP;
536
else if (strcEQ(arg1, "connect")) {
537
seed->nCtx = SSL_RSCTX_CONNECT;
540
return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
541
"invalid context: `", arg1, "'",
545
if ((arg2len > 5) && strEQn(arg2, "file:", 5)) {
546
seed->nSrc = SSL_RSSRC_FILE;
547
seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
549
else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) {
550
seed->nSrc = SSL_RSSRC_EXEC;
551
seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
553
else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
554
#ifdef HAVE_SSL_RAND_EGD
555
seed->nSrc = SSL_RSSRC_EGD;
556
seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
558
return "egd not supported with this SSL toolkit";
561
else if (strcEQ(arg2, "builtin")) {
562
seed->nSrc = SSL_RSSRC_BUILTIN;
566
seed->nSrc = SSL_RSSRC_FILE;
567
seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
570
if (seed->nSrc != SSL_RSSRC_BUILTIN) {
572
return apr_pstrcat(cmd->pool,
573
"Invalid SSLRandomSeed path ",
576
if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) {
577
return apr_pstrcat(cmd->pool,
578
"SSLRandomSeed: source path '",
579
seed->cpPath, "' does not exist", NULL);
584
seed->nBytes = 0; /* read whole file */
587
if (seed->nSrc == SSL_RSSRC_BUILTIN) {
588
return "SSLRandomSeed: byte specification not "
589
"allowed for builtin seed source";
592
seed->nBytes = atoi(arg3);
594
if (seed->nBytes < 0) {
595
return "SSLRandomSeed: invalid number of bytes specified";
602
const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
604
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
606
if (!strcasecmp(arg, "On")) {
607
sc->enabled = SSL_ENABLED_TRUE;
610
else if (!strcasecmp(arg, "Off")) {
611
sc->enabled = SSL_ENABLED_FALSE;
614
else if (!strcasecmp(arg, "Optional")) {
615
sc->enabled = SSL_ENABLED_OPTIONAL;
619
return "Argument must be On, Off, or Optional";
622
const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
626
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
627
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
630
dc->szCipherSuite = arg;
633
sc->server->auth.cipher_suite = arg;
639
#define SSL_FLAGS_CHECK_FILE \
640
(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
642
#define SSL_FLAGS_CHECK_DIR \
643
(SSL_PCM_EXISTS|SSL_PCM_ISDIR)
645
static const char *ssl_cmd_check_file(cmd_parms *parms,
648
const char *filepath = ap_server_root_relative(parms->pool, *file);
651
return apr_pstrcat(parms->pool, parms->cmd->name,
652
": Invalid file path ", *file, NULL);
656
if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
660
return apr_pstrcat(parms->pool, parms->cmd->name,
662
"' does not exist or is empty", NULL);
666
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
668
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
669
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
670
sc->cipher_server_pref = flag?TRUE:FALSE;
673
return "SSLHonorCiperOrder unsupported; not implemented by the SSL library";
677
static const char *ssl_cmd_check_dir(cmd_parms *parms,
680
const char *dirpath = ap_server_root_relative(parms->pool, *dir);
683
return apr_pstrcat(parms->pool, parms->cmd->name,
684
": Invalid dir path ", *dir, NULL);
688
if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
692
return apr_pstrcat(parms->pool, parms->cmd->name,
693
": directory '", *dir,
694
"' does not exist", NULL);
698
#define SSL_AIDX_CERTS 1
699
#define SSL_AIDX_KEYS 2
701
static const char *ssl_cmd_check_aidx_max(cmd_parms *parms,
705
SSLSrvConfigRec *sc = mySrvConfig(parms->server);
706
const char *err, *desc=NULL, **files=NULL;
709
if ((err = ssl_cmd_check_file(parms, &arg))) {
715
desc = "certificates";
716
files = sc->server->pks->cert_files;
719
desc = "private keys";
720
files = sc->server->pks->key_files;
724
for (i = 0; i < SSL_AIDX_MAX; i++) {
731
return apr_psprintf(parms->pool,
733
"different %s per virtual host allowed",
734
parms->cmd->name, SSL_AIDX_MAX, desc);
737
const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
744
if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) {
751
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
757
if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) {
764
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
768
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
771
if ((err = ssl_cmd_check_file(cmd, &arg))) {
775
sc->server->cert_chain = arg;
780
#define NO_PER_DIR_SSL_CA \
781
"Your ssl library does not have support for per-directory CA"
783
#ifdef HAVE_SSL_SET_CERT_STORE
784
# define MODSSL_HAVE_SSL_SET_CERT_STORE 1
786
# define MODSSL_HAVE_SSL_SET_CERT_STORE 0
789
#define MODSSL_SET_CA(f) \
791
if (MODSSL_HAVE_SSL_SET_CERT_STORE) \
794
return NO_PER_DIR_SSL_CA; \
798
const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
802
/*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
803
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
806
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
810
/* XXX: bring back per-dir */
811
sc->server->auth.ca_cert_path = arg;
816
const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
820
/*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
821
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
824
if ((err = ssl_cmd_check_file(cmd, &arg))) {
828
/* XXX: bring back per-dir */
829
sc->server->auth.ca_cert_file = arg;
834
const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg,
837
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
840
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
844
sc->server->pks->ca_name_path = arg;
849
const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg,
852
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
855
if ((err = ssl_cmd_check_file(cmd, &arg))) {
859
sc->server->pks->ca_name_file = arg;
864
const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
868
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
871
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
875
sc->server->crl_path = arg;
880
const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
884
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
887
if ((err = ssl_cmd_check_file(cmd, &arg))) {
891
sc->server->crl_file = arg;
896
static const char *ssl_cmd_verify_parse(cmd_parms *parms,
900
if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
901
*id = SSL_CVERIFY_NONE;
903
else if (strcEQ(arg, "optional")) {
904
*id = SSL_CVERIFY_OPTIONAL;
906
else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
907
*id = SSL_CVERIFY_REQUIRE;
909
else if (strcEQ(arg, "optional_no_ca")) {
910
*id = SSL_CVERIFY_OPTIONAL_NO_CA;
913
return apr_pstrcat(parms->temp_pool, parms->cmd->name,
914
": Invalid argument '", arg, "'",
921
const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd,
925
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
926
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
930
if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
935
dc->nVerifyClient = mode;
938
sc->server->auth.verify_mode = mode;
944
static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
948
if ((*depth = atoi(arg)) >= 0) {
952
return apr_pstrcat(parms->temp_pool, parms->cmd->name,
953
": Invalid argument '", arg, "'",
957
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
961
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
962
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
966
if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
971
dc->nVerifyDepth = depth;
974
sc->server->auth.verify_depth = depth;
980
#define MODSSL_NO_SHARED_MEMORY_ERROR \
981
"SSLSessionCache: shared memory cache not useable on this platform"
983
const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
987
SSLModConfigRec *mc = myModConfig(cmd->server);
988
const char *err, *colon;
990
int arglen = strlen(arg);
992
if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
996
if (ssl_config_global_isfixed(mc)) {
1000
if (strcEQ(arg, "none")) {
1001
mc->nSessionCacheMode = SSL_SCMODE_NONE;
1002
mc->szSessionCacheDataFile = NULL;
1004
else if (strcEQ(arg, "nonenotnull")) {
1005
mc->nSessionCacheMode = SSL_SCMODE_NONE_NOT_NULL;
1006
mc->szSessionCacheDataFile = NULL;
1008
else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) {
1009
mc->nSessionCacheMode = SSL_SCMODE_DBM;
1010
mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4);
1011
if (!mc->szSessionCacheDataFile) {
1012
return apr_psprintf(cmd->pool,
1013
"SSLSessionCache: Invalid cache file path %s",
1017
else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) ||
1018
((arglen > 6) && strcEQn(arg, "shmht:", 6)) ||
1019
((arglen > 6) && strcEQn(arg, "shmcb:", 6))) {
1020
#if !APR_HAS_SHARED_MEMORY
1021
return MODSSL_NO_SHARED_MEMORY_ERROR;
1023
mc->nSessionCacheMode = SSL_SCMODE_SHMCB;
1024
colon = ap_strchr_c(arg, ':');
1025
mc->szSessionCacheDataFile =
1026
ap_server_root_relative(mc->pPool, colon+1);
1027
if (!mc->szSessionCacheDataFile) {
1028
return apr_psprintf(cmd->pool,
1029
"SSLSessionCache: Invalid cache file path %s",
1032
mc->tSessionCacheDataTable = NULL;
1033
mc->nSessionCacheDataSize = 1024*512; /* 512KB */
1035
if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
1038
if (!(cp2 = strchr(cp, ')'))) {
1039
return "SSLSessionCache: Invalid argument: "
1040
"no closing parenthesis";
1045
mc->nSessionCacheDataSize = atoi(cp);
1047
if (mc->nSessionCacheDataSize < 8192) {
1048
return "SSLSessionCache: Invalid argument: "
1049
"size has to be >= 8192 bytes";
1053
if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) {
1054
return apr_psprintf(cmd->pool,
1055
"SSLSessionCache: Invalid argument: "
1056
"size has to be < %d bytes on this "
1057
"platform", APR_SHM_MAXSIZE);
1062
else if ((arglen > 3) && strcEQn(arg, "dc:", 3)) {
1063
#ifdef HAVE_DISTCACHE
1064
mc->nSessionCacheMode = SSL_SCMODE_DC;
1065
mc->szSessionCacheDataFile = apr_pstrdup(mc->pPool, arg+3);
1066
if (!mc->szSessionCacheDataFile) {
1067
return apr_pstrcat(cmd->pool,
1068
"SSLSessionCache: Invalid cache file path: ",
1072
return "SSLSessionCache: distcache support disabled";
1076
return "SSLSessionCache: Invalid argument";
1082
const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd,
1086
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1088
sc->session_cache_timeout = atoi(arg);
1090
if (sc->session_cache_timeout < 0) {
1091
return "SSLSessionCacheTimeout: Invalid argument";
1097
const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
1101
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1107
w = ap_getword_conf(cmd->pool, &arg);
1110
if ((*w == '+') || (*w == '-')) {
1114
dc->nOptions = SSL_OPT_NONE;
1118
if (strcEQ(w, "StdEnvVars")) {
1119
opt = SSL_OPT_STDENVVARS;
1121
else if (strcEQ(w, "ExportCertData")) {
1122
opt = SSL_OPT_EXPORTCERTDATA;
1124
else if (strcEQ(w, "FakeBasicAuth")) {
1125
opt = SSL_OPT_FAKEBASICAUTH;
1127
else if (strcEQ(w, "StrictRequire")) {
1128
opt = SSL_OPT_STRICTREQUIRE;
1130
else if (strcEQ(w, "OptRenegotiate")) {
1131
opt = SSL_OPT_OPTRENEGOTIATE;
1134
return apr_pstrcat(cmd->pool,
1135
"SSLOptions: Illegal option '", w, "'",
1139
if (action == '-') {
1140
dc->nOptionsAdd &= ~opt;
1141
dc->nOptionsDel |= opt;
1142
dc->nOptions &= ~opt;
1144
else if (action == '+') {
1145
dc->nOptionsAdd |= opt;
1146
dc->nOptionsDel &= ~opt;
1147
dc->nOptions |= opt;
1151
dc->nOptionsAdd = opt;
1152
dc->nOptionsDel = SSL_OPT_NONE;
1159
const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg)
1161
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1163
dc->bSSLRequired = TRUE;
1168
const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
1172
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1174
ssl_require_t *require;
1176
if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) {
1177
return apr_pstrcat(cmd->pool, "SSLRequire: ",
1178
ssl_expr_get_error(), NULL);
1181
require = apr_array_push(dc->aRequirement);
1182
require->cpExpr = apr_pstrdup(cmd->pool, arg);
1183
require->mpExpr = expr;
1188
static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
1190
ssl_proto_t *options)
1192
ssl_proto_t thisopt;
1194
*options = SSL_PROTOCOL_NONE;
1197
char *w = ap_getword_conf(parms->temp_pool, &arg);
1200
if ((*w == '+') || (*w == '-')) {
1204
if (strcEQ(w, "SSLv2")) {
1205
thisopt = SSL_PROTOCOL_SSLV2;
1207
else if (strcEQ(w, "SSLv3")) {
1208
thisopt = SSL_PROTOCOL_SSLV3;
1210
else if (strcEQ(w, "TLSv1")) {
1211
thisopt = SSL_PROTOCOL_TLSV1;
1213
else if (strcEQ(w, "all")) {
1214
thisopt = SSL_PROTOCOL_ALL;
1217
return apr_pstrcat(parms->temp_pool,
1219
": Illegal protocol '",
1223
if (action == '-') {
1224
*options &= ~thisopt;
1226
else if (action == '+') {
1227
*options |= thisopt;
1237
const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
1241
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1243
return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
1246
const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
1248
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1250
sc->proxy_enabled = flag ? TRUE : FALSE;
1255
const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,
1259
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1261
return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
1264
const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
1268
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1270
sc->proxy->auth.cipher_suite = arg;
1275
const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
1279
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1283
if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
1287
sc->proxy->auth.verify_mode = mode;
1292
const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
1296
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1300
if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1304
sc->proxy->auth.verify_depth = depth;
1309
const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
1313
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1316
if ((err = ssl_cmd_check_file(cmd, &arg))) {
1320
sc->proxy->auth.ca_cert_file = arg;
1325
const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
1329
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1332
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1336
sc->proxy->auth.ca_cert_path = arg;
1341
const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
1345
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1348
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1352
sc->proxy->crl_path = arg;
1357
const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
1361
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1364
if ((err = ssl_cmd_check_file(cmd, &arg))) {
1368
sc->proxy->crl_file = arg;
1373
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
1377
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1380
if ((err = ssl_cmd_check_file(cmd, &arg))) {
1384
sc->proxy->pkp->cert_file = arg;
1389
const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
1393
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1396
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1400
sc->proxy->pkp->cert_path = arg;
1406
const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
1409
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1410
dc->szUserName = arg;
1414
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
1416
if (!ap_exists_config_define("DUMP_CERTS")) {
1420
/* Dump the filenames of all configured server certificates to
1423
SSLSrvConfigRec *sc = mySrvConfig(s);
1425
if (sc && sc->server && sc->server->pks) {
1426
modssl_pk_server_t *const pks = sc->server->pks;
1429
for (i = 0; (i < SSL_AIDX_MAX) && pks->cert_files[i]; i++) {
1430
printf("%s\n", pks->cert_files[i]);