1 /*                      _             _
2 **  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
3 ** | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
4 ** | | | | | | (_) | (_| |   \__ \__ \ |  www.modssl.org
5 ** |_| |_| |_|\___/ \__,_|___|___/___/_|  ftp.modssl.org
6 **                      |_____|
7 **  ssl_engine_config.c
8 **  Apache Configuration Directives
9 */
10 
11 /* ====================================================================
12  * Copyright (c) 1998-2003 Ralf S. Engelschall. All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  *
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  *
21  * 2. Redistributions in binary form must reproduce the above copyright
22  *    notice, this list of conditions and the following
23  *    disclaimer in the documentation and/or other materials
24  *    provided with the distribution.
25  *
26  * 3. All advertising materials mentioning features or use of this
27  *    software must display the following acknowledgment:
28  *    "This product includes software developed by
29  *     Ralf S. Engelschall <rse@engelschall.com> for use in the
30  *     mod_ssl project (http://www.modssl.org/)."
31  *
32  * 4. The names "mod_ssl" must not be used to endorse or promote
33  *    products derived from this software without prior written
34  *    permission. For written permission, please contact
35  *    rse@engelschall.com.
36  *
37  * 5. Products derived from this software may not be called "mod_ssl"
38  *    nor may "mod_ssl" appear in their names without prior
39  *    written permission of Ralf S. Engelschall.
40  *
41  * 6. Redistributions of any form whatsoever must retain the following
42  *    acknowledgment:
43  *    "This product includes software developed by
44  *     Ralf S. Engelschall <rse@engelschall.com> for use in the
45  *     mod_ssl project (http://www.modssl.org/)."
46  *
47  * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
48  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL RALF S. ENGELSCHALL OR
51  * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
58  * OF THE POSSIBILITY OF SUCH DAMAGE.
59  * ====================================================================
60  */
61 
62                                       /* ``Damned if you do,
63                                            damned if you don't.''
64                                                -- Unknown        */
65 #include "mod_ssl.h"
66 
67 
68 /*  _________________________________________________________________
69 **
70 **  Support for Global Configuration
71 **  _________________________________________________________________
72 */
73 
ssl_hook_AddModule(module * m)74 void ssl_hook_AddModule(module *m)
75 {
76     if (m == &ssl_module) {
77         /*
78          * Announce us for the configuration files
79          */
80         ap_add_config_define("MOD_SSL");
81 
82         /*
83          * Link ourself into the Apache kernel
84          */
85         ssl_var_register();
86         ssl_ext_register();
87         ssl_io_register();
88 #if defined(SSL_VENDOR) && defined(SSL_VENDOR_OBJS)
89         ssl_vendor_register();
90 #endif
91     }
92     return;
93 }
94 
ssl_hook_RemoveModule(module * m)95 void ssl_hook_RemoveModule(module *m)
96 {
97     if (m == &ssl_module) {
98         /*
99          * Unlink ourself from the Apache kernel
100          */
101         ssl_var_unregister();
102         ssl_ext_unregister();
103         ssl_io_unregister();
104 #if defined(SSL_VENDOR) && defined(SSL_VENDOR_OBJS)
105         ssl_vendor_unregister();
106 #endif
107     }
108     return;
109 }
110 
ssl_config_global_create(void)111 void ssl_config_global_create(void)
112 {
113     pool *pPool;
114     SSLModConfigRec *mc;
115 
116     mc = ap_ctx_get(ap_global_ctx, "ssl_module");
117     if (mc == NULL) {
118         /*
119          * allocate an own subpool which survives server restarts
120          */
121         pPool = ap_make_sub_pool(NULL);
122         mc = (SSLModConfigRec *)ap_palloc(pPool, sizeof(SSLModConfigRec));
123         mc->pPool = pPool;
124         mc->bFixed = FALSE;
125 
126         /*
127          * initialize per-module configuration
128          */
129         mc->nInitCount             = 0;
130         mc->nSessionCacheMode      = SSL_SCMODE_UNSET;
131         mc->szSessionCacheDataFile = NULL;
132         mc->nSessionCacheDataSize  = 0;
133         mc->pSessionCacheDataMM    = NULL;
134         mc->tSessionCacheDataTable = NULL;
135         mc->nMutexMode             = SSL_MUTEXMODE_UNSET;
136         mc->szMutexFile            = NULL;
137         mc->nMutexFD               = -1;
138         mc->nMutexSEMID            = -1;
139         mc->aRandSeed              = ap_make_array(pPool, 4, sizeof(ssl_randseed_t));
140         mc->tPrivateKey            = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
141         mc->tPublicCert            = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
142         mc->tTmpKeys               = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t));
143 #ifdef SSL_EXPERIMENTAL_ENGINE
144         mc->szCryptoDevice         = NULL;
145 #endif
146 
147         (void)memset(mc->pTmpKeys, 0, SSL_TKPIDX_MAX*sizeof(void *));
148 
149 #ifdef SSL_VENDOR
150         mc->ctx = ap_ctx_new(pPool);
151         ap_hook_use("ap::mod_ssl::vendor::config_global_create",
152                 AP_HOOK_SIG2(void,ptr), AP_HOOK_MODE_ALL, mc);
153 #endif
154 
155         /*
156          * And push it into Apache's global context
157          */
158         ap_ctx_set(ap_global_ctx, "ssl_module", mc);
159     }
160     return;
161 }
162 
ssl_config_global_fix(void)163 void ssl_config_global_fix(void)
164 {
165     SSLModConfigRec *mc = myModConfig();
166     mc->bFixed = TRUE;
167     return;
168 }
169 
ssl_config_global_isfixed(void)170 BOOL ssl_config_global_isfixed(void)
171 {
172     SSLModConfigRec *mc = myModConfig();
173     return (mc->bFixed);
174 }
175 
176 
177 /*  _________________________________________________________________
178 **
179 **  Configuration handling
180 **  _________________________________________________________________
181 */
182 
183 /*
184  *  Create per-server SSL configuration
185  */
ssl_config_server_create(pool * p,server_rec * s)186 void *ssl_config_server_create(pool *p, server_rec *s)
187 {
188     SSLSrvConfigRec *sc;
189 
190     ssl_config_global_create();
191 
192     sc = ap_palloc(p, sizeof(SSLSrvConfigRec));
193     sc->bEnabled               = UNSET;
194     sc->szCACertificatePath    = NULL;
195     sc->szCACertificateFile    = NULL;
196     sc->szCertificateChain     = NULL;
197     sc->szLogFile              = NULL;
198     sc->szCipherSuite          = NULL;
199     sc->nLogLevel              = SSL_LOG_NONE;
200     sc->nVerifyDepth           = UNSET;
201     sc->nVerifyClient          = SSL_CVERIFY_UNSET;
202     sc->nSessionCacheTimeout   = UNSET;
203     sc->nPassPhraseDialogType  = SSL_PPTYPE_UNSET;
204     sc->szPassPhraseDialogPath = NULL;
205     sc->nProtocol              = SSL_PROTOCOL_ALL;
206     sc->fileLogFile            = NULL;
207     sc->pSSLCtx                = NULL;
208     sc->szCARevocationPath     = NULL;
209     sc->szCARevocationFile     = NULL;
210     sc->pRevocationStore       = NULL;
211 
212 #ifdef SSL_EXPERIMENTAL_PROXY
213     sc->nProxyVerifyDepth             = UNSET;
214     sc->szProxyCACertificatePath      = NULL;
215     sc->szProxyCACertificateFile      = NULL;
216     sc->szProxyClientCertificateFile  = NULL;
217     sc->szProxyClientCertificatePath  = NULL;
218     sc->szProxyCipherSuite            = NULL;
219     sc->nProxyProtocol                = SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_TLSV1;
220     sc->bProxyVerify                  = UNSET;
221     sc->pSSLProxyCtx                  = NULL;
222 #endif
223 
224     (void)memset(sc->szPublicCertFile, 0, SSL_AIDX_MAX*sizeof(char *));
225     (void)memset(sc->szPrivateKeyFile, 0, SSL_AIDX_MAX*sizeof(char *));
226     (void)memset(sc->pPublicCert, 0, SSL_AIDX_MAX*sizeof(X509 *));
227     (void)memset(sc->pPrivateKey, 0, SSL_AIDX_MAX*sizeof(EVP_PKEY *));
228 
229 #ifdef SSL_VENDOR
230     sc->ctx = ap_ctx_new(p);
231     ap_hook_use("ap::mod_ssl::vendor::config_server_create",
232                 AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
233                 p, s, sc);
234 #endif
235 
236     return sc;
237 }
238 
239 /*
240  *  Merge per-server SSL configurations
241  */
ssl_config_server_merge(pool * p,void * basev,void * addv)242 void *ssl_config_server_merge(pool *p, void *basev, void *addv)
243 {
244     SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
245     SSLSrvConfigRec *add  = (SSLSrvConfigRec *)addv;
246     SSLSrvConfigRec *new  = (SSLSrvConfigRec *)ap_palloc(p, sizeof(SSLSrvConfigRec));
247     int i;
248 
249     cfgMergeBool(bEnabled);
250     cfgMergeString(szCACertificatePath);
251     cfgMergeString(szCACertificateFile);
252     cfgMergeString(szCertificateChain);
253     cfgMergeString(szLogFile);
254     cfgMergeString(szCipherSuite);
255     cfgMerge(nLogLevel, SSL_LOG_NONE);
256     cfgMergeInt(nVerifyDepth);
257     cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
258     cfgMergeInt(nSessionCacheTimeout);
259     cfgMerge(nPassPhraseDialogType, SSL_PPTYPE_UNSET);
260     cfgMergeString(szPassPhraseDialogPath);
261     cfgMerge(nProtocol, SSL_PROTOCOL_ALL);
262     cfgMerge(fileLogFile, NULL);
263     cfgMerge(pSSLCtx, NULL);
264     cfgMerge(szCARevocationPath, NULL);
265     cfgMerge(szCARevocationFile, NULL);
266     cfgMerge(pRevocationStore, NULL);
267 
268     for (i = 0; i < SSL_AIDX_MAX; i++) {
269         cfgMergeString(szPublicCertFile[i]);
270         cfgMergeString(szPrivateKeyFile[i]);
271         cfgMerge(pPublicCert[i], NULL);
272         cfgMerge(pPrivateKey[i], NULL);
273     }
274 
275 #ifdef SSL_VENDOR
276     cfgMergeCtx(ctx);
277     ap_hook_use("ap::mod_ssl::vendor::config_server_merge",
278                 AP_HOOK_SIG5(void,ptr,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
279                 p, base, add, new);
280 #endif
281 
282 #ifdef SSL_EXPERIMENTAL_PROXY
283     cfgMergeInt(nProxyVerifyDepth);
284     cfgMergeString(szProxyCACertificatePath);
285     cfgMergeString(szProxyCACertificateFile);
286     cfgMergeString(szProxyClientCertificateFile);
287     cfgMergeString(szProxyClientCertificatePath);
288     cfgMergeString(szProxyCipherSuite);
289     cfgMerge(nProxyProtocol, (SSL_PROTOCOL_ALL & ~SSL_PROTOCOL_TLSV1));
290     cfgMergeBool(bProxyVerify);
291     cfgMerge(pSSLProxyCtx, NULL);
292 #endif
293 
294     return new;
295 }
296 
297 /*
298  *  Create per-directory SSL configuration
299  */
ssl_config_perdir_create(pool * p,char * dir)300 void *ssl_config_perdir_create(pool *p, char *dir)
301 {
302     SSLDirConfigRec *dc = ap_palloc(p, sizeof(SSLDirConfigRec));
303 
304     dc->bSSLRequired  = FALSE;
305     dc->aRequirement  = ap_make_array(p, 4, sizeof(ssl_require_t));
306     dc->nOptions      = SSL_OPT_NONE|SSL_OPT_RELSET;
307     dc->nOptionsAdd   = SSL_OPT_NONE;
308     dc->nOptionsDel   = SSL_OPT_NONE;
309 
310     dc->szCipherSuite          = NULL;
311     dc->nVerifyClient          = SSL_CVERIFY_UNSET;
312     dc->nVerifyDepth           = UNSET;
313 #ifdef SSL_EXPERIMENTAL_PERDIRCA
314     dc->szCACertificatePath    = NULL;
315     dc->szCACertificateFile    = NULL;
316 #endif
317 
318 #ifdef SSL_VENDOR
319     dc->ctx = ap_ctx_new(p);
320     ap_hook_use("ap::mod_ssl::vendor::config_perdir_create",
321                 AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
322                 p, dir, dc);
323 #endif
324 
325     return dc;
326 }
327 
328 /*
329  *  Merge per-directory SSL configurations
330  */
ssl_config_perdir_merge(pool * p,void * basev,void * addv)331 void *ssl_config_perdir_merge(pool *p, void *basev, void *addv)
332 {
333     SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
334     SSLDirConfigRec *add  = (SSLDirConfigRec *)addv;
335     SSLDirConfigRec *new  = (SSLDirConfigRec *)ap_palloc(p,
336                                                sizeof(SSLDirConfigRec));
337 
338     cfgMerge(bSSLRequired, FALSE);
339     cfgMergeArray(aRequirement);
340 
341     if (add->nOptions & SSL_OPT_RELSET) {
342         new->nOptionsAdd = (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
343         new->nOptionsDel = (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
344         new->nOptions    = (base->nOptions    & ~(new->nOptionsDel)) | new->nOptionsAdd;
345     }
346     else {
347         new->nOptions    = add->nOptions;
348         new->nOptionsAdd = add->nOptionsAdd;
349         new->nOptionsDel = add->nOptionsDel;
350     }
351 
352     cfgMergeString(szCipherSuite);
353     cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
354     cfgMergeInt(nVerifyDepth);
355 #ifdef SSL_EXPERIMENTAL_PERDIRCA
356     cfgMergeString(szCACertificatePath);
357     cfgMergeString(szCACertificateFile);
358 #endif
359 
360 #ifdef SSL_VENDOR
361     cfgMergeCtx(ctx);
362     ap_hook_use("ap::mod_ssl::vendor::config_perdir_merge",
363                 AP_HOOK_SIG5(void,ptr,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
364                 p, base, add, new);
365 #endif
366 
367     return new;
368 }
369 
370 /*
371  * Directive Rewriting
372  */
373 
ssl_hook_RewriteCommand(cmd_parms * cmd,void * config,const char * cmd_line)374 char *ssl_hook_RewriteCommand(cmd_parms *cmd, void *config, const char *cmd_line)
375 {
376 #ifdef SSL_COMPAT
377     return ssl_compat_directive(cmd->server, cmd->pool, cmd_line);
378 #else
379     return NULL;
380 #endif
381 }
382 
383 /*
384  *  Configuration functions for particular directives
385  */
386 
ssl_cmd_SSLMutex(cmd_parms * cmd,char * struct_ptr,char * arg)387 const char *ssl_cmd_SSLMutex(
388     cmd_parms *cmd, char *struct_ptr, char *arg)
389 {
390     const char *err;
391     SSLModConfigRec *mc = myModConfig();
392 
393     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
394         return err;
395     if (ssl_config_global_isfixed())
396         return NULL;
397     if (strcEQ(arg, "none")) {
398         mc->nMutexMode  = SSL_MUTEXMODE_NONE;
399     }
400     else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) {
401         mc->nMutexMode  = SSL_MUTEXMODE_FILE;
402         mc->szMutexFile = ap_psprintf(mc->pPool, "%s.%lu",
403                                       ssl_util_server_root_relative(cmd->pool, "mutex", arg+5),
404                                       (unsigned long)getpid());
405     }
406     else if (strcEQ(arg, "sem")) {
407         mc->nMutexMode  = SSL_MUTEXMODE_SEM;
408     }
409     else
410         return "SSLMutex: Invalid argument";
411     return NULL;
412 }
413 
ssl_cmd_SSLPassPhraseDialog(cmd_parms * cmd,char * struct_ptr,char * arg)414 const char *ssl_cmd_SSLPassPhraseDialog(
415     cmd_parms *cmd, char *struct_ptr, char *arg)
416 {
417     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
418     const char *err;
419 
420     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
421         return err;
422     if (strcEQ(arg, "builtin")) {
423         sc->nPassPhraseDialogType  = SSL_PPTYPE_BUILTIN;
424         sc->szPassPhraseDialogPath = NULL;
425     }
426     else if (strlen(arg) > 5 && strEQn(arg, "exec:", 5)) {
427         sc->nPassPhraseDialogType  = SSL_PPTYPE_FILTER;
428         sc->szPassPhraseDialogPath = ssl_util_server_root_relative(cmd->pool, "dialog", arg+5);
429         if (!ssl_util_path_check(SSL_PCM_EXISTS, sc->szPassPhraseDialogPath))
430             return ap_pstrcat(cmd->pool, "SSLPassPhraseDialog: file '",
431                               sc->szPassPhraseDialogPath, "' not exists", NULL);
432     }
433     else
434         return "SSLPassPhraseDialog: Invalid argument";
435     return NULL;
436 }
437 
438 #ifdef SSL_EXPERIMENTAL_ENGINE
ssl_cmd_SSLCryptoDevice(cmd_parms * cmd,char * struct_ptr,char * arg)439 const char *ssl_cmd_SSLCryptoDevice(
440     cmd_parms *cmd, char *struct_ptr, char *arg)
441 {
442     SSLModConfigRec *mc = myModConfig();
443     const char *err;
444     ENGINE *e;
445     static int loaded_engines = FALSE;
446 
447     /* early loading to make sure the engines are already
448        available for ENGINE_by_id() above... */
449     if (!loaded_engines) {
450         ENGINE_load_builtin_engines();
451         loaded_engines = TRUE;
452     }
453     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
454         return err;
455     if (strcEQ(arg, "builtin")) {
456         mc->szCryptoDevice = NULL;
457     }
458     else if ((e = ENGINE_by_id(arg)) != NULL) {
459         mc->szCryptoDevice = arg;
460         ENGINE_free(e);
461     }
462     else
463         return "SSLCryptoDevice: Invalid argument";
464     return NULL;
465 }
466 #endif
467 
ssl_cmd_SSLRandomSeed(cmd_parms * cmd,char * struct_ptr,char * arg1,char * arg2,char * arg3)468 const char *ssl_cmd_SSLRandomSeed(
469     cmd_parms *cmd, char *struct_ptr, char *arg1, char *arg2, char *arg3)
470 {
471     SSLModConfigRec *mc = myModConfig();
472     const char *err;
473     ssl_randseed_t *pRS;
474 
475     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
476         return err;
477     if (ssl_config_global_isfixed())
478         return NULL;
479     pRS = ap_push_array(mc->aRandSeed);
480     if (strcEQ(arg1, "startup"))
481         pRS->nCtx = SSL_RSCTX_STARTUP;
482     else if (strcEQ(arg1, "connect"))
483         pRS->nCtx = SSL_RSCTX_CONNECT;
484     else
485         return ap_pstrcat(cmd->pool, "SSLRandomSeed: "
486                           "invalid context: `", arg1, "'", NULL);
487     if (strlen(arg2) > 5 && strEQn(arg2, "file:", 5)) {
488         pRS->nSrc   = SSL_RSSRC_FILE;
489         pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2+5));
490     }
491     else if (strlen(arg2) > 5 && strEQn(arg2, "exec:", 5)) {
492         pRS->nSrc   = SSL_RSSRC_EXEC;
493         pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2+5));
494     }
495     else if (strlen(arg2) > 4 && strEQn(arg2, "egd:", 4)) {
496         pRS->nSrc   = SSL_RSSRC_EGD;
497         pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2+4));
498     }
499     else if (strcEQ(arg2, "builtin")) {
500         pRS->nSrc   = SSL_RSSRC_BUILTIN;
501         pRS->cpPath = NULL;
502     }
503     else {
504         pRS->nSrc   = SSL_RSSRC_FILE;
505         pRS->cpPath = ap_pstrdup(mc->pPool, ssl_util_server_root_relative(cmd->pool, "random", arg2));
506     }
507     if (pRS->nSrc != SSL_RSSRC_BUILTIN)
508         if (!ssl_util_path_check(SSL_PCM_EXISTS, pRS->cpPath))
509             return ap_pstrcat(cmd->pool, "SSLRandomSeed: source path '",
510                               pRS->cpPath, "' not exists", NULL);
511     if (arg3 == NULL)
512         pRS->nBytes = 0; /* read whole file */
513     else {
514         if (pRS->nSrc == SSL_RSSRC_BUILTIN)
515             return "SSLRandomSeed: byte specification not "
516                    "allowed for builtin seed source";
517         pRS->nBytes = atoi(arg3);
518         if (pRS->nBytes < 0)
519             return "SSLRandomSeed: invalid number of bytes specified";
520     }
521     return NULL;
522 }
523 
ssl_cmd_SSLEngine(cmd_parms * cmd,char * struct_ptr,int flag)524 const char *ssl_cmd_SSLEngine(
525     cmd_parms *cmd, char *struct_ptr, int flag)
526 {
527     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
528 
529     sc->bEnabled = (flag ? TRUE : FALSE);
530     return NULL;
531 }
532 
ssl_cmd_SSLCipherSuite(cmd_parms * cmd,SSLDirConfigRec * dc,char * arg)533 const char *ssl_cmd_SSLCipherSuite(
534     cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
535 {
536     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
537 
538     if (cmd->path == NULL || dc == NULL)
539         sc->szCipherSuite = arg;
540     else
541         dc->szCipherSuite = arg;
542     return NULL;
543 }
544 
ssl_cmd_SSLCertificateFile(cmd_parms * cmd,char * struct_ptr,char * arg)545 const char *ssl_cmd_SSLCertificateFile(
546     cmd_parms *cmd, char *struct_ptr, char *arg)
547 {
548     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
549     char *cpPath;
550     int i;
551 
552     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
553     if (!ap_server_is_chrooted() && !ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
554         return ap_pstrcat(cmd->pool, "SSLCertificateFile: file '",
555                           cpPath, "' not exists or empty", NULL);
556     for (i = 0; i < SSL_AIDX_MAX && sc->szPublicCertFile[i] != NULL; i++)
557         ;
558     if (i == SSL_AIDX_MAX)
559         return ap_psprintf(cmd->pool, "SSLCertificateFile: only up to %d "
560                           "different certificates per virtual host allowed",
561                           SSL_AIDX_MAX);
562     sc->szPublicCertFile[i] = cpPath;
563     return NULL;
564 }
565 
ssl_cmd_SSLCertificateKeyFile(cmd_parms * cmd,char * struct_ptr,char * arg)566 const char *ssl_cmd_SSLCertificateKeyFile(
567     cmd_parms *cmd, char *struct_ptr, char *arg)
568 {
569     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
570     char *cpPath;
571     int i;
572 
573     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
574     if (!ap_server_is_chrooted() && !ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
575         return ap_pstrcat(cmd->pool, "SSLCertificateKeyFile: file '",
576                           cpPath, "' not exists or empty", NULL);
577     for (i = 0; i < SSL_AIDX_MAX && sc->szPrivateKeyFile[i] != NULL; i++)
578         ;
579     if (i == SSL_AIDX_MAX)
580         return ap_psprintf(cmd->pool, "SSLCertificateKeyFile: only up to %d "
581                           "different private keys per virtual host allowed",
582                           SSL_AIDX_MAX);
583     sc->szPrivateKeyFile[i] = cpPath;
584     return NULL;
585 }
586 
ssl_cmd_SSLCertificateChainFile(cmd_parms * cmd,char * struct_ptr,char * arg)587 const char *ssl_cmd_SSLCertificateChainFile(
588     cmd_parms *cmd, char *struct_ptr, char *arg)
589 {
590     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
591     char *cpPath;
592 
593     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
594     if (!ap_server_is_chrooted() && !ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
595         return ap_pstrcat(cmd->pool, "SSLCertificateChainFile: file '",
596                           cpPath, "' not exists or empty", NULL);
597     ap_server_strip_chroot(cpPath, 0);
598     sc->szCertificateChain = cpPath;
599     return NULL;
600 }
601 
ssl_cmd_SSLCACertificatePath(cmd_parms * cmd,SSLDirConfigRec * dc,char * arg)602 const char *ssl_cmd_SSLCACertificatePath(
603     cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
604 {
605     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
606     char *cpPath;
607 
608     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
609     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
610         return ap_pstrcat(cmd->pool, "SSLCACertificatePath: directory '",
611                           cpPath, "' not exists", NULL);
612 #ifdef SSL_EXPERIMENTAL_PERDIRCA
613     if (cmd->path == NULL || dc == NULL)
614         sc->szCACertificatePath = cpPath;
615     else
616         dc->szCACertificatePath = cpPath;
617 #else
618     sc->szCACertificatePath = cpPath;
619 #endif
620     return NULL;
621 }
622 
ssl_cmd_SSLCACertificateFile(cmd_parms * cmd,SSLDirConfigRec * dc,char * arg)623 const char *ssl_cmd_SSLCACertificateFile(
624     cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
625 {
626     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
627     char *cpPath;
628 
629     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
630     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
631         return ap_pstrcat(cmd->pool, "SSLCACertificateFile: file '",
632                           cpPath, "' not exists or empty", NULL);
633 #ifdef SSL_EXPERIMENTAL_PERDIRCA
634     if (cmd->path == NULL || dc == NULL)
635         sc->szCACertificateFile = cpPath;
636     else
637         dc->szCACertificateFile = cpPath;
638 #else
639     sc->szCACertificateFile = cpPath;
640 #endif
641     return NULL;
642 }
643 
ssl_cmd_SSLCARevocationPath(cmd_parms * cmd,SSLDirConfigRec * dc,char * arg)644 const char *ssl_cmd_SSLCARevocationPath(
645     cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
646 {
647     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
648     char *cpPath;
649 
650     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
651     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
652         return ap_pstrcat(cmd->pool, "SSLCARecocationPath: directory '",
653                           cpPath, "' not exists", NULL);
654     sc->szCARevocationPath = cpPath;
655     return NULL;
656 }
657 
ssl_cmd_SSLCARevocationFile(cmd_parms * cmd,SSLDirConfigRec * dc,char * arg)658 const char *ssl_cmd_SSLCARevocationFile(
659     cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
660 {
661     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
662     char *cpPath;
663 
664     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
665     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
666         return ap_pstrcat(cmd->pool, "SSLCARevocationFile: file '",
667                           cpPath, "' not exists or empty", NULL);
668     sc->szCARevocationFile = cpPath;
669     return NULL;
670 }
671 
ssl_cmd_SSLVerifyClient(cmd_parms * cmd,SSLDirConfigRec * dc,char * level)672 const char *ssl_cmd_SSLVerifyClient(
673     cmd_parms *cmd, SSLDirConfigRec *dc, char *level)
674 {
675     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
676     ssl_verify_t id;
677 
678     if (strEQ(level, "0") || strcEQ(level, "none"))
679         id = SSL_CVERIFY_NONE;
680     else if (strEQ(level, "1") || strcEQ(level, "optional"))
681         id = SSL_CVERIFY_OPTIONAL;
682     else if (strEQ(level, "2") || strcEQ(level, "require"))
683         id = SSL_CVERIFY_REQUIRE;
684     else if (strEQ(level, "3") || strcEQ(level, "optional_no_ca"))
685         id = SSL_CVERIFY_OPTIONAL_NO_CA;
686     else
687         return "SSLVerifyClient: Invalid argument";
688     if (cmd->path == NULL || dc == NULL)
689         sc->nVerifyClient = id;
690     else
691         dc->nVerifyClient = id;
692     return NULL;
693 }
694 
ssl_cmd_SSLVerifyDepth(cmd_parms * cmd,SSLDirConfigRec * dc,char * arg)695 const char *ssl_cmd_SSLVerifyDepth(
696     cmd_parms *cmd, SSLDirConfigRec *dc, char *arg)
697 {
698     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
699     int d;
700 
701     d = atoi(arg);
702     if (d < 0)
703         return "SSLVerifyDepth: Invalid argument";
704     if (cmd->path == NULL || dc == NULL)
705         sc->nVerifyDepth = d;
706     else
707         dc->nVerifyDepth = d;
708     return NULL;
709 }
710 
ssl_cmd_SSLSessionCache(cmd_parms * cmd,char * struct_ptr,char * arg)711 const char *ssl_cmd_SSLSessionCache(
712     cmd_parms *cmd, char *struct_ptr, char *arg)
713 {
714     const char *err;
715     SSLModConfigRec *mc = myModConfig();
716     char *cp, *cp2;
717     int maxsize;
718 
719     if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL)
720         return err;
721     if (ssl_config_global_isfixed())
722         return NULL;
723     if (strcEQ(arg, "none")) {
724         mc->nSessionCacheMode      = SSL_SCMODE_NONE;
725         mc->szSessionCacheDataFile = NULL;
726     }
727     else if (strlen(arg) > 4 && strcEQn(arg, "dbm:", 4)) {
728         mc->nSessionCacheMode      = SSL_SCMODE_DBM;
729         mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool,
730                                      ssl_util_server_root_relative(cmd->pool, "scache", arg+4));
731     }
732     else if (   (strlen(arg) > 4 && strcEQn(arg, "shm:",   4))
733              || (strlen(arg) > 6 && strcEQn(arg, "shmht:", 6))) {
734         if (!ap_mm_useable())
735             return "SSLSessionCache: shared memory cache not useable on this platform";
736         mc->nSessionCacheMode      = SSL_SCMODE_SHMHT;
737         cp = strchr(arg, ':');
738         mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool,
739                                      ssl_util_server_root_relative(cmd->pool, "scache", cp+1));
740         mc->tSessionCacheDataTable = NULL;
741         mc->nSessionCacheDataSize  = 1024*512; /* 512KB */
742         if ((cp = strchr(mc->szSessionCacheDataFile, '(')) != NULL) {
743             *cp++ = NUL;
744             if ((cp2 = strchr(cp, ')')) == NULL)
745                 return "SSLSessionCache: Invalid argument: no closing parenthesis";
746             *cp2 = NUL;
747             mc->nSessionCacheDataSize = atoi(cp);
748             if (mc->nSessionCacheDataSize < 8192)
749                 return "SSLSessionCache: Invalid argument: size has to be >= 8192 bytes";
750             maxsize = ap_mm_core_maxsegsize();
751             if (mc->nSessionCacheDataSize >= maxsize)
752                 return ap_psprintf(cmd->pool, "SSLSessionCache: Invalid argument: "
753                                    "size has to be < %d bytes on this platform", maxsize);
754         }
755     }
756     else if (strlen(arg) > 6 && strcEQn(arg, "shmcb:", 6)) {
757         if (!ap_mm_useable())
758             return "SSLSessionCache: shared memory cache not useable on this platform";
759         mc->nSessionCacheMode      = SSL_SCMODE_SHMCB;
760         mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool,
761                                      ap_server_root_relative(cmd->pool, arg+6));
762         mc->tSessionCacheDataTable = NULL;
763         mc->nSessionCacheDataSize  = 1024*512; /* 512KB */
764         if ((cp = strchr(mc->szSessionCacheDataFile, '(')) != NULL) {
765             *cp++ = NUL;
766             if ((cp2 = strchr(cp, ')')) == NULL)
767                 return "SSLSessionCache: Invalid argument: no closing parenthesis";
768             *cp2 = NUL;
769             mc->nSessionCacheDataSize = atoi(cp);
770             if (mc->nSessionCacheDataSize < 8192)
771                 return "SSLSessionCache: Invalid argument: size has to be >= 8192 bytes";
772             maxsize = ap_mm_core_maxsegsize();
773             if (mc->nSessionCacheDataSize >= maxsize)
774                 return ap_psprintf(cmd->pool, "SSLSessionCache: Invalid argument: "
775                                    "size has to be < %d bytes on this platform", maxsize);
776         }
777     }
778 	else
779 #ifdef SSL_VENDOR
780         if (!ap_hook_use("ap::mod_ssl::vendor::cmd_sslsessioncache",
781              AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL,
782              cmd, arg, mc))
783 #endif
784         return "SSLSessionCache: Invalid argument";
785     return NULL;
786 }
787 
ssl_cmd_SSLSessionCacheTimeout(cmd_parms * cmd,char * struct_ptr,char * arg)788 const char *ssl_cmd_SSLSessionCacheTimeout(
789     cmd_parms *cmd, char *struct_ptr, char *arg)
790 {
791     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
792 
793     sc->nSessionCacheTimeout = atoi(arg);
794     if (sc->nSessionCacheTimeout < 0)
795         return "SSLSessionCacheTimeout: Invalid argument";
796     return NULL;
797 }
798 
ssl_cmd_SSLLog(cmd_parms * cmd,char * struct_ptr,char * arg)799 const char *ssl_cmd_SSLLog(
800     cmd_parms *cmd, char *struct_ptr, char *arg)
801 {
802     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
803     const char *err;
804 
805     if ((err = ap_check_cmd_context(cmd,  NOT_IN_LIMIT|NOT_IN_DIRECTORY
806                                          |NOT_IN_LOCATION|NOT_IN_FILES )) != NULL)
807         return err;
808     sc->szLogFile = arg;
809     return NULL;
810 }
811 
ssl_cmd_SSLLogLevel(cmd_parms * cmd,char * struct_ptr,char * level)812 const char *ssl_cmd_SSLLogLevel(
813     cmd_parms *cmd, char *struct_ptr, char *level)
814 {
815     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
816     const char *err;
817 
818     if ((err = ap_check_cmd_context(cmd,  NOT_IN_LIMIT|NOT_IN_DIRECTORY
819                                          |NOT_IN_LOCATION|NOT_IN_FILES )) != NULL)
820         return err;
821     if (strcEQ(level, "none"))
822         sc->nLogLevel = SSL_LOG_NONE;
823     else if (strcEQ(level, "error"))
824         sc->nLogLevel = SSL_LOG_ERROR;
825     else if (strcEQ(level, "warn"))
826         sc->nLogLevel = SSL_LOG_WARN;
827     else if (strcEQ(level, "info"))
828         sc->nLogLevel = SSL_LOG_INFO;
829     else if (strcEQ(level, "trace"))
830         sc->nLogLevel = SSL_LOG_TRACE;
831     else if (strcEQ(level, "debug"))
832         sc->nLogLevel = SSL_LOG_DEBUG;
833     else
834         return "SSLLogLevel: Invalid argument";
835     return NULL;
836 }
837 
ssl_cmd_SSLOptions(cmd_parms * cmd,SSLDirConfigRec * dc,const char * cpLine)838 const char *ssl_cmd_SSLOptions(
839     cmd_parms *cmd, SSLDirConfigRec *dc, const char *cpLine)
840 {
841     ssl_opt_t opt;
842     int first;
843     char action;
844     char *w;
845 
846     first = TRUE;
847     while (cpLine[0] != NUL) {
848         w = ap_getword_conf(cmd->pool, &cpLine);
849         action = NUL;
850 
851         if (*w == '+' || *w == '-') {
852             action = *(w++);
853         }
854         else if (first) {
855             dc->nOptions = SSL_OPT_NONE;
856             first = FALSE;
857         }
858 
859         if (strcEQ(w, "StdEnvVars"))
860             opt = SSL_OPT_STDENVVARS;
861         else if (strcEQ(w, "CompatEnvVars"))
862             opt = SSL_OPT_COMPATENVVARS;
863         else if (strcEQ(w, "ExportCertData"))
864             opt = SSL_OPT_EXPORTCERTDATA;
865         else if (strcEQ(w, "FakeBasicAuth"))
866             opt = SSL_OPT_FAKEBASICAUTH;
867         else if (strcEQ(w, "StrictRequire"))
868             opt = SSL_OPT_STRICTREQUIRE;
869         else if (strcEQ(w, "OptRenegotiate"))
870             opt = SSL_OPT_OPTRENEGOTIATE;
871         else
872             return ap_pstrcat(cmd->pool, "SSLOptions: Illegal option '", w, "'", NULL);
873 
874         if (action == '-') {
875             dc->nOptionsAdd &= ~opt;
876             dc->nOptionsDel |=  opt;
877             dc->nOptions    &= ~opt;
878         }
879         else if (action == '+') {
880             dc->nOptionsAdd |=  opt;
881             dc->nOptionsDel &= ~opt;
882             dc->nOptions    |=  opt;
883         }
884         else {
885             dc->nOptions    = opt;
886             dc->nOptionsAdd = opt;
887             dc->nOptionsDel = SSL_OPT_NONE;
888         }
889     }
890     return NULL;
891 }
892 
ssl_cmd_SSLRequireSSL(cmd_parms * cmd,SSLDirConfigRec * dc,char * cipher)893 const char *ssl_cmd_SSLRequireSSL(
894     cmd_parms *cmd, SSLDirConfigRec *dc, char *cipher)
895 {
896     dc->bSSLRequired = TRUE;
897     return NULL;
898 }
899 
ssl_cmd_SSLRequire(cmd_parms * cmd,SSLDirConfigRec * dc,char * cpExpr)900 const char *ssl_cmd_SSLRequire(
901     cmd_parms *cmd, SSLDirConfigRec *dc, char *cpExpr)
902 {
903     ssl_expr *mpExpr;
904     ssl_require_t *pReqRec;
905 
906     if ((mpExpr = ssl_expr_comp(cmd->pool, cpExpr)) == NULL)
907         return ap_pstrcat(cmd->pool, "SSLRequire: ", ssl_expr_get_error(), NULL);
908     pReqRec = ap_push_array(dc->aRequirement);
909     pReqRec->cpExpr = ap_pstrdup(cmd->pool, cpExpr);
910     pReqRec->mpExpr = mpExpr;
911     return NULL;
912 }
913 
ssl_cmd_SSLProtocol(cmd_parms * cmd,char * struct_ptr,const char * opt)914 const char *ssl_cmd_SSLProtocol(
915     cmd_parms *cmd, char *struct_ptr, const char *opt)
916 {
917     SSLSrvConfigRec *sc;
918     ssl_proto_t options, thisopt;
919     char action;
920     char *w;
921 
922     sc = mySrvConfig(cmd->server);
923     options = SSL_PROTOCOL_NONE;
924     while (opt[0] != NUL) {
925         w = ap_getword_conf(cmd->pool, &opt);
926 
927         action = NUL;
928         if (*w == '+' || *w == '-')
929             action = *(w++);
930 
931         if (strcEQ(w, "SSLv2"))
932             thisopt = SSL_PROTOCOL_SSLV2;
933         else if (strcEQ(w, "SSLv3"))
934             thisopt = SSL_PROTOCOL_SSLV3;
935         else if (strcEQ(w, "TLSv1"))
936             thisopt = SSL_PROTOCOL_TLSV1;
937         else if (strcEQ(w, "all"))
938             thisopt = SSL_PROTOCOL_ALL;
939         else
940             return ap_pstrcat(cmd->pool, "SSLProtocol: Illegal protocol '", w, "'", NULL);
941 
942         if (action == '-')
943             options &= ~thisopt;
944         else if (action == '+')
945             options |= thisopt;
946         else
947             options = thisopt;
948     }
949     sc->nProtocol = options;
950     return NULL;
951 }
952 
953 #ifdef SSL_EXPERIMENTAL_PROXY
954 
ssl_cmd_SSLProxyProtocol(cmd_parms * cmd,char * struct_ptr,const char * opt)955 const char *ssl_cmd_SSLProxyProtocol(
956     cmd_parms *cmd, char *struct_ptr, const char *opt)
957 {
958     SSLSrvConfigRec *sc;
959     ssl_proto_t options, thisopt;
960     char action;
961     char *w;
962 
963     sc = mySrvConfig(cmd->server);
964     options = SSL_PROTOCOL_NONE;
965     while (opt[0] != NUL) {
966         w = ap_getword_conf(cmd->pool, &opt);
967 
968         action = NUL;
969         if (*w == '+' || *w == '-')
970             action = *(w++);
971 
972         if (strcEQ(w, "SSLv2"))
973             thisopt = SSL_PROTOCOL_SSLV2;
974         else if (strcEQ(w, "SSLv3"))
975             thisopt = SSL_PROTOCOL_SSLV3;
976         else if (strcEQ(w, "TLSv1"))
977             thisopt = SSL_PROTOCOL_TLSV1;
978         else if (strcEQ(w, "all"))
979             thisopt = SSL_PROTOCOL_ALL;
980         else
981             return ap_pstrcat(cmd->pool, "SSLProxyProtocol: "
982                               "Illegal protocol '", w, "'", NULL);
983         if (action == '-')
984             options &= ~thisopt;
985         else if (action == '+')
986             options |= thisopt;
987         else
988             options = thisopt;
989     }
990     sc->nProxyProtocol = options;
991     return NULL;
992 }
993 
ssl_cmd_SSLProxyCipherSuite(cmd_parms * cmd,char * struct_ptr,char * arg)994 const char *ssl_cmd_SSLProxyCipherSuite(
995     cmd_parms *cmd, char *struct_ptr, char *arg)
996 {
997     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
998 
999     sc->szProxyCipherSuite = arg;
1000     return NULL;
1001 }
1002 
ssl_cmd_SSLProxyVerify(cmd_parms * cmd,char * struct_ptr,int flag)1003 const char *ssl_cmd_SSLProxyVerify(
1004     cmd_parms *cmd, char *struct_ptr, int flag)
1005 {
1006     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1007 
1008     sc->bProxyVerify = (flag ? TRUE : FALSE);
1009     return NULL;
1010 }
1011 
ssl_cmd_SSLProxyVerifyDepth(cmd_parms * cmd,char * struct_ptr,char * arg)1012 const char *ssl_cmd_SSLProxyVerifyDepth(
1013     cmd_parms *cmd, char *struct_ptr, char *arg)
1014 {
1015     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1016     int d;
1017 
1018     d = atoi(arg);
1019     if (d < 0)
1020         return "SSLProxyVerifyDepth: Invalid argument";
1021     sc->nProxyVerifyDepth = d;
1022     return NULL;
1023 }
1024 
ssl_cmd_SSLProxyCACertificateFile(cmd_parms * cmd,char * struct_ptr,char * arg)1025 const char *ssl_cmd_SSLProxyCACertificateFile(
1026     cmd_parms *cmd, char *struct_ptr, char *arg)
1027 {
1028     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1029     char *cpPath;
1030 
1031     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1032     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
1033         return ap_pstrcat(cmd->pool, "SSLProxyCACertificateFile: file '",
1034                           cpPath, "' not exists or empty", NULL);
1035     sc->szProxyCACertificateFile = cpPath;
1036     return NULL;
1037 }
1038 
ssl_cmd_SSLProxyCACertificatePath(cmd_parms * cmd,char * struct_ptr,char * arg)1039 const char *ssl_cmd_SSLProxyCACertificatePath(
1040     cmd_parms *cmd, char *struct_ptr, char *arg)
1041 {
1042     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1043     char *cpPath;
1044 
1045     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1046     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
1047         return ap_pstrcat(cmd->pool, "SSLProxyCACertificatePath: directory '",
1048                           cpPath, "' does not exists", NULL);
1049     sc->szProxyCACertificatePath = cpPath;
1050     return NULL;
1051 }
1052 
ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms * cmd,char * struct_ptr,char * arg)1053 const char *ssl_cmd_SSLProxyMachineCertificateFile(
1054     cmd_parms *cmd, char *struct_ptr, char *arg)
1055 {
1056     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1057     char *cpPath;
1058 
1059     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1060     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath))
1061         return ap_pstrcat(cmd->pool, "SSLProxyMachineCertFile: file '",
1062                           cpPath, "' not exists or empty", NULL);
1063     sc->szProxyClientCertificateFile = cpPath;
1064     return NULL;
1065 }
1066 
ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms * cmd,char * struct_ptr,char * arg)1067 const char *ssl_cmd_SSLProxyMachineCertificatePath(
1068     cmd_parms *cmd, char *struct_ptr, char *arg)
1069 {
1070     SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1071     char *cpPath;
1072 
1073     cpPath = ssl_util_server_root_relative(cmd->pool, "certkey", arg);
1074     if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath))
1075         return ap_pstrcat(cmd->pool, "SSLProxyMachineCertPath: directory '",
1076                           cpPath, "' does not exists", NULL);
1077     sc->szProxyClientCertificatePath = cpPath;
1078     return NULL;
1079 }
1080 
1081 #endif /* SSL_EXPERIMENTAL_PROXY */
1082 
1083