Blame modules/ssl/ssl_engine_config.c

Packit 90a5c9
/* Licensed to the Apache Software Foundation (ASF) under one or more
Packit 90a5c9
 * contributor license agreements.  See the NOTICE file distributed with
Packit 90a5c9
 * this work for additional information regarding copyright ownership.
Packit 90a5c9
 * The ASF licenses this file to You under the Apache License, Version 2.0
Packit 90a5c9
 * (the "License"); you may not use this file except in compliance with
Packit 90a5c9
 * the License.  You may obtain a copy of the License at
Packit 90a5c9
 *
Packit 90a5c9
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 90a5c9
 *
Packit 90a5c9
 * Unless required by applicable law or agreed to in writing, software
Packit 90a5c9
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 90a5c9
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 90a5c9
 * See the License for the specific language governing permissions and
Packit 90a5c9
 * limitations under the License.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
/*                      _             _
Packit 90a5c9
 *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
Packit 90a5c9
 * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
Packit 90a5c9
 * | | | | | | (_) | (_| |   \__ \__ \ |
Packit 90a5c9
 * |_| |_| |_|\___/ \__,_|___|___/___/_|
Packit 90a5c9
 *                      |_____|
Packit 90a5c9
 *  ssl_engine_config.c
Packit 90a5c9
 *  Apache Configuration Directives
Packit 90a5c9
 */
Packit 90a5c9
                                      /* ``Damned if you do,
Packit 90a5c9
                                           damned if you don't.''
Packit 90a5c9
                                               -- Unknown        */
Packit 90a5c9
#include "ssl_private.h"
Packit 90a5c9
#include "util_mutex.h"
Packit 90a5c9
#include "ap_provider.h"
Packit 90a5c9
Packit 90a5c9
/*  _________________________________________________________________
Packit 90a5c9
**
Packit 90a5c9
**  Support for Global Configuration
Packit 90a5c9
**  _________________________________________________________________
Packit 90a5c9
*/
Packit 90a5c9
Packit 90a5c9
#define SSL_MOD_CONFIG_KEY "ssl_module"
Packit 90a5c9
Packit 90a5c9
SSLModConfigRec *ssl_config_global_create(server_rec *s)
Packit 90a5c9
{
Packit 90a5c9
    apr_pool_t *pool = s->process->pool;
Packit 90a5c9
    SSLModConfigRec *mc;
Packit 90a5c9
    void *vmc;
Packit 90a5c9
Packit 90a5c9
    apr_pool_userdata_get(&vmc, SSL_MOD_CONFIG_KEY, pool);
Packit 90a5c9
    if (vmc) {
Packit 90a5c9
        return vmc; /* reused for lifetime of the server */
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /*
Packit 90a5c9
     * allocate an own subpool which survives server restarts
Packit 90a5c9
     */
Packit 90a5c9
    mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc));
Packit 90a5c9
    mc->pPool = pool;
Packit 90a5c9
    mc->bFixed = FALSE;
Packit 90a5c9
Packit 90a5c9
    /*
Packit 90a5c9
     * initialize per-module configuration
Packit 90a5c9
     */
Packit 90a5c9
    mc->sesscache_mode         = SSL_SESS_CACHE_OFF;
Packit 90a5c9
    mc->sesscache              = NULL;
Packit 90a5c9
    mc->pMutex                 = NULL;
Packit 90a5c9
    mc->aRandSeed              = apr_array_make(pool, 4,
Packit 90a5c9
                                                sizeof(ssl_randseed_t));
Packit 90a5c9
    mc->tVHostKeys             = apr_hash_make(pool);
Packit 90a5c9
    mc->tPrivateKey            = apr_hash_make(pool);
Packit 90a5c9
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
Packit 90a5c9
    mc->szCryptoDevice         = NULL;
Packit 90a5c9
#endif
Packit 90a5c9
#ifdef HAVE_OCSP_STAPLING
Packit 90a5c9
    mc->stapling_cache         = NULL;
Packit 90a5c9
    mc->stapling_cache_mutex   = NULL;
Packit 90a5c9
    mc->stapling_refresh_mutex = NULL;
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
    apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
Packit 90a5c9
                          apr_pool_cleanup_null,
Packit 90a5c9
                          pool);
Packit 90a5c9
Packit 90a5c9
    return mc;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void ssl_config_global_fix(SSLModConfigRec *mc)
Packit 90a5c9
{
Packit 90a5c9
    mc->bFixed = TRUE;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
Packit 90a5c9
{
Packit 90a5c9
    return mc->bFixed;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*  _________________________________________________________________
Packit 90a5c9
**
Packit 90a5c9
**  Configuration handling
Packit 90a5c9
**  _________________________________________________________________
Packit 90a5c9
*/
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_SSL_CONF_CMD
Packit 90a5c9
static apr_status_t modssl_ctx_config_cleanup(void *ctx)
Packit 90a5c9
{
Packit 90a5c9
    SSL_CONF_CTX_free(ctx);
Packit 90a5c9
    return APR_SUCCESS;
Packit 90a5c9
}
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
Packit 90a5c9
{
Packit 90a5c9
    mctx->sc                  = NULL; /* set during module init */
Packit 90a5c9
Packit 90a5c9
    mctx->ssl_ctx             = NULL; /* set during module init */
Packit 90a5c9
Packit 90a5c9
    mctx->pks                 = NULL;
Packit 90a5c9
    mctx->pkp                 = NULL;
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_TLS_SESSION_TICKETS
Packit 90a5c9
    mctx->ticket_key          = NULL;
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
    mctx->protocol            = SSL_PROTOCOL_DEFAULT;
Packit 90a5c9
    mctx->protocol_set        = 0;
Packit 90a5c9
Packit 90a5c9
    mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
Packit 90a5c9
    mctx->pphrase_dialog_path = NULL;
Packit 90a5c9
Packit 90a5c9
    mctx->cert_chain          = NULL;
Packit 90a5c9
Packit 90a5c9
    mctx->crl_path            = NULL;
Packit 90a5c9
    mctx->crl_file            = NULL;
Packit 90a5c9
    mctx->crl_check_mask      = UNSET;
Packit 90a5c9
Packit 90a5c9
    mctx->auth.ca_cert_path   = NULL;
Packit 90a5c9
    mctx->auth.ca_cert_file   = NULL;
Packit 90a5c9
    mctx->auth.cipher_suite   = NULL;
Packit 90a5c9
    mctx->auth.verify_depth   = UNSET;
Packit 90a5c9
    mctx->auth.verify_mode    = SSL_CVERIFY_UNSET;
Packit 90a5c9
    mctx->auth.tls13_ciphers = NULL;
Packit 90a5c9
Packit 90a5c9
    mctx->ocsp_mask           = UNSET;
Packit 90a5c9
    mctx->ocsp_force_default  = UNSET;
Packit 90a5c9
    mctx->ocsp_responder      = NULL;
Packit 90a5c9
    mctx->ocsp_resptime_skew  = UNSET;
Packit 90a5c9
    mctx->ocsp_resp_maxage    = UNSET;
Packit 90a5c9
    mctx->ocsp_responder_timeout = UNSET;
Packit 90a5c9
    mctx->ocsp_use_request_nonce = UNSET;
Packit 90a5c9
    mctx->proxy_uri              = NULL;
Packit 90a5c9
Packit 90a5c9
/* Set OCSP Responder Certificate Verification variable */
Packit 90a5c9
    mctx->ocsp_noverify       = UNSET;
Packit 90a5c9
/* Set OCSP Responder File variables */
Packit 90a5c9
    mctx->ocsp_verify_flags   = 0;
Packit 90a5c9
    mctx->ocsp_certs_file     = NULL;
Packit 90a5c9
    mctx->ocsp_certs          = NULL;
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_OCSP_STAPLING
Packit 90a5c9
    mctx->stapling_enabled           = UNSET;
Packit 90a5c9
    mctx->stapling_resptime_skew     = UNSET;
Packit 90a5c9
    mctx->stapling_resp_maxage       = UNSET;
Packit 90a5c9
    mctx->stapling_cache_timeout     = UNSET;
Packit 90a5c9
    mctx->stapling_return_errors     = UNSET;
Packit 90a5c9
    mctx->stapling_fake_trylater     = UNSET;
Packit 90a5c9
    mctx->stapling_errcache_timeout  = UNSET;
Packit 90a5c9
    mctx->stapling_responder_timeout = UNSET;
Packit 90a5c9
    mctx->stapling_force_url         = NULL;
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_SRP
Packit 90a5c9
    mctx->srp_vfile =             NULL;
Packit 90a5c9
    mctx->srp_unknown_user_seed = NULL;
Packit 90a5c9
    mctx->srp_vbase =             NULL;
Packit 90a5c9
#endif
Packit 90a5c9
#ifdef HAVE_SSL_CONF_CMD
Packit 90a5c9
    mctx->ssl_ctx_config = SSL_CONF_CTX_new();
Packit 90a5c9
    apr_pool_cleanup_register(p, mctx->ssl_ctx_config,
Packit 90a5c9
                              modssl_ctx_config_cleanup,
Packit 90a5c9
                              apr_pool_cleanup_null);
Packit 90a5c9
    SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_FILE);
Packit 90a5c9
    SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_SERVER);
Packit 90a5c9
    SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_CERTIFICATE);
Packit 90a5c9
    mctx->ssl_ctx_param = apr_array_make(p, 5, sizeof(ssl_ctx_param_t));
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
    mctx->ssl_check_peer_cn     = UNSET;
Packit 90a5c9
    mctx->ssl_check_peer_name   = UNSET;
Packit 90a5c9
    mctx->ssl_check_peer_expire = UNSET;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
Packit 90a5c9
                                   apr_pool_t *p)
Packit 90a5c9
{
Packit 90a5c9
    modssl_ctx_t *mctx;
Packit 90a5c9
Packit 90a5c9
    mctx = sc->server = apr_palloc(p, sizeof(*sc->server));
Packit 90a5c9
Packit 90a5c9
    modssl_ctx_init(mctx, p);
Packit 90a5c9
Packit 90a5c9
    mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks));
Packit 90a5c9
Packit 90a5c9
    mctx->pks->cert_files = apr_array_make(p, 3, sizeof(char *));
Packit 90a5c9
    mctx->pks->key_files  = apr_array_make(p, 3, sizeof(char *));
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_TLS_SESSION_TICKETS
Packit 90a5c9
    mctx->ticket_key = apr_pcalloc(p, sizeof(*mctx->ticket_key));
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
Packit 90a5c9
Packit 90a5c9
    sc->mc                     = NULL;
Packit 90a5c9
    sc->enabled                = SSL_ENABLED_UNSET;
Packit 90a5c9
    sc->vhost_id               = NULL;  /* set during module init */
Packit 90a5c9
    sc->vhost_id_len           = 0;     /* set during module init */
Packit 90a5c9
    sc->session_cache_timeout  = UNSET;
Packit 90a5c9
    sc->cipher_server_pref     = UNSET;
Packit 90a5c9
    sc->insecure_reneg         = UNSET;
Packit 90a5c9
#ifdef HAVE_TLSEXT
Packit 90a5c9
    sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
Packit 90a5c9
#endif
Packit 90a5c9
#ifdef HAVE_FIPS
Packit 90a5c9
    sc->fips                   = UNSET;
Packit 90a5c9
#endif
Packit 90a5c9
#ifndef OPENSSL_NO_COMP
Packit 90a5c9
    sc->compression            = UNSET;
Packit 90a5c9
#endif
Packit 90a5c9
    sc->session_tickets        = UNSET;
Packit 90a5c9
Packit 90a5c9
    modssl_ctx_init_server(sc, p);
Packit 90a5c9
Packit 90a5c9
    return sc;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 *  Create per-server SSL configuration
Packit 90a5c9
 */
Packit 90a5c9
void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = ssl_config_server_new(p);
Packit 90a5c9
Packit 90a5c9
    sc->mc = ssl_config_global_create(s);
Packit 90a5c9
Packit 90a5c9
    return sc;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#define cfgMerge(el,unset)  mrg->el = (add->el == (unset)) ? base->el : add->el
Packit 90a5c9
#define cfgMergeArray(el)   mrg->el = apr_array_append(p, base->el, add->el)
Packit 90a5c9
#define cfgMergeString(el)  cfgMerge(el, NULL)
Packit 90a5c9
#define cfgMergeBool(el)    cfgMerge(el, UNSET)
Packit 90a5c9
#define cfgMergeInt(el)     cfgMerge(el, UNSET)
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 *  Merge per-server SSL configurations
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
static void modssl_ctx_cfg_merge(apr_pool_t *p,
Packit 90a5c9
                                 modssl_ctx_t *base,
Packit 90a5c9
                                 modssl_ctx_t *add,
Packit 90a5c9
                                 modssl_ctx_t *mrg)
Packit 90a5c9
{
Packit 90a5c9
    if (add->protocol_set) {
Packit 90a5c9
        mrg->protocol = add->protocol;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        mrg->protocol = base->protocol;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
Packit 90a5c9
    cfgMergeString(pphrase_dialog_path);
Packit 90a5c9
Packit 90a5c9
    cfgMergeString(cert_chain);
Packit 90a5c9
Packit 90a5c9
    cfgMerge(crl_path, NULL);
Packit 90a5c9
    cfgMerge(crl_file, NULL);
Packit 90a5c9
    cfgMergeInt(crl_check_mask);
Packit 90a5c9
Packit 90a5c9
    cfgMergeString(auth.ca_cert_path);
Packit 90a5c9
    cfgMergeString(auth.ca_cert_file);
Packit 90a5c9
    cfgMergeString(auth.cipher_suite);
Packit 90a5c9
    cfgMergeInt(auth.verify_depth);
Packit 90a5c9
    cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
Packit 90a5c9
    cfgMergeString(auth.tls13_ciphers);
Packit 90a5c9
Packit 90a5c9
    cfgMergeInt(ocsp_mask);
Packit 90a5c9
    cfgMergeBool(ocsp_force_default);
Packit 90a5c9
    cfgMerge(ocsp_responder, NULL);
Packit 90a5c9
    cfgMergeInt(ocsp_resptime_skew);
Packit 90a5c9
    cfgMergeInt(ocsp_resp_maxage);
Packit 90a5c9
    cfgMergeInt(ocsp_responder_timeout);
Packit 90a5c9
    cfgMergeBool(ocsp_use_request_nonce);
Packit 90a5c9
    cfgMerge(proxy_uri, NULL);
Packit 90a5c9
Packit 90a5c9
/* Set OCSP Responder Certificate Verification directive */
Packit 90a5c9
    cfgMergeBool(ocsp_noverify);  
Packit 90a5c9
/* Set OCSP Responder File directive for importing */
Packit 90a5c9
    cfgMerge(ocsp_certs_file, NULL);
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_OCSP_STAPLING
Packit 90a5c9
    cfgMergeBool(stapling_enabled);
Packit 90a5c9
    cfgMergeInt(stapling_resptime_skew);
Packit 90a5c9
    cfgMergeInt(stapling_resp_maxage);
Packit 90a5c9
    cfgMergeInt(stapling_cache_timeout);
Packit 90a5c9
    cfgMergeBool(stapling_return_errors);
Packit 90a5c9
    cfgMergeBool(stapling_fake_trylater);
Packit 90a5c9
    cfgMergeInt(stapling_errcache_timeout);
Packit 90a5c9
    cfgMergeInt(stapling_responder_timeout);
Packit 90a5c9
    cfgMerge(stapling_force_url, NULL);
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_SRP
Packit 90a5c9
    cfgMergeString(srp_vfile);
Packit 90a5c9
    cfgMergeString(srp_unknown_user_seed);
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_SSL_CONF_CMD
Packit 90a5c9
    cfgMergeArray(ssl_ctx_param);
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
    cfgMergeBool(ssl_check_peer_cn);
Packit 90a5c9
    cfgMergeBool(ssl_check_peer_name);
Packit 90a5c9
    cfgMergeBool(ssl_check_peer_expire);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static void modssl_ctx_cfg_merge_certkeys_array(apr_pool_t *p,
Packit 90a5c9
                                                apr_array_header_t *base,
Packit 90a5c9
                                                apr_array_header_t *add,
Packit 90a5c9
                                                apr_array_header_t *mrg)
Packit 90a5c9
{
Packit 90a5c9
    int i;
Packit 90a5c9
Packit 90a5c9
    /*
Packit 90a5c9
     * pick up to CERTKEYS_IDX_MAX+1 entries from "add" (in which case they
Packit 90a5c9
     * they "knock out" their corresponding entries in "base", emulating
Packit 90a5c9
     * the behavior with cfgMergeString in releases up to 2.4.7)
Packit 90a5c9
     */
Packit 90a5c9
    for (i = 0; i < add->nelts && i <= CERTKEYS_IDX_MAX; i++) {
Packit 90a5c9
        APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(add, i, const char *);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* add remaining ones from "base" */
Packit 90a5c9
    while (i < base->nelts) {
Packit 90a5c9
        APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(base, i, const char *);
Packit 90a5c9
        i++;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* and finally, append the rest of "add" (if there are any) */
Packit 90a5c9
    for (i = CERTKEYS_IDX_MAX+1; i < add->nelts; i++) {
Packit 90a5c9
        APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(add, i, const char *);
Packit 90a5c9
    }
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static void modssl_ctx_cfg_merge_server(apr_pool_t *p,
Packit 90a5c9
                                        modssl_ctx_t *base,
Packit 90a5c9
                                        modssl_ctx_t *add,
Packit 90a5c9
                                        modssl_ctx_t *mrg)
Packit 90a5c9
{
Packit 90a5c9
    modssl_ctx_cfg_merge(p, base, add, mrg);
Packit 90a5c9
Packit 90a5c9
    /*
Packit 90a5c9
     * For better backwards compatibility with releases up to 2.4.7,
Packit 90a5c9
     * merging global and vhost-level SSLCertificateFile and
Packit 90a5c9
     * SSLCertificateKeyFile directives needs special treatment.
Packit 90a5c9
     * See also PR 56306 and 56353.
Packit 90a5c9
     */
Packit 90a5c9
    modssl_ctx_cfg_merge_certkeys_array(p, base->pks->cert_files,
Packit 90a5c9
                                        add->pks->cert_files,
Packit 90a5c9
                                        mrg->pks->cert_files);
Packit 90a5c9
    modssl_ctx_cfg_merge_certkeys_array(p, base->pks->key_files,
Packit 90a5c9
                                        add->pks->key_files,
Packit 90a5c9
                                        mrg->pks->key_files);
Packit 90a5c9
Packit 90a5c9
    cfgMergeString(pks->ca_name_path);
Packit 90a5c9
    cfgMergeString(pks->ca_name_file);
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_TLS_SESSION_TICKETS
Packit 90a5c9
    cfgMergeString(ticket_key->file_path);
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
Packit 90a5c9
    SSLSrvConfigRec *add  = (SSLSrvConfigRec *)addv;
Packit 90a5c9
    SSLSrvConfigRec *mrg  = ssl_config_server_new(p);
Packit 90a5c9
Packit 90a5c9
    cfgMerge(mc, NULL);
Packit 90a5c9
    cfgMerge(enabled, SSL_ENABLED_UNSET);
Packit 90a5c9
    cfgMergeInt(session_cache_timeout);
Packit 90a5c9
    cfgMergeBool(cipher_server_pref);
Packit 90a5c9
    cfgMergeBool(insecure_reneg);
Packit 90a5c9
#ifdef HAVE_TLSEXT
Packit 90a5c9
    cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
Packit 90a5c9
#endif
Packit 90a5c9
#ifdef HAVE_FIPS
Packit 90a5c9
    cfgMergeBool(fips);
Packit 90a5c9
#endif
Packit 90a5c9
#ifndef OPENSSL_NO_COMP
Packit 90a5c9
    cfgMergeBool(compression);
Packit 90a5c9
#endif
Packit 90a5c9
    cfgMergeBool(session_tickets);
Packit 90a5c9
Packit 90a5c9
    modssl_ctx_cfg_merge_server(p, base->server, add->server, mrg->server);
Packit 90a5c9
Packit 90a5c9
    return mrg;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 *  Create per-directory SSL configuration
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
static void modssl_ctx_init_proxy(SSLDirConfigRec *dc,
Packit 90a5c9
                                  apr_pool_t *p)
Packit 90a5c9
{
Packit 90a5c9
    modssl_ctx_t *mctx;
Packit 90a5c9
Packit 90a5c9
    mctx = dc->proxy = apr_palloc(p, sizeof(*dc->proxy));
Packit 90a5c9
Packit 90a5c9
    modssl_ctx_init(mctx, p);
Packit 90a5c9
Packit 90a5c9
    mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
Packit 90a5c9
Packit 90a5c9
    mctx->pkp->cert_file = NULL;
Packit 90a5c9
    mctx->pkp->cert_path = NULL;
Packit 90a5c9
    mctx->pkp->ca_cert_file = NULL;
Packit 90a5c9
    mctx->pkp->certs     = NULL;
Packit 90a5c9
    mctx->pkp->ca_certs  = NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
Packit 90a5c9
Packit 90a5c9
    dc->bSSLRequired  = FALSE;
Packit 90a5c9
    dc->aRequirement  = apr_array_make(p, 4, sizeof(ssl_require_t));
Packit 90a5c9
    dc->nOptions      = SSL_OPT_NONE|SSL_OPT_RELSET;
Packit 90a5c9
    dc->nOptionsAdd   = SSL_OPT_NONE;
Packit 90a5c9
    dc->nOptionsDel   = SSL_OPT_NONE;
Packit 90a5c9
Packit 90a5c9
    dc->szCipherSuite          = NULL;
Packit 90a5c9
    dc->nVerifyClient          = SSL_CVERIFY_UNSET;
Packit 90a5c9
    dc->nVerifyDepth           = UNSET;
Packit 90a5c9
Packit 90a5c9
    dc->szUserName             = NULL;
Packit 90a5c9
Packit 90a5c9
    dc->nRenegBufferSize = UNSET;
Packit 90a5c9
Packit 90a5c9
    dc->proxy_enabled = UNSET;
Packit 90a5c9
    modssl_ctx_init_proxy(dc, p);
Packit 90a5c9
    dc->proxy_post_config = FALSE;
Packit 90a5c9
Packit 90a5c9
    return dc;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 *  Merge per-directory SSL configurations
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p,
Packit 90a5c9
                                       modssl_ctx_t *base,
Packit 90a5c9
                                       modssl_ctx_t *add,
Packit 90a5c9
                                       modssl_ctx_t *mrg)
Packit 90a5c9
{
Packit 90a5c9
    modssl_ctx_cfg_merge(p, base, add, mrg);
Packit 90a5c9
Packit 90a5c9
    cfgMergeString(pkp->cert_file);
Packit 90a5c9
    cfgMergeString(pkp->cert_path);
Packit 90a5c9
    cfgMergeString(pkp->ca_cert_file);
Packit 90a5c9
    cfgMergeString(pkp->certs);
Packit 90a5c9
    cfgMergeString(pkp->ca_certs);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
Packit 90a5c9
    SSLDirConfigRec *add  = (SSLDirConfigRec *)addv;
Packit 90a5c9
    SSLDirConfigRec *mrg  = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
Packit 90a5c9
Packit 90a5c9
    cfgMerge(bSSLRequired, FALSE);
Packit 90a5c9
    cfgMergeArray(aRequirement);
Packit 90a5c9
Packit 90a5c9
    if (add->nOptions & SSL_OPT_RELSET) {
Packit 90a5c9
        mrg->nOptionsAdd =
Packit 90a5c9
            (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
Packit 90a5c9
        mrg->nOptionsDel =
Packit 90a5c9
            (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
Packit 90a5c9
        mrg->nOptions    =
Packit 90a5c9
            (base->nOptions    & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        mrg->nOptions    = add->nOptions;
Packit 90a5c9
        mrg->nOptionsAdd = add->nOptionsAdd;
Packit 90a5c9
        mrg->nOptionsDel = add->nOptionsDel;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    cfgMergeString(szCipherSuite);
Packit 90a5c9
    cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
Packit 90a5c9
    cfgMergeInt(nVerifyDepth);
Packit 90a5c9
Packit 90a5c9
    cfgMergeString(szUserName);
Packit 90a5c9
Packit 90a5c9
    cfgMergeInt(nRenegBufferSize);
Packit 90a5c9
Packit 90a5c9
    mrg->proxy_post_config = add->proxy_post_config;
Packit 90a5c9
    if (!mrg->proxy_post_config) {
Packit 90a5c9
        cfgMergeBool(proxy_enabled);
Packit 90a5c9
        modssl_ctx_init_proxy(mrg, p);
Packit 90a5c9
        modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy);
Packit 90a5c9
Packit 90a5c9
        /* Since ssl_proxy_section_post_config() hook won't be called if there
Packit 90a5c9
         * is no SSLProxy* in this dir config, the ssl_ctx may still be NULL
Packit 90a5c9
         * here at runtime. Merging it is either a no-op (NULL => NULL) because
Packit 90a5c9
         * we are still before post config, or we really want to reuse the one
Packit 90a5c9
         * from the upper/server context (outside of <Proxy> sections).
Packit 90a5c9
         */
Packit 90a5c9
        cfgMerge(proxy->ssl_ctx, NULL);
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        /* The post_config hook has already merged and initialized the
Packit 90a5c9
         * proxy context, use it.
Packit 90a5c9
         */
Packit 90a5c9
        mrg->proxy_enabled = add->proxy_enabled;
Packit 90a5c9
        mrg->proxy = add->proxy;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return mrg;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/* Simply merge conf with base into conf, no third party. */
Packit 90a5c9
void ssl_config_proxy_merge(apr_pool_t *p,
Packit 90a5c9
                            SSLDirConfigRec *base,
Packit 90a5c9
                            SSLDirConfigRec *conf)
Packit 90a5c9
{
Packit 90a5c9
    if (conf->proxy_enabled == UNSET) {
Packit 90a5c9
        conf->proxy_enabled = base->proxy_enabled;
Packit 90a5c9
    }
Packit 90a5c9
    modssl_ctx_cfg_merge_proxy(p, base->proxy, conf->proxy, conf->proxy);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 *  Configuration functions for particular directives
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
Packit 90a5c9
                                        void *dcfg,
Packit 90a5c9
                                        const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
    int arglen = strlen(arg);
Packit 90a5c9
Packit 90a5c9
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (strcEQ(arg, "builtin")) {
Packit 90a5c9
        sc->server->pphrase_dialog_type  = SSL_PPTYPE_BUILTIN;
Packit 90a5c9
        sc->server->pphrase_dialog_path = NULL;
Packit 90a5c9
    }
Packit 90a5c9
    else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
Packit 90a5c9
        sc->server->pphrase_dialog_type  = SSL_PPTYPE_FILTER;
Packit 90a5c9
        sc->server->pphrase_dialog_path =
Packit 90a5c9
            ap_server_root_relative(cmd->pool, arg+5);
Packit 90a5c9
        if (!sc->server->pphrase_dialog_path) {
Packit 90a5c9
            return apr_pstrcat(cmd->pool,
Packit 90a5c9
                               "Invalid SSLPassPhraseDialog exec: path ",
Packit 90a5c9
                               arg+5, NULL);
Packit 90a5c9
        }
Packit 90a5c9
        if (!ssl_util_path_check(SSL_PCM_EXISTS,
Packit 90a5c9
                                 sc->server->pphrase_dialog_path,
Packit 90a5c9
                                 cmd->pool))
Packit 90a5c9
        {
Packit 90a5c9
            return apr_pstrcat(cmd->pool,
Packit 90a5c9
                               "SSLPassPhraseDialog: file '",
Packit 90a5c9
                               sc->server->pphrase_dialog_path,
Packit 90a5c9
                               "' does not exist", NULL);
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
    }
Packit 90a5c9
    else if ((arglen > 1) && (arg[0] == '|')) {
Packit 90a5c9
        sc->server->pphrase_dialog_type  = SSL_PPTYPE_PIPE;
Packit 90a5c9
        sc->server->pphrase_dialog_path = arg + 1;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        return "SSLPassPhraseDialog: Invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
Packit 90a5c9
const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
Packit 90a5c9
                                    void *dcfg,
Packit 90a5c9
                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLModConfigRec *mc = myModConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
    ENGINE *e;
Packit 90a5c9
Packit 90a5c9
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (strcEQ(arg, "builtin")) {
Packit 90a5c9
        mc->szCryptoDevice = NULL;
Packit 90a5c9
    }
Packit 90a5c9
    else if ((e = ENGINE_by_id(arg))) {
Packit 90a5c9
        mc->szCryptoDevice = arg;
Packit 90a5c9
        ENGINE_free(e);
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        err = "SSLCryptoDevice: Invalid argument; must be one of: "
Packit 90a5c9
              "'builtin' (none)";
Packit 90a5c9
        e = ENGINE_get_first();
Packit 90a5c9
        while (e) {
Packit 90a5c9
            err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e),
Packit 90a5c9
                                         "' (", ENGINE_get_name(e), ")", NULL);
Packit 90a5c9
            /* Iterate; this call implicitly decrements the refcount
Packit 90a5c9
             * on the 'old' e, per the docs in engine.h. */
Packit 90a5c9
            e = ENGINE_get_next(e);
Packit 90a5c9
        }
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
Packit 90a5c9
                                  void *dcfg,
Packit 90a5c9
                                  const char *arg1,
Packit 90a5c9
                                  const char *arg2,
Packit 90a5c9
                                  const char *arg3)
Packit 90a5c9
{
Packit 90a5c9
    SSLModConfigRec *mc = myModConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
    ssl_randseed_t *seed;
Packit 90a5c9
    int arg2len = strlen(arg2);
Packit 90a5c9
Packit 90a5c9
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (ssl_config_global_isfixed(mc)) {
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    seed = apr_array_push(mc->aRandSeed);
Packit 90a5c9
Packit 90a5c9
    if (strcEQ(arg1, "startup")) {
Packit 90a5c9
        seed->nCtx = SSL_RSCTX_STARTUP;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(arg1, "connect")) {
Packit 90a5c9
        seed->nCtx = SSL_RSCTX_CONNECT;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
Packit 90a5c9
                           "invalid context: `", arg1, "'",
Packit 90a5c9
                           NULL);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if ((arg2len > 5) && strEQn(arg2, "file:", 5)) {
Packit 90a5c9
        seed->nSrc   = SSL_RSSRC_FILE;
Packit 90a5c9
        seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
Packit 90a5c9
    }
Packit 90a5c9
    else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) {
Packit 90a5c9
        seed->nSrc   = SSL_RSSRC_EXEC;
Packit 90a5c9
        seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
Packit 90a5c9
    }
Packit 90a5c9
    else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
Packit 90a5c9
#ifdef HAVE_RAND_EGD
Packit 90a5c9
        seed->nSrc   = SSL_RSSRC_EGD;
Packit 90a5c9
        seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
Packit 90a5c9
#else
Packit 90a5c9
        return apr_pstrcat(cmd->pool, "Invalid SSLRandomSeed entropy source `",
Packit 90a5c9
                           arg2, "': This version of " MODSSL_LIBRARY_NAME
Packit 90a5c9
                           " does not support the Entropy Gathering Daemon "
Packit 90a5c9
                           "(EGD).", NULL);
Packit 90a5c9
#endif
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(arg2, "builtin")) {
Packit 90a5c9
        seed->nSrc   = SSL_RSSRC_BUILTIN;
Packit 90a5c9
        seed->cpPath = NULL;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        seed->nSrc   = SSL_RSSRC_FILE;
Packit 90a5c9
        seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (seed->nSrc != SSL_RSSRC_BUILTIN) {
Packit 90a5c9
        if (!seed->cpPath) {
Packit 90a5c9
            return apr_pstrcat(cmd->pool,
Packit 90a5c9
                               "Invalid SSLRandomSeed path ",
Packit 90a5c9
                               arg2, NULL);
Packit 90a5c9
        }
Packit 90a5c9
        if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) {
Packit 90a5c9
            return apr_pstrcat(cmd->pool,
Packit 90a5c9
                               "SSLRandomSeed: source path '",
Packit 90a5c9
                               seed->cpPath, "' does not exist", NULL);
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (!arg3) {
Packit 90a5c9
        seed->nBytes = 0; /* read whole file */
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        if (seed->nSrc == SSL_RSSRC_BUILTIN) {
Packit 90a5c9
            return "SSLRandomSeed: byte specification not "
Packit 90a5c9
                   "allowed for builtin seed source";
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        seed->nBytes = atoi(arg3);
Packit 90a5c9
Packit 90a5c9
        if (seed->nBytes < 0) {
Packit 90a5c9
            return "SSLRandomSeed: invalid number of bytes specified";
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    if (!strcasecmp(arg, "On")) {
Packit 90a5c9
        sc->enabled = SSL_ENABLED_TRUE;
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
    else if (!strcasecmp(arg, "Off")) {
Packit 90a5c9
        sc->enabled = SSL_ENABLED_FALSE;
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
    else if (!strcasecmp(arg, "Optional")) {
Packit 90a5c9
        sc->enabled = SSL_ENABLED_OPTIONAL;
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return "Argument must be On, Off, or Optional";
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
#ifdef HAVE_FIPS
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
#endif
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_FIPS
Packit 90a5c9
    if ((sc->fips != UNSET) && (sc->fips != (BOOL)(flag ? TRUE : FALSE)))
Packit 90a5c9
        return "Conflicting SSLFIPS options, cannot be both On and Off";
Packit 90a5c9
    sc->fips = flag ? TRUE : FALSE;
Packit 90a5c9
#else
Packit 90a5c9
    if (flag)
Packit 90a5c9
        return "SSLFIPS invalid, rebuild httpd and openssl compiled for FIPS";
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
Packit 90a5c9
                                   void *dcfg,
Packit 90a5c9
                                   const char *arg1, const char *arg2)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    if (arg2 == NULL) {
Packit 90a5c9
        arg2 = arg1;
Packit 90a5c9
        arg1 = "SSL";
Packit 90a5c9
    }
Packit 90a5c9
    
Packit 90a5c9
    if (!strcmp("SSL", arg1)) {
Packit 90a5c9
        if (cmd->path) {
Packit efb929
            /* Disable null and export ciphers by default, except for PROFILE=
Packit efb929
             * configs where the parser doesn't cope. */
Packit efb929
            if (strncmp(arg2, "PROFILE=", 8) != 0)
Packit efb929
                arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
Packit 90a5c9
            dc->szCipherSuite = arg2;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            sc->server->auth.cipher_suite = arg2;
Packit 90a5c9
        }
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
#if SSL_HAVE_PROTOCOL_TLSV1_3
Packit 90a5c9
    else if (!strcmp("TLSv1.3", arg1)) {
Packit 90a5c9
        if (cmd->path) {
Packit 90a5c9
            return "TLSv1.3 ciphers cannot be set inside a directory context";
Packit 90a5c9
        }
Packit 90a5c9
        sc->server->auth.tls13_ciphers = arg2;
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
#endif
Packit 90a5c9
    return apr_pstrcat(cmd->pool, "procotol '", arg1, "' not supported", NULL);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#define SSL_FLAGS_CHECK_FILE \
Packit 90a5c9
    (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
Packit 90a5c9
Packit 90a5c9
#define SSL_FLAGS_CHECK_DIR \
Packit 90a5c9
    (SSL_PCM_EXISTS|SSL_PCM_ISDIR)
Packit 90a5c9
Packit 90a5c9
static const char *ssl_cmd_check_file(cmd_parms *parms,
Packit 90a5c9
                                      const char **file)
Packit 90a5c9
{
Packit 90a5c9
    const char *filepath = ap_server_root_relative(parms->pool, *file);
Packit 90a5c9
Packit 90a5c9
    if (!filepath) {
Packit 90a5c9
        return apr_pstrcat(parms->pool, parms->cmd->name,
Packit 90a5c9
                           ": Invalid file path ", *file, NULL);
Packit 90a5c9
    }
Packit 90a5c9
    *file = filepath;
Packit 90a5c9
Packit 90a5c9
    if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return apr_pstrcat(parms->pool, parms->cmd->name,
Packit 90a5c9
                       ": file '", *file,
Packit 90a5c9
                       "' does not exist or is empty", NULL);
Packit 90a5c9
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCompression(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
#if !defined(OPENSSL_NO_COMP)
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
#ifndef SSL_OP_NO_COMPRESSION
Packit 90a5c9
    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
Packit 90a5c9
    if (err)
Packit 90a5c9
        return "This version of OpenSSL does not support enabling "
Packit 90a5c9
               "SSLCompression within <VirtualHost> sections.";
Packit 90a5c9
#endif
Packit 90a5c9
    if (flag) {
Packit 90a5c9
        /* Some (packaged) versions of OpenSSL do not support
Packit 90a5c9
         * compression by default.  Enabling this directive would not
Packit 90a5c9
         * have the desired effect, so fail with an error. */
Packit 90a5c9
        STACK_OF(SSL_COMP) *meths = SSL_COMP_get_compression_methods();
Packit 90a5c9
Packit 90a5c9
        if (sk_SSL_COMP_num(meths) == 0) {
Packit 90a5c9
            return "This version of OpenSSL does not have any compression methods "
Packit 90a5c9
                "available, cannot enable SSLCompression.";
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
    sc->compression = flag ? TRUE : FALSE;
Packit 90a5c9
    return NULL;
Packit 90a5c9
#else
Packit 90a5c9
    return "Setting Compression mode unsupported; not implemented by the SSL library";
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->cipher_server_pref = flag?TRUE:FALSE;
Packit 90a5c9
    return NULL;
Packit 90a5c9
#else
Packit 90a5c9
    return "SSLHonorCipherOrder unsupported; not implemented by the SSL library";
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLSessionTickets(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
#ifndef SSL_OP_NO_TICKET
Packit 90a5c9
    return "This version of OpenSSL does not support using "
Packit 90a5c9
           "SSLSessionTickets.";
Packit 90a5c9
#endif
Packit 90a5c9
    sc->session_tickets = flag ? TRUE : FALSE;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->insecure_reneg = flag?TRUE:FALSE;
Packit 90a5c9
    return NULL;
Packit 90a5c9
#else
Packit 90a5c9
    return "The SSLInsecureRenegotiation directive is not available "
Packit 90a5c9
        "with this SSL library";
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
static const char *ssl_cmd_check_dir(cmd_parms *parms,
Packit 90a5c9
                                     const char **dir)
Packit 90a5c9
{
Packit 90a5c9
    const char *dirpath = ap_server_root_relative(parms->pool, *dir);
Packit 90a5c9
Packit 90a5c9
    if (!dirpath) {
Packit 90a5c9
        return apr_pstrcat(parms->pool, parms->cmd->name,
Packit 90a5c9
                           ": Invalid dir path ", *dir, NULL);
Packit 90a5c9
    }
Packit 90a5c9
    *dir = dirpath;
Packit 90a5c9
Packit 90a5c9
    if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return apr_pstrcat(parms->pool, parms->cmd->name,
Packit 90a5c9
                       ": directory '", *dir,
Packit 90a5c9
                       "' does not exist", NULL);
Packit 90a5c9
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
Packit 90a5c9
                                       void *dcfg,
Packit 90a5c9
                                       const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    *(const char **)apr_array_push(sc->server->pks->cert_files) = arg;
Packit 90a5c9
    
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
Packit 90a5c9
                                          void *dcfg,
Packit 90a5c9
                                          const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    *(const char **)apr_array_push(sc->server->pks->key_files) = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
Packit 90a5c9
                                            void *dcfg,
Packit 90a5c9
                                            const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    sc->server->cert_chain = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_TLS_SESSION_TICKETS
Packit 90a5c9
const char *ssl_cmd_SSLSessionTicketKeyFile(cmd_parms *cmd,
Packit 90a5c9
                                            void *dcfg,
Packit 90a5c9
                                            const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    sc->server->ticket_key->file_path = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
#define NO_PER_DIR_SSL_CA \
Packit 90a5c9
    "Your SSL library does not have support for per-directory CA"
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
Packit 90a5c9
                                         void *dcfg,
Packit 90a5c9
                                         const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (cmd->path) {
Packit 90a5c9
        return NO_PER_DIR_SSL_CA;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* XXX: bring back per-dir */
Packit 90a5c9
    sc->server->auth.ca_cert_path = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
Packit 90a5c9
                                         void *dcfg,
Packit 90a5c9
                                         const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (cmd->path) {
Packit 90a5c9
        return NO_PER_DIR_SSL_CA;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* XXX: bring back per-dir */
Packit 90a5c9
    sc->server->auth.ca_cert_file = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                       const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    sc->server->pks->ca_name_path = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                       const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    sc->server->pks->ca_name_file = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
Packit 90a5c9
                                        void *dcfg,
Packit 90a5c9
                                        const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    sc->server->crl_path = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
Packit 90a5c9
                                        void *dcfg,
Packit 90a5c9
                                        const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    sc->server->crl_file = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static const char *ssl_cmd_crlcheck_parse(cmd_parms *parms,
Packit 90a5c9
                                          const char *arg,
Packit 90a5c9
                                          int *mask)
Packit 90a5c9
{
Packit 90a5c9
    const char *w;
Packit 90a5c9
Packit 90a5c9
    w = ap_getword_conf(parms->temp_pool, &arg;;
Packit 90a5c9
    if (strcEQ(w, "none")) {
Packit 90a5c9
        *mask = SSL_CRLCHECK_NONE;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(w, "leaf")) {
Packit 90a5c9
        *mask = SSL_CRLCHECK_LEAF;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(w, "chain")) {
Packit 90a5c9
        *mask = SSL_CRLCHECK_CHAIN;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        return apr_pstrcat(parms->temp_pool, parms->cmd->name,
Packit 90a5c9
                           ": Invalid argument '", w, "'",
Packit 90a5c9
                           NULL);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    while (*arg) {
Packit 90a5c9
        w = ap_getword_conf(parms->temp_pool, &arg;;
Packit 90a5c9
        if (strcEQ(w, "no_crl_for_cert_ok")) {
Packit 90a5c9
            *mask |= SSL_CRLCHECK_NO_CRL_FOR_CERT_OK;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            return apr_pstrcat(parms->temp_pool, parms->cmd->name,
Packit 90a5c9
                               ": Invalid argument '", w, "'",
Packit 90a5c9
                               NULL);
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd,
Packit 90a5c9
                                         void *dcfg,
Packit 90a5c9
                                         const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mask);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static const char *ssl_cmd_verify_parse(cmd_parms *parms,
Packit 90a5c9
                                        const char *arg,
Packit 90a5c9
                                        ssl_verify_t *id)
Packit 90a5c9
{
Packit 90a5c9
    if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
Packit 90a5c9
        *id = SSL_CVERIFY_NONE;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(arg, "optional")) {
Packit 90a5c9
        *id = SSL_CVERIFY_OPTIONAL;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
Packit 90a5c9
        *id = SSL_CVERIFY_REQUIRE;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(arg, "optional_no_ca")) {
Packit 90a5c9
        *id = SSL_CVERIFY_OPTIONAL_NO_CA;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        return apr_pstrcat(parms->temp_pool, parms->cmd->name,
Packit 90a5c9
                           ": Invalid argument '", arg, "'",
Packit 90a5c9
                           NULL);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd,
Packit 90a5c9
                                    void *dcfg,
Packit 90a5c9
                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    ssl_verify_t mode = SSL_CVERIFY_NONE;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (cmd->path) {
Packit 90a5c9
        dc->nVerifyClient = mode;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        sc->server->auth.verify_mode = mode;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
Packit 90a5c9
                                              const char *arg,
Packit 90a5c9
                                              int *depth)
Packit 90a5c9
{
Packit 90a5c9
    if ((*depth = atoi(arg)) >= 0) {
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return apr_pstrcat(parms->temp_pool, parms->cmd->name,
Packit 90a5c9
                       ": Invalid argument '", arg, "'",
Packit 90a5c9
                       NULL);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
Packit 90a5c9
                                   void *dcfg,
Packit 90a5c9
                                   const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    int depth;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (cmd->path) {
Packit 90a5c9
        dc->nVerifyDepth = depth;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        sc->server->auth.verify_depth = depth;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
Packit 90a5c9
                                    void *dcfg,
Packit 90a5c9
                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLModConfigRec *mc = myModConfig(cmd->server);
Packit 90a5c9
    const char *err, *sep, *name;
Packit 90a5c9
    long enabled_flags;
Packit 90a5c9
Packit 90a5c9
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* The OpenSSL session cache mode must have both the flags
Packit 90a5c9
     * SSL_SESS_CACHE_SERVER and SSL_SESS_CACHE_NO_INTERNAL set if a
Packit 90a5c9
     * session cache is configured; NO_INTERNAL prevents the
Packit 90a5c9
     * OpenSSL-internal session cache being used in addition to the
Packit 90a5c9
     * "external" (mod_ssl-provided) cache, which otherwise causes
Packit 90a5c9
     * additional memory consumption. */
Packit 90a5c9
    enabled_flags = SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL;
Packit 90a5c9
Packit 90a5c9
    if (strcEQ(arg, "none")) {
Packit 90a5c9
        /* Nothing to do; session cache will be off. */
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(arg, "nonenotnull")) {
Packit 90a5c9
        /* ### Having a separate mode for this seems logically
Packit 90a5c9
         * unnecessary; the stated purpose of sending non-empty
Packit 90a5c9
         * session IDs would be better fixed in OpenSSL or simply
Packit 90a5c9
         * doing it by default if "none" is used. */
Packit 90a5c9
        mc->sesscache_mode = enabled_flags;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        /* Argument is of form 'name:args' or just 'name'. */
Packit 90a5c9
        sep = ap_strchr_c(arg, ':');
Packit 90a5c9
        if (sep) {
Packit 90a5c9
            name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
Packit 90a5c9
            sep++;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            name = arg;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        /* Find the provider of given name. */
Packit 90a5c9
        mc->sesscache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
Packit 90a5c9
                                           name,
Packit 90a5c9
                                           AP_SOCACHE_PROVIDER_VERSION);
Packit 90a5c9
        if (mc->sesscache) {
Packit 90a5c9
            /* Cache found; create it, passing anything beyond the colon. */
Packit 90a5c9
            mc->sesscache_mode = enabled_flags;
Packit 90a5c9
            err = mc->sesscache->create(&mc->sesscache_context, sep,
Packit 90a5c9
                                        cmd->temp_pool, cmd->pool);
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            apr_array_header_t *name_list;
Packit 90a5c9
            const char *all_names;
Packit 90a5c9
Packit 90a5c9
            /* Build a comma-separated list of all registered provider
Packit 90a5c9
             * names: */
Packit 90a5c9
            name_list = ap_list_provider_names(cmd->pool,
Packit 90a5c9
                                               AP_SOCACHE_PROVIDER_GROUP,
Packit 90a5c9
                                               AP_SOCACHE_PROVIDER_VERSION);
Packit 90a5c9
            all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
Packit 90a5c9
Packit 90a5c9
            err = apr_psprintf(cmd->pool, "'%s' session cache not supported "
Packit 90a5c9
                               "(known names: %s). Maybe you need to load the "
Packit 90a5c9
                               "appropriate socache module (mod_socache_%s?).",
Packit 90a5c9
                               name, all_names, name);
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (err) {
Packit 90a5c9
        return apr_psprintf(cmd->pool, "SSLSessionCache: %s", err);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd,
Packit 90a5c9
                                           void *dcfg,
Packit 90a5c9
                                           const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    sc->session_cache_timeout = atoi(arg);
Packit 90a5c9
Packit 90a5c9
    if (sc->session_cache_timeout < 0) {
Packit 90a5c9
        return "SSLSessionCacheTimeout: Invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
Packit 90a5c9
                               void *dcfg,
Packit 90a5c9
                               const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    ssl_opt_t opt;
Packit 90a5c9
    int first = TRUE;
Packit 90a5c9
    char action, *w;
Packit 90a5c9
Packit 90a5c9
    while (*arg) {
Packit 90a5c9
        w = ap_getword_conf(cmd->temp_pool, &arg;;
Packit 90a5c9
        action = NUL;
Packit 90a5c9
Packit 90a5c9
        if ((*w == '+') || (*w == '-')) {
Packit 90a5c9
            action = *(w++);
Packit 90a5c9
        }
Packit 90a5c9
        else if (first) {
Packit 90a5c9
            dc->nOptions = SSL_OPT_NONE;
Packit 90a5c9
            first = FALSE;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        if (strcEQ(w, "StdEnvVars")) {
Packit 90a5c9
            opt = SSL_OPT_STDENVVARS;
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "ExportCertData")) {
Packit 90a5c9
            opt = SSL_OPT_EXPORTCERTDATA;
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "FakeBasicAuth")) {
Packit 90a5c9
            opt = SSL_OPT_FAKEBASICAUTH;
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "StrictRequire")) {
Packit 90a5c9
            opt = SSL_OPT_STRICTREQUIRE;
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "OptRenegotiate")) {
Packit 90a5c9
            opt = SSL_OPT_OPTRENEGOTIATE;
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "LegacyDNStringFormat")) {
Packit 90a5c9
            opt = SSL_OPT_LEGACYDNFORMAT;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            return apr_pstrcat(cmd->pool,
Packit 90a5c9
                               "SSLOptions: Illegal option '", w, "'",
Packit 90a5c9
                               NULL);
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        if (action == '-') {
Packit 90a5c9
            dc->nOptionsAdd &= ~opt;
Packit 90a5c9
            dc->nOptionsDel |=  opt;
Packit 90a5c9
            dc->nOptions    &= ~opt;
Packit 90a5c9
        }
Packit 90a5c9
        else if (action == '+') {
Packit 90a5c9
            dc->nOptionsAdd |=  opt;
Packit 90a5c9
            dc->nOptionsDel &= ~opt;
Packit 90a5c9
            dc->nOptions    |=  opt;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            dc->nOptions    = opt;
Packit 90a5c9
            dc->nOptionsAdd = opt;
Packit 90a5c9
            dc->nOptionsDel = SSL_OPT_NONE;
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    dc->bSSLRequired = TRUE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
Packit 90a5c9
                               void *dcfg,
Packit 90a5c9
                               const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
Packit 90a5c9
    ssl_require_t *require;
Packit 90a5c9
    const char *errstring;
Packit 90a5c9
Packit 90a5c9
    info->flags = AP_EXPR_FLAG_SSL_EXPR_COMPAT;
Packit 90a5c9
    info->filename = cmd->directive->filename;
Packit 90a5c9
    info->line_number = cmd->directive->line_num;
Packit 90a5c9
    info->module_index = APLOG_MODULE_INDEX;
Packit 90a5c9
    errstring = ap_expr_parse(cmd->pool, cmd->temp_pool, info, arg, NULL);
Packit 90a5c9
    if (errstring) {
Packit 90a5c9
        return apr_pstrcat(cmd->pool, "SSLRequire: ", errstring, NULL);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    require = apr_array_push(dc->aRequirement);
Packit 90a5c9
    require->cpExpr = arg;
Packit 90a5c9
    require->mpExpr = info;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = dcfg;
Packit 90a5c9
    int val;
Packit 90a5c9
Packit 90a5c9
    val = atoi(arg);
Packit 90a5c9
    if (val < 0) {
Packit 90a5c9
        return apr_pstrcat(cmd->pool, "Invalid size for SSLRenegBufferSize: ",
Packit 90a5c9
                           arg, NULL);
Packit 90a5c9
    }
Packit 90a5c9
    dc->nRenegBufferSize = val;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
Packit 90a5c9
                                          const char *arg,
Packit 90a5c9
                                          ssl_proto_t *options)
Packit 90a5c9
{
Packit 90a5c9
    ssl_proto_t thisopt;
Packit 90a5c9
Packit 90a5c9
    *options = SSL_PROTOCOL_NONE;
Packit 90a5c9
Packit 90a5c9
    while (*arg) {
Packit 90a5c9
        char *w = ap_getword_conf(parms->temp_pool, &arg;;
Packit 90a5c9
        char action = '\0';
Packit 90a5c9
Packit 90a5c9
        if ((*w == '+') || (*w == '-')) {
Packit 90a5c9
            action = *(w++);
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        if (strcEQ(w, "SSLv2")) {
Packit 90a5c9
            if (action == '-') {
Packit 90a5c9
                continue;
Packit 90a5c9
            }
Packit 90a5c9
            else {
Packit 90a5c9
                return "SSLProtocol: SSLv2 is no longer supported";
Packit 90a5c9
            }
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "SSLv3")) {
Packit 90a5c9
#ifdef OPENSSL_NO_SSL3
Packit 90a5c9
            if (action != '-') {
Packit 90a5c9
                return "SSLv3 not supported by this version of OpenSSL";
Packit 90a5c9
            }
Packit 90a5c9
            /* Nothing to do, the flag is not present to be toggled */
Packit 90a5c9
            continue;
Packit 90a5c9
#else
Packit 90a5c9
            thisopt = SSL_PROTOCOL_SSLV3;
Packit 90a5c9
#endif
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "TLSv1")) {
Packit 90a5c9
            thisopt = SSL_PROTOCOL_TLSV1;
Packit 90a5c9
        }
Packit 90a5c9
#ifdef HAVE_TLSV1_X
Packit 90a5c9
        else if (strcEQ(w, "TLSv1.1")) {
Packit 90a5c9
            thisopt = SSL_PROTOCOL_TLSV1_1;
Packit 90a5c9
        }
Packit 90a5c9
        else if (strcEQ(w, "TLSv1.2")) {
Packit 90a5c9
            thisopt = SSL_PROTOCOL_TLSV1_2;
Packit 90a5c9
        }
Packit 90a5c9
        else if (SSL_HAVE_PROTOCOL_TLSV1_3 && strcEQ(w, "TLSv1.3")) {
Packit 90a5c9
            thisopt = SSL_PROTOCOL_TLSV1_3;
Packit 90a5c9
        }
Packit 90a5c9
#endif
Packit 90a5c9
        else if (strcEQ(w, "all")) {
Packit 90a5c9
            thisopt = SSL_PROTOCOL_ALL;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            return apr_pstrcat(parms->temp_pool,
Packit 90a5c9
                               parms->cmd->name,
Packit 90a5c9
                               ": Illegal protocol '", w, "'", NULL);
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        if (action == '-') {
Packit 90a5c9
            *options &= ~thisopt;
Packit 90a5c9
        }
Packit 90a5c9
        else if (action == '+') {
Packit 90a5c9
            *options |= thisopt;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            if (*options != SSL_PROTOCOL_NONE) {
Packit 90a5c9
                ap_log_error(APLOG_MARK, APLOG_WARNING, 0, parms->server, APLOGNO(02532)
Packit 90a5c9
                             "%s: Protocol '%s' overrides already set parameter(s). "
Packit 90a5c9
                             "Check if a +/- prefix is missing.",
Packit 90a5c9
                             parms->cmd->name, w);
Packit 90a5c9
            }
Packit 90a5c9
            *options = thisopt;
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
Packit 90a5c9
                                void *dcfg,
Packit 90a5c9
                                const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    sc->server->protocol_set = 1;
Packit 90a5c9
    return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    dc->proxy_enabled = flag ? TRUE : FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,
Packit 90a5c9
                                     void *dcfg,
Packit 90a5c9
                                     const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    dc->proxy->protocol_set = 1;
Packit 90a5c9
    return ssl_cmd_protocol_parse(cmd, arg, &dc->proxy->protocol);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
Packit 90a5c9
                                        void *dcfg,
Packit 90a5c9
                                        const char *arg1, const char *arg2)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    
Packit 90a5c9
    if (arg2 == NULL) {
Packit 90a5c9
        arg2 = arg1;
Packit 90a5c9
        arg1 = "SSL";
Packit 90a5c9
    }
Packit 90a5c9
    
Packit 90a5c9
    if (!strcmp("SSL", arg1)) {
Packit efb929
        /* Disable null and export ciphers by default, except for PROFILE=
Packit efb929
         * configs where the parser doesn't cope. */
Packit efb929
        if (strncmp(arg2, "PROFILE=", 8) != 0)
Packit efb929
            arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
Packit 90a5c9
        dc->proxy->auth.cipher_suite = arg2;
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
#if SSL_HAVE_PROTOCOL_TLSV1_3
Packit 90a5c9
    else if (!strcmp("TLSv1.3", arg1)) {
Packit 90a5c9
        dc->proxy->auth.tls13_ciphers = arg2;
Packit 90a5c9
        return NULL;
Packit 90a5c9
    }
Packit 90a5c9
#endif
Packit 90a5c9
    return apr_pstrcat(cmd->pool, "procotol '", arg1, "' not supported", NULL);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
Packit 90a5c9
                                   void *dcfg,
Packit 90a5c9
                                   const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    ssl_verify_t mode = SSL_CVERIFY_NONE;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->auth.verify_mode = mode;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
Packit 90a5c9
                                        void *dcfg,
Packit 90a5c9
                                        const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    int depth;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->auth.verify_depth = depth;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
Packit 90a5c9
                                              void *dcfg,
Packit 90a5c9
                                              const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->auth.ca_cert_file = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
Packit 90a5c9
                                              void *dcfg,
Packit 90a5c9
                                              const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->auth.ca_cert_path = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
Packit 90a5c9
                                             void *dcfg,
Packit 90a5c9
                                             const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->crl_path = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
Packit 90a5c9
                                             void *dcfg,
Packit 90a5c9
                                             const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->crl_file = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd,
Packit 90a5c9
                                              void *dcfg,
Packit 90a5c9
                                              const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    return ssl_cmd_crlcheck_parse(cmd, arg, &dc->proxy->crl_check_mask);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
Packit 90a5c9
                                                   void *dcfg,
Packit 90a5c9
                                                   const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->pkp->cert_file = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
Packit 90a5c9
                                                   void *dcfg,
Packit 90a5c9
                                                   const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_dir(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->pkp->cert_path = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *cmd,
Packit 90a5c9
                                                   void *dcfg,
Packit 90a5c9
                                                   const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    dc->proxy->pkp->ca_cert_file = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
    dc->szUserName = arg;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
static const char *ssl_cmd_ocspcheck_parse(cmd_parms *parms,
Packit 90a5c9
                                           const char *arg,
Packit 90a5c9
                                           int *mask)
Packit 90a5c9
{
Packit 90a5c9
    const char *w;
Packit 90a5c9
Packit 90a5c9
    w = ap_getword_conf(parms->temp_pool, &arg;;
Packit 90a5c9
    if (strcEQ(w, "off")) {
Packit 90a5c9
        *mask = SSL_OCSPCHECK_NONE;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(w, "leaf")) {
Packit 90a5c9
        *mask = SSL_OCSPCHECK_LEAF;
Packit 90a5c9
    }
Packit 90a5c9
    else if (strcEQ(w, "on")) {
Packit 90a5c9
        *mask = SSL_OCSPCHECK_CHAIN;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        return apr_pstrcat(parms->temp_pool, parms->cmd->name,
Packit 90a5c9
                           ": Invalid argument '", w, "'",
Packit 90a5c9
                           NULL);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    while (*arg) {
Packit 90a5c9
        w = ap_getword_conf(parms->temp_pool, &arg;;
Packit 90a5c9
        if (strcEQ(w, "no_ocsp_for_cert_ok")) {
Packit 90a5c9
            *mask |= SSL_OCSPCHECK_NO_OCSP_FOR_CERT_OK;
Packit 90a5c9
        }
Packit 90a5c9
        else {
Packit 90a5c9
            return apr_pstrcat(parms->temp_pool, parms->cmd->name,
Packit 90a5c9
                               ": Invalid argument '", w, "'",
Packit 90a5c9
                               NULL);
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
#ifdef OPENSSL_NO_OCSP
Packit 90a5c9
    if (flag) {
Packit 90a5c9
        return "OCSP support disabled in SSL library; cannot enable "
Packit 90a5c9
            "OCSP validation";
Packit 90a5c9
    }
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
    return ssl_cmd_ocspcheck_parse(cmd, arg, &sc->server->ocsp_mask);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    sc->server->ocsp_force_default = flag ? TRUE : FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    sc->server->ocsp_responder = arg;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->ocsp_resptime_skew = atoi(arg);
Packit 90a5c9
    if (sc->server->ocsp_resptime_skew < 0) {
Packit 90a5c9
        return "SSLOCSPResponseTimeSkew: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->ocsp_resp_maxage = atoi(arg);
Packit 90a5c9
    if (sc->server->ocsp_resp_maxage < 0) {
Packit 90a5c9
        return "SSLOCSPResponseMaxAge: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->ocsp_responder_timeout = apr_time_from_sec(atoi(arg));
Packit 90a5c9
    if (sc->server->ocsp_responder_timeout < 0) {
Packit 90a5c9
        return "SSLOCSPResponderTimeout: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPUseRequestNonce(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    sc->server->ocsp_use_request_nonce = flag ? TRUE : FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->proxy_uri = apr_palloc(cmd->pool, sizeof(apr_uri_t));
Packit 90a5c9
    if (apr_uri_parse(cmd->pool, arg, sc->server->proxy_uri) != APR_SUCCESS) {
Packit 90a5c9
        return apr_psprintf(cmd->pool,
Packit 90a5c9
                            "SSLOCSPProxyURL: Cannot parse URL %s", arg);
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
/* Set OCSP responder certificate verification directive */
Packit 90a5c9
const char *ssl_cmd_SSLOCSPNoVerify(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    sc->server->ocsp_noverify = flag ? TRUE : FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    dc->proxy->ssl_check_peer_expire = flag ? TRUE : FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    dc->proxy->ssl_check_peer_cn = flag ? TRUE : FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLProxyCheckPeerName(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
Packit 90a5c9
Packit 90a5c9
    dc->proxy->ssl_check_peer_name = flag ? TRUE : FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char  *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
#ifdef HAVE_TLSEXT
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
Packit 90a5c9
    sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
#else
Packit 90a5c9
    return "SSLStrictSNIVHostCheck failed; OpenSSL is not built with support "
Packit 90a5c9
           "for TLS extensions and SNI indication. Refer to the "
Packit 90a5c9
           "documentation, and build a compatible version of OpenSSL.";
Packit 90a5c9
#endif
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_OCSP_STAPLING
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd,
Packit 90a5c9
                                    void *dcfg,
Packit 90a5c9
                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLModConfigRec *mc = myModConfig(cmd->server);
Packit 90a5c9
    const char *err, *sep, *name;
Packit 90a5c9
Packit 90a5c9
    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* Argument is of form 'name:args' or just 'name'. */
Packit 90a5c9
    sep = ap_strchr_c(arg, ':');
Packit 90a5c9
    if (sep) {
Packit 90a5c9
        name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
Packit 90a5c9
        sep++;
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        name = arg;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    /* Find the provider of given name. */
Packit 90a5c9
    mc->stapling_cache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
Packit 90a5c9
                                            name,
Packit 90a5c9
                                            AP_SOCACHE_PROVIDER_VERSION);
Packit 90a5c9
    if (mc->stapling_cache) {
Packit 90a5c9
        /* Cache found; create it, passing anything beyond the colon. */
Packit 90a5c9
        err = mc->stapling_cache->create(&mc->stapling_cache_context,
Packit 90a5c9
                                         sep, cmd->temp_pool,
Packit 90a5c9
                                         cmd->pool);
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        apr_array_header_t *name_list;
Packit 90a5c9
        const char *all_names;
Packit 90a5c9
Packit 90a5c9
        /* Build a comma-separated list of all registered provider
Packit 90a5c9
         * names: */
Packit 90a5c9
        name_list = ap_list_provider_names(cmd->pool,
Packit 90a5c9
                                           AP_SOCACHE_PROVIDER_GROUP,
Packit 90a5c9
                                           AP_SOCACHE_PROVIDER_VERSION);
Packit 90a5c9
        all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
Packit 90a5c9
Packit 90a5c9
        err = apr_psprintf(cmd->pool, "'%s' stapling cache not supported "
Packit 90a5c9
                           "(known names: %s) Maybe you need to load the "
Packit 90a5c9
                           "appropriate socache module (mod_socache_%s?)",
Packit 90a5c9
                           name, all_names, name);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (err) {
Packit 90a5c9
        return apr_psprintf(cmd->pool, "SSLStaplingCache: %s", err);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLUseStapling(cmd_parms *cmd, void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_enabled = flag ? TRUE : FALSE;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_resptime_skew = atoi(arg);
Packit 90a5c9
    if (sc->server->stapling_resptime_skew < 0) {
Packit 90a5c9
        return "SSLStaplingResponseTimeSkew: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingResponseMaxAge(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_resp_maxage = atoi(arg);
Packit 90a5c9
    if (sc->server->stapling_resp_maxage < 0) {
Packit 90a5c9
        return "SSLStaplingResponseMaxAge: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingStandardCacheTimeout(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                                    const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_cache_timeout = atoi(arg);
Packit 90a5c9
    if (sc->server->stapling_cache_timeout < 0) {
Packit 90a5c9
        return "SSLStaplingStandardCacheTimeout: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                                 const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_errcache_timeout = atoi(arg);
Packit 90a5c9
    if (sc->server->stapling_errcache_timeout < 0) {
Packit 90a5c9
        return "SSLStaplingErrorCacheTimeout: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *cmd,
Packit 90a5c9
                                                     void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_return_errors = flag ? TRUE : FALSE;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *cmd,
Packit 90a5c9
                                            void *dcfg, int flag)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_fake_trylater = flag ? TRUE : FALSE;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                                const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_responder_timeout = atoi(arg);
Packit 90a5c9
    sc->server->stapling_responder_timeout *= APR_USEC_PER_SEC;
Packit 90a5c9
    if (sc->server->stapling_responder_timeout < 0) {
Packit 90a5c9
        return "SSLStaplingResponderTimeout: invalid argument";
Packit 90a5c9
    }
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                        const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    sc->server->stapling_force_url = arg;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#endif /* HAVE_OCSP_STAPLING */
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_SSL_CONF_CMD
Packit 90a5c9
const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                      const char *arg1, const char *arg2)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config;
Packit 90a5c9
    int value_type = SSL_CONF_cmd_value_type(cctx, arg1);
Packit 90a5c9
    const char *err;
Packit 90a5c9
    ssl_ctx_param_t *param;
Packit 90a5c9
Packit 90a5c9
    if (value_type == SSL_CONF_TYPE_UNKNOWN) {
Packit 90a5c9
        return apr_psprintf(cmd->pool,
Packit 90a5c9
                            "'%s': invalid OpenSSL configuration command",
Packit 90a5c9
                            arg1);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (value_type == SSL_CONF_TYPE_FILE) {
Packit 90a5c9
        if ((err = ssl_cmd_check_file(cmd, &arg2)))
Packit 90a5c9
            return err;
Packit 90a5c9
    }
Packit 90a5c9
    else if (value_type == SSL_CONF_TYPE_DIR) {
Packit 90a5c9
        if ((err = ssl_cmd_check_dir(cmd, &arg2)))
Packit 90a5c9
            return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (strcEQ(arg1, "CipherString")) {
Packit 90a5c9
        /* always disable null and export ciphers */
Packit 90a5c9
        arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    param = apr_array_push(sc->server->ssl_ctx_param);
Packit 90a5c9
    param->name = arg1;
Packit 90a5c9
    param->value = arg2;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
#ifdef HAVE_SRP
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                       const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg)))
Packit 90a5c9
        return err;
Packit 90a5c9
    /* SRP_VBASE_init takes char*, not const char*  */
Packit 90a5c9
    sc->server->srp_vfile = apr_pstrdup(cmd->pool, arg);
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg,
Packit 90a5c9
                                          const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    /* SRP_VBASE_new takes char*, not const char*  */
Packit 90a5c9
    sc->server->srp_unknown_user_seed = apr_pstrdup(cmd->pool, arg);
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
#endif /* HAVE_SRP */
Packit 90a5c9
Packit 90a5c9
/* OCSP Responder File Function to read in value */
Packit 90a5c9
const char *ssl_cmd_SSLOCSPResponderCertificateFile(cmd_parms *cmd, void *dcfg, 
Packit 90a5c9
					   const char *arg)
Packit 90a5c9
{
Packit 90a5c9
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
Packit 90a5c9
    const char *err;
Packit 90a5c9
Packit 90a5c9
    if ((err = ssl_cmd_check_file(cmd, &arg))) {
Packit 90a5c9
        return err;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    sc->server->ocsp_certs_file = arg;
Packit 90a5c9
    return NULL;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
Packit 90a5c9
{
Packit 90a5c9
    apr_file_t *out = NULL;
Packit 90a5c9
    if (!ap_exists_config_define("DUMP_CERTS")) {
Packit 90a5c9
        return;
Packit 90a5c9
    }
Packit 90a5c9
    apr_file_open_stdout(&out, pconf);
Packit 90a5c9
    apr_file_printf(out, "Server certificates:\n");
Packit 90a5c9
Packit 90a5c9
    /* Dump the filenames of all configured server certificates to
Packit 90a5c9
     * stdout. */
Packit 90a5c9
    while (s) {
Packit 90a5c9
        SSLSrvConfigRec *sc = mySrvConfig(s);
Packit 90a5c9
Packit 90a5c9
        if (sc && sc->server && sc->server->pks) {
Packit 90a5c9
            modssl_pk_server_t *const pks = sc->server->pks;
Packit 90a5c9
            int i;
Packit 90a5c9
Packit 90a5c9
            for (i = 0; (i < pks->cert_files->nelts) &&
Packit 90a5c9
                        APR_ARRAY_IDX(pks->cert_files, i, const char *);
Packit 90a5c9
                 i++) {
Packit 90a5c9
                apr_file_printf(out, "  %s\n",
Packit 90a5c9
                                APR_ARRAY_IDX(pks->cert_files,
Packit 90a5c9
                                              i, const char *));
Packit 90a5c9
            }
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        s = s->next;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
}
Packit 90a5c9