bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / modules / ssl / ssl_engine_config.c
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 "mod_ssl.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 #ifdef SSL_EXPERIMENTAL_ENGINE
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_palloc(p, sizeof(*mctx->pks));
157
158     memset((void*)mctx->pks->cert_files, 0, sizeof(mctx->pks->cert_files));
159
160     memset((void*)mctx->pks->key_files, 0, sizeof(mctx->pks->key_files));
161
162     /* certs/keys are set during module init */
163
164     memset(mctx->pks->certs, 0, sizeof(mctx->pks->certs));
165
166     memset(mctx->pks->keys, 0, sizeof(mctx->pks->keys));
167 }
168
169 static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
170 {
171     SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
172
173     sc->mc                     = NULL;
174     sc->enabled                = UNSET;
175     sc->proxy_enabled          = UNSET;
176     sc->vhost_id               = NULL;  /* set during module init */
177     sc->vhost_id_len           = 0;     /* set during module init */
178     sc->session_cache_timeout  = UNSET;
179     sc->insecure_reneg         = UNSET;
180
181     modssl_ctx_init_proxy(sc, p);
182
183     modssl_ctx_init_server(sc, p);
184
185     return sc;
186 }
187
188 /*
189  *  Create per-server SSL configuration
190  */
191 void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
192 {
193     SSLSrvConfigRec *sc = ssl_config_server_new(p);
194
195     sc->mc = ssl_config_global_create(s);
196
197     return sc;
198 }
199
200 #define cfgMerge(el,unset)  mrg->el = (add->el == (unset)) ? base->el : add->el
201 #define cfgMergeArray(el)   mrg->el = apr_array_append(p, add->el, base->el)
202 #define cfgMergeString(el)  cfgMerge(el, NULL)
203 #define cfgMergeBool(el)    cfgMerge(el, UNSET)
204 #define cfgMergeInt(el)     cfgMerge(el, UNSET)
205
206 static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
207                                  modssl_ctx_t *add,
208                                  modssl_ctx_t *mrg)
209 {
210     cfgMerge(protocol, SSL_PROTOCOL_ALL);
211
212     cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
213     cfgMergeString(pphrase_dialog_path);
214
215     cfgMergeString(cert_chain);
216
217     cfgMerge(crl_path, NULL);
218     cfgMerge(crl_file, NULL);
219
220     cfgMergeString(auth.ca_cert_path);
221     cfgMergeString(auth.ca_cert_file);
222     cfgMergeString(auth.cipher_suite);
223     cfgMergeInt(auth.verify_depth);
224     cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
225 }
226
227 static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
228                                        modssl_ctx_t *add,
229                                        modssl_ctx_t *mrg)
230 {
231     modssl_ctx_cfg_merge(base, add, mrg);
232
233     cfgMergeString(pkp->cert_file);
234     cfgMergeString(pkp->cert_path);
235 }
236
237 static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
238                                         modssl_ctx_t *add,
239                                         modssl_ctx_t *mrg)
240 {
241     int i;
242
243     modssl_ctx_cfg_merge(base, add, mrg);
244
245     for (i = 0; i < SSL_AIDX_MAX; i++) {
246         cfgMergeString(pks->cert_files[i]);
247         cfgMergeString(pks->key_files[i]);
248     }
249 }
250
251 /*
252  *  Merge per-server SSL configurations
253  */
254 void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
255 {
256     SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
257     SSLSrvConfigRec *add  = (SSLSrvConfigRec *)addv;
258     SSLSrvConfigRec *mrg  = ssl_config_server_new(p);
259
260     cfgMerge(mc, NULL);
261     cfgMergeBool(enabled);
262     cfgMergeBool(proxy_enabled);
263     cfgMergeInt(session_cache_timeout);
264     cfgMergeBool(insecure_reneg);
265
266     modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
267
268     modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server);
269
270     return mrg;
271 }
272
273 /*
274  *  Create per-directory SSL configuration
275  */
276 void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
277 {
278     SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
279
280     dc->bSSLRequired  = FALSE;
281     dc->aRequirement  = apr_array_make(p, 4, sizeof(ssl_require_t));
282     dc->nOptions      = SSL_OPT_NONE|SSL_OPT_RELSET;
283     dc->nOptionsAdd   = SSL_OPT_NONE;
284     dc->nOptionsDel   = SSL_OPT_NONE;
285
286     dc->szCipherSuite          = NULL;
287     dc->nVerifyClient          = SSL_CVERIFY_UNSET;
288     dc->nVerifyDepth           = UNSET;
289
290     dc->szCACertificatePath    = NULL;
291     dc->szCACertificateFile    = NULL;
292     dc->szUserName             = NULL;
293
294     return dc;
295 }
296
297 /*
298  *  Merge per-directory SSL configurations
299  */
300 void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
301 {
302     SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
303     SSLDirConfigRec *add  = (SSLDirConfigRec *)addv;
304     SSLDirConfigRec *mrg  = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
305
306     cfgMerge(bSSLRequired, FALSE);
307     cfgMergeArray(aRequirement);
308
309     if (add->nOptions & SSL_OPT_RELSET) {
310         mrg->nOptionsAdd =
311             (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
312         mrg->nOptionsDel =
313             (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
314         mrg->nOptions    =
315             (base->nOptions    & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd;
316     }
317     else {
318         mrg->nOptions    = add->nOptions;
319         mrg->nOptionsAdd = add->nOptionsAdd;
320         mrg->nOptionsDel = add->nOptionsDel;
321     }
322
323     cfgMergeString(szCipherSuite);
324     cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
325     cfgMergeInt(nVerifyDepth);
326
327     cfgMergeString(szCACertificatePath);
328     cfgMergeString(szCACertificateFile);
329     cfgMergeString(szUserName);
330
331     return mrg;
332 }
333
334 /*
335  *  Configuration functions for particular directives
336  */
337
338 const char *ssl_cmd_SSLMutex(cmd_parms *cmd,
339                              void *dcfg,
340                              const char *arg)
341 {
342     const char *err;
343     SSLModConfigRec *mc = myModConfig(cmd->server);
344
345     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
346         return err;
347     }
348
349     if (ssl_config_global_isfixed(mc)) {
350         return NULL;
351     }
352
353     if (strcEQ(arg, "none") || strcEQ(arg, "no")) {
354         mc->nMutexMode  = SSL_MUTEXMODE_NONE;
355     }
356     /* NOTE: previously, 'yes' implied 'sem' */
357     else if (strcEQ(arg, "default") || strcEQ(arg, "yes")) {
358         mc->nMutexMode  = SSL_MUTEXMODE_USED;
359         mc->nMutexMech = APR_LOCK_DEFAULT;
360         mc->szMutexFile = NULL; /* APR determines temporary filename */
361     }
362 #if APR_HAS_FLOCK_SERIALIZE
363     else if (strlen(arg) > 6 && strcEQn(arg, "flock:", 6)) {
364         const char *file = ap_server_root_relative(cmd->pool, arg+6);
365         if (!file) {
366             return apr_pstrcat(cmd->pool, "Invalid SSLMutex flock: path ", 
367                                arg+6, NULL);
368         }
369         mc->nMutexMode  = SSL_MUTEXMODE_USED;
370         mc->nMutexMech = APR_LOCK_FLOCK;
371         mc->szMutexFile = apr_psprintf(mc->pPool, "%s.%lu",
372                                        file, (unsigned long)getpid());
373     }
374 #endif
375 #if APR_HAS_FCNTL_SERIALIZE
376     else if (strlen(arg) > 6 && strcEQn(arg, "fcntl:", 6)) {
377         const char *file = ap_server_root_relative(cmd->pool, arg+6);
378         if (!file) {
379             return apr_pstrcat(cmd->pool, "Invalid SSLMutex fcntl: path ", 
380                                arg+6, NULL);
381         }
382         mc->nMutexMode  = SSL_MUTEXMODE_USED;
383         mc->nMutexMech = APR_LOCK_FCNTL;
384         mc->szMutexFile = apr_psprintf(mc->pPool, "%s.%lu",
385                                        file, (unsigned long)getpid());
386     }
387 #endif
388 #if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
389     else if (strcEQ(arg, "sysvsem")) {
390         mc->nMutexMode  = SSL_MUTEXMODE_USED;
391         mc->nMutexMech = APR_LOCK_SYSVSEM;
392         mc->szMutexFile = NULL; /* APR determines temporary filename */
393     }
394 #endif
395 #if APR_HAS_POSIXSEM_SERIALIZE
396     else if (strcEQ(arg, "posixsem")) {
397         mc->nMutexMode  = SSL_MUTEXMODE_USED;
398         mc->nMutexMech = APR_LOCK_POSIXSEM;
399         mc->szMutexFile = NULL; /* APR determines temporary filename */
400     }
401 #endif
402 #if APR_HAS_PROC_PTHREAD_SERIALIZE
403     else if (strcEQ(arg, "pthread")) {
404         mc->nMutexMode  = SSL_MUTEXMODE_USED;
405         mc->nMutexMech = APR_LOCK_PROC_PTHREAD;
406         mc->szMutexFile = NULL; /* APR determines temporary filename */
407     }
408 #endif
409 #if APR_HAS_FLOCK_SERIALIZE || APR_HAS_FCNTL_SERIALIZE
410     else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) {
411         const char *file = ap_server_root_relative(cmd->pool, arg+5);
412         if (!file) {
413             return apr_pstrcat(cmd->pool, "Invalid SSLMutex file: path ", 
414                                arg+5, NULL);
415         }
416         mc->nMutexMode  = SSL_MUTEXMODE_USED;
417 #if APR_HAS_FLOCK_SERIALIZE
418         mc->nMutexMech  = APR_LOCK_FLOCK;
419 #endif
420 #if APR_HAS_FCNTL_SERIALIZE
421         mc->nMutexMech  = APR_LOCK_FCNTL;
422 #endif
423         mc->szMutexFile =
424             apr_psprintf(mc->pPool, "%s.%lu",
425                          file, (unsigned long)getpid());
426     }
427 #endif
428 #if (APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)) || APR_HAS_POSIXSEM_SERIALIZE
429     else if (strcEQ(arg, "sem")) {
430         mc->nMutexMode  = SSL_MUTEXMODE_USED;
431 #if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
432         mc->nMutexMech  = APR_LOCK_SYSVSEM;
433 #endif
434 #if APR_HAS_POSIXSEM_SERIALIZE
435         mc->nMutexMech  = APR_LOCK_POSIXSEM;
436 #endif
437         mc->szMutexFile = NULL; /* APR determines temporary filename */
438     }
439 #endif
440     else {
441         return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", 
442                            arg, " (", ssl_valid_ssl_mutex_string, ")", NULL);
443     }
444
445     return NULL;
446 }
447
448 const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
449                                         void *dcfg,
450                                         const char *arg)
451 {
452     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
453     const char *err;
454     int arglen = strlen(arg);
455
456     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
457         return err;
458     }
459
460     if (strcEQ(arg, "builtin")) {
461         sc->server->pphrase_dialog_type  = SSL_PPTYPE_BUILTIN;
462         sc->server->pphrase_dialog_path = NULL;
463     }
464     else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
465         sc->server->pphrase_dialog_type  = SSL_PPTYPE_FILTER;
466         /* ### This is broken, exec: may contain args, no? */
467         sc->server->pphrase_dialog_path =
468             ap_server_root_relative(cmd->pool, arg+5);
469         if (!sc->server->pphrase_dialog_path) {
470             return apr_pstrcat(cmd->pool,
471                                "Invalid SSLPassPhraseDialog exec: path ",
472                                arg+5, NULL);
473         }
474         if (!ssl_util_path_check(SSL_PCM_EXISTS,
475                                  sc->server->pphrase_dialog_path,
476                                  cmd->pool))
477         {
478             return apr_pstrcat(cmd->pool,
479                                "SSLPassPhraseDialog: file '",
480                                sc->server->pphrase_dialog_path,
481                                "' does not exist", NULL);
482         }
483
484     }
485     else if ((arglen > 1) && (arg[0] == '|')) {
486         sc->server->pphrase_dialog_type  = SSL_PPTYPE_PIPE;
487         sc->server->pphrase_dialog_path = arg + 1;
488     }
489     else {
490         return "SSLPassPhraseDialog: Invalid argument";
491     }
492
493     return NULL;
494 }
495
496 #ifdef SSL_EXPERIMENTAL_ENGINE
497 const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
498                                     void *dcfg,
499                                     const char *arg)
500 {
501     SSLModConfigRec *mc = myModConfig(cmd->server);
502     const char *err;
503     ENGINE *e;
504 #if SSL_LIBRARY_VERSION >= 0x00907000
505     static int loaded_engines = FALSE;
506
507     /* early loading to make sure the engines are already 
508        available for ENGINE_by_id() above... */
509     if (!loaded_engines) {
510         ENGINE_load_builtin_engines();
511         loaded_engines = TRUE;
512     }
513 #endif
514     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
515         return err;
516     }
517
518     if (strcEQ(arg, "builtin")) {
519         mc->szCryptoDevice = NULL;
520     }
521     else if ((e = ENGINE_by_id(arg))) {
522         mc->szCryptoDevice = arg;
523         ENGINE_free(e);
524     }
525     else {
526         return "SSLCryptoDevice: Invalid argument";
527     }
528
529     return NULL;
530 }
531 #endif
532
533 const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
534                                   void *dcfg,
535                                   const char *arg1, 
536                                   const char *arg2,
537                                   const char *arg3)
538 {
539     SSLModConfigRec *mc = myModConfig(cmd->server);
540     const char *err;
541     ssl_randseed_t *seed;
542     int arg2len = strlen(arg2);
543
544     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
545         return err;
546     }
547
548     if (ssl_config_global_isfixed(mc)) {
549         return NULL;
550     }
551
552     seed = apr_array_push(mc->aRandSeed);
553
554     if (strcEQ(arg1, "startup")) {
555         seed->nCtx = SSL_RSCTX_STARTUP;
556     }
557     else if (strcEQ(arg1, "connect")) {
558         seed->nCtx = SSL_RSCTX_CONNECT;
559     }
560     else {
561         return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
562                            "invalid context: `", arg1, "'",
563                            NULL);
564     }
565
566     if ((arg2len > 5) && strEQn(arg2, "file:", 5)) {
567         seed->nSrc   = SSL_RSSRC_FILE;
568         seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
569     }
570     else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) {
571         seed->nSrc   = SSL_RSSRC_EXEC;
572         seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
573     }
574     else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
575 #ifdef HAVE_SSL_RAND_EGD
576         seed->nSrc   = SSL_RSSRC_EGD;
577         seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
578 #else
579     return "egd not supported with this SSL toolkit";
580 #endif
581     }
582     else if (strcEQ(arg2, "builtin")) {
583         seed->nSrc   = SSL_RSSRC_BUILTIN;
584         seed->cpPath = NULL;
585     }
586     else {
587         seed->nSrc   = SSL_RSSRC_FILE;
588         seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
589     }
590
591     if (seed->nSrc != SSL_RSSRC_BUILTIN) {
592         if (!seed->cpPath) {
593             return apr_pstrcat(cmd->pool,
594                                "Invalid SSLRandomSeed path ",
595                                arg2, NULL);
596         }
597         if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) {
598             return apr_pstrcat(cmd->pool,
599                                "SSLRandomSeed: source path '",
600                                seed->cpPath, "' does not exist", NULL);
601         }
602     }
603
604     if (!arg3) {
605         seed->nBytes = 0; /* read whole file */
606     }
607     else {
608         if (seed->nSrc == SSL_RSSRC_BUILTIN) {
609             return "SSLRandomSeed: byte specification not "
610                    "allowed for builtin seed source";
611         }
612
613         seed->nBytes = atoi(arg3);
614
615         if (seed->nBytes < 0) {
616             return "SSLRandomSeed: invalid number of bytes specified";
617         }
618     }
619
620     return NULL;
621 }
622
623 const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, int flag)
624 {
625     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
626
627     sc->enabled = flag ? TRUE : FALSE;
628
629     return NULL;
630 }
631
632 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
633                                    void *dcfg,
634                                    const char *arg)
635 {
636     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
637     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
638
639     if (cmd->path) {
640         dc->szCipherSuite = arg;
641     }
642     else {
643         sc->server->auth.cipher_suite = arg;
644     }
645
646     return NULL;
647 }
648
649 #define SSL_FLAGS_CHECK_FILE \
650     (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
651
652 #define SSL_FLAGS_CHECK_DIR \
653     (SSL_PCM_EXISTS|SSL_PCM_ISDIR)
654
655 static const char *ssl_cmd_check_file(cmd_parms *parms,
656                                       const char **file)
657 {
658     const char *filepath = ap_server_root_relative(parms->pool, *file);
659
660     if (!filepath) {
661         return apr_pstrcat(parms->pool, parms->cmd->name,
662                            ": Invalid file path ", *file, NULL);
663     }
664     *file = filepath;
665
666     if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
667         return NULL;
668     }
669
670     return apr_pstrcat(parms->pool, parms->cmd->name,
671                        ": file '", *file, 
672                        "' does not exist or is empty", NULL);
673
674 }
675
676 const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag)
677 {
678 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
679     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
680     sc->insecure_reneg = flag?TRUE:FALSE;
681     return NULL;
682 #else
683     return "The SSLInsecureRenegotiation directive is not available "
684         "with this SSL library";
685 #endif
686 }
687
688
689 static const char *ssl_cmd_check_dir(cmd_parms *parms,
690                                      const char **dir)
691 {
692     const char *dirpath = ap_server_root_relative(parms->pool, *dir);
693
694     if (!dirpath) {
695         return apr_pstrcat(parms->pool, parms->cmd->name,
696                            ": Invalid dir path ", *dir, NULL);
697     }
698     *dir = dirpath;
699
700     if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
701         return NULL;
702     }
703
704     return apr_pstrcat(parms->pool, parms->cmd->name,
705                        ": directory '", *dir, 
706                        "' does not exist", NULL);
707
708 }
709
710 #define SSL_AIDX_CERTS 1
711 #define SSL_AIDX_KEYS  2
712
713 static const char *ssl_cmd_check_aidx_max(cmd_parms *parms,
714                                           const char *arg,
715                                           int idx)
716 {
717     SSLSrvConfigRec *sc = mySrvConfig(parms->server);
718     const char *err, *desc=NULL, **files=NULL;
719     int i;
720
721     if ((err = ssl_cmd_check_file(parms, &arg))) {
722         return err;
723     }
724
725     switch (idx) {
726       case SSL_AIDX_CERTS:
727         desc = "certificates";
728         files = sc->server->pks->cert_files;
729         break;
730       case SSL_AIDX_KEYS:
731         desc = "private keys";
732         files = sc->server->pks->key_files;
733         break;
734     }
735
736     for (i = 0; i < SSL_AIDX_MAX; i++) {
737         if (!files[i]) {
738             files[i] = arg;
739             return NULL;
740         }
741     }
742
743     return apr_psprintf(parms->pool,
744                         "%s: only up to %d "
745                         "different %s per virtual host allowed", 
746                          parms->cmd->name, SSL_AIDX_MAX, desc);
747 }
748
749 const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
750                                        void *dcfg,
751                                        const char *arg)
752 {
753
754     const char *err;
755
756     if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) {
757         return err;
758     }
759
760     return NULL;
761 }
762
763 const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
764                                           void *dcfg,
765                                           const char *arg)
766 {
767     const char *err;
768
769     if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) {
770         return err;
771     }
772
773     return NULL;
774 }
775
776 const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
777                                             void *dcfg,
778                                             const char *arg)
779 {
780     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
781     const char *err;
782
783     if ((err = ssl_cmd_check_file(cmd, &arg))) {
784         return err;
785     }
786
787     sc->server->cert_chain = arg;
788
789     return NULL;
790 }
791
792 #define NO_PER_DIR_SSL_CA \
793     "Your ssl library does not have support for per-directory CA"
794
795 #ifdef HAVE_SSL_SET_CERT_STORE
796 #   define MODSSL_HAVE_SSL_SET_CERT_STORE 1
797 #else
798 #   define MODSSL_HAVE_SSL_SET_CERT_STORE 0
799 #endif
800
801 #define MODSSL_SET_CA(f) \
802     if (cmd->path) \
803         if (MODSSL_HAVE_SSL_SET_CERT_STORE) \
804             dc->f = arg; \
805         else \
806             return NO_PER_DIR_SSL_CA; \
807     else \
808         sc->f = arg \
809
810 const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
811                                          void *dcfg,
812                                          const char *arg)
813 {
814     /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
815     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
816     const char *err;
817
818     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
819         return err;
820     }
821
822     /* XXX: bring back per-dir */
823     sc->server->auth.ca_cert_path = arg;
824
825     return NULL;
826 }
827
828 const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
829                                          void *dcfg,
830                                          const char *arg)
831 {
832     /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
833     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
834     const char *err;
835
836     if ((err = ssl_cmd_check_file(cmd, &arg))) {
837         return err;
838     }
839
840     /* XXX: bring back per-dir */
841     sc->server->auth.ca_cert_file = arg;
842
843     return NULL;
844 }
845
846 const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
847                                         void *dcfg,
848                                         const char *arg)
849 {
850     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
851     const char *err;
852
853     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
854         return err;
855     }
856
857     sc->server->crl_path = arg;
858
859     return NULL;
860 }
861
862 const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
863                                         void *dcfg,
864                                         const char *arg)
865 {
866     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
867     const char *err;
868
869     if ((err = ssl_cmd_check_file(cmd, &arg))) {
870         return err;
871     }
872
873     sc->server->crl_file = arg;
874
875     return NULL;
876 }
877
878 static const char *ssl_cmd_verify_parse(cmd_parms *parms,
879                                         const char *arg,
880                                         ssl_verify_t *id)
881 {
882     if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
883         *id = SSL_CVERIFY_NONE;
884     }
885     else if (strcEQ(arg, "optional")) {
886         *id = SSL_CVERIFY_OPTIONAL;
887     }
888     else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
889         *id = SSL_CVERIFY_REQUIRE;
890     }
891     else if (strcEQ(arg, "optional_no_ca")) {
892         *id = SSL_CVERIFY_OPTIONAL_NO_CA;
893     }
894     else {
895         return apr_pstrcat(parms->temp_pool, parms->cmd->name,
896                            ": Invalid argument '", arg, "'",
897                            NULL);
898     }
899
900     return NULL;
901 }
902
903 const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd,
904                                     void *dcfg,
905                                     const char *arg)
906 {
907     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
908     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
909     ssl_verify_t mode;
910     const char *err;
911
912     if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
913         return err;
914     }
915     
916     if (cmd->path) {
917         dc->nVerifyClient = mode;
918     }
919     else {
920         sc->server->auth.verify_mode = mode;
921     }
922
923     return NULL;
924 }
925
926 static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
927                                               const char *arg,
928                                               int *depth)
929 {
930     if ((*depth = atoi(arg)) >= 0) {
931         return NULL;
932     }
933
934     return apr_pstrcat(parms->temp_pool, parms->cmd->name,
935                        ": Invalid argument '", arg, "'",
936                        NULL);
937 }
938
939 const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
940                                    void *dcfg,
941                                    const char *arg)
942 {
943     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
944     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
945     int depth;
946     const char *err;
947
948     if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
949         return err;
950     }
951
952     if (cmd->path) {
953         dc->nVerifyDepth = depth;
954     }
955     else {
956         sc->server->auth.verify_depth = depth;
957     }
958
959     return NULL;
960 }
961
962 #define MODSSL_NO_SHARED_MEMORY_ERROR \
963     "SSLSessionCache: shared memory cache not useable on this platform"
964
965 const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
966                                     void *dcfg,
967                                     const char *arg)
968 {
969     SSLModConfigRec *mc = myModConfig(cmd->server);
970     const char *err, *colon;
971     char *cp, *cp2;
972     int arglen = strlen(arg);
973
974     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
975         return err;
976     }
977
978     if (ssl_config_global_isfixed(mc)) {
979         return NULL;
980     }
981
982     if (strcEQ(arg, "none")) {
983         mc->nSessionCacheMode      = SSL_SCMODE_NONE;
984         mc->szSessionCacheDataFile = NULL;
985     }
986     else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) {
987         mc->nSessionCacheMode      = SSL_SCMODE_DBM;
988         mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4);
989         if (!mc->szSessionCacheDataFile) {
990             return apr_psprintf(cmd->pool,
991                                 "SSLSessionCache: Invalid cache file path %s",
992                                 arg+4);
993         }
994     }
995     else if ((arglen > 6) && strcEQn(arg, "shmht:", 6)) {
996 #if !APR_HAS_SHARED_MEMORY
997         return MODSSL_NO_SHARED_MEMORY_ERROR;
998 #endif
999         mc->nSessionCacheMode = SSL_SCMODE_SHMHT;
1000         colon = ap_strchr_c(arg, ':');
1001         mc->szSessionCacheDataFile =
1002             ap_server_root_relative(mc->pPool, colon+1);
1003         if (!mc->szSessionCacheDataFile) {
1004             return apr_psprintf(cmd->pool,
1005                                 "SSLSessionCache: Invalid cache file path %s",
1006                                 colon+1);
1007         }
1008         mc->tSessionCacheDataTable = NULL;
1009         mc->nSessionCacheDataSize  = 1024*512; /* 512KB */
1010
1011         if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
1012             *cp++ = NUL;
1013
1014             if (!(cp2 = strchr(cp, ')'))) {
1015                 return "SSLSessionCache: Invalid argument: "
1016                        "no closing parenthesis";
1017             }
1018
1019             *cp2 = NUL;
1020
1021             mc->nSessionCacheDataSize = atoi(cp);
1022
1023             if (mc->nSessionCacheDataSize < 8192) {
1024                 return "SSLSessionCache: Invalid argument: "
1025                        "size has to be >= 8192 bytes";
1026             }
1027
1028             if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) {
1029                 return apr_psprintf(cmd->pool,
1030                                     "SSLSessionCache: Invalid argument: "
1031                                     "size has to be < %d bytes on this "
1032                                     "platform", APR_SHM_MAXSIZE);
1033             }
1034         }
1035     }
1036     else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) ||
1037              ((arglen > 6) && strcEQn(arg, "shmcb:", 6))) {
1038 #if !APR_HAS_SHARED_MEMORY
1039         return MODSSL_NO_SHARED_MEMORY_ERROR;
1040 #endif
1041         mc->nSessionCacheMode      = SSL_SCMODE_SHMCB;
1042         colon = ap_strchr_c(arg, ':');
1043         mc->szSessionCacheDataFile =
1044             ap_server_root_relative(mc->pPool, colon+1);
1045         if (!mc->szSessionCacheDataFile) {
1046             return apr_psprintf(cmd->pool,
1047                                 "SSLSessionCache: Invalid cache file path %s",
1048                                 colon+1);
1049         }
1050         mc->tSessionCacheDataTable = NULL;
1051         mc->nSessionCacheDataSize  = 1024*512; /* 512KB */
1052
1053         if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
1054             *cp++ = NUL;
1055
1056             if (!(cp2 = strchr(cp, ')'))) {
1057                 return "SSLSessionCache: Invalid argument: "
1058                        "no closing parenthesis";
1059             }
1060
1061             *cp2 = NUL;
1062
1063             mc->nSessionCacheDataSize = atoi(cp);
1064
1065             if (mc->nSessionCacheDataSize < 8192) {
1066                 return "SSLSessionCache: Invalid argument: "
1067                        "size has to be >= 8192 bytes";
1068
1069             }
1070
1071             if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) {
1072                 return apr_psprintf(cmd->pool,
1073                                     "SSLSessionCache: Invalid argument: "
1074                                     "size has to be < %d bytes on this "
1075                                     "platform", APR_SHM_MAXSIZE);
1076
1077             }
1078         }
1079     }
1080     else {
1081         return "SSLSessionCache: Invalid argument";
1082     }
1083
1084     return NULL;
1085 }
1086
1087 const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd,
1088                                            void *dcfg,
1089                                            const char *arg)
1090 {
1091     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1092
1093     sc->session_cache_timeout = atoi(arg);
1094
1095     if (sc->session_cache_timeout < 0) {
1096         return "SSLSessionCacheTimeout: Invalid argument";
1097     }
1098
1099     return NULL;
1100 }
1101
1102 const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
1103                                void *dcfg,
1104                                const char *arg)
1105 {
1106     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1107     ssl_opt_t opt;
1108     int first = TRUE;
1109     char action, *w;
1110
1111     while (*arg) {
1112         w = ap_getword_conf(cmd->pool, &arg);
1113         action = NUL;
1114
1115         if ((*w == '+') || (*w == '-')) {
1116             action = *(w++);
1117         }
1118         else if (first) {
1119             dc->nOptions = SSL_OPT_NONE;
1120             first = FALSE;
1121         }
1122
1123         if (strcEQ(w, "StdEnvVars")) {
1124             opt = SSL_OPT_STDENVVARS;
1125         }
1126         else if (strcEQ(w, "CompatEnvVars")) {
1127             opt = SSL_OPT_COMPATENVVARS;
1128         }
1129         else if (strcEQ(w, "ExportCertData")) {
1130             opt = SSL_OPT_EXPORTCERTDATA;
1131         }
1132         else if (strcEQ(w, "FakeBasicAuth")) {
1133             opt = SSL_OPT_FAKEBASICAUTH;
1134         }
1135         else if (strcEQ(w, "StrictRequire")) {
1136             opt = SSL_OPT_STRICTREQUIRE;
1137         }
1138         else if (strcEQ(w, "OptRenegotiate")) {
1139             opt = SSL_OPT_OPTRENEGOTIATE;
1140         }
1141         else {
1142             return apr_pstrcat(cmd->pool,
1143                                "SSLOptions: Illegal option '", w, "'",
1144                                NULL);
1145         }
1146
1147         if (action == '-') {
1148             dc->nOptionsAdd &= ~opt;
1149             dc->nOptionsDel |=  opt;
1150             dc->nOptions    &= ~opt;
1151         }
1152         else if (action == '+') {
1153             dc->nOptionsAdd |=  opt;
1154             dc->nOptionsDel &= ~opt;
1155             dc->nOptions    |=  opt;
1156         }
1157         else {
1158             dc->nOptions    = opt;
1159             dc->nOptionsAdd = opt;
1160             dc->nOptionsDel = SSL_OPT_NONE;
1161         }
1162     }
1163
1164     return NULL;
1165 }
1166
1167 const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg)
1168 {
1169     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1170
1171     dc->bSSLRequired = TRUE;
1172
1173     return NULL;
1174 }
1175
1176 const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
1177                                void *dcfg,
1178                                const char *arg)
1179 {
1180     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1181     ssl_expr *expr;
1182     ssl_require_t *require;
1183
1184     if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) {
1185         return apr_pstrcat(cmd->pool, "SSLRequire: ",
1186                            ssl_expr_get_error(), NULL);
1187     }
1188
1189     require = apr_array_push(dc->aRequirement);
1190     require->cpExpr = apr_pstrdup(cmd->pool, arg);
1191     require->mpExpr = expr;
1192
1193     return NULL;
1194 }
1195
1196 static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
1197                                           const char *arg,
1198                                           ssl_proto_t *options)
1199 {
1200     ssl_proto_t thisopt;
1201
1202     *options = SSL_PROTOCOL_NONE;
1203
1204     while (*arg) {
1205         char *w = ap_getword_conf(parms->temp_pool, &arg);
1206         char action = '\0';
1207
1208         if ((*w == '+') || (*w == '-')) {
1209             action = *(w++);
1210         }
1211
1212         if (strcEQ(w, "SSLv2")) {
1213             thisopt = SSL_PROTOCOL_SSLV2;
1214         }
1215         else if (strcEQ(w, "SSLv3")) {
1216             thisopt = SSL_PROTOCOL_SSLV3;
1217         }
1218         else if (strcEQ(w, "TLSv1")) {
1219             thisopt = SSL_PROTOCOL_TLSV1;
1220         }
1221         else if (strcEQ(w, "all")) {
1222             thisopt = SSL_PROTOCOL_ALL;
1223         }
1224         else {
1225             return apr_pstrcat(parms->temp_pool,
1226                                parms->cmd->name,
1227                                ": Illegal protocol '",
1228                                w, "'", NULL);
1229         }
1230
1231         if (action == '-') {
1232             *options &= ~thisopt;
1233         }
1234         else if (action == '+') {
1235             *options |= thisopt;
1236         }
1237         else {
1238             *options = thisopt;
1239         }
1240     }
1241
1242     return NULL;
1243 }
1244
1245 const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
1246                                 void *dcfg,
1247                                 const char *arg)
1248 {
1249     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1250
1251     return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
1252 }
1253
1254 const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
1255 {
1256     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1257
1258     sc->proxy_enabled = flag ? TRUE : FALSE;
1259
1260     return NULL;
1261 }
1262
1263 const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd, 
1264                                      void *dcfg,
1265                                      const char *arg)
1266 {
1267     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1268
1269     return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
1270 }
1271
1272 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
1273                                         void *dcfg,
1274                                         const char *arg)
1275 {
1276     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1277
1278     sc->proxy->auth.cipher_suite = arg;
1279
1280     return NULL;
1281 }
1282
1283 const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
1284                                    void *dcfg,
1285                                    const char *arg)
1286 {
1287     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1288     ssl_verify_t mode;
1289     const char *err;
1290
1291     if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
1292         return err;
1293     }
1294
1295     sc->proxy->auth.verify_mode = mode;
1296
1297     return NULL;
1298 }
1299
1300 const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
1301                                         void *dcfg,
1302                                         const char *arg)
1303 {
1304     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1305     int depth;
1306     const char *err;
1307
1308     if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1309         return err;
1310     }
1311
1312     sc->proxy->auth.verify_depth = depth;
1313
1314     return NULL;
1315 }
1316
1317 const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
1318                                               void *dcfg,
1319                                               const char *arg)
1320 {
1321     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1322     const char *err;
1323
1324     if ((err = ssl_cmd_check_file(cmd, &arg))) {
1325         return err;
1326     }
1327
1328     sc->proxy->auth.ca_cert_file = arg;
1329
1330     return NULL;
1331 }
1332
1333 const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
1334                                               void *dcfg,
1335                                               const char *arg)
1336 {
1337     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1338     const char *err;
1339
1340     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1341         return err;
1342     }
1343
1344     sc->proxy->auth.ca_cert_path = arg;
1345
1346     return NULL;
1347 }
1348
1349 const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
1350                                              void *dcfg,
1351                                              const char *arg)
1352 {
1353     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1354     const char *err;
1355
1356     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1357         return err;
1358     }
1359
1360     sc->proxy->crl_path = arg;
1361
1362     return NULL;
1363 }
1364
1365 const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
1366                                              void *dcfg,
1367                                              const char *arg)
1368 {
1369     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1370     const char *err;
1371
1372     if ((err = ssl_cmd_check_file(cmd, &arg))) {
1373         return err;
1374     }
1375
1376     sc->proxy->crl_file = arg;
1377
1378     return NULL;
1379 }
1380
1381 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
1382                                                    void *dcfg,
1383                                                    const char *arg)
1384 {
1385     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1386     const char *err;
1387
1388     if ((err = ssl_cmd_check_file(cmd, &arg))) {
1389         return err;
1390     }
1391
1392     sc->proxy->pkp->cert_file = arg;
1393
1394     return NULL;
1395 }
1396
1397 const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
1398                                                    void *dcfg,
1399                                                    const char *arg)
1400 {
1401     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1402     const char *err;
1403
1404     if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1405         return err;
1406     }
1407
1408     sc->proxy->pkp->cert_path = arg;
1409
1410     return NULL;
1411 }
1412
1413
1414 const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg, 
1415                                 const char *arg)
1416 {
1417     SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1418     dc->szUserName = arg;
1419     return NULL;
1420 }