~ubuntu-branches/ubuntu/feisty/apache2/feisty

« back to all changes in this revision

Viewing changes to modules/ssl/ssl_engine_config.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2006-12-09 21:05:45 UTC
  • mfrom: (0.6.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061209210545-h70s0xaqc2v8vqr2
Tags: 2.2.3-3.2
* Non-maintainer upload.
* 043_ajp_connection_reuse: Patch from upstream Bugzilla, fixing a critical
  issue with regard to connection reuse in mod_proxy_ajp.
  Closes: #396265

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
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.
 
15
 */
 
16
 
 
17
/*                      _             _
 
18
 *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
 
19
 * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
 
20
 * | | | | | | (_) | (_| |   \__ \__ \ |
 
21
 * |_| |_| |_|\___/ \__,_|___|___/___/_|
 
22
 *                      |_____|
 
23
 *  ssl_engine_config.c
 
24
 *  Apache Configuration Directives
 
25
 */
 
26
                                      /* ``Damned if you do,
 
27
                                           damned if you don't.''
 
28
                                               -- Unknown        */
 
29
#include "ssl_private.h"
 
30
 
 
31
/*  _________________________________________________________________
 
32
**
 
33
**  Support for Global Configuration
 
34
**  _________________________________________________________________
 
35
*/
 
36
 
 
37
#define SSL_MOD_CONFIG_KEY "ssl_module"
 
38
 
 
39
SSLModConfigRec *ssl_config_global_create(server_rec *s)
 
40
{
 
41
    apr_pool_t *pool = s->process->pool;
 
42
    SSLModConfigRec *mc;
 
43
    void *vmc;
 
44
 
 
45
    apr_pool_userdata_get(&vmc, SSL_MOD_CONFIG_KEY, pool);
 
46
    if (vmc) {
 
47
        return vmc; /* reused for lifetime of the server */
 
48
    }
 
49
 
 
50
    /*
 
51
     * allocate an own subpool which survives server restarts
 
52
     */
 
53
    mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc));
 
54
    mc->pPool = pool;
 
55
    mc->bFixed = FALSE;
 
56
 
 
57
    /*
 
58
     * initialize per-module configuration
 
59
     */
 
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;
 
69
    mc->pMutex                 = 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;
 
77
#endif
 
78
 
 
79
    memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
 
80
 
 
81
    apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
 
82
                          apr_pool_cleanup_null,
 
83
                          pool);
 
84
 
 
85
    return mc;
 
86
}
 
87
 
 
88
void ssl_config_global_fix(SSLModConfigRec *mc)
 
89
{
 
90
    mc->bFixed = TRUE;
 
91
}
 
92
 
 
93
BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
 
94
{
 
95
    return mc->bFixed;
 
96
}
 
97
 
 
98
/*  _________________________________________________________________
 
99
**
 
100
**  Configuration handling
 
101
**  _________________________________________________________________
 
102
*/
 
103
 
 
104
static void modssl_ctx_init(modssl_ctx_t *mctx)
 
105
{
 
106
    mctx->sc                  = NULL; /* set during module init */
 
107
 
 
108
    mctx->ssl_ctx             = NULL; /* set during module init */
 
109
 
 
110
    mctx->pks                 = NULL;
 
111
    mctx->pkp                 = NULL;
 
112
 
 
113
    mctx->protocol            = SSL_PROTOCOL_ALL;
 
114
 
 
115
    mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
 
116
    mctx->pphrase_dialog_path = NULL;
 
117
 
 
118
    mctx->cert_chain          = NULL;
 
119
 
 
120
    mctx->crl_path            = NULL;
 
121
    mctx->crl_file            = NULL;
 
122
    mctx->crl                 = NULL; /* set during module init */
 
123
 
 
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;
 
129
}
 
130
 
 
131
static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
 
132
                                  apr_pool_t *p)
 
133
{
 
134
    modssl_ctx_t *mctx;
 
135
 
 
136
    mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy));
 
137
 
 
138
    modssl_ctx_init(mctx);
 
139
 
 
140
    mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
 
141
 
 
142
    mctx->pkp->cert_file = NULL;
 
143
    mctx->pkp->cert_path = NULL;
 
144
    mctx->pkp->certs     = NULL;
 
145
}
 
146
 
 
147
static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
 
148
                                   apr_pool_t *p)
 
149
{
 
150
    modssl_ctx_t *mctx;
 
151
 
 
152
    mctx = sc->server = apr_palloc(p, sizeof(*sc->server));
 
153
 
 
154
    modssl_ctx_init(mctx);
 
155
 
 
156
    mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks));
 
157
 
 
158
    /* mctx->pks->... certs/keys are set during module init */
 
159
}
 
160
 
 
161
static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
 
162
{
 
163
    SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
 
164
 
 
165
    sc->mc                     = NULL;
 
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;
 
172
 
 
173
    modssl_ctx_init_proxy(sc, p);
 
174
 
 
175
    modssl_ctx_init_server(sc, p);
 
176
 
 
177
    return sc;
 
178
}
 
179
 
 
180
/*
 
181
 *  Create per-server SSL configuration
 
182
 */
 
183
void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
 
184
{
 
185
    SSLSrvConfigRec *sc = ssl_config_server_new(p);
 
186
 
 
187
    sc->mc = ssl_config_global_create(s);
 
188
 
 
189
    return sc;
 
190
}
 
191
 
 
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)
 
197
 
 
198
static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
 
199
                                 modssl_ctx_t *add,
 
200
                                 modssl_ctx_t *mrg)
 
201
{
 
202
    cfgMerge(protocol, SSL_PROTOCOL_ALL);
 
203
 
 
204
    cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
 
205
    cfgMergeString(pphrase_dialog_path);
 
206
 
 
207
    cfgMergeString(cert_chain);
 
208
 
 
209
    cfgMerge(crl_path, NULL);
 
210
    cfgMerge(crl_file, NULL);
 
211
 
 
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);
 
217
}
 
218
 
 
219
static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
 
220
                                       modssl_ctx_t *add,
 
221
                                       modssl_ctx_t *mrg)
 
222
{
 
223
    modssl_ctx_cfg_merge(base, add, mrg);
 
224
 
 
225
    cfgMergeString(pkp->cert_file);
 
226
    cfgMergeString(pkp->cert_path);
 
227
}
 
228
 
 
229
static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
 
230
                                        modssl_ctx_t *add,
 
231
                                        modssl_ctx_t *mrg)
 
232
{
 
233
    int i;
 
234
 
 
235
    modssl_ctx_cfg_merge(base, add, mrg);
 
236
 
 
237
    for (i = 0; i < SSL_AIDX_MAX; i++) {
 
238
        cfgMergeString(pks->cert_files[i]);
 
239
        cfgMergeString(pks->key_files[i]);
 
240
    }
 
241
 
 
242
    cfgMergeString(pks->ca_name_path);
 
243
    cfgMergeString(pks->ca_name_file);
 
244
}
 
245
 
 
246
/*
 
247
 *  Merge per-server SSL configurations
 
248
 */
 
249
void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
 
250
{
 
251
    SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
 
252
    SSLSrvConfigRec *add  = (SSLSrvConfigRec *)addv;
 
253
    SSLSrvConfigRec *mrg  = ssl_config_server_new(p);
 
254
 
 
255
    cfgMerge(mc, NULL);
 
256
    cfgMerge(enabled, SSL_ENABLED_UNSET);
 
257
    cfgMergeBool(proxy_enabled);
 
258
    cfgMergeInt(session_cache_timeout);
 
259
    cfgMergeBool(cipher_server_pref);
 
260
 
 
261
    modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
 
262
 
 
263
    modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server);
 
264
 
 
265
    return mrg;
 
266
}
 
267
 
 
268
/*
 
269
 *  Create per-directory SSL configuration
 
270
 */
 
271
void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
 
272
{
 
273
    SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
 
274
 
 
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;
 
280
 
 
281
    dc->szCipherSuite          = NULL;
 
282
    dc->nVerifyClient          = SSL_CVERIFY_UNSET;
 
283
    dc->nVerifyDepth           = UNSET;
 
284
 
 
285
    dc->szCACertificatePath    = NULL;
 
286
    dc->szCACertificateFile    = NULL;
 
287
    dc->szUserName             = NULL;
 
288
 
 
289
    return dc;
 
290
}
 
291
 
 
292
/*
 
293
 *  Merge per-directory SSL configurations
 
294
 */
 
295
void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
 
296
{
 
297
    SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
 
298
    SSLDirConfigRec *add  = (SSLDirConfigRec *)addv;
 
299
    SSLDirConfigRec *mrg  = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
 
300
 
 
301
    cfgMerge(bSSLRequired, FALSE);
 
302
    cfgMergeArray(aRequirement);
 
303
 
 
304
    if (add->nOptions & SSL_OPT_RELSET) {
 
305
        mrg->nOptionsAdd =
 
306
            (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
 
307
        mrg->nOptionsDel =
 
308
            (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
 
309
        mrg->nOptions    =
 
310
            (base->nOptions    & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd;
 
311
    }
 
312
    else {
 
313
        mrg->nOptions    = add->nOptions;
 
314
        mrg->nOptionsAdd = add->nOptionsAdd;
 
315
        mrg->nOptionsDel = add->nOptionsDel;
 
316
    }
 
317
 
 
318
    cfgMergeString(szCipherSuite);
 
319
    cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
 
320
    cfgMergeInt(nVerifyDepth);
 
321
 
 
322
    cfgMergeString(szCACertificatePath);
 
323
    cfgMergeString(szCACertificateFile);
 
324
    cfgMergeString(szUserName);
 
325
 
 
326
    return mrg;
 
327
}
 
328
 
 
329
/*
 
330
 *  Configuration functions for particular directives
 
331
 */
 
332
 
 
333
const char *ssl_cmd_SSLMutex(cmd_parms *cmd,
 
334
                             void *dcfg,
 
335
                             const char *arg_)
 
336
{
 
337
    const char *err;
 
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, ':');
 
342
    if (file) {
 
343
        *(file++) = '\0';
 
344
        if (!*file) {
 
345
            file = NULL;
 
346
        }
 
347
    }
 
348
 
 
349
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
 
350
        return err;
 
351
    }
 
352
 
 
353
    if (ssl_config_global_isfixed(mc)) {
 
354
        return NULL;
 
355
    }
 
356
    if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) {
 
357
        mc->nMutexMode  = SSL_MUTEXMODE_NONE;
 
358
        return NULL;
 
359
    }
 
360
 
 
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
 
364
     */
 
365
    mc->nMutexMode  = SSL_MUTEXMODE_USED;
 
366
    mc->szMutexFile = NULL;
 
367
 
 
368
    /* NOTE: previously, 'yes' implied 'sem' */
 
369
    if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) {
 
370
        mc->nMutexMech = APR_LOCK_DEFAULT;
 
371
    }
 
372
#if APR_HAS_FCNTL_SERIALIZE
 
373
    else if ((!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) && file) {
 
374
        mc->nMutexMech = APR_LOCK_FCNTL;
 
375
    }
 
376
#endif
 
377
#if APR_HAS_FLOCK_SERIALIZE
 
378
    else if ((!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) && file) {
 
379
        mc->nMutexMech = APR_LOCK_FLOCK;
 
380
    }
 
381
#endif
 
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.
 
388
         */
 
389
        if (file) {
 
390
            mc->szMutexFile = apr_pstrdup(cmd->server->process->pool, file);
 
391
 
 
392
            file = NULL;
 
393
        }
 
394
    }
 
395
#endif
 
396
#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
 
397
    else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) {
 
398
        mc->nMutexMech = APR_LOCK_SYSVSEM;
 
399
    }
 
400
#endif
 
401
#if APR_HAS_PROC_PTHREAD_SERIALIZE
 
402
    else if (!strcasecmp(meth, "pthread")) {
 
403
        mc->nMutexMech = APR_LOCK_PROC_PTHREAD;
 
404
    }
 
405
#endif
 
406
    else {
 
407
        return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", arg_,
 
408
                           " (", ssl_valid_ssl_mutex_string, ")", NULL);
 
409
    }
 
410
 
 
411
    /* Unless the method above assumed responsibility for setting up
 
412
     * mc->szMutexFile and NULLing out file, presume it is a file we
 
413
     * are looking to use
 
414
     */
 
415
    if (file) {
 
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);
 
420
        }
 
421
    }
 
422
 
 
423
    return NULL;
 
424
}
 
425
 
 
426
const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
 
427
                                        void *dcfg,
 
428
                                        const char *arg)
 
429
{
 
430
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
431
    const char *err;
 
432
    int arglen = strlen(arg);
 
433
 
 
434
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
 
435
        return err;
 
436
    }
 
437
 
 
438
    if (strcEQ(arg, "builtin")) {
 
439
        sc->server->pphrase_dialog_type  = SSL_PPTYPE_BUILTIN;
 
440
        sc->server->pphrase_dialog_path = NULL;
 
441
    }
 
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 ",
 
449
                               arg+5, NULL);
 
450
        }
 
451
        if (!ssl_util_path_check(SSL_PCM_EXISTS,
 
452
                                 sc->server->pphrase_dialog_path,
 
453
                                 cmd->pool))
 
454
        {
 
455
            return apr_pstrcat(cmd->pool,
 
456
                               "SSLPassPhraseDialog: file '",
 
457
                               sc->server->pphrase_dialog_path,
 
458
                               "' does not exist", NULL);
 
459
        }
 
460
 
 
461
    }
 
462
    else if ((arglen > 1) && (arg[0] == '|')) {
 
463
        sc->server->pphrase_dialog_type  = SSL_PPTYPE_PIPE;
 
464
        sc->server->pphrase_dialog_path = arg + 1;
 
465
    }
 
466
    else {
 
467
        return "SSLPassPhraseDialog: Invalid argument";
 
468
    }
 
469
 
 
470
    return NULL;
 
471
}
 
472
 
 
473
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
 
474
const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
 
475
                                    void *dcfg,
 
476
                                    const char *arg)
 
477
{
 
478
    SSLModConfigRec *mc = myModConfig(cmd->server);
 
479
    const char *err;
 
480
    ENGINE *e;
 
481
 
 
482
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
 
483
        return err;
 
484
    }
 
485
 
 
486
    if (strcEQ(arg, "builtin")) {
 
487
        mc->szCryptoDevice = NULL;
 
488
    }
 
489
    else if ((e = ENGINE_by_id(arg))) {
 
490
        mc->szCryptoDevice = arg;
 
491
        ENGINE_free(e);
 
492
    }
 
493
    else {
 
494
        err = "SSLCryptoDevice: Invalid argument; must be one of: "
 
495
              "'builtin' (none)";
 
496
        e = ENGINE_get_first();
 
497
        while (e) {
 
498
            ENGINE *en;
 
499
            err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e),
 
500
                                         "' (", ENGINE_get_name(e), ")", NULL);
 
501
            en = ENGINE_get_next(e);
 
502
            ENGINE_free(e);
 
503
            e = en;
 
504
        }
 
505
        return err;
 
506
    }
 
507
 
 
508
    return NULL;
 
509
}
 
510
#endif
 
511
 
 
512
const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
 
513
                                  void *dcfg,
 
514
                                  const char *arg1,
 
515
                                  const char *arg2,
 
516
                                  const char *arg3)
 
517
{
 
518
    SSLModConfigRec *mc = myModConfig(cmd->server);
 
519
    const char *err;
 
520
    ssl_randseed_t *seed;
 
521
    int arg2len = strlen(arg2);
 
522
 
 
523
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
 
524
        return err;
 
525
    }
 
526
 
 
527
    if (ssl_config_global_isfixed(mc)) {
 
528
        return NULL;
 
529
    }
 
530
 
 
531
    seed = apr_array_push(mc->aRandSeed);
 
532
 
 
533
    if (strcEQ(arg1, "startup")) {
 
534
        seed->nCtx = SSL_RSCTX_STARTUP;
 
535
    }
 
536
    else if (strcEQ(arg1, "connect")) {
 
537
        seed->nCtx = SSL_RSCTX_CONNECT;
 
538
    }
 
539
    else {
 
540
        return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
 
541
                           "invalid context: `", arg1, "'",
 
542
                           NULL);
 
543
    }
 
544
 
 
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);
 
548
    }
 
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);
 
552
    }
 
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);
 
557
#else
 
558
    return "egd not supported with this SSL toolkit";
 
559
#endif
 
560
    }
 
561
    else if (strcEQ(arg2, "builtin")) {
 
562
        seed->nSrc   = SSL_RSSRC_BUILTIN;
 
563
        seed->cpPath = NULL;
 
564
    }
 
565
    else {
 
566
        seed->nSrc   = SSL_RSSRC_FILE;
 
567
        seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
 
568
    }
 
569
 
 
570
    if (seed->nSrc != SSL_RSSRC_BUILTIN) {
 
571
        if (!seed->cpPath) {
 
572
            return apr_pstrcat(cmd->pool,
 
573
                               "Invalid SSLRandomSeed path ",
 
574
                               arg2, NULL);
 
575
        }
 
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);
 
580
        }
 
581
    }
 
582
 
 
583
    if (!arg3) {
 
584
        seed->nBytes = 0; /* read whole file */
 
585
    }
 
586
    else {
 
587
        if (seed->nSrc == SSL_RSSRC_BUILTIN) {
 
588
            return "SSLRandomSeed: byte specification not "
 
589
                   "allowed for builtin seed source";
 
590
        }
 
591
 
 
592
        seed->nBytes = atoi(arg3);
 
593
 
 
594
        if (seed->nBytes < 0) {
 
595
            return "SSLRandomSeed: invalid number of bytes specified";
 
596
        }
 
597
    }
 
598
 
 
599
    return NULL;
 
600
}
 
601
 
 
602
const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
 
603
{
 
604
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
605
 
 
606
    if (!strcasecmp(arg, "On")) {
 
607
        sc->enabled = SSL_ENABLED_TRUE;
 
608
    return NULL;
 
609
    }
 
610
    else if (!strcasecmp(arg, "Off")) {
 
611
        sc->enabled = SSL_ENABLED_FALSE;
 
612
        return NULL;
 
613
    }
 
614
    else if (!strcasecmp(arg, "Optional")) {
 
615
        sc->enabled = SSL_ENABLED_OPTIONAL;
 
616
        return NULL;
 
617
    }
 
618
 
 
619
    return "Argument must be On, Off, or Optional";
 
620
}
 
621
 
 
622
const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
 
623
                                   void *dcfg,
 
624
                                   const char *arg)
 
625
{
 
626
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
627
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
 
628
 
 
629
    if (cmd->path) {
 
630
        dc->szCipherSuite = arg;
 
631
    }
 
632
    else {
 
633
        sc->server->auth.cipher_suite = arg;
 
634
    }
 
635
 
 
636
    return NULL;
 
637
}
 
638
 
 
639
#define SSL_FLAGS_CHECK_FILE \
 
640
    (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
 
641
 
 
642
#define SSL_FLAGS_CHECK_DIR \
 
643
    (SSL_PCM_EXISTS|SSL_PCM_ISDIR)
 
644
 
 
645
static const char *ssl_cmd_check_file(cmd_parms *parms,
 
646
                                      const char **file)
 
647
{
 
648
    const char *filepath = ap_server_root_relative(parms->pool, *file);
 
649
 
 
650
    if (!filepath) {
 
651
        return apr_pstrcat(parms->pool, parms->cmd->name,
 
652
                           ": Invalid file path ", *file, NULL);
 
653
    }
 
654
    *file = filepath;
 
655
 
 
656
    if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
 
657
        return NULL;
 
658
    }
 
659
 
 
660
    return apr_pstrcat(parms->pool, parms->cmd->name,
 
661
                       ": file '", *file,
 
662
                       "' does not exist or is empty", NULL);
 
663
 
 
664
}
 
665
 
 
666
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
 
667
{
 
668
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
 
669
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
670
    sc->cipher_server_pref = flag?TRUE:FALSE;
 
671
    return NULL;
 
672
#else
 
673
    return "SSLHonorCiperOrder unsupported; not implemented by the SSL library";
 
674
#endif
 
675
}
 
676
 
 
677
static const char *ssl_cmd_check_dir(cmd_parms *parms,
 
678
                                     const char **dir)
 
679
{
 
680
    const char *dirpath = ap_server_root_relative(parms->pool, *dir);
 
681
 
 
682
    if (!dirpath) {
 
683
        return apr_pstrcat(parms->pool, parms->cmd->name,
 
684
                           ": Invalid dir path ", *dir, NULL);
 
685
    }
 
686
    *dir = dirpath;
 
687
 
 
688
    if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
 
689
        return NULL;
 
690
    }
 
691
 
 
692
    return apr_pstrcat(parms->pool, parms->cmd->name,
 
693
                       ": directory '", *dir,
 
694
                       "' does not exist", NULL);
 
695
 
 
696
}
 
697
 
 
698
#define SSL_AIDX_CERTS 1
 
699
#define SSL_AIDX_KEYS  2
 
700
 
 
701
static const char *ssl_cmd_check_aidx_max(cmd_parms *parms,
 
702
                                          const char *arg,
 
703
                                          int idx)
 
704
{
 
705
    SSLSrvConfigRec *sc = mySrvConfig(parms->server);
 
706
    const char *err, *desc=NULL, **files=NULL;
 
707
    int i;
 
708
 
 
709
    if ((err = ssl_cmd_check_file(parms, &arg))) {
 
710
        return err;
 
711
    }
 
712
 
 
713
    switch (idx) {
 
714
      case SSL_AIDX_CERTS:
 
715
        desc = "certificates";
 
716
        files = sc->server->pks->cert_files;
 
717
        break;
 
718
      case SSL_AIDX_KEYS:
 
719
        desc = "private keys";
 
720
        files = sc->server->pks->key_files;
 
721
        break;
 
722
    }
 
723
 
 
724
    for (i = 0; i < SSL_AIDX_MAX; i++) {
 
725
        if (!files[i]) {
 
726
            files[i] = arg;
 
727
            return NULL;
 
728
        }
 
729
    }
 
730
 
 
731
    return apr_psprintf(parms->pool,
 
732
                        "%s: only up to %d "
 
733
                        "different %s per virtual host allowed",
 
734
                         parms->cmd->name, SSL_AIDX_MAX, desc);
 
735
}
 
736
 
 
737
const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
 
738
                                       void *dcfg,
 
739
                                       const char *arg)
 
740
{
 
741
 
 
742
    const char *err;
 
743
 
 
744
    if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) {
 
745
        return err;
 
746
    }
 
747
 
 
748
    return NULL;
 
749
}
 
750
 
 
751
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
 
752
                                          void *dcfg,
 
753
                                          const char *arg)
 
754
{
 
755
    const char *err;
 
756
 
 
757
    if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) {
 
758
        return err;
 
759
    }
 
760
 
 
761
    return NULL;
 
762
}
 
763
 
 
764
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
 
765
                                            void *dcfg,
 
766
                                            const char *arg)
 
767
{
 
768
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
769
    const char *err;
 
770
 
 
771
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
 
772
        return err;
 
773
    }
 
774
 
 
775
    sc->server->cert_chain = arg;
 
776
 
 
777
    return NULL;
 
778
}
 
779
 
 
780
#define NO_PER_DIR_SSL_CA \
 
781
    "Your ssl library does not have support for per-directory CA"
 
782
 
 
783
#ifdef HAVE_SSL_SET_CERT_STORE
 
784
#   define MODSSL_HAVE_SSL_SET_CERT_STORE 1
 
785
#else
 
786
#   define MODSSL_HAVE_SSL_SET_CERT_STORE 0
 
787
#endif
 
788
 
 
789
#define MODSSL_SET_CA(f) \
 
790
    if (cmd->path) \
 
791
        if (MODSSL_HAVE_SSL_SET_CERT_STORE) \
 
792
            dc->f = arg; \
 
793
        else \
 
794
            return NO_PER_DIR_SSL_CA; \
 
795
    else \
 
796
        sc->f = arg \
 
797
 
 
798
const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
 
799
                                         void *dcfg,
 
800
                                         const char *arg)
 
801
{
 
802
    /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
 
803
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
804
    const char *err;
 
805
 
 
806
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
 
807
        return err;
 
808
    }
 
809
 
 
810
    /* XXX: bring back per-dir */
 
811
    sc->server->auth.ca_cert_path = arg;
 
812
 
 
813
    return NULL;
 
814
}
 
815
 
 
816
const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
 
817
                                         void *dcfg,
 
818
                                         const char *arg)
 
819
{
 
820
    /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
 
821
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
822
    const char *err;
 
823
 
 
824
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
 
825
        return err;
 
826
    }
 
827
 
 
828
    /* XXX: bring back per-dir */
 
829
    sc->server->auth.ca_cert_file = arg;
 
830
 
 
831
    return NULL;
 
832
}
 
833
 
 
834
const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg,
 
835
                                       const char *arg)
 
836
{
 
837
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
838
    const char *err;
 
839
 
 
840
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
 
841
        return err;
 
842
    }
 
843
 
 
844
    sc->server->pks->ca_name_path = arg;
 
845
 
 
846
    return NULL;
 
847
}
 
848
 
 
849
const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg,
 
850
                                       const char *arg)
 
851
{
 
852
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
853
    const char *err;
 
854
 
 
855
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
 
856
        return err;
 
857
    }
 
858
 
 
859
    sc->server->pks->ca_name_file = arg;
 
860
 
 
861
    return NULL;
 
862
}
 
863
 
 
864
const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
 
865
                                        void *dcfg,
 
866
                                        const char *arg)
 
867
{
 
868
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
869
    const char *err;
 
870
 
 
871
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
 
872
        return err;
 
873
    }
 
874
 
 
875
    sc->server->crl_path = arg;
 
876
 
 
877
    return NULL;
 
878
}
 
879
 
 
880
const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
 
881
                                        void *dcfg,
 
882
                                        const char *arg)
 
883
{
 
884
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
885
    const char *err;
 
886
 
 
887
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
 
888
        return err;
 
889
    }
 
890
 
 
891
    sc->server->crl_file = arg;
 
892
 
 
893
    return NULL;
 
894
}
 
895
 
 
896
static const char *ssl_cmd_verify_parse(cmd_parms *parms,
 
897
                                        const char *arg,
 
898
                                        ssl_verify_t *id)
 
899
{
 
900
    if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
 
901
        *id = SSL_CVERIFY_NONE;
 
902
    }
 
903
    else if (strcEQ(arg, "optional")) {
 
904
        *id = SSL_CVERIFY_OPTIONAL;
 
905
    }
 
906
    else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
 
907
        *id = SSL_CVERIFY_REQUIRE;
 
908
    }
 
909
    else if (strcEQ(arg, "optional_no_ca")) {
 
910
        *id = SSL_CVERIFY_OPTIONAL_NO_CA;
 
911
    }
 
912
    else {
 
913
        return apr_pstrcat(parms->temp_pool, parms->cmd->name,
 
914
                           ": Invalid argument '", arg, "'",
 
915
                           NULL);
 
916
    }
 
917
 
 
918
    return NULL;
 
919
}
 
920
 
 
921
const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd,
 
922
                                    void *dcfg,
 
923
                                    const char *arg)
 
924
{
 
925
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
 
926
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
927
    ssl_verify_t mode;
 
928
    const char *err;
 
929
 
 
930
    if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
 
931
        return err;
 
932
    }
 
933
 
 
934
    if (cmd->path) {
 
935
        dc->nVerifyClient = mode;
 
936
    }
 
937
    else {
 
938
        sc->server->auth.verify_mode = mode;
 
939
    }
 
940
 
 
941
    return NULL;
 
942
}
 
943
 
 
944
static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
 
945
                                              const char *arg,
 
946
                                              int *depth)
 
947
{
 
948
    if ((*depth = atoi(arg)) >= 0) {
 
949
        return NULL;
 
950
    }
 
951
 
 
952
    return apr_pstrcat(parms->temp_pool, parms->cmd->name,
 
953
                       ": Invalid argument '", arg, "'",
 
954
                       NULL);
 
955
}
 
956
 
 
957
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
 
958
                                   void *dcfg,
 
959
                                   const char *arg)
 
960
{
 
961
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
 
962
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
963
    int depth;
 
964
    const char *err;
 
965
 
 
966
    if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
 
967
        return err;
 
968
    }
 
969
 
 
970
    if (cmd->path) {
 
971
        dc->nVerifyDepth = depth;
 
972
    }
 
973
    else {
 
974
        sc->server->auth.verify_depth = depth;
 
975
    }
 
976
 
 
977
    return NULL;
 
978
}
 
979
 
 
980
#define MODSSL_NO_SHARED_MEMORY_ERROR \
 
981
    "SSLSessionCache: shared memory cache not useable on this platform"
 
982
 
 
983
const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
 
984
                                    void *dcfg,
 
985
                                    const char *arg)
 
986
{
 
987
    SSLModConfigRec *mc = myModConfig(cmd->server);
 
988
    const char *err, *colon;
 
989
    char *cp, *cp2;
 
990
    int arglen = strlen(arg);
 
991
 
 
992
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
 
993
        return err;
 
994
    }
 
995
 
 
996
    if (ssl_config_global_isfixed(mc)) {
 
997
        return NULL;
 
998
    }
 
999
 
 
1000
    if (strcEQ(arg, "none")) {
 
1001
        mc->nSessionCacheMode      = SSL_SCMODE_NONE;
 
1002
        mc->szSessionCacheDataFile = NULL;
 
1003
    }
 
1004
    else if (strcEQ(arg, "nonenotnull")) {
 
1005
        mc->nSessionCacheMode      = SSL_SCMODE_NONE_NOT_NULL;
 
1006
        mc->szSessionCacheDataFile = NULL;
 
1007
    }
 
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",
 
1014
                                arg+4);
 
1015
        }
 
1016
    }
 
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;
 
1022
#endif
 
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",
 
1030
                                colon+1);
 
1031
        }
 
1032
        mc->tSessionCacheDataTable = NULL;
 
1033
        mc->nSessionCacheDataSize  = 1024*512; /* 512KB */
 
1034
 
 
1035
        if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
 
1036
            *cp++ = NUL;
 
1037
 
 
1038
            if (!(cp2 = strchr(cp, ')'))) {
 
1039
                return "SSLSessionCache: Invalid argument: "
 
1040
                       "no closing parenthesis";
 
1041
            }
 
1042
 
 
1043
            *cp2 = NUL;
 
1044
 
 
1045
            mc->nSessionCacheDataSize = atoi(cp);
 
1046
 
 
1047
            if (mc->nSessionCacheDataSize < 8192) {
 
1048
                return "SSLSessionCache: Invalid argument: "
 
1049
                       "size has to be >= 8192 bytes";
 
1050
 
 
1051
            }
 
1052
 
 
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);
 
1058
 
 
1059
            }
 
1060
        }
 
1061
    }
 
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: ",
 
1069
                               arg+3, NULL);
 
1070
        }
 
1071
#else
 
1072
        return "SSLSessionCache: distcache support disabled";
 
1073
#endif
 
1074
    }
 
1075
    else {
 
1076
        return "SSLSessionCache: Invalid argument";
 
1077
    }
 
1078
 
 
1079
    return NULL;
 
1080
}
 
1081
 
 
1082
const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd,
 
1083
                                           void *dcfg,
 
1084
                                           const char *arg)
 
1085
{
 
1086
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1087
 
 
1088
    sc->session_cache_timeout = atoi(arg);
 
1089
 
 
1090
    if (sc->session_cache_timeout < 0) {
 
1091
        return "SSLSessionCacheTimeout: Invalid argument";
 
1092
    }
 
1093
 
 
1094
    return NULL;
 
1095
}
 
1096
 
 
1097
const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
 
1098
                               void *dcfg,
 
1099
                               const char *arg)
 
1100
{
 
1101
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
 
1102
    ssl_opt_t opt;
 
1103
    int first = TRUE;
 
1104
    char action, *w;
 
1105
 
 
1106
    while (*arg) {
 
1107
        w = ap_getword_conf(cmd->pool, &arg);
 
1108
        action = NUL;
 
1109
 
 
1110
        if ((*w == '+') || (*w == '-')) {
 
1111
            action = *(w++);
 
1112
        }
 
1113
        else if (first) {
 
1114
            dc->nOptions = SSL_OPT_NONE;
 
1115
            first = FALSE;
 
1116
        }
 
1117
 
 
1118
        if (strcEQ(w, "StdEnvVars")) {
 
1119
            opt = SSL_OPT_STDENVVARS;
 
1120
        }
 
1121
        else if (strcEQ(w, "ExportCertData")) {
 
1122
            opt = SSL_OPT_EXPORTCERTDATA;
 
1123
        }
 
1124
        else if (strcEQ(w, "FakeBasicAuth")) {
 
1125
            opt = SSL_OPT_FAKEBASICAUTH;
 
1126
        }
 
1127
        else if (strcEQ(w, "StrictRequire")) {
 
1128
            opt = SSL_OPT_STRICTREQUIRE;
 
1129
        }
 
1130
        else if (strcEQ(w, "OptRenegotiate")) {
 
1131
            opt = SSL_OPT_OPTRENEGOTIATE;
 
1132
        }
 
1133
        else {
 
1134
            return apr_pstrcat(cmd->pool,
 
1135
                               "SSLOptions: Illegal option '", w, "'",
 
1136
                               NULL);
 
1137
        }
 
1138
 
 
1139
        if (action == '-') {
 
1140
            dc->nOptionsAdd &= ~opt;
 
1141
            dc->nOptionsDel |=  opt;
 
1142
            dc->nOptions    &= ~opt;
 
1143
        }
 
1144
        else if (action == '+') {
 
1145
            dc->nOptionsAdd |=  opt;
 
1146
            dc->nOptionsDel &= ~opt;
 
1147
            dc->nOptions    |=  opt;
 
1148
        }
 
1149
        else {
 
1150
            dc->nOptions    = opt;
 
1151
            dc->nOptionsAdd = opt;
 
1152
            dc->nOptionsDel = SSL_OPT_NONE;
 
1153
        }
 
1154
    }
 
1155
 
 
1156
    return NULL;
 
1157
}
 
1158
 
 
1159
const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg)
 
1160
{
 
1161
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
 
1162
 
 
1163
    dc->bSSLRequired = TRUE;
 
1164
 
 
1165
    return NULL;
 
1166
}
 
1167
 
 
1168
const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
 
1169
                               void *dcfg,
 
1170
                               const char *arg)
 
1171
{
 
1172
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
 
1173
    ssl_expr *expr;
 
1174
    ssl_require_t *require;
 
1175
 
 
1176
    if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) {
 
1177
        return apr_pstrcat(cmd->pool, "SSLRequire: ",
 
1178
                           ssl_expr_get_error(), NULL);
 
1179
    }
 
1180
 
 
1181
    require = apr_array_push(dc->aRequirement);
 
1182
    require->cpExpr = apr_pstrdup(cmd->pool, arg);
 
1183
    require->mpExpr = expr;
 
1184
 
 
1185
    return NULL;
 
1186
}
 
1187
 
 
1188
static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
 
1189
                                          const char *arg,
 
1190
                                          ssl_proto_t *options)
 
1191
{
 
1192
    ssl_proto_t thisopt;
 
1193
 
 
1194
    *options = SSL_PROTOCOL_NONE;
 
1195
 
 
1196
    while (*arg) {
 
1197
        char *w = ap_getword_conf(parms->temp_pool, &arg);
 
1198
        char action = '\0';
 
1199
 
 
1200
        if ((*w == '+') || (*w == '-')) {
 
1201
            action = *(w++);
 
1202
        }
 
1203
 
 
1204
        if (strcEQ(w, "SSLv2")) {
 
1205
            thisopt = SSL_PROTOCOL_SSLV2;
 
1206
        }
 
1207
        else if (strcEQ(w, "SSLv3")) {
 
1208
            thisopt = SSL_PROTOCOL_SSLV3;
 
1209
        }
 
1210
        else if (strcEQ(w, "TLSv1")) {
 
1211
            thisopt = SSL_PROTOCOL_TLSV1;
 
1212
        }
 
1213
        else if (strcEQ(w, "all")) {
 
1214
            thisopt = SSL_PROTOCOL_ALL;
 
1215
        }
 
1216
        else {
 
1217
            return apr_pstrcat(parms->temp_pool,
 
1218
                               parms->cmd->name,
 
1219
                               ": Illegal protocol '",
 
1220
                               w, "'", NULL);
 
1221
        }
 
1222
 
 
1223
        if (action == '-') {
 
1224
            *options &= ~thisopt;
 
1225
        }
 
1226
        else if (action == '+') {
 
1227
            *options |= thisopt;
 
1228
        }
 
1229
        else {
 
1230
            *options = thisopt;
 
1231
        }
 
1232
    }
 
1233
 
 
1234
    return NULL;
 
1235
}
 
1236
 
 
1237
const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
 
1238
                                void *dcfg,
 
1239
                                const char *arg)
 
1240
{
 
1241
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1242
 
 
1243
    return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
 
1244
}
 
1245
 
 
1246
const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
 
1247
{
 
1248
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1249
 
 
1250
    sc->proxy_enabled = flag ? TRUE : FALSE;
 
1251
 
 
1252
    return NULL;
 
1253
}
 
1254
 
 
1255
const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,
 
1256
                                     void *dcfg,
 
1257
                                     const char *arg)
 
1258
{
 
1259
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1260
 
 
1261
    return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
 
1262
}
 
1263
 
 
1264
const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
 
1265
                                        void *dcfg,
 
1266
                                        const char *arg)
 
1267
{
 
1268
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1269
 
 
1270
    sc->proxy->auth.cipher_suite = arg;
 
1271
 
 
1272
    return NULL;
 
1273
}
 
1274
 
 
1275
const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
 
1276
                                   void *dcfg,
 
1277
                                   const char *arg)
 
1278
{
 
1279
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1280
    ssl_verify_t mode;
 
1281
    const char *err;
 
1282
 
 
1283
    if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
 
1284
        return err;
 
1285
    }
 
1286
 
 
1287
    sc->proxy->auth.verify_mode = mode;
 
1288
 
 
1289
    return NULL;
 
1290
}
 
1291
 
 
1292
const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
 
1293
                                        void *dcfg,
 
1294
                                        const char *arg)
 
1295
{
 
1296
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1297
    int depth;
 
1298
    const char *err;
 
1299
 
 
1300
    if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
 
1301
        return err;
 
1302
    }
 
1303
 
 
1304
    sc->proxy->auth.verify_depth = depth;
 
1305
 
 
1306
    return NULL;
 
1307
}
 
1308
 
 
1309
const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
 
1310
                                              void *dcfg,
 
1311
                                              const char *arg)
 
1312
{
 
1313
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1314
    const char *err;
 
1315
 
 
1316
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
 
1317
        return err;
 
1318
    }
 
1319
 
 
1320
    sc->proxy->auth.ca_cert_file = arg;
 
1321
 
 
1322
    return NULL;
 
1323
}
 
1324
 
 
1325
const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
 
1326
                                              void *dcfg,
 
1327
                                              const char *arg)
 
1328
{
 
1329
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1330
    const char *err;
 
1331
 
 
1332
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
 
1333
        return err;
 
1334
    }
 
1335
 
 
1336
    sc->proxy->auth.ca_cert_path = arg;
 
1337
 
 
1338
    return NULL;
 
1339
}
 
1340
 
 
1341
const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
 
1342
                                             void *dcfg,
 
1343
                                             const char *arg)
 
1344
{
 
1345
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1346
    const char *err;
 
1347
 
 
1348
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
 
1349
        return err;
 
1350
    }
 
1351
 
 
1352
    sc->proxy->crl_path = arg;
 
1353
 
 
1354
    return NULL;
 
1355
}
 
1356
 
 
1357
const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
 
1358
                                             void *dcfg,
 
1359
                                             const char *arg)
 
1360
{
 
1361
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1362
    const char *err;
 
1363
 
 
1364
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
 
1365
        return err;
 
1366
    }
 
1367
 
 
1368
    sc->proxy->crl_file = arg;
 
1369
 
 
1370
    return NULL;
 
1371
}
 
1372
 
 
1373
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
 
1374
                                                   void *dcfg,
 
1375
                                                   const char *arg)
 
1376
{
 
1377
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1378
    const char *err;
 
1379
 
 
1380
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
 
1381
        return err;
 
1382
    }
 
1383
 
 
1384
    sc->proxy->pkp->cert_file = arg;
 
1385
 
 
1386
    return NULL;
 
1387
}
 
1388
 
 
1389
const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
 
1390
                                                   void *dcfg,
 
1391
                                                   const char *arg)
 
1392
{
 
1393
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
 
1394
    const char *err;
 
1395
 
 
1396
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
 
1397
        return err;
 
1398
    }
 
1399
 
 
1400
    sc->proxy->pkp->cert_path = arg;
 
1401
 
 
1402
    return NULL;
 
1403
}
 
1404
 
 
1405
 
 
1406
const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
 
1407
                                const char *arg)
 
1408
{
 
1409
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
 
1410
    dc->szUserName = arg;
 
1411
    return NULL;
 
1412
}
 
1413
 
 
1414
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
 
1415
{
 
1416
    if (!ap_exists_config_define("DUMP_CERTS")) {
 
1417
        return;
 
1418
    }
 
1419
 
 
1420
    /* Dump the filenames of all configured server certificates to
 
1421
     * stdout. */
 
1422
    while (s) {
 
1423
        SSLSrvConfigRec *sc = mySrvConfig(s);
 
1424
 
 
1425
        if (sc && sc->server && sc->server->pks) {
 
1426
            modssl_pk_server_t *const pks = sc->server->pks;
 
1427
            int i;
 
1428
 
 
1429
            for (i = 0; (i < SSL_AIDX_MAX) && pks->cert_files[i]; i++) {
 
1430
                printf("%s\n", pks->cert_files[i]);
 
1431
            }
 
1432
        }
 
1433
 
 
1434
        s = s->next;
 
1435
    }
 
1436
 
 
1437
}