You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2018/02/16 13:05:27 UTC
svn commit: r1824465 - /httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
Author: icing
Date: Fri Feb 16 13:05:27 2018
New Revision: 1824465
URL: http://svn.apache.org/viewvc?rev=1824465&view=rev
Log:
sslpolicy patch for 2.4.x
Added:
httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
Added: httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
URL: http://svn.apache.org/viewvc/httpd/httpd/patches/2.4.x/mod_ssl_policy.diff?rev=1824465&view=auto
==============================================================================
--- httpd/httpd/patches/2.4.x/mod_ssl_policy.diff (added)
+++ httpd/httpd/patches/2.4.x/mod_ssl_policy.diff Fri Feb 16 13:05:27 2018
@@ -0,0 +1,1256 @@
+Index: docs/conf/extra/httpd-ssl.conf.in
+===================================================================
+--- docs/conf/extra/httpd-ssl.conf.in (revision 1824437)
++++ docs/conf/extra/httpd-ssl.conf.in (working copy)
+@@ -42,6 +42,34 @@
+ ## the main server and all SSL-enabled virtual hosts.
+ ##
+
++# SSL Policy:
++# Choose from a pre-defined setting of SSL* configurations, based on
++# the Mozilla recommendations from:
++# https://wiki.mozilla.org/Security/Server_Side_TLS
++# These policies will be updated over time in new releases to keep
++# settings compatible and secure with "modern" browser, or if you
++# need to support legacy installtions, "intermediate" might be your
++# choice.
++# If you run the following command on your installation, the exact
++# contents of the defined SSL policies will be listed:
++#
++# > httpd -t -D DUMP_SSL_POLICIES
++#
++# Worth noting, a SSLPolicy defines the ground rules. What ever is
++# configured beside it, is added "on top". If a configuration has
++# a SSLPolicy *and* a SSLCipherSuite, any cipher suite in the policy
++# will be overwritten in this context.
++#
++# If your OpenSSL library does not support TLSv1.2 (OpenSSL 1.0.2
++# and later), "modern" will not be available.
++# If you enable one of the policies below, we recommend that you
++# refrain from configuring any of the following, unless you are
++# certain that you want to override:
++# SSLCipherSuite, SSLProxyCipherSuite, SSLHonorCipherOrder,
++# SSLProtocol, SSLProxyProtocol
++#SSLPolicy intermediate
++#SSLPolicy modern
++
+ # SSL Cipher Suite:
+ # List the ciphers that the client is permitted to negotiate,
+ # and that httpd will negotiate as the client of a proxied server.
+Index: docs/manual/mod/mod_ssl.xml
+===================================================================
+--- docs/manual/mod/mod_ssl.xml (revision 1824437)
++++ docs/manual/mod/mod_ssl.xml (working copy)
+@@ -2827,4 +2827,206 @@
+ </usage>
+ </directivesynopsis>
+
++<directivesynopsis type="section" idtype="section">
++<name>SSLPolicyDefine</name>
++<description>Define a named set of SSL configurations</description>
++<syntax><SSLPolicy <em>name</em>></syntax>
++<contextlist><context>server config</context></contextlist>
++<compatibility>Available in httpd 2.4.30 and later</compatibility>
++
++<usage>
++<p>This directive defines a set of SSL* configurations under
++and gives it a name. This name can be used in the directives
++<directive>SSLPolicy</directive> and <directive>SSLProxyPolicy</directive>
++to apply this configuration set in the current context.</p>
++
++<example><title>Examples</title>
++<highlight language="config">
++<SSLPolicyDefine safe-stapling>
++ SSLUseStapling on
++ SSLStaplingResponderTimeout 2
++ SSLStaplingReturnResponderErrors off
++ SSLStaplingFakeTryLater off
++ SSLStaplingStandardCacheTimeout 86400
++</SSLPolicyDefine>
++
++ ...
++ <VirtualHost...>
++ SSLPolicy safe-stapling
++ ...
++</highlight>
++</example>
++
++<p>On the one hand, this can make server configurations easier to
++<em>read</em> and <em>maintain</em>. On the other hand, it is
++intended to make SSL easier and safer to <em>use</em>. For the
++latter, Apache httpd ships with a set of pre-defined policies
++that reflect good open source practise. The policy "modern",
++for example, carries the settings to make your server work
++compatible and securely with current browsers.</p>
++
++<p>The list of predefined policies in your Apache can be obtained
++by running the following command. This list shows you the
++detailed configurations each policy is made of:</p>
++
++<example><title>Examples</title>
++<highlight language="sh">
++> httpd -t -D DUMP_SSL_POLICIES
++</highlight>
++</example>
++
++<p>The directive can only be used in the server config (global context). It can take
++most SSL* directives, however a few can only be set once and are not allowed inside
++policy defintions. These are <directive>SSLCryptoDevice</directive>,
++<directive>SSLRandomSeed</directive>,
++<directive>SSLSessionCache</directive> and
++<directive>SSLStaplingCache</directive>.
++</p>
++<p>Two policies cannot have the same name. However, policies can
++be redefined:</p>
++
++<example><title>Examples</title>
++<highlight language="config">
++<SSLPolicyDefine proxy-trust>
++ SSLProxyVerify require
++</SSLPolicyDefine>
++ ...
++<SSLPolicyDefine proxy-trust>
++ SSLProxyVerify none
++</SSLPolicyDefine>
++</highlight>
++</example>
++
++<p>Policy definitions are <em>added</em> in the order they appear, but are
++<em>applied</em> when the whole configuration is read. This means that any
++use of 'proxy-trust' will mean 'SSLProxyVerify none'. The first definition
++has no effect at all. You can replace policy definitions that have been
++pre-installed without the need to disable them.</p>
++
++<p>Additional to replacing policies, redefinitions may just alter
++an aspect of a policy:</p>
++
++<example><title>Examples</title>
++<highlight language="config">
++<SSLPolicyDefine proxy-trust>
++ SSLProxyVerify require
++</SSLPolicyDefine>
++ ...
++<SSLPolicyDefine proxy-trust>
++ SSLPolicy proxy-trust
++ SSLProxyVerifyDepth 10
++</SSLPolicyDefine>
++</highlight>
++</example>
++
++<p>This re-uses all settings from the previous 'proxy-trust' and adds
++one directive on top of it. All others still apply. This is very handy
++when pre-defined policies (from Apache itself or a distributor)
++that <em>almost</em> fit ones needs. Previously, such definitions were
++(copied and) edited. This made updating them difficult. Now they can
++be setup like this:</p>
++
++<example><title>Examples</title>
++<highlight language="config">
++Include ssl-policies.conf
++
++<SSLPolicyDefine modern>
++ SSLPolicy modern
++ SSLProxyVerify none
++</SSLPolicyDefine>
++</highlight>
++</example>
++
++</usage>
++</directivesynopsis>
++
++<directivesynopsis>
++<name>SSLPolicy</name>
++<description></description>
++<syntax>SSLPolicy <em>name</em></syntax>
++<contextlist><context>server config</context>
++<context>virtual host</context></contextlist>
++<compatibility>Available in httpd 2.4.30 and later</compatibility>
++
++<usage>
++<p>This directive applies the set of SSL* directives defined
++under 'name' (see <directive type="section">SSLPolicyDefine</directive>) as the <em>base</em>
++settings in the current context. Apache comes with the following pre-defined policies from
++Mozilla, the makers of the Firefox browser
++(<a href="https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations">see here
++for a detailed description by them.</a>):
++</p>
++<ul>
++ <li><code>modern</code>: recommended when your server is accessible on the open Internet. Works with all modern browsers, but old devices might be unable to connect.</li>
++ <li><code>intermediate</code>: the fallback if you need to support old (but not very old) clients.</li>
++ <li><code>old</code>: when you need to give Windows XP/Internet Explorer 6 access. The last resort.</li>
++</ul>
++
++<example><title>Examples</title>
++<highlight language="config">
++ <VirtualHost...> # effective: 'all'
++ SSLPolicy modern
++ SSLProtocol all
++ </VirtualHost>
++
++ <VirtualHost...> # effective: 'all'
++ SSLProtocol all
++ SSLPolicy modern
++ </VirtualHost>
++
++ SSLPolicy modern
++ <VirtualHost...> # effective: 'all'
++ SSLProtocol all
++ </VirtualHost>
++
++ SSLProtocol all
++ <VirtualHost...> # effective: '+TLSv1.2'
++ SSLPolicy modern
++ </VirtualHost>
++</highlight>
++</example>
++
++<p>There can be more than one policy applied in a context. The
++later ones overshadowing the earlier ones:</p>
++
++<example><title>Examples</title>
++<highlight language="config">
++ <VirtualHost...> # effective: 'intermediate > modern'
++ SSLPolicy modern
++ SSLPolicy intermediate
++ </VirtualHost>
++
++ <VirtualHost...> # effective: 'modern > intermediate'
++ SSLPolicy intermediate
++ SSLPolicy modern
++ </VirtualHost>
++</highlight>
++</example>
++
++</usage>
++</directivesynopsis>
++
++<directivesynopsis>
++<name>SSLProxyPolicy</name>
++<description></description>
++<syntax>SSLProxyPolicy <em>name</em></syntax>
++<contextlist><context>server config</context>
++<context>virtual host</context></contextlist>
++<compatibility>Available in httpd 2.4.30 and later</compatibility>
++
++<usage>
++<p>This directive is similar to <directive>SSLPolicy</directive>, but
++applies only the SSLProxy* directives defined in the policy. This helps
++when you need different policies for front and backends:</p>
++
++<example><title>Examples</title>
++<highlight language="config">
++SSLPolicy modern
++SSLProxyPolicy intermediate
++</highlight>
++</example>
++
++</usage>
++</directivesynopsis>
++
+ </modulesynopsis>
+Index: docs/manual/sections.xml
+===================================================================
+--- docs/manual/sections.xml (revision 1824437)
++++ docs/manual/sections.xml (working copy)
+@@ -54,6 +54,7 @@
+ <directive type="section" idtype="section" module="mod_md">MDomainSet</directive>
+ <directive type="section" module="mod_proxy">Proxy</directive>
+ <directive type="section" module="mod_proxy">ProxyMatch</directive>
++<directive type="section" idtype="section" module="mod_ssl">SSLPolicyDefine</directive>
+ <directive type="section" module="core">VirtualHost</directive>
+ </directivelist>
+ </related>
+Index: modules/ssl/mod_ssl.c
+===================================================================
+--- modules/ssl/mod_ssl.c (revision 1824437)
++++ modules/ssl/mod_ssl.c (working copy)
+@@ -308,6 +308,15 @@
+ AP_INIT_RAW_ARGS("SSLLogLevel", ap_set_deprecated, NULL, OR_ALL,
+ "SSLLogLevel directive is no longer supported - use LogLevel."),
+
++ AP_INIT_TAKE1("<SSLPolicyDefine", ssl_cmd_SSLPolicyDefine, NULL, RSRC_CONF,
++ "Define a set of SSL* configurations under a new name. Such a policy may "
++ "be used in any location where the SSL* directives are viable. The policy "
++ "may contain both SSL* and SSLProxy* specific settings. Which one is applied "
++ "depends on the use."),
++ AP_INIT_TAKE1("SSLPolicy", ssl_cmd_SSLPolicyApply, NULL, RSRC_CONF,
++ "Apply the SSL* (not the SSLProxy*) settings from the policy with the given name."),
++ AP_INIT_TAKE1("SSLProxyPolicy", ssl_cmd_SSLProxyPolicyApply, NULL, RSRC_CONF|PROXY_CONF,
++ "Use the SSLProxy* settings from the policy with the given name."),
+ AP_END_CMD
+ };
+
+Index: modules/ssl/mod_ssl.dsp
+===================================================================
+--- modules/ssl/mod_ssl.dsp (revision 1824437)
++++ modules/ssl/mod_ssl.dsp (working copy)
+@@ -180,6 +180,10 @@
+ # End Source File
+ # Begin Source File
+
++SOURCE=.\ssl_policies.h
++# End Source File
++# Begin Source File
++
+ SOURCE=.\ssl_util_ssl.h
+ # End Source File
+ # Begin Source File
+Index: modules/ssl/ssl_engine_config.c
+===================================================================
+--- modules/ssl/ssl_engine_config.c (revision 1824437)
++++ modules/ssl/ssl_engine_config.c (working copy)
+@@ -26,7 +26,11 @@
+ /* ``Damned if you do,
+ damned if you don't.''
+ -- Unknown */
++#include <stdio.h>
++#include <stdlib.h>
++
+ #include "ssl_private.h"
++#include "ssl_policies.h"
+ #include "util_mutex.h"
+ #include "ap_provider.h"
+
+@@ -89,7 +93,7 @@
+
+ BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
+ {
+- return mc->bFixed;
++ return mc && mc->bFixed;
+ }
+
+ /* _________________________________________________________________
+@@ -226,6 +230,8 @@
+ sc->compression = UNSET;
+ #endif
+ sc->session_tickets = UNSET;
++ sc->policies = NULL;
++ sc->error_policy = NULL;
+
+ modssl_ctx_init_server(sc, p);
+
+@@ -377,6 +383,9 @@
+ #endif
+ }
+
++static void ssl_policy_apply(SSLSrvConfigRec *sc, apr_pool_t *p);
++static void ssl_dir_policy_apply(SSLDirConfigRec *dc, apr_pool_t *p);
++
+ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
+ {
+ SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
+@@ -383,6 +392,10 @@
+ SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv;
+ SSLSrvConfigRec *mrg = ssl_config_server_new(p);
+
++ /* This is a NOP, unless a policy has not been applied yet */
++ ssl_policy_apply(base, p);
++ ssl_policy_apply(add, p);
++
+ cfgMerge(mc, NULL);
+ cfgMerge(enabled, SSL_ENABLED_UNSET);
+ cfgMergeInt(session_cache_timeout);
+@@ -399,6 +412,9 @@
+ #endif
+ cfgMergeBool(session_tickets);
+
++ mrg->policies = NULL;
++ cfgMergeString(error_policy);
++
+ modssl_ctx_cfg_merge_server(p, base->server, add->server, mrg->server);
+
+ return mrg;
+@@ -448,6 +464,9 @@
+ modssl_ctx_init_proxy(dc, p);
+ dc->proxy_post_config = FALSE;
+
++ dc->policies = NULL;
++ dc->error_policy = NULL;
++
+ return dc;
+ }
+
+@@ -473,6 +492,9 @@
+ SSLDirConfigRec *add = (SSLDirConfigRec *)addv;
+ SSLDirConfigRec *mrg = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
+
++ ssl_dir_policy_apply(base, p);
++ ssl_dir_policy_apply(add, p);
++
+ cfgMerge(bSSLRequired, FALSE);
+ cfgMergeArray(aRequirement);
+
+@@ -512,6 +534,9 @@
+ mrg->proxy = add->proxy;
+ }
+
++ mrg->policies = NULL;
++ cfgMergeString(error_policy);
++
+ return mrg;
+ }
+
+@@ -526,6 +551,268 @@
+ modssl_ctx_cfg_merge_proxy(p, base->proxy, conf->proxy, conf->proxy);
+ }
+
++/* _________________________________________________________________
++**
++** Policy handling
++** _________________________________________________________________
++*/
++
++static void add_policy(apr_hash_t *policies, apr_pool_t *p, const char *name,
++ int protocols, const char *ciphers,
++ int honor_order, int compression, int session_tickets,
++ ssl_verify_t proxy_verify_mode, int proxy_verify_depth)
++{
++ SSLPolicyRec *policy;
++
++ policy = apr_pcalloc(p, sizeof(*policy));
++ policy->name = name;
++ policy->sc = ssl_config_server_new(p);
++ policy->dc = ssl_config_perdir_create(p, "/");
++
++ if (protocols || ciphers) {
++ policy->sc->server->protocol_set = 1;
++ policy->sc->server->protocol = protocols;
++ policy->dc->proxy->protocol_set = 1;
++ policy->dc->proxy->protocol = protocols;
++ }
++
++ if (ciphers) {
++ policy->sc->server->auth.cipher_suite = ciphers;
++ policy->dc->proxy->auth.cipher_suite = ciphers;
++ }
++
++#ifndef OPENSSL_NO_COMP
++ policy->sc->compression = compression ? TRUE : FALSE;
++#endif
++ policy->sc->session_tickets = session_tickets ? TRUE : FALSE;
++
++ policy->dc->proxy->auth.verify_mode = proxy_verify_mode;
++ if (proxy_verify_depth >= 0) {
++ policy->dc->proxy->auth.verify_depth = proxy_verify_depth;
++ }
++
++ apr_hash_set(policies, policy->name, APR_HASH_KEY_STRING, policy);
++}
++
++static apr_hash_t *get_policies(apr_pool_t *p, int create)
++{
++ apr_hash_t *policies;
++ void *vp;
++
++ apr_pool_userdata_get(&vp, SSL_MOD_POLICIES_KEY, p);
++ if (vp) {
++ return vp; /* reused for lifetime of the pool */
++ }
++ if (create) {
++ policies = apr_hash_make(p);
++
++#if SSL_POLICY_MODERN
++ add_policy(policies, p, "modern",
++ SSL_POLICY_MODERN_PROTOCOLS,
++ SSL_POLICY_MODERN_CIPHERS,
++ SSL_POLICY_HONOR_ORDER,
++ SSL_POLICY_COMPRESSION,
++ SSL_POLICY_SESSION_TICKETS,
++ SSL_POLICY_PROXY_VERIFY_MODE,
++ SSL_POLICY_PROXY_VERIFY_DEPTH);
++#endif
++#if SSL_POLICY_INTERMEDIATE
++ add_policy(policies, p, "intermediate",
++ SSL_POLICY_INTERMEDIATE_PROTOCOLS,
++ SSL_POLICY_INTERMEDIATE_CIPHERS,
++ SSL_POLICY_HONOR_ORDER,
++ SSL_POLICY_COMPRESSION,
++ SSL_POLICY_SESSION_TICKETS,
++ SSL_POLICY_PROXY_VERIFY_MODE,
++ SSL_POLICY_PROXY_VERIFY_DEPTH);
++#endif
++#if SSL_POLICY_OLD
++ add_policy(policies, p, "old",
++ SSL_POLICY_OLD_PROTOCOLS,
++ SSL_POLICY_OLD_CIPHERS,
++ SSL_POLICY_HONOR_ORDER,
++ SSL_POLICY_COMPRESSION,
++ SSL_POLICY_SESSION_TICKETS,
++ SSL_CVERIFY_NONE,
++ SSL_POLICY_PROXY_VERIFY_DEPTH);
++#endif
++
++ apr_pool_userdata_set(policies, SSL_MOD_POLICIES_KEY,
++ apr_pool_cleanup_null, p);
++ return policies;
++ }
++ return NULL;
++}
++
++static int policy_collect_names(void *baton, const void *key, apr_ssize_t klen, const void *val)
++{
++ apr_array_header_t *names = baton;
++ APR_ARRAY_PUSH(names, const char *) = (const char*)key;
++ return 1;
++}
++
++static int qstrcmp(const void *v1, const void *v2)
++{
++ return strcmp(*(const char**)v1, *(const char**)v2);
++}
++
++static apr_array_header_t *get_policy_names(apr_pool_t *p, int create)
++{
++ apr_array_header_t *names = apr_array_make(p, 10, sizeof(const char*));
++ apr_hash_t *policies = get_policies(p, create);
++
++ if (policies) {
++ apr_hash_do(policy_collect_names, names, policies);
++ qsort(names->elts, names->nelts, sizeof(const char*), qstrcmp);
++ }
++ return names;
++}
++
++SSLPolicyRec *ssl_policy_lookup(apr_pool_t *pool, const char *name)
++{
++ apr_hash_t *policies = get_policies(pool, 1);
++ return apr_hash_get(policies, name, APR_HASH_KEY_STRING);
++}
++
++static void ssl_policy_set(apr_pool_t *pool, SSLPolicyRec *policy)
++{
++ apr_hash_t *policies = get_policies(pool, 1);
++ return apr_hash_set(policies, policy->name, APR_HASH_KEY_STRING, policy);
++}
++
++const char *ssl_cmd_SSLPolicyDefine(cmd_parms *cmd, void *mconfig, const char *arg)
++{
++ server_rec *s = cmd->server;
++ SSLSrvConfigRec *sc = mySrvConfig(s);
++ SSLDirConfigRec *dc = ap_get_module_config(s->lookup_defaults, &ssl_module);
++ SSLPolicyRec *policy;
++ const char *endp = ap_strrchr_c(arg, '>');
++ const char *err, *name;
++
++ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
++ return err;
++ }
++
++ if (endp == NULL) {
++ return apr_pstrcat(cmd->pool, cmd->cmd->name, "> directive missing closing '>'", NULL);
++ }
++
++ arg = apr_pstrndup(cmd->pool, arg, endp-arg);
++ if (!arg || !*arg) {
++ return "<SSLPolicyDefine > block must specify a name";
++ }
++
++ name = ap_getword_white(cmd->pool, &arg);
++ if (*arg != '\0') {
++ return apr_pstrcat(cmd->pool, cmd->cmd->name, "> takes only 1 argument", NULL);
++ }
++
++ policy = apr_pcalloc(cmd->pool, sizeof(*policy));
++ policy->name = name;
++ policy->sc = ssl_config_server_new(cmd->pool);
++ policy->sc->mc = NULL; /* No global configs during SSLPolicy definition */
++ policy->dc = ssl_config_perdir_create(cmd->pool, "/");/* TODO */
++
++ ap_set_module_config(s->module_config, &ssl_module, policy->sc);
++ ap_set_module_config(s->lookup_defaults, &ssl_module, policy->dc);
++
++ err = ap_walk_config(cmd->directive->first_child, cmd, cmd->context);
++ if (!err) {
++ /* If this new policy uses other policies, we need to merge it
++ * before adding, otherwise a policy cannot re-use an existing one */
++ ssl_policy_apply(policy->sc, cmd->pool);
++ ssl_dir_policy_apply(policy->dc, cmd->pool);
++ /* time to persist */
++ ssl_policy_set(cmd->pool, policy);
++ }
++
++ ap_set_module_config(s->module_config, &ssl_module, sc);
++ ap_set_module_config(s->lookup_defaults, &ssl_module, dc);
++
++ return err;
++}
++
++const char *ssl_cmd_SSLPolicyApply(cmd_parms *cmd, void *mconfig, const char *arg)
++{
++ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
++
++ if (!sc->policies) {
++ sc->policies = apr_array_make(cmd->pool, 5, sizeof(const char*));
++ }
++ APR_ARRAY_PUSH(sc->policies, const char *) = arg;
++
++ /* Also apply the proxy parts of the policy */
++ return ssl_cmd_SSLProxyPolicyApply(cmd, mconfig, arg);
++}
++
++const char *ssl_cmd_SSLProxyPolicyApply(cmd_parms *cmd, void *mconfig, const char *arg)
++{
++ SSLDirConfigRec *dc = ap_get_module_config(cmd->server->lookup_defaults, &ssl_module);
++
++ if (!dc->policies) {
++ dc->policies = apr_array_make(cmd->pool, 5, sizeof(const char*));
++ }
++ APR_ARRAY_PUSH(dc->policies, const char *) = arg;
++
++ return NULL;
++}
++
++void ssl_policy_apply(SSLSrvConfigRec *sc, apr_pool_t *p)
++{
++ SSLSrvConfigRec *mrg;
++ SSLPolicyRec *policy;
++ apr_array_header_t *policies;
++ const char *name;
++ int i;
++
++ policies = sc->policies;
++ if (policies && policies->nelts > 0 && !sc->error_policy) {
++ sc->policies = NULL;
++ for (i = policies->nelts - 1; i >= 0; --i) {
++ name = APR_ARRAY_IDX(policies, i, const char *);
++ policy = ssl_policy_lookup(p, name);
++ if (policy) {
++ mrg = ssl_config_server_merge(p, policy->sc, sc);
++ /* apply in place */
++ memcpy(sc, mrg, sizeof(*sc));
++ }
++ else {
++ sc->error_policy = name;
++ break;
++ /* report error policies in post_config */
++ }
++ }
++ }
++}
++
++void ssl_dir_policy_apply(SSLDirConfigRec *dc, apr_pool_t *p)
++{
++ SSLDirConfigRec *mrg;
++ SSLPolicyRec *policy;
++ apr_array_header_t *policies;
++ const char *name;
++ int i;
++
++ policies = dc->policies;
++ if (policies && policies->nelts > 0 &&!dc->error_policy) {
++ dc->policies = NULL;
++ for (i = policies->nelts - 1; i >= 0; --i) {
++ name = APR_ARRAY_IDX(policies, i, const char *);
++ policy = ssl_policy_lookup(p, name);
++ if (policy) {
++ mrg = ssl_config_perdir_merge(p, policy->dc, dc);
++ /* apply in place */
++ memcpy(dc, mrg, sizeof(*dc));
++ }
++ else {
++ dc->error_policy = name;
++ break;
++ /* report error policies in post_config */
++ }
++ }
++ }
++}
++
+ /*
+ * Configuration functions for particular directives
+ */
+@@ -589,6 +876,9 @@
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+ return err;
+ }
++ if (!mc) {
++ return "SSLCryptoDevice: cannot be used inside SSLPolicyDefine";
++ }
+
+ if (strcEQ(arg, "builtin")) {
+ mc->szCryptoDevice = NULL;
+@@ -626,9 +916,13 @@
+ ssl_randseed_t *seed;
+ int arg2len = strlen(arg2);
+
++ /* replace: check_no_policy_and(flags) */
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+ return err;
+ }
++ if (!mc) {
++ return "SSLRandomSeed: cannot be used inside SSLPolicyDefine";
++ }
+
+ if (ssl_config_global_isfixed(mc)) {
+ return NULL;
+@@ -1198,6 +1492,9 @@
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+ return err;
+ }
++ if (!mc) {
++ return "SSLSessionCache: cannot be used inside SSLPolicyDefine";
++ }
+
+ /* The OpenSSL session cache mode must have both the flags
+ * SSL_SESS_CACHE_SERVER and SSL_SESS_CACHE_NO_INTERNAL set if a
+@@ -1822,6 +2119,9 @@
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+ return err;
+ }
++ if (!mc) {
++ return "SSLStaplingCache: cannot be used inside SSLPolicyDefine";
++ }
+
+ /* Argument is of form 'name:args' or just 'name'. */
+ sep = ap_strchr_c(arg, ':');
+@@ -2034,6 +2334,13 @@
+ return NULL;
+ }
+
++static void ssl_srv_dump(SSLSrvConfigRec *sc, apr_pool_t *p,
++ apr_file_t *out, const char *indent, const char **psep);
++static void ssl_dir_dump(SSLDirConfigRec *dc, apr_pool_t *p,
++ apr_file_t *out, const char *indent, const char **psep);
++static void ssl_policy_dump(SSLPolicyRec *policy, apr_pool_t *p,
++ apr_file_t *out, const char *indent);
++
+ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
+ {
+ apr_file_t *out = NULL;
+@@ -2064,4 +2371,412 @@
+ s = s->next;
+ }
+
++ if (ap_exists_config_define("DUMP_SSL_POLICIES")) {
++ apr_array_header_t *names = get_policy_names(pconf, 1);
++ SSLPolicyRec *policy;
++ const char *name, *sep = "";
++ int i;
++
++ apr_file_open_stdout(&out, pconf);
++ apr_file_printf(out, "SSLPolicies: {");
++ for (i = 0; i < names->nelts; ++i) {
++ name = APR_ARRAY_IDX(names, i, const char*);
++ policy = ssl_policy_lookup(pconf, name);
++ if (policy) {
++ apr_file_printf(out, "%s\n \"%s\": {", sep, name);
++ sep = ", ";
++ ssl_policy_dump(policy, pconf, out, " ");
++ apr_file_printf(out, "\n }");
++ }
++ }
++ apr_file_printf(out, "\n}\n");
++ return;
++ }
+ }
++
++/* _________________________________________________________________
++**
++** Dump Config Data
++** _________________________________________________________________
++*/
++
++static const char *json_quote(const char *s, apr_pool_t *p)
++{
++ const char *src, *dq = s;
++ int n = 0;
++
++ while ((dq = ap_strchr_c(dq, '\"'))) {
++ ++n;
++ ++dq;
++ }
++ if (n > 0) {
++ char *dst, c;
++ src = s;
++ s = dst = apr_pcalloc(p, strlen(s) + n + 1);
++ while ((c = *src++)) {
++ if (c == '\"') {
++ *dst++ = '\\';
++ }
++ *dst++ = c;
++ }
++ }
++ return s;
++}
++
++static void val_str_dump(apr_file_t *out, const char *key, const char *val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val) {
++ /* TODO: JSON quite string val */
++ apr_file_printf(out, "%s\n%s\"%s\": \"%s\"", *psep, indent, key, json_quote(val, p));
++ *psep = ", ";
++ }
++}
++
++static void val_str_array_dump(apr_file_t *out, const char *key, apr_array_header_t *val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val && val->nelts > 0) {
++ const char *s;
++ int i;
++
++ for (i = 0; i < val->nelts; ++i) {
++ s = APR_ARRAY_IDX(val, i, const char*);
++ val_str_dump(out, key, s, p, indent, psep);
++ }
++ }
++}
++
++static void val_long_dump(apr_file_t *out, const char *key, long val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val != UNSET) {
++ apr_file_printf(out, "%s\n%s\"%s\": %ld", *psep, indent, key, val);
++ *psep = ", ";
++ }
++}
++
++static void val_itime_dump(apr_file_t *out, const char *key, apr_interval_time_t val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val != UNSET) {
++ apr_file_printf(out, "%s\n%s\"%s\": %f", *psep, indent, key,
++ ((double)val/APR_USEC_PER_SEC));
++ *psep = ", ";
++ }
++}
++
++static void val_onoff_dump(apr_file_t *out, const char *key, BOOL val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val != UNSET) {
++ val_str_dump(out, key, val? "on" : "off", p, indent, psep);
++ }
++}
++
++static void val_uri_dump(apr_file_t *out, const char *key, apr_uri_t *val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (val) {
++ val_str_dump(out, key, apr_uri_unparse(p, val, 0), p, indent, psep);
++ }
++}
++
++static void val_verify_dump(apr_file_t *out, const char *key, ssl_verify_t mode,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ switch (mode) {
++ case SSL_CVERIFY_NONE:
++ val_str_dump(out, key, "none", p, indent, psep);
++ return;
++ case SSL_CVERIFY_OPTIONAL:
++ val_str_dump(out, key, "optional", p, indent, psep);
++ return;
++ case SSL_CVERIFY_REQUIRE:
++ val_str_dump(out, key, "require", p, indent, psep);
++ return;
++ case SSL_CVERIFY_OPTIONAL_NO_CA:
++ val_str_dump(out, key, "optional_no_ca", p, indent, psep);
++ return;
++ default:
++ return;
++ }
++}
++
++static void val_enabled_dump(apr_file_t *out, const char *key, ssl_enabled_t val,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ switch (val) {
++ case SSL_ENABLED_FALSE:
++ val_str_dump(out, key, "off", p, indent, psep);
++ return;
++ case SSL_ENABLED_TRUE:
++ val_str_dump(out, key, "on", p, indent, psep);
++ return;
++ case SSL_ENABLED_OPTIONAL:
++ val_str_dump(out, key, "optional", p, indent, psep);
++ return;
++ default:
++ return;
++ }
++}
++
++static void val_pphrase_dump(apr_file_t *out, const char *key,
++ ssl_pphrase_t pphrase_type, const char *path,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ switch (pphrase_type) {
++ case SSL_PPTYPE_BUILTIN:
++ val_str_dump(out, key, "builtin", p, indent, psep);
++ return;
++ case SSL_PPTYPE_FILTER:
++ val_str_dump(out, key, apr_pstrcat(p, "|", path, NULL), p, indent, psep);
++ return;
++ case SSL_PPTYPE_PIPE:
++ val_str_dump(out, key, apr_pstrcat(p, "exec:", path, NULL), p, indent, psep);
++ return;
++ default:
++ return;
++ }
++}
++
++static void val_crl_check_dump(apr_file_t *out, const char *key, int mask,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ if (mask != UNSET) {
++ if (mask == SSL_CRLCHECK_NONE) {
++ val_str_dump(out, key, "none", p, indent, psep);
++ }
++ else if (mask == SSL_CRLCHECK_LEAF) {
++ val_str_dump(out, key, "leaf", p, indent, psep);
++ }
++ else if (mask == SSL_CRLCHECK_CHAIN) {
++ val_str_dump(out, key, "chain", p, indent, psep);
++ }
++ else if (mask == (SSL_CRLCHECK_CHAIN|SSL_CRLCHECK_NO_CRL_FOR_CERT_OK)) {
++ val_str_dump(out, key, "chain no_crl_for_cert_ok", p, indent, psep);
++ }
++ else {
++ val_str_dump(out, key, "???", p, indent, psep);
++ }
++ }
++}
++
++static void val_option_dump(apr_file_t *out, const char *key, const char *optname,
++ int val, int set_mask, int add_mask, int del_mask,
++ apr_pool_t *p, const char *indent, const char **psep)
++{
++ const char *op = ((val & set_mask)? "" :
++ ((val & add_mask)? "+" :
++ (val & del_mask)? "-" : NULL));
++ if (op) {
++ apr_file_printf(out, "%s\n%s\"%s\": \"%s%s\"", *psep, indent, key, op,
++ json_quote(optname, p));
++ *psep = ", ";
++ }
++}
++
++static const char *protocol_str(ssl_proto_t proto, apr_pool_t *p)
++{
++ if (SSL_PROTOCOL_NONE == proto) {
++ return "none";
++ }
++ else if (SSL_PROTOCOL_ALL == proto) {
++ return "all";
++ }
++ else {
++ /* icing: I think it is nuts that we define our own IETF protocol constants
++ * only whent the linked *SSL lib supports them. */
++ apr_array_header_t *names = apr_array_make(p, 5, sizeof(const char*));
++ if ((1<<4) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+TLSv1.2";
++ }
++ if ((1<<3) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+TLSv1.1";
++ }
++ if ((1<<2) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+TLSv1.0";
++ }
++ if ((1<<1) & proto) {
++ APR_ARRAY_PUSH(names, const char*) = "+SSLv3";
++ }
++ return apr_array_pstrcat(p, names, ' ');
++ }
++}
++
++#define DMP_STRING(k,v) \
++ val_str_dump(out, k, v, p, indent, psep)
++#define DMP_LONG(k,v) \
++ val_long_dump(out, k, v, p, indent, psep)
++#define DMP_ITIME(k,v) \
++ val_itime_dump(out, k, v, p, indent, psep)
++#define DMP_STRARR(k,v) \
++ val_str_array_dump(out, k, v, p, indent, psep)
++#define DMP_VERIFY(k,v) \
++ val_verify_dump(out, k, v, p, indent, psep)
++#define DMP_ON_OFF(k,v) \
++ val_onoff_dump(out, k, v, p, indent, psep)
++#define DMP_URI(k,v) \
++ val_uri_dump(out, k, v, p, indent, psep)
++#define DMP_CRLCHK(k,v) \
++ val_crl_check_dump(out, k, v, p, indent, psep)
++#define DMP_PHRASE(k,v, v2) \
++ val_pphrase_dump(out, k, v, v2, p, indent, psep)
++#define DMP_ENABLD(k,v) \
++ val_enabled_dump(out, k, v, p, indent, psep)
++#define DMP_OPTION(n,v) \
++ val_option_dump(out, "SSLOption", n, v, \
++ dc->nOptions, dc->nOptionsAdd, dc->nOptionsDel, p, indent, psep);
++
++static void modssl_auth_ctx_dump(modssl_auth_ctx_t *auth, apr_pool_t *p, int proxy,
++ apr_file_t *out, const char *indent, const char **psep)
++{
++ DMP_STRING(proxy? "SSLProxyCipherSuite" : "SSLCipherSuite", auth->cipher_suite);
++ DMP_VERIFY(proxy? "SSLProxyVerify" : "SSLVerifyClient", auth->verify_mode);
++ DMP_LONG( proxy? "SSLProxyVerify" : "SSLVerifyDepth", auth->verify_depth);
++ DMP_STRING(proxy? "SSLProxyCACertificateFile" : "SSLCACertificateFile", auth->ca_cert_file);
++ DMP_STRING(proxy? "SSLProxyCACertificatePath" : "SSLCACertificatePath", auth->ca_cert_path);
++}
++
++static void modssl_ctx_dump(modssl_ctx_t *ctx, apr_pool_t *p, int proxy,
++ apr_file_t *out, const char *indent, const char **psep)
++{
++ int i;
++
++ if (ctx->protocol_set) {
++ DMP_STRING(proxy? "SSLProxyProtocol" : "SSLProtocol", protocol_str(ctx->protocol, p));
++ }
++
++ modssl_auth_ctx_dump(&ctx->auth, p, proxy, out, indent, psep);
++
++ DMP_STRING(proxy? "SSLProxyCARevocationFile" : "SSLCARevocationFile", ctx->crl_file);
++ DMP_STRING(proxy? "SSLProxyCARevocationPath" : "SSLCARevocationPath", ctx->crl_path);
++ DMP_CRLCHK(proxy? "SSLProxyCARevocationCheck" : "SSLCARevocationCheck", ctx->crl_check_mask);
++ if (!proxy) {
++ DMP_PHRASE("SSLPassPhraseDialog", ctx->pphrase_dialog_type, ctx->pphrase_dialog_path);
++ if (ctx->pks) {
++ DMP_STRING("SSLCADNRequestFile", ctx->pks->ca_name_file);
++ DMP_STRING("SSLCADNRequestPath", ctx->pks->ca_name_path);
++ DMP_STRARR("SSLCertificateFile", ctx->pks->cert_files);
++ DMP_STRARR("SSLCertificateKeyFile", ctx->pks->key_files);
++ }
++#ifdef HAVE_OCSP_STAPLING
++ DMP_ON_OFF("SSLUseStapling", ctx->stapling_enabled);
++ DMP_LONG( "SSLStaplingResponseTimeSkew", ctx->stapling_resptime_skew);
++ DMP_LONG( "SSLStaplingResponseMaxAge", ctx->stapling_resp_maxage);
++ DMP_LONG( "SSLStaplingStandardCacheTimeout", ctx->stapling_cache_timeout);
++ DMP_ON_OFF("SSLStaplingReturnResponderErrors", ctx->stapling_return_errors);
++ DMP_ON_OFF("SSLStaplingFakeTryLater", ctx->stapling_fake_trylater);
++ DMP_LONG( "SSLStaplingErrorCacheTimeout", ctx->stapling_errcache_timeout);
++ DMP_ITIME( "SSLStaplingResponderTimeout", ctx->stapling_responder_timeout);
++ DMP_STRING("SSLStaplingForceURL", ctx->stapling_force_url);
++#endif /* if HAVE_OCSP_STAPLING */
++
++#ifdef HAVE_SRP
++ DMP_STRING("SSLSRPUnknownUserSeed", ctx->srp_unknown_user_seed);
++ DMP_STRING("SSLSRPVerifierFile", ctx->srp_vfile);
++#endif
++ DMP_ON_OFF("SSLOCSPEnable", ctx->ocsp_enabled);
++ DMP_ON_OFF("SSLOCSPOverrideResponder", ctx->ocsp_force_default);
++ DMP_STRING("SSLOCSPDefaultResponder", ctx->ocsp_responder);
++ DMP_LONG( "SSLOCSPResponseTimeSkew", ctx->ocsp_resptime_skew);
++ DMP_LONG( "SSLOCSPResponseMaxAge", ctx->ocsp_resp_maxage);
++ DMP_ITIME( "SSLOCSPResponderTimeout", ctx->ocsp_responder_timeout);
++ DMP_ON_OFF("SSLOCSPUseRequestNonce", ctx->ocsp_use_request_nonce);
++ DMP_URI( "SSLOCSPProxyURL", ctx->proxy_uri);
++ DMP_ON_OFF("SSLOCSPNoVerify", ctx->ocsp_noverify);
++ DMP_STRING("SSLOCSPResponderCertificateFile", ctx->ocsp_certs_file);
++
++#ifdef HAVE_SSL_CONF_CMD
++ if (ctx->ssl_ctx_param && ctx->ssl_ctx_param->nelts > 0) {
++ ssl_ctx_param_t *param = (ssl_ctx_param_t *)ctx->ssl_ctx_param->elts;
++ for (i = 0; i < ctx->ssl_ctx_param->nelts; ++i, ++param) {
++ apr_file_printf(out, "%s\n%s\"%s\": \"%s %s\"", *psep, indent,
++ "SSLOpenSSLConfCmd", json_quote(param->name, p),
++ json_quote(param->value, p));
++ *psep = ", ";
++ }
++ }
++#endif
++
++#ifdef HAVE_TLS_SESSION_TICKETS
++ if (ctx->ticket_key) {
++ DMP_STRING("SSLSessionTicketKeyFile", ctx->ticket_key->file_path);
++ }
++#endif
++ }
++ else { /* proxy */
++ if (ctx->pkp) {
++ DMP_STRING("SSLProxyMachineCertificateFile", ctx->pkp->cert_file);
++ DMP_STRING("SSLProxyMachineCertificatePath", ctx->pkp->cert_path);
++ DMP_STRING("SSLProxyMachineCertificateChainFile", ctx->pkp->ca_cert_file);
++ }
++ DMP_ON_OFF("SSLProxyCheckPeerCN", ctx->ssl_check_peer_cn);
++ DMP_ON_OFF("SSLProxyCheckPeerName", ctx->ssl_check_peer_cn);
++ DMP_ON_OFF("SSLProxyCheckPeerExpire", ctx->ssl_check_peer_expire);
++ }
++}
++
++static void ssl_srv_dump(SSLSrvConfigRec *sc, apr_pool_t *p,
++ apr_file_t *out, const char *indent, const char **psep)
++{
++ DMP_ENABLD("SSLEngine", sc->enabled);
++ DMP_ON_OFF("SSLHonorCipherOrder", sc->cipher_server_pref);
++
++#ifndef OPENSSL_NO_COMP
++ DMP_ON_OFF("SSLCompression", sc->compression);
++#endif
++
++ modssl_ctx_dump(sc->server, p, 0, out, indent, psep);
++
++ DMP_LONG( "SSLSessionCacheTimeout", sc->session_cache_timeout);
++ DMP_ON_OFF("SSLInsecureRenegotiation", sc->insecure_reneg);
++ DMP_ON_OFF("SSLStrictSNIVHostCheck", sc->strict_sni_vhost_check);
++#ifdef HAVE_FIPS
++ DMP_ON_OFF("SSLFIPS", sc->fips);
++#endif
++ DMP_ON_OFF("SSLSessionTickets", sc->session_tickets);
++ DMP_STRARR("SSLPolicy", sc->policies);
++}
++
++static void ssl_dir_dump(SSLDirConfigRec *dc, apr_pool_t *p,
++ apr_file_t *out, const char *indent, const char **psep)
++{
++ int i;
++
++ DMP_ON_OFF("SSLProxyEngine", dc->proxy_enabled);
++
++ modssl_ctx_dump(dc->proxy, p, 1, out, indent, psep);
++
++ if (dc->bSSLRequired == TRUE) {
++ DMP_ON_OFF("SSLRequireSSL", dc->bSSLRequired);
++ }
++ if (dc->aRequirement && dc->aRequirement->nelts > 0) {
++ ssl_require_t *r = (ssl_require_t *)dc->aRequirement->elts;
++ for (i = 0; i < dc->aRequirement->nelts; ++i, ++r) {
++ DMP_STRING("SSLRequire", r->cpExpr);
++ }
++ }
++ DMP_OPTION("StdEnvVars", SSL_OPT_STDENVVARS);
++ DMP_OPTION("ExportCertData", SSL_OPT_EXPORTCERTDATA);
++ DMP_OPTION("FakeBasicAuth", SSL_OPT_FAKEBASICAUTH);
++ DMP_OPTION("StrictRequire", SSL_OPT_STRICTREQUIRE);
++ DMP_OPTION("OptRenegotiate", SSL_OPT_OPTRENEGOTIATE);
++ DMP_OPTION("LegacyDNStringFormat", SSL_OPT_LEGACYDNFORMAT);
++ DMP_STRARR("SSLProxyPolicy", dc->policies);
++}
++
++static void ssl_policy_dump(SSLPolicyRec *policy, apr_pool_t *p,
++ apr_file_t *out, const char *indent)
++{
++ const char *sep = "";
++ if (policy->sc) {
++ ssl_srv_dump(policy->sc, p, out, indent, &sep);
++ }
++ if (policy->dc) {
++ ssl_dir_dump(policy->dc, p, out, indent, &sep);
++ }
++}
++
++
++
+Index: modules/ssl/ssl_engine_init.c
+===================================================================
+--- modules/ssl/ssl_engine_init.c (revision 1824437)
++++ modules/ssl/ssl_engine_init.c (working copy)
+@@ -284,6 +284,13 @@
+ sc->fips = FALSE;
+ }
+ #endif
++
++ if (sc->error_policy) {
++ rv = ssl_policy_lookup(p, sc->error_policy)? APR_EGENERAL : APR_ENOENT;
++ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO()
++ "Applying SSLPolicy '%s'", sc->error_policy);
++ return rv;
++ }
+ }
+
+ #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API
+Index: modules/ssl/ssl_policies.h
+===================================================================
+--- modules/ssl/ssl_policies.h (revision 1808335)
++++ modules/ssl/ssl_policies.h (working copy)
+@@ -65,13 +65,13 @@
+
+ #define SSL_POLICY_MOZILLA_VERSION 4.0
+
+-#ifdef HAVE_TLS1_X
++#ifdef HAVE_TLSV1_X
+ #define SSL_POLICY_MODERN 1
+ #define SSL_POLICY_MODERN_CIPHERS "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
+ #define SSL_POLICY_MODERN_PROTOCOLS SSL_PROTOCOL_TLSV1_2
+-#else /* ifdef HAVE_TLS1_X */
++#else /* ifdef HAVE_TLSV1_X */
+ #define SSL_POLICY_MODERN 0
+-#endif /* ifdef HAVE_TLS1_X, else part */
++#endif /* ifdef HAVE_TLSV1_X, else part */
+
+ #define SSL_POLICY_INTERMEDIATE 1
+ #define SSL_POLICY_INTERMEDIATE_CIPHERS "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
+Index: modules/ssl/ssl_policies.h.in
+===================================================================
+Index: modules/ssl/ssl_private.h
+===================================================================
+--- modules/ssl/ssl_private.h (revision 1824437)
++++ modules/ssl/ssl_private.h (working copy)
+@@ -596,6 +596,7 @@
+ apr_global_mutex_t *stapling_cache_mutex;
+ apr_global_mutex_t *stapling_refresh_mutex;
+ #endif
++
+ } SSLModConfigRec;
+
+ /** Structure representing configured filenames for certs and keys for
+@@ -746,6 +747,9 @@
+ BOOL compression;
+ #endif
+ BOOL session_tickets;
++
++ apr_array_header_t *policies; /* policy that shall be applied to this config */
++ const char *error_policy; /* error in policy merge, bubble up */
+ };
+
+ /**
+@@ -768,8 +772,20 @@
+ modssl_ctx_t *proxy;
+ BOOL proxy_enabled;
+ BOOL proxy_post_config;
++
++ apr_array_header_t *policies; /* policy that shall be applied to this config */
++ const char *error_policy; /* error in policy merge, bubble up */
+ };
+
++typedef struct SSLPolicyRec SSLPolicyRec;
++struct SSLPolicyRec {
++ const char *name;
++ SSLSrvConfigRec *sc;
++ SSLDirConfigRec *dc;
++};
++
++SSLPolicyRec *ssl_policy_lookup(apr_pool_t *pool, const char *name);
++
+ /**
+ * function prototypes
+ */
+@@ -787,6 +803,8 @@
+ void *ssl_config_perdir_merge(apr_pool_t *, void *, void *);
+ void ssl_config_proxy_merge(apr_pool_t *,
+ SSLDirConfigRec *, SSLDirConfigRec *);
++const char *ssl_cmd_SSLPolicyDefine(cmd_parms *, void *, const char *);
++const char *ssl_cmd_SSLPolicyApply(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
+@@ -818,6 +836,7 @@
+ const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag);
+ const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag);
+
++const char *ssl_cmd_SSLProxyPolicyApply(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
+ const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *);
+ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *, void *, const char *);
+Index: modules/ssl/update_policies.py
+===================================================================
+--- modules/ssl/update_policies.py (revision 1808335)
++++ modules/ssl/update_policies.py (working copy)
+@@ -70,7 +70,7 @@
+ # if it has a non-1_X protocol, it works without OpenSSL 1.0.2
+ if not tlsv in TLS_1_X_VERSIONS:
+ return None
+- return "HAVE_TLS1_X"
++ return "HAVE_TLSV1_X"
+
+
+ def getPolicyDef():
+Index: .
+===================================================================
+--- . (revision 1824437)
++++ . (working copy)
+
+Property changes on: .
+___________________________________________________________________
+Modified: svn:mergeinfo
+## -0,0 +0,1 ##
+ Merged /httpd/httpd/trunk:r1805182,1805186,1808335,1811475,1817381,1817894
Re: svn commit: r1824465 -
/httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
Posted by Stefan Eissing <st...@greenbytes.de>.
> Am 19.02.2018 um 10:54 schrieb Yann Ylavic <yl...@gmail.com>:
>
> On Mon, Feb 19, 2018 at 10:42 AM, Stefan Eissing
> <st...@greenbytes.de> wrote:
>> After pondering your comments and questions a bit over the weekend, I decided to
>> withdraw the backport proposal for 2.4.x. Instead, I will simplify SSLPolicy in
>> trunk and propose a backport for the next release.
>>
>> My current thinking is to get rid of "<SSLPolicyDefine>" and just introduce
>> a fixed "SSLPolicy modern|intermediate|old" which is updated from the Mozilla
>> definitions of these terms (a script for that is already in modules/ssl). This
>> will only apply to the client facing SSL properties.
>>
>> "SSLPolicy" will then just act as a normal SSL configuration directive, that
>> sets a defined number of parameters. Those parameters will get updated in our
>> releases (and by distros if they want to update a LTS version with a more secure
>> setting).
>>
>> If can be overridden by site admins, just like any other directive. The configuration
>>
>> SSLProtocol all
>> SSLPolicy modern
>>
>> would just enable TLSv1.2 (and newer), while
>>
>> SSLPolicy modern
>> SSLProtocol +TLSv1.3
>>
>> would override it.
>
> Looks good to me.
>
> The all in one defined policy is interesting still, let's take the
> time to think more about it.
> It could possibly be implemented as macros too, no?
*Anything* can be implemented as a macro... ;-)
SSLPolicy does *not* mean: "compression off, protocols x y z, ciphers blabla-256"
SSLPolicy means: "what your Apache provider considers best SSL settings for modern browsers"
If you build from source from httpd.apache.org, it is what Mozilla considers modern
at the time of our release. If you get it from a distro, it means what they think relevant.
They could update it in years to come for an Apache in their LTS line.
By doing it as a new directive, we enable good advice:
"If you have an Apache > 2.4.30, use the following to configure your https: site."
Instead of:
"If you have an Apache > 2.4.30 with the standard macro definitions included and mod_macro
enabled, use the following... Btw. do not edit the macro definitions or your settings will
no longer auto-update. But if you do, check after every update also, if the macros are still
as you want them, because your changes may also have been overwritten."
The macro approach will not work for an internet that will be 99% https: very, very soon, IMO.
Cheers, Stefan
Re: svn commit: r1824465 - /httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
Posted by Yann Ylavic <yl...@gmail.com>.
On Mon, Feb 19, 2018 at 10:42 AM, Stefan Eissing
<st...@greenbytes.de> wrote:
> After pondering your comments and questions a bit over the weekend, I decided to
> withdraw the backport proposal for 2.4.x. Instead, I will simplify SSLPolicy in
> trunk and propose a backport for the next release.
>
> My current thinking is to get rid of "<SSLPolicyDefine>" and just introduce
> a fixed "SSLPolicy modern|intermediate|old" which is updated from the Mozilla
> definitions of these terms (a script for that is already in modules/ssl). This
> will only apply to the client facing SSL properties.
>
> "SSLPolicy" will then just act as a normal SSL configuration directive, that
> sets a defined number of parameters. Those parameters will get updated in our
> releases (and by distros if they want to update a LTS version with a more secure
> setting).
>
> If can be overridden by site admins, just like any other directive. The configuration
>
> SSLProtocol all
> SSLPolicy modern
>
> would just enable TLSv1.2 (and newer), while
>
> SSLPolicy modern
> SSLProtocol +TLSv1.3
>
> would override it.
Looks good to me.
The all in one defined policy is interesting still, let's take the
time to think more about it.
It could possibly be implemented as macros too, no?
Thanks,
Yann.
Re: svn commit: r1824465 -
/httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
Posted by Stefan Eissing <st...@greenbytes.de>.
After pondering your comments and questions a bit over the weekend, I decided to
withdraw the backport proposal for 2.4.x. Instead, I will simplify SSLPolicy in
trunk and propose a backport for the next release.
My current thinking is to get rid of "<SSLPolicyDefine>" and just introduce
a fixed "SSLPolicy modern|intermediate|old" which is updated from the Mozilla
definitions of these terms (a script for that is already in modules/ssl). This
will only apply to the client facing SSL properties.
"SSLPolicy" will then just act as a normal SSL configuration directive, that
sets a defined number of parameters. Those parameters will get updated in our
releases (and by distros if they want to update a LTS version with a more secure
setting).
If can be overridden by site admins, just like any other directive. The configuration
SSLProtocol all
SSLPolicy modern
would just enable TLSv1.2 (and newer), while
SSLPolicy modern
SSLProtocol +TLSv1.3
would override it.
Cheers,
Stefan
> Am 17.02.2018 um 18:20 schrieb Stefan Eissing <st...@greenbytes.de>:
>
>>
>> Am 16.02.2018 um 17:34 schrieb Yann Ylavic <yl...@gmail.com>:
>>
>> Hi Stefan,
>>
>> On Fri, Feb 16, 2018 at 2:05 PM, <ic...@apache.org> wrote:
>>> Author: icing
>>> Date: Fri Feb 16 13:05:27 2018
>>> New Revision: 1824465
>>>
>>> URL: http://svn.apache.org/viewvc?rev=1824465&view=rev
>>> Log:
>>> sslpolicy patch for 2.4.x
>>
>> Quick incomplete/review, two question...
>
> Thanks for reviewing.
>
>> There seems to be predefined/moz policies with "SSLProxyVerify
>> require" enforced, how can it work w/o a CA? That impose also setting
>> SSLProxyCACertificate* for httpd to start/work, right?
>
> If it only works with an explicit CA file, then it should not be
> on. I think I was hoping that openssl tied into some CA vault on
> its own and a CA file was only necessary for non-public certs.
>
>> <SSLPolicyDefine> is global only, but since it's not a real
>> directory/section itself anything can nest inside (including another
>> <SSLPolicyDefine>)?
>
> Any non-SSL directive inside would not be part of it. That could
> lead to confusion, since other directives will not see the difference
> and will not complain. I am not sure if introducing new section types,
> which adds complexity in the server is worth it. We could add a section
> to the documentation that states this limitation more clearly.
>
> Also, nesting <SSLPolicyDefine> should be prevented, as it will
> not give the results that one would expect (I have not tested that,
> but I think it would behave as if the two were side by side).
>
> Cheers,
>
> Stefan
Re: svn commit: r1824465 -
/httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
Posted by Stefan Eissing <st...@greenbytes.de>.
> Am 16.02.2018 um 17:34 schrieb Yann Ylavic <yl...@gmail.com>:
>
> Hi Stefan,
>
> On Fri, Feb 16, 2018 at 2:05 PM, <ic...@apache.org> wrote:
>> Author: icing
>> Date: Fri Feb 16 13:05:27 2018
>> New Revision: 1824465
>>
>> URL: http://svn.apache.org/viewvc?rev=1824465&view=rev
>> Log:
>> sslpolicy patch for 2.4.x
>
> Quick incomplete/review, two question...
Thanks for reviewing.
> There seems to be predefined/moz policies with "SSLProxyVerify
> require" enforced, how can it work w/o a CA? That impose also setting
> SSLProxyCACertificate* for httpd to start/work, right?
If it only works with an explicit CA file, then it should not be
on. I think I was hoping that openssl tied into some CA vault on
its own and a CA file was only necessary for non-public certs.
> <SSLPolicyDefine> is global only, but since it's not a real
> directory/section itself anything can nest inside (including another
> <SSLPolicyDefine>)?
Any non-SSL directive inside would not be part of it. That could
lead to confusion, since other directives will not see the difference
and will not complain. I am not sure if introducing new section types,
which adds complexity in the server is worth it. We could add a section
to the documentation that states this limitation more clearly.
Also, nesting <SSLPolicyDefine> should be prevented, as it will
not give the results that one would expect (I have not tested that,
but I think it would behave as if the two were side by side).
Cheers,
Stefan
Re: svn commit: r1824465 - /httpd/httpd/patches/2.4.x/mod_ssl_policy.diff
Posted by Yann Ylavic <yl...@gmail.com>.
Hi Stefan,
On Fri, Feb 16, 2018 at 2:05 PM, <ic...@apache.org> wrote:
> Author: icing
> Date: Fri Feb 16 13:05:27 2018
> New Revision: 1824465
>
> URL: http://svn.apache.org/viewvc?rev=1824465&view=rev
> Log:
> sslpolicy patch for 2.4.x
Quick incomplete/review, two question...
There seems to be predefined/moz policies with "SSLProxyVerify
require" enforced, how can it work w/o a CA? That impose also setting
SSLProxyCACertificate* for httpd to start/work, right?
<SSLPolicyDefine> is global only, but since it's not a real
directory/section itself anything can nest inside (including another
<SSLPolicyDefine>)?
Thanks,
Yann.