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 39SSLModConfigRec *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 88void ssl_config_global_fix(SSLModConfigRec *mc) 89{ 90 mc->bFixed = TRUE; 91} 92 93BOOL ssl_config_global_isfixed(SSLModConfigRec *mc) 94{ 95 return mc->bFixed; 96} 97 98/* _________________________________________________________________ 99** 100** Configuration handling 101** _________________________________________________________________ 102*/ 103 104static 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 131static 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->ca_cert_file = NULL; 145 mctx->pkp->certs = NULL; 146 mctx->pkp->ca_certs = NULL; 147} 148 149static void modssl_ctx_init_server(SSLSrvConfigRec *sc, 150 apr_pool_t *p) 151{ 152 modssl_ctx_t *mctx; 153 154 mctx = sc->server = apr_palloc(p, sizeof(*sc->server)); 155 156 modssl_ctx_init(mctx); 157 158 mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks)); 159 160 /* mctx->pks->... certs/keys are set during module init */ 161} 162 163static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p) 164{ 165 SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc)); 166 167 sc->mc = NULL; 168 sc->enabled = SSL_ENABLED_FALSE; 169 sc->proxy_enabled = UNSET; 170 sc->vhost_id = NULL; /* set during module init */ 171 sc->vhost_id_len = 0; /* set during module init */ 172 sc->session_cache_timeout = UNSET; 173 sc->cipher_server_pref = UNSET; 174 sc->insecure_reneg = UNSET; 175 sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET; 176 sc->proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET; 177#ifndef OPENSSL_NO_TLSEXT 178 sc->strict_sni_vhost_check = SSL_ENABLED_UNSET; 179#endif 180#ifdef HAVE_FIPS 181 sc->fips = UNSET; 182#endif 183#ifndef OPENSSL_NO_COMP 184 sc->compression = UNSET; 185#endif 186 sc->allow_empty_fragments = UNSET; 187 188 modssl_ctx_init_proxy(sc, p); 189 190 modssl_ctx_init_server(sc, p); 191 192 return sc; 193} 194 195/* 196 * Create per-server SSL configuration 197 */ 198void *ssl_config_server_create(apr_pool_t *p, server_rec *s) 199{ 200 SSLSrvConfigRec *sc = ssl_config_server_new(p); 201 202 sc->mc = ssl_config_global_create(s); 203 204 return sc; 205} 206 207#define cfgMerge(el,unset) mrg->el = (add->el == (unset)) ? base->el : add->el 208#define cfgMergeArray(el) mrg->el = apr_array_append(p, add->el, base->el) 209#define cfgMergeString(el) cfgMerge(el, NULL) 210#define cfgMergeBool(el) cfgMerge(el, UNSET) 211#define cfgMergeInt(el) cfgMerge(el, UNSET) 212 213static void modssl_ctx_cfg_merge(modssl_ctx_t *base, 214 modssl_ctx_t *add, 215 modssl_ctx_t *mrg) 216{ 217 cfgMerge(protocol, SSL_PROTOCOL_ALL); 218 219 cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET); 220 cfgMergeString(pphrase_dialog_path); 221 222 cfgMergeString(cert_chain); 223 224 cfgMerge(crl_path, NULL); 225 cfgMerge(crl_file, NULL); 226 227 cfgMergeString(auth.ca_cert_path); 228 cfgMergeString(auth.ca_cert_file); 229 cfgMergeString(auth.cipher_suite); 230 cfgMergeInt(auth.verify_depth); 231 cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET); 232} 233 234static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base, 235 modssl_ctx_t *add, 236 modssl_ctx_t *mrg) 237{ 238 modssl_ctx_cfg_merge(base, add, mrg); 239 240 cfgMergeString(pkp->cert_file); 241 cfgMergeString(pkp->cert_path); 242 cfgMergeString(pkp->ca_cert_file); 243} 244 245static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base, 246 modssl_ctx_t *add, 247 modssl_ctx_t *mrg) 248{ 249 int i; 250 251 modssl_ctx_cfg_merge(base, add, mrg); 252 253 for (i = 0; i < SSL_AIDX_MAX; i++) { 254 cfgMergeString(pks->cert_files[i]); 255 cfgMergeString(pks->key_files[i]); 256 } 257 258 cfgMergeString(pks->ca_name_path); 259 cfgMergeString(pks->ca_name_file); 260} 261 262/* 263 * Merge per-server SSL configurations 264 */ 265void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) 266{ 267 SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev; 268 SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv; 269 SSLSrvConfigRec *mrg = ssl_config_server_new(p); 270 271 cfgMerge(mc, NULL); 272 cfgMerge(enabled, SSL_ENABLED_UNSET); 273 cfgMergeBool(proxy_enabled); 274 cfgMergeInt(session_cache_timeout); 275 cfgMergeBool(cipher_server_pref); 276 cfgMergeBool(insecure_reneg); 277 cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET); 278 cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET); 279#ifndef OPENSSL_NO_TLSEXT 280 cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET); 281#endif 282#ifdef HAVE_FIPS 283 cfgMergeBool(fips); 284#endif 285#ifndef OPENSSL_NO_COMP 286 cfgMergeBool(compression); 287#endif 288 cfgMergeBool(allow_empty_fragments); 289 290 modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); 291 292 modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server); 293 294 return mrg; 295} 296 297/* 298 * Create per-directory SSL configuration 299 */ 300void *ssl_config_perdir_create(apr_pool_t *p, char *dir) 301{ 302 SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc)); 303 304 dc->bSSLRequired = FALSE; 305 dc->aRequirement = apr_array_make(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 314 dc->szCACertificatePath = NULL; 315 dc->szCACertificateFile = NULL; 316 dc->szUserName = NULL; 317 318 dc->nRenegBufferSize = UNSET; 319 320 return dc; 321} 322 323/* 324 * Merge per-directory SSL configurations 325 */ 326void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv) 327{ 328 SSLDirConfigRec *base = (SSLDirConfigRec *)basev; 329 SSLDirConfigRec *add = (SSLDirConfigRec *)addv; 330 SSLDirConfigRec *mrg = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg)); 331 332 cfgMerge(bSSLRequired, FALSE); 333 cfgMergeArray(aRequirement); 334 335 if (add->nOptions & SSL_OPT_RELSET) { 336 mrg->nOptionsAdd = 337 (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd; 338 mrg->nOptionsDel = 339 (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel; 340 mrg->nOptions = 341 (base->nOptions & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd; 342 } 343 else { 344 mrg->nOptions = add->nOptions; 345 mrg->nOptionsAdd = add->nOptionsAdd; 346 mrg->nOptionsDel = add->nOptionsDel; 347 } 348 349 cfgMergeString(szCipherSuite); 350 cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET); 351 cfgMergeInt(nVerifyDepth); 352 353 cfgMergeString(szCACertificatePath); 354 cfgMergeString(szCACertificateFile); 355 cfgMergeString(szUserName); 356 357 cfgMergeInt(nRenegBufferSize); 358 359 return mrg; 360} 361 362/* 363 * Configuration functions for particular directives 364 */ 365 366const char *ssl_cmd_SSLMutex(cmd_parms *cmd, 367 void *dcfg, 368 const char *arg_) 369{ 370 const char *err; 371 SSLModConfigRec *mc = myModConfig(cmd->server); 372 /* Split arg_ into meth and file */ 373 char *meth = apr_pstrdup(cmd->temp_pool, arg_); 374 char *file = strchr(meth, ':'); 375 if (file) { 376 *(file++) = '\0'; 377 if (!*file) { 378 file = NULL; 379 } 380 } 381 382 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { 383 return err; 384 } 385 386 if (ssl_config_global_isfixed(mc)) { 387 return NULL; 388 } 389 if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) { 390 mc->nMutexMode = SSL_MUTEXMODE_NONE; 391 return NULL; 392 } 393 394 /* APR determines temporary filename unless overridden below, 395 * we presume file indicates an szMutexFile is a file path 396 * unless the method sets szMutexFile=file and NULLs file 397 */ 398 mc->nMutexMode = SSL_MUTEXMODE_USED; 399 mc->szMutexFile = NULL; 400 401 /* NOTE: previously, 'yes' implied 'sem' */ 402 if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) { 403 mc->nMutexMech = APR_LOCK_DEFAULT; 404 } 405#if APR_HAS_FCNTL_SERIALIZE 406 else if ((!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) && file) { 407 mc->nMutexMech = APR_LOCK_FCNTL; 408 } 409#endif 410#if APR_HAS_FLOCK_SERIALIZE 411 else if ((!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) && file) { 412 mc->nMutexMech = APR_LOCK_FLOCK; 413 } 414#endif 415#if APR_HAS_POSIXSEM_SERIALIZE 416 else if (!strcasecmp(meth, "posixsem") || !strcasecmp(meth, "sem")) { 417 mc->nMutexMech = APR_LOCK_POSIXSEM; 418 /* Posix/SysV semaphores aren't file based, use the literal name 419 * if provided and fall back on APR's default if not. Today, APR 420 * will ignore it, but once supported it has an absurdly short limit. 421 */ 422 if (file) { 423 mc->szMutexFile = apr_pstrdup(cmd->server->process->pool, file); 424 425 file = NULL; 426 } 427 } 428#endif 429#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) 430 else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) { 431 mc->nMutexMech = APR_LOCK_SYSVSEM; 432 } 433#endif 434#if APR_HAS_PROC_PTHREAD_SERIALIZE 435 else if (!strcasecmp(meth, "pthread")) { 436 mc->nMutexMech = APR_LOCK_PROC_PTHREAD; 437 } 438#endif 439 else { 440 return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", arg_, 441 " (", ssl_valid_ssl_mutex_string, ")", NULL); 442 } 443 444 /* Unless the method above assumed responsibility for setting up 445 * mc->szMutexFile and NULLing out file, presume it is a file we 446 * are looking to use 447 */ 448 if (file) { 449 mc->szMutexFile = ap_server_root_relative(cmd->server->process->pool, file); 450 if (!mc->szMutexFile) { 451 return apr_pstrcat(cmd->pool, "Invalid SSLMutex ", meth, 452 ": filepath ", file, NULL); 453 } 454 } 455 456 return NULL; 457} 458 459const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd, 460 void *dcfg, 461 const char *arg) 462{ 463 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 464 const char *err; 465 int arglen = strlen(arg); 466 467 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { 468 return err; 469 } 470 471 if (strcEQ(arg, "builtin")) { 472 sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN; 473 sc->server->pphrase_dialog_path = NULL; 474 } 475 else if ((arglen > 5) && strEQn(arg, "exec:", 5)) { 476 sc->server->pphrase_dialog_type = SSL_PPTYPE_FILTER; 477 sc->server->pphrase_dialog_path = 478 ap_server_root_relative(cmd->pool, arg+5); 479 if (!sc->server->pphrase_dialog_path) { 480 return apr_pstrcat(cmd->pool, 481 "Invalid SSLPassPhraseDialog exec: path ", 482 arg+5, NULL); 483 } 484 if (!ssl_util_path_check(SSL_PCM_EXISTS, 485 sc->server->pphrase_dialog_path, 486 cmd->pool)) 487 { 488 return apr_pstrcat(cmd->pool, 489 "SSLPassPhraseDialog: file '", 490 sc->server->pphrase_dialog_path, 491 "' does not exist", NULL); 492 } 493 494 } 495 else if ((arglen > 1) && (arg[0] == '|')) { 496 sc->server->pphrase_dialog_type = SSL_PPTYPE_PIPE; 497 sc->server->pphrase_dialog_path = arg + 1; 498 } 499 else { 500 return "SSLPassPhraseDialog: Invalid argument"; 501 } 502 503 return NULL; 504} 505 506#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) 507const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd, 508 void *dcfg, 509 const char *arg) 510{ 511 SSLModConfigRec *mc = myModConfig(cmd->server); 512 const char *err; 513 ENGINE *e; 514 515 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { 516 return err; 517 } 518 519 if (strcEQ(arg, "builtin")) { 520 mc->szCryptoDevice = NULL; 521 } 522 else if ((e = ENGINE_by_id(arg))) { 523 mc->szCryptoDevice = arg; 524 ENGINE_free(e); 525 } 526 else { 527 err = "SSLCryptoDevice: Invalid argument; must be one of: " 528 "'builtin' (none)"; 529 e = ENGINE_get_first(); 530 while (e) { 531 ENGINE *en; 532 err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e), 533 "' (", ENGINE_get_name(e), ")", NULL); 534 en = ENGINE_get_next(e); 535 ENGINE_free(e); 536 e = en; 537 } 538 return err; 539 } 540 541 return NULL; 542} 543#endif 544 545const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd, 546 void *dcfg, 547 const char *arg1, 548 const char *arg2, 549 const char *arg3) 550{ 551 SSLModConfigRec *mc = myModConfig(cmd->server); 552 const char *err; 553 ssl_randseed_t *seed; 554 int arg2len = strlen(arg2); 555 556 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { 557 return err; 558 } 559 560 if (ssl_config_global_isfixed(mc)) { 561 return NULL; 562 } 563 564 seed = apr_array_push(mc->aRandSeed); 565 566 if (strcEQ(arg1, "startup")) { 567 seed->nCtx = SSL_RSCTX_STARTUP; 568 } 569 else if (strcEQ(arg1, "connect")) { 570 seed->nCtx = SSL_RSCTX_CONNECT; 571 } 572 else { 573 return apr_pstrcat(cmd->pool, "SSLRandomSeed: " 574 "invalid context: `", arg1, "'", 575 NULL); 576 } 577 578 if ((arg2len > 5) && strEQn(arg2, "file:", 5)) { 579 seed->nSrc = SSL_RSSRC_FILE; 580 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5); 581 } 582 else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) { 583 seed->nSrc = SSL_RSSRC_EXEC; 584 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5); 585 } 586 else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) { 587#ifdef HAVE_SSL_RAND_EGD 588 seed->nSrc = SSL_RSSRC_EGD; 589 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4); 590#else 591 return "egd not supported with this SSL toolkit"; 592#endif 593 } 594 else if (strcEQ(arg2, "builtin")) { 595 seed->nSrc = SSL_RSSRC_BUILTIN; 596 seed->cpPath = NULL; 597 } 598 else { 599 seed->nSrc = SSL_RSSRC_FILE; 600 seed->cpPath = ap_server_root_relative(mc->pPool, arg2); 601 } 602 603 if (seed->nSrc != SSL_RSSRC_BUILTIN) { 604 if (!seed->cpPath) { 605 return apr_pstrcat(cmd->pool, 606 "Invalid SSLRandomSeed path ", 607 arg2, NULL); 608 } 609 if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) { 610 return apr_pstrcat(cmd->pool, 611 "SSLRandomSeed: source path '", 612 seed->cpPath, "' does not exist", NULL); 613 } 614 } 615 616 if (!arg3) { 617 seed->nBytes = 0; /* read whole file */ 618 } 619 else { 620 if (seed->nSrc == SSL_RSSRC_BUILTIN) { 621 return "SSLRandomSeed: byte specification not " 622 "allowed for builtin seed source"; 623 } 624 625 seed->nBytes = atoi(arg3); 626 627 if (seed->nBytes < 0) { 628 return "SSLRandomSeed: invalid number of bytes specified"; 629 } 630 } 631 632 return NULL; 633} 634 635const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg) 636{ 637 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 638 639 if (!strcasecmp(arg, "On")) { 640 sc->enabled = SSL_ENABLED_TRUE; 641 return NULL; 642 } 643 else if (!strcasecmp(arg, "Off")) { 644 sc->enabled = SSL_ENABLED_FALSE; 645 return NULL; 646 } 647 else if (!strcasecmp(arg, "Optional")) { 648 sc->enabled = SSL_ENABLED_OPTIONAL; 649 return NULL; 650 } 651 652 return "Argument must be On, Off, or Optional"; 653} 654 655const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag) 656{ 657#ifdef HAVE_FIPS 658 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 659#endif 660 const char *err; 661 662 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { 663 return err; 664 } 665 666#ifdef HAVE_FIPS 667 if ((sc->fips != UNSET) && (sc->fips != (BOOL)(flag ? TRUE : FALSE))) 668 return "Conflicting SSLFIPS options, cannot be both On and Off"; 669 sc->fips = flag ? TRUE : FALSE; 670#else 671 if (flag) 672 return "SSLFIPS invalid, rebuild httpd and openssl compiled for FIPS"; 673#endif 674 675 return NULL; 676} 677 678const char *ssl_cmd_SSLAllowEmptyFragments(cmd_parms *cmd, void *dcfg, int flag) 679{ 680 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 681 const char *err; 682 683 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { 684 return err; 685 } 686 687 if ((sc->allow_empty_fragments != UNSET) && (sc->allow_empty_fragments != (BOOL)(flag ? TRUE : FALSE))) 688 return "Conflicting SSLAllowEmptyFragments options, cannot be both On and Off"; 689 sc->allow_empty_fragments = flag ? TRUE : FALSE; 690 691 return NULL; 692} 693 694const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd, 695 void *dcfg, 696 const char *arg) 697{ 698 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 699 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; 700 701 if (cmd->path) { 702 dc->szCipherSuite = arg; 703 } 704 else { 705 sc->server->auth.cipher_suite = arg; 706 } 707 708 return NULL; 709} 710 711#define SSL_FLAGS_CHECK_FILE \ 712 (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO) 713 714#define SSL_FLAGS_CHECK_DIR \ 715 (SSL_PCM_EXISTS|SSL_PCM_ISDIR) 716 717static const char *ssl_cmd_check_file(cmd_parms *parms, 718 const char **file) 719{ 720 const char *filepath = ap_server_root_relative(parms->pool, *file); 721 722 if (!filepath) { 723 return apr_pstrcat(parms->pool, parms->cmd->name, 724 ": Invalid file path ", *file, NULL); 725 } 726 *file = filepath; 727 728 if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) { 729 return NULL; 730 } 731 732 return apr_pstrcat(parms->pool, parms->cmd->name, 733 ": file '", *file, 734 "' does not exist or is empty", NULL); 735 736} 737 738const char *ssl_cmd_SSLCompression(cmd_parms *cmd, void *dcfg, int flag) 739{ 740#if !defined(OPENSSL_NO_COMP) 741 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 742#ifndef SSL_OP_NO_COMPRESSION 743 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); 744 if (err) 745 return "This version of openssl does not support configuring " 746 "compression within <VirtualHost> sections."; 747#endif 748 sc->compression = flag ? TRUE : FALSE; 749 return NULL; 750#else 751 return "Setting Compression mode unsupported; not implemented by the SSL library"; 752#endif 753} 754 755const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag) 756{ 757#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE 758 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 759 sc->cipher_server_pref = flag?TRUE:FALSE; 760 return NULL; 761#else 762 return "SSLHonorCiperOrder unsupported; not implemented by the SSL library"; 763#endif 764} 765 766const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag) 767{ 768#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 769 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 770 sc->insecure_reneg = flag?TRUE:FALSE; 771 return NULL; 772#else 773 return "The SSLInsecureRenegotiation directive is not available " 774 "with this SSL library"; 775#endif 776} 777 778 779static const char *ssl_cmd_check_dir(cmd_parms *parms, 780 const char **dir) 781{ 782 const char *dirpath = ap_server_root_relative(parms->pool, *dir); 783 784 if (!dirpath) { 785 return apr_pstrcat(parms->pool, parms->cmd->name, 786 ": Invalid dir path ", *dir, NULL); 787 } 788 *dir = dirpath; 789 790 if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) { 791 return NULL; 792 } 793 794 return apr_pstrcat(parms->pool, parms->cmd->name, 795 ": directory '", *dir, 796 "' does not exist", NULL); 797 798} 799 800#define SSL_AIDX_CERTS 1 801#define SSL_AIDX_KEYS 2 802 803static const char *ssl_cmd_check_aidx_max(cmd_parms *parms, 804 const char *arg, 805 int idx) 806{ 807 SSLSrvConfigRec *sc = mySrvConfig(parms->server); 808 const char *err, *desc=NULL, **files=NULL; 809 int i; 810 811 if ((err = ssl_cmd_check_file(parms, &arg))) { 812 return err; 813 } 814 815 switch (idx) { 816 case SSL_AIDX_CERTS: 817 desc = "certificates"; 818 files = sc->server->pks->cert_files; 819 break; 820 case SSL_AIDX_KEYS: 821 desc = "private keys"; 822 files = sc->server->pks->key_files; 823 break; 824 } 825 826 for (i = 0; i < SSL_AIDX_MAX; i++) { 827 if (!files[i]) { 828 files[i] = arg; 829 return NULL; 830 } 831 } 832 833 return apr_psprintf(parms->pool, 834 "%s: only up to %d " 835 "different %s per virtual host allowed", 836 parms->cmd->name, SSL_AIDX_MAX, desc); 837} 838 839const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd, 840 void *dcfg, 841 const char *arg) 842{ 843 844 const char *err; 845 846 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) { 847 return err; 848 } 849 850 return NULL; 851} 852 853const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd, 854 void *dcfg, 855 const char *arg) 856{ 857 const char *err; 858 859 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) { 860 return err; 861 } 862 863 return NULL; 864} 865 866const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd, 867 void *dcfg, 868 const char *arg) 869{ 870 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 871 const char *err; 872 873 if ((err = ssl_cmd_check_file(cmd, &arg))) { 874 return err; 875 } 876 877 sc->server->cert_chain = arg; 878 879 return NULL; 880} 881 882#define NO_PER_DIR_SSL_CA \ 883 "Your ssl library does not have support for per-directory CA" 884 885#ifdef HAVE_SSL_SET_CERT_STORE 886# define MODSSL_HAVE_SSL_SET_CERT_STORE 1 887#else 888# define MODSSL_HAVE_SSL_SET_CERT_STORE 0 889#endif 890 891#define MODSSL_SET_CA(f) \ 892 if (cmd->path) \ 893 if (MODSSL_HAVE_SSL_SET_CERT_STORE) \ 894 dc->f = arg; \ 895 else \ 896 return NO_PER_DIR_SSL_CA; \ 897 else \ 898 sc->f = arg \ 899 900const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd, 901 void *dcfg, 902 const char *arg) 903{ 904 /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/ 905 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 906 const char *err; 907 908 if ((err = ssl_cmd_check_dir(cmd, &arg))) { 909 return err; 910 } 911 912 /* XXX: bring back per-dir */ 913 sc->server->auth.ca_cert_path = arg; 914 915 return NULL; 916} 917 918const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd, 919 void *dcfg, 920 const char *arg) 921{ 922 /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/ 923 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 924 const char *err; 925 926 if ((err = ssl_cmd_check_file(cmd, &arg))) { 927 return err; 928 } 929 930 /* XXX: bring back per-dir */ 931 sc->server->auth.ca_cert_file = arg; 932 933 return NULL; 934} 935 936const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg, 937 const char *arg) 938{ 939 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 940 const char *err; 941 942 if ((err = ssl_cmd_check_dir(cmd, &arg))) { 943 return err; 944 } 945 946 sc->server->pks->ca_name_path = arg; 947 948 return NULL; 949} 950 951const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg, 952 const char *arg) 953{ 954 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 955 const char *err; 956 957 if ((err = ssl_cmd_check_file(cmd, &arg))) { 958 return err; 959 } 960 961 sc->server->pks->ca_name_file = arg; 962 963 return NULL; 964} 965 966const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd, 967 void *dcfg, 968 const char *arg) 969{ 970 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 971 const char *err; 972 973 if ((err = ssl_cmd_check_dir(cmd, &arg))) { 974 return err; 975 } 976 977 sc->server->crl_path = arg; 978 979 return NULL; 980} 981 982const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd, 983 void *dcfg, 984 const char *arg) 985{ 986 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 987 const char *err; 988 989 if ((err = ssl_cmd_check_file(cmd, &arg))) { 990 return err; 991 } 992 993 sc->server->crl_file = arg; 994 995 return NULL; 996} 997 998static const char *ssl_cmd_verify_parse(cmd_parms *parms, 999 const char *arg, 1000 ssl_verify_t *id) 1001{ 1002 if (strcEQ(arg, "none") || strcEQ(arg, "off")) { 1003 *id = SSL_CVERIFY_NONE; 1004 } 1005 else if (strcEQ(arg, "optional")) { 1006 *id = SSL_CVERIFY_OPTIONAL; 1007 } 1008 else if (strcEQ(arg, "require") || strcEQ(arg, "on")) { 1009 *id = SSL_CVERIFY_REQUIRE; 1010 } 1011 else if (strcEQ(arg, "optional_no_ca")) { 1012 *id = SSL_CVERIFY_OPTIONAL_NO_CA; 1013 } 1014 else { 1015 return apr_pstrcat(parms->temp_pool, parms->cmd->name, 1016 ": Invalid argument '", arg, "'", 1017 NULL); 1018 } 1019 1020 return NULL; 1021} 1022 1023const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd, 1024 void *dcfg, 1025 const char *arg) 1026{ 1027 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; 1028 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1029 ssl_verify_t mode; 1030 const char *err; 1031 1032 if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) { 1033 return err; 1034 } 1035 1036 if (cmd->path) { 1037 dc->nVerifyClient = mode; 1038 } 1039 else { 1040 sc->server->auth.verify_mode = mode; 1041 } 1042 1043 return NULL; 1044} 1045 1046static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms, 1047 const char *arg, 1048 int *depth) 1049{ 1050 if ((*depth = atoi(arg)) >= 0) { 1051 return NULL; 1052 } 1053 1054 return apr_pstrcat(parms->temp_pool, parms->cmd->name, 1055 ": Invalid argument '", arg, "'", 1056 NULL); 1057} 1058 1059const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd, 1060 void *dcfg, 1061 const char *arg) 1062{ 1063 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; 1064 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1065 int depth; 1066 const char *err; 1067 1068 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) { 1069 return err; 1070 } 1071 1072 if (cmd->path) { 1073 dc->nVerifyDepth = depth; 1074 } 1075 else { 1076 sc->server->auth.verify_depth = depth; 1077 } 1078 1079 return NULL; 1080} 1081 1082#define MODSSL_NO_SHARED_MEMORY_ERROR \ 1083 "SSLSessionCache: shared memory cache not useable on this platform" 1084 1085const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd, 1086 void *dcfg, 1087 const char *arg) 1088{ 1089 SSLModConfigRec *mc = myModConfig(cmd->server); 1090 const char *err, *colon; 1091 char *cp, *cp2; 1092 int arglen = strlen(arg); 1093 1094 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { 1095 return err; 1096 } 1097 1098 if (ssl_config_global_isfixed(mc)) { 1099 return NULL; 1100 } 1101 1102 if (strcEQ(arg, "none")) { 1103 mc->nSessionCacheMode = SSL_SCMODE_NONE; 1104 mc->szSessionCacheDataFile = NULL; 1105 } 1106 else if (strcEQ(arg, "nonenotnull")) { 1107 mc->nSessionCacheMode = SSL_SCMODE_NONE_NOT_NULL; 1108 mc->szSessionCacheDataFile = NULL; 1109 } 1110 else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) { 1111 mc->nSessionCacheMode = SSL_SCMODE_DBM; 1112 mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4); 1113 if (!mc->szSessionCacheDataFile) { 1114 return apr_psprintf(cmd->pool, 1115 "SSLSessionCache: Invalid cache file path %s", 1116 arg+4); 1117 } 1118 } 1119 else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) || 1120 ((arglen > 6) && strcEQn(arg, "shmht:", 6)) || 1121 ((arglen > 6) && strcEQn(arg, "shmcb:", 6))) { 1122#if !APR_HAS_SHARED_MEMORY 1123 return MODSSL_NO_SHARED_MEMORY_ERROR; 1124#endif 1125 mc->nSessionCacheMode = SSL_SCMODE_SHMCB; 1126 colon = ap_strchr_c(arg, ':'); 1127 mc->szSessionCacheDataFile = 1128 ap_server_root_relative(mc->pPool, colon+1); 1129 if (!mc->szSessionCacheDataFile) { 1130 return apr_psprintf(cmd->pool, 1131 "SSLSessionCache: Invalid cache file path %s", 1132 colon+1); 1133 } 1134 mc->tSessionCacheDataTable = NULL; 1135 mc->nSessionCacheDataSize = 1024*512; /* 512KB */ 1136 1137 if ((cp = strchr(mc->szSessionCacheDataFile, '('))) { 1138 *cp++ = NUL; 1139 1140 if (!(cp2 = strchr(cp, ')'))) { 1141 return "SSLSessionCache: Invalid argument: " 1142 "no closing parenthesis"; 1143 } 1144 1145 *cp2 = NUL; 1146 1147 mc->nSessionCacheDataSize = atoi(cp); 1148 1149 if (mc->nSessionCacheDataSize < 8192) { 1150 return "SSLSessionCache: Invalid argument: " 1151 "size has to be >= 8192 bytes"; 1152 1153 } 1154 1155 if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) { 1156 return apr_psprintf(cmd->pool, 1157 "SSLSessionCache: Invalid argument: " 1158 "size has to be < %d bytes on this " 1159 "platform", APR_SHM_MAXSIZE); 1160 1161 } 1162 } 1163 } 1164 else if ((arglen > 3) && strcEQn(arg, "dc:", 3)) { 1165#ifdef HAVE_DISTCACHE 1166 mc->nSessionCacheMode = SSL_SCMODE_DC; 1167 mc->szSessionCacheDataFile = apr_pstrdup(mc->pPool, arg+3); 1168 if (!mc->szSessionCacheDataFile) { 1169 return apr_pstrcat(cmd->pool, 1170 "SSLSessionCache: Invalid cache file path: ", 1171 arg+3, NULL); 1172 } 1173#else 1174 return "SSLSessionCache: distcache support disabled"; 1175#endif 1176 } 1177 else { 1178 return "SSLSessionCache: Invalid argument"; 1179 } 1180 1181 return NULL; 1182} 1183 1184const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd, 1185 void *dcfg, 1186 const char *arg) 1187{ 1188 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1189 1190 sc->session_cache_timeout = atoi(arg); 1191 1192 if (sc->session_cache_timeout < 0) { 1193 return "SSLSessionCacheTimeout: Invalid argument"; 1194 } 1195 1196 return NULL; 1197} 1198 1199const char *ssl_cmd_SSLOptions(cmd_parms *cmd, 1200 void *dcfg, 1201 const char *arg) 1202{ 1203 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; 1204 ssl_opt_t opt; 1205 int first = TRUE; 1206 char action, *w; 1207 1208 while (*arg) { 1209 w = ap_getword_conf(cmd->pool, &arg); 1210 action = NUL; 1211 1212 if ((*w == '+') || (*w == '-')) { 1213 action = *(w++); 1214 } 1215 else if (first) { 1216 dc->nOptions = SSL_OPT_NONE; 1217 first = FALSE; 1218 } 1219 1220 if (strcEQ(w, "StdEnvVars")) { 1221 opt = SSL_OPT_STDENVVARS; 1222 } 1223 else if (strcEQ(w, "ExportCertData")) { 1224 opt = SSL_OPT_EXPORTCERTDATA; 1225 } 1226 else if (strcEQ(w, "FakeBasicAuth")) { 1227 opt = SSL_OPT_FAKEBASICAUTH; 1228 } 1229 else if (strcEQ(w, "StrictRequire")) { 1230 opt = SSL_OPT_STRICTREQUIRE; 1231 } 1232 else if (strcEQ(w, "OptRenegotiate")) { 1233 opt = SSL_OPT_OPTRENEGOTIATE; 1234 } 1235 else { 1236 return apr_pstrcat(cmd->pool, 1237 "SSLOptions: Illegal option '", w, "'", 1238 NULL); 1239 } 1240 1241 if (action == '-') { 1242 dc->nOptionsAdd &= ~opt; 1243 dc->nOptionsDel |= opt; 1244 dc->nOptions &= ~opt; 1245 } 1246 else if (action == '+') { 1247 dc->nOptionsAdd |= opt; 1248 dc->nOptionsDel &= ~opt; 1249 dc->nOptions |= opt; 1250 } 1251 else { 1252 dc->nOptions = opt; 1253 dc->nOptionsAdd = opt; 1254 dc->nOptionsDel = SSL_OPT_NONE; 1255 } 1256 } 1257 1258 return NULL; 1259} 1260 1261const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg) 1262{ 1263 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; 1264 1265 dc->bSSLRequired = TRUE; 1266 1267 return NULL; 1268} 1269 1270const char *ssl_cmd_SSLRequire(cmd_parms *cmd, 1271 void *dcfg, 1272 const char *arg) 1273{ 1274 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; 1275 ssl_expr *expr; 1276 ssl_require_t *require; 1277 1278 if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) { 1279 return apr_pstrcat(cmd->pool, "SSLRequire: ", 1280 ssl_expr_get_error(), NULL); 1281 } 1282 1283 require = apr_array_push(dc->aRequirement); 1284 require->cpExpr = apr_pstrdup(cmd->pool, arg); 1285 require->mpExpr = expr; 1286 1287 return NULL; 1288} 1289 1290const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg) 1291{ 1292 SSLDirConfigRec *dc = dcfg; 1293 int val; 1294 1295 val = atoi(arg); 1296 if (val < 0) { 1297 return apr_pstrcat(cmd->pool, "Invalid size for SSLRenegBufferSize: ", 1298 arg, NULL); 1299 } 1300 dc->nRenegBufferSize = val; 1301 1302 return NULL; 1303} 1304 1305static const char *ssl_cmd_protocol_parse(cmd_parms *parms, 1306 const char *arg, 1307 ssl_proto_t *options) 1308{ 1309 ssl_proto_t thisopt; 1310 1311 *options = SSL_PROTOCOL_NONE; 1312 1313 while (*arg) { 1314 char *w = ap_getword_conf(parms->temp_pool, &arg); 1315 char action = '\0'; 1316 1317 if ((*w == '+') || (*w == '-')) { 1318 action = *(w++); 1319 } 1320 1321 if (strcEQ(w, "SSLv2")) { 1322#ifdef OPENSSL_NO_SSL2 1323 if (action != '-') { 1324 return "SSLv2 not supported by this version of OpenSSL"; 1325 } 1326 /* Nothing to do, the flag is not present to be toggled */ 1327 continue; 1328#else 1329 thisopt = SSL_PROTOCOL_SSLV2; 1330#endif 1331 } 1332 else if (strcEQ(w, "SSLv3")) { 1333 thisopt = SSL_PROTOCOL_SSLV3; 1334 } 1335 else if (strcEQ(w, "TLSv1")) { 1336 thisopt = SSL_PROTOCOL_TLSV1; 1337 } 1338#ifdef HAVE_TLSV1_X 1339 else if (strcEQ(w, "TLSv1.1")) { 1340 thisopt = SSL_PROTOCOL_TLSV1_1; 1341 } 1342 else if (strcEQ(w, "TLSv1.2")) { 1343 thisopt = SSL_PROTOCOL_TLSV1_2; 1344 } 1345#endif 1346 else if (strcEQ(w, "all")) { 1347 thisopt = SSL_PROTOCOL_ALL; 1348 } 1349 else { 1350 return apr_pstrcat(parms->temp_pool, 1351 parms->cmd->name, 1352 ": Illegal protocol '", 1353 w, "'", NULL); 1354 } 1355 1356 if (action == '-') { 1357 *options &= ~thisopt; 1358 } 1359 else if (action == '+') { 1360 *options |= thisopt; 1361 } 1362 else { 1363 *options = thisopt; 1364 } 1365 } 1366 1367 return NULL; 1368} 1369 1370const char *ssl_cmd_SSLProtocol(cmd_parms *cmd, 1371 void *dcfg, 1372 const char *arg) 1373{ 1374 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1375 1376 return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol); 1377} 1378 1379const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag) 1380{ 1381 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1382 1383 sc->proxy_enabled = flag ? TRUE : FALSE; 1384 1385 return NULL; 1386} 1387 1388const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd, 1389 void *dcfg, 1390 const char *arg) 1391{ 1392 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1393 1394 return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol); 1395} 1396 1397const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd, 1398 void *dcfg, 1399 const char *arg) 1400{ 1401 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1402 1403 sc->proxy->auth.cipher_suite = arg; 1404 1405 return NULL; 1406} 1407 1408const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd, 1409 void *dcfg, 1410 const char *arg) 1411{ 1412 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1413 ssl_verify_t mode; 1414 const char *err; 1415 1416 if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) { 1417 return err; 1418 } 1419 1420 sc->proxy->auth.verify_mode = mode; 1421 1422 return NULL; 1423} 1424 1425const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd, 1426 void *dcfg, 1427 const char *arg) 1428{ 1429 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1430 int depth; 1431 const char *err; 1432 1433 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) { 1434 return err; 1435 } 1436 1437 sc->proxy->auth.verify_depth = depth; 1438 1439 return NULL; 1440} 1441 1442const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd, 1443 void *dcfg, 1444 const char *arg) 1445{ 1446 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1447 const char *err; 1448 1449 if ((err = ssl_cmd_check_file(cmd, &arg))) { 1450 return err; 1451 } 1452 1453 sc->proxy->auth.ca_cert_file = arg; 1454 1455 return NULL; 1456} 1457 1458const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd, 1459 void *dcfg, 1460 const char *arg) 1461{ 1462 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1463 const char *err; 1464 1465 if ((err = ssl_cmd_check_dir(cmd, &arg))) { 1466 return err; 1467 } 1468 1469 sc->proxy->auth.ca_cert_path = arg; 1470 1471 return NULL; 1472} 1473 1474const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd, 1475 void *dcfg, 1476 const char *arg) 1477{ 1478 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1479 const char *err; 1480 1481 if ((err = ssl_cmd_check_dir(cmd, &arg))) { 1482 return err; 1483 } 1484 1485 sc->proxy->crl_path = arg; 1486 1487 return NULL; 1488} 1489 1490const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd, 1491 void *dcfg, 1492 const char *arg) 1493{ 1494 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1495 const char *err; 1496 1497 if ((err = ssl_cmd_check_file(cmd, &arg))) { 1498 return err; 1499 } 1500 1501 sc->proxy->crl_file = arg; 1502 1503 return NULL; 1504} 1505 1506const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd, 1507 void *dcfg, 1508 const char *arg) 1509{ 1510 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1511 const char *err; 1512 1513 if ((err = ssl_cmd_check_file(cmd, &arg))) { 1514 return err; 1515 } 1516 1517 sc->proxy->pkp->cert_file = arg; 1518 1519 return NULL; 1520} 1521 1522const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd, 1523 void *dcfg, 1524 const char *arg) 1525{ 1526 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1527 const char *err; 1528 1529 if ((err = ssl_cmd_check_dir(cmd, &arg))) { 1530 return err; 1531 } 1532 1533 sc->proxy->pkp->cert_path = arg; 1534 1535 return NULL; 1536} 1537 1538const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *cmd, 1539 void *dcfg, 1540 const char *arg) 1541{ 1542 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1543 const char *err; 1544 1545 if ((err = ssl_cmd_check_file(cmd, &arg))) { 1546 return err; 1547 } 1548 1549 sc->proxy->pkp->ca_cert_file = arg; 1550 1551 return NULL; 1552} 1553 1554const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg, 1555 const char *arg) 1556{ 1557 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg; 1558 dc->szUserName = arg; 1559 return NULL; 1560} 1561 1562const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag) 1563{ 1564 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1565 1566 sc->proxy_ssl_check_peer_expire = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE; 1567 1568 return NULL; 1569} 1570 1571const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag) 1572{ 1573 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1574 1575 sc->proxy_ssl_check_peer_cn = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE; 1576 1577 return NULL; 1578} 1579 1580const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag) 1581{ 1582#ifndef OPENSSL_NO_TLSEXT 1583 SSLSrvConfigRec *sc = mySrvConfig(cmd->server); 1584 1585 sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE; 1586 1587 return NULL; 1588#else 1589 return "SSLStrictSNIVHostCheck failed; OpenSSL is not built with support " 1590 "for TLS extensions and SNI indication. Refer to the " 1591 "documentation, and build a compatible version of OpenSSL."; 1592#endif 1593} 1594 1595void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) 1596{ 1597 if (!ap_exists_config_define("DUMP_CERTS")) { 1598 return; 1599 } 1600 1601 /* Dump the filenames of all configured server certificates to 1602 * stdout. */ 1603 while (s) { 1604 SSLSrvConfigRec *sc = mySrvConfig(s); 1605 1606 if (sc && sc->server && sc->server->pks) { 1607 modssl_pk_server_t *const pks = sc->server->pks; 1608 int i; 1609 1610 for (i = 0; (i < SSL_AIDX_MAX) && pks->cert_files[i]; i++) { 1611 printf("%s\n", pks->cert_files[i]); 1612 } 1613 } 1614 1615 s = s->next; 1616 } 1617 1618} 1619