📄 ssl_engine_config.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* _ _ * _ __ ___ ___ __| | ___ ___| | mod_ssl * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL * | | | | | | (_) | (_| | \__ \__ \ | * |_| |_| |_|\___/ \__,_|___|___/___/_| * |_____| * ssl_engine_config.c * Apache Configuration Directives */ /* ``Damned if you do, damned if you don't.'' -- Unknown */#include "ssl_private.h"/* _________________________________________________________________**** Support for Global Configuration** _________________________________________________________________*/#define SSL_MOD_CONFIG_KEY "ssl_module"SSLModConfigRec *ssl_config_global_create(server_rec *s){ apr_pool_t *pool = s->process->pool; SSLModConfigRec *mc; void *vmc; apr_pool_userdata_get(&vmc, SSL_MOD_CONFIG_KEY, pool); if (vmc) { return vmc; /* reused for lifetime of the server */ } /* * allocate an own subpool which survives server restarts */ mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc)); mc->pPool = pool; mc->bFixed = FALSE; /* * initialize per-module configuration */ mc->nSessionCacheMode = SSL_SCMODE_UNSET; mc->szSessionCacheDataFile = NULL; mc->nSessionCacheDataSize = 0; mc->pSessionCacheDataMM = NULL; mc->pSessionCacheDataRMM = NULL; mc->tSessionCacheDataTable = NULL; mc->nMutexMode = SSL_MUTEXMODE_UNSET; mc->nMutexMech = APR_LOCK_DEFAULT; mc->szMutexFile = NULL; mc->pMutex = NULL; mc->aRandSeed = apr_array_make(pool, 4, sizeof(ssl_randseed_t)); mc->tVHostKeys = apr_hash_make(pool); mc->tPrivateKey = apr_hash_make(pool); mc->tPublicCert = apr_hash_make(pool);#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) mc->szCryptoDevice = NULL;#endif memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys)); apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY, apr_pool_cleanup_null, pool); return mc;}void ssl_config_global_fix(SSLModConfigRec *mc){ mc->bFixed = TRUE;}BOOL ssl_config_global_isfixed(SSLModConfigRec *mc){ return mc->bFixed;}/* _________________________________________________________________**** Configuration handling** _________________________________________________________________*/static void modssl_ctx_init(modssl_ctx_t *mctx){ mctx->sc = NULL; /* set during module init */ mctx->ssl_ctx = NULL; /* set during module init */ mctx->pks = NULL; mctx->pkp = NULL; mctx->protocol = SSL_PROTOCOL_ALL; mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET; mctx->pphrase_dialog_path = NULL; mctx->cert_chain = NULL; mctx->crl_path = NULL; mctx->crl_file = NULL; mctx->crl = NULL; /* set during module init */ mctx->auth.ca_cert_path = NULL; mctx->auth.ca_cert_file = NULL; mctx->auth.cipher_suite = NULL; mctx->auth.verify_depth = UNSET; mctx->auth.verify_mode = SSL_CVERIFY_UNSET;}static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc, apr_pool_t *p){ modssl_ctx_t *mctx; mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy)); modssl_ctx_init(mctx); mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp)); mctx->pkp->cert_file = NULL; mctx->pkp->cert_path = NULL; mctx->pkp->certs = NULL;}static void modssl_ctx_init_server(SSLSrvConfigRec *sc, apr_pool_t *p){ modssl_ctx_t *mctx; mctx = sc->server = apr_palloc(p, sizeof(*sc->server)); modssl_ctx_init(mctx); mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks)); /* mctx->pks->... certs/keys are set during module init */}static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p){ SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc)); sc->mc = NULL; sc->enabled = SSL_ENABLED_FALSE; sc->proxy_enabled = UNSET; sc->vhost_id = NULL; /* set during module init */ sc->vhost_id_len = 0; /* set during module init */ sc->session_cache_timeout = UNSET; sc->cipher_server_pref = UNSET; modssl_ctx_init_proxy(sc, p); modssl_ctx_init_server(sc, p); return sc;}/* * Create per-server SSL configuration */void *ssl_config_server_create(apr_pool_t *p, server_rec *s){ SSLSrvConfigRec *sc = ssl_config_server_new(p); sc->mc = ssl_config_global_create(s); return sc;}#define cfgMerge(el,unset) mrg->el = (add->el == (unset)) ? base->el : add->el#define cfgMergeArray(el) mrg->el = apr_array_append(p, add->el, base->el)#define cfgMergeString(el) cfgMerge(el, NULL)#define cfgMergeBool(el) cfgMerge(el, UNSET)#define cfgMergeInt(el) cfgMerge(el, UNSET)static void modssl_ctx_cfg_merge(modssl_ctx_t *base, modssl_ctx_t *add, modssl_ctx_t *mrg){ cfgMerge(protocol, SSL_PROTOCOL_ALL); cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET); cfgMergeString(pphrase_dialog_path); cfgMergeString(cert_chain); cfgMerge(crl_path, NULL); cfgMerge(crl_file, NULL); cfgMergeString(auth.ca_cert_path); cfgMergeString(auth.ca_cert_file); cfgMergeString(auth.cipher_suite); cfgMergeInt(auth.verify_depth); cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);}static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base, modssl_ctx_t *add, modssl_ctx_t *mrg){ modssl_ctx_cfg_merge(base, add, mrg); cfgMergeString(pkp->cert_file); cfgMergeString(pkp->cert_path);}static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base, modssl_ctx_t *add, modssl_ctx_t *mrg){ int i; modssl_ctx_cfg_merge(base, add, mrg); for (i = 0; i < SSL_AIDX_MAX; i++) { cfgMergeString(pks->cert_files[i]); cfgMergeString(pks->key_files[i]); } cfgMergeString(pks->ca_name_path); cfgMergeString(pks->ca_name_file);}/* * Merge per-server SSL configurations */void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv){ SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev; SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv; SSLSrvConfigRec *mrg = ssl_config_server_new(p); cfgMerge(mc, NULL); cfgMerge(enabled, SSL_ENABLED_UNSET); cfgMergeBool(proxy_enabled); cfgMergeInt(session_cache_timeout); cfgMergeBool(cipher_server_pref); modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server); return mrg;}/* * Create per-directory SSL configuration */void *ssl_config_perdir_create(apr_pool_t *p, char *dir){ SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc)); dc->bSSLRequired = FALSE; dc->aRequirement = apr_array_make(p, 4, sizeof(ssl_require_t)); dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET; dc->nOptionsAdd = SSL_OPT_NONE; dc->nOptionsDel = SSL_OPT_NONE; dc->szCipherSuite = NULL; dc->nVerifyClient = SSL_CVERIFY_UNSET; dc->nVerifyDepth = UNSET; dc->szCACertificatePath = NULL; dc->szCACertificateFile = NULL; dc->szUserName = NULL; return dc;}/* * Merge per-directory SSL configurations */void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv){ SSLDirConfigRec *base = (SSLDirConfigRec *)basev; SSLDirConfigRec *add = (SSLDirConfigRec *)addv; SSLDirConfigRec *mrg = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg)); cfgMerge(bSSLRequired, FALSE); cfgMergeArray(aRequirement); if (add->nOptions & SSL_OPT_RELSET) { mrg->nOptionsAdd = (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd; mrg->nOptionsDel = (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel; mrg->nOptions = (base->nOptions & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd; } else { mrg->nOptions = add->nOptions; mrg->nOptionsAdd = add->nOptionsAdd; mrg->nOptionsDel = add->nOptionsDel; } cfgMergeString(szCipherSuite); cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET); cfgMergeInt(nVerifyDepth); cfgMergeString(szCACertificatePath); cfgMergeString(szCACertificateFile); cfgMergeString(szUserName); return mrg;}/* * Configuration functions for particular directives */const char *ssl_cmd_SSLMutex(cmd_parms *cmd, void *dcfg, const char *arg_){ const char *err; SSLModConfigRec *mc = myModConfig(cmd->server); /* Split arg_ into meth and file */ char *meth = apr_pstrdup(cmd->temp_pool, arg_); char *file = strchr(meth, ':'); if (file) { *(file++) = '\0'; if (!*file) { file = NULL; } } if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { return err; } if (ssl_config_global_isfixed(mc)) { return NULL; } if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) { mc->nMutexMode = SSL_MUTEXMODE_NONE; return NULL; } /* APR determines temporary filename unless overridden below, * we presume file indicates an szMutexFile is a file path * unless the method sets szMutexFile=file and NULLs file */ mc->nMutexMode = SSL_MUTEXMODE_USED; mc->szMutexFile = NULL; /* NOTE: previously, 'yes' implied 'sem' */ if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) { mc->nMutexMech = APR_LOCK_DEFAULT; }#if APR_HAS_FCNTL_SERIALIZE else if ((!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) && file) { mc->nMutexMech = APR_LOCK_FCNTL; }#endif#if APR_HAS_FLOCK_SERIALIZE else if ((!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) && file) { mc->nMutexMech = APR_LOCK_FLOCK; }#endif#if APR_HAS_POSIXSEM_SERIALIZE else if (!strcasecmp(meth, "posixsem") || !strcasecmp(meth, "sem")) { mc->nMutexMech = APR_LOCK_POSIXSEM; /* Posix/SysV semaphores aren't file based, use the literal name * if provided and fall back on APR's default if not. Today, APR * will ignore it, but once supported it has an absurdly short limit. */ if (file) { mc->szMutexFile = apr_pstrdup(cmd->server->process->pool, file); file = NULL; } }#endif#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) { mc->nMutexMech = APR_LOCK_SYSVSEM; }#endif#if APR_HAS_PROC_PTHREAD_SERIALIZE else if (!strcasecmp(meth, "pthread")) { mc->nMutexMech = APR_LOCK_PROC_PTHREAD; }#endif else { return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", arg_, " (", ssl_valid_ssl_mutex_string, ")", NULL); } /* Unless the method above assumed responsibility for setting up * mc->szMutexFile and NULLing out file, presume it is a file we * are looking to use */ if (file) { mc->szMutexFile = ap_server_root_relative(cmd->server->process->pool, file); if (!mc->szMutexFile) { return apr_pstrcat(cmd->pool, "Invalid SSLMutex ", meth, ": filepath ", file, NULL); } } return NULL;}const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd, void *dcfg, const char *arg){ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); const char *err; int arglen = strlen(arg); if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { return err; } if (strcEQ(arg, "builtin")) { sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN; sc->server->pphrase_dialog_path = NULL; } else if ((arglen > 5) && strEQn(arg, "exec:", 5)) { sc->server->pphrase_dialog_type = SSL_PPTYPE_FILTER; sc->server->pphrase_dialog_path = ap_server_root_relative(cmd->pool, arg+5); if (!sc->server->pphrase_dialog_path) { return apr_pstrcat(cmd->pool, "Invalid SSLPassPhraseDialog exec: path ", arg+5, NULL); } if (!ssl_util_path_check(SSL_PCM_EXISTS, sc->server->pphrase_dialog_path, cmd->pool)) { return apr_pstrcat(cmd->pool, "SSLPassPhraseDialog: file '", sc->server->pphrase_dialog_path, "' does not exist", NULL); } } else if ((arglen > 1) && (arg[0] == '|')) { sc->server->pphrase_dialog_type = SSL_PPTYPE_PIPE; sc->server->pphrase_dialog_path = arg + 1; } else { return "SSLPassPhraseDialog: Invalid argument"; } return NULL;}#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd, void *dcfg, const char *arg){ SSLModConfigRec *mc = myModConfig(cmd->server); const char *err; ENGINE *e;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -