-*- coding: utf-8 -*-
Changes with Apache 2.4.30
+ *) mod_proxy, mod_ssl: Handle SSLProxy* directives in <Proxy> sections,
+ allowing per backend TLS configuration. [Yann Ylavic]
+
*) mod_proxy_uwsgi: Add in UWSGI proxy (sub)module. [Roberto De Ioris,
Jim Jagielski]
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- *) mod_proxy, mod_ssl: Handle SSLProxy* directives in <Proxy> sections,
- allowing per backend TLS configuration.
- trunk patch: http://svn.apache.org/r1740928
- http://svn.apache.org/r1740960
- http://svn.apache.org/r1740967
- http://svn.apache.org/r1740987
- http://svn.apache.org/r1740998
- http://svn.apache.org/r1742697
- http://svn.apache.org/r1756976
- http://svn.apache.org/r1781313
- http://svn.apache.org/r1812193
- 2.4.x patch: https://svn.apache.org/repos/asf/httpd/httpd/patches/2.4.x/httpd-2.4.x-r1740928_and_co-v6.patch
- +1: ylavic, icing, minfrin
-
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
[ New proposals should be added at the end of the list ]
<name>SSLProxyMachineCertificatePath</name>
<description>Directory of PEM-encoded client certificates and keys to be used by the proxy</description>
<syntax>SSLProxyMachineCertificatePath <em>directory</em></syntax>
-<contextlist><context>server config</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
<usage>
<p>
<name>SSLProxyMachineCertificateFile</name>
<description>File of concatenated PEM-encoded client certificates and keys to be used by the proxy</description>
<syntax>SSLProxyMachineCertificateFile <em>filename</em></syntax>
-<contextlist><context>server config</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
<usage>
<p>
<name>SSLProxyMachineCertificateChainFile</name>
<description>File of concatenated PEM-encoded CA certificates to be used by the proxy for choosing a certificate</description>
<syntax>SSLProxyMachineCertificateChainFile <em>filename</em></syntax>
-<contextlist><context>server config</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
<usage>
<p>
<description>Type of remote server Certificate verification</description>
<syntax>SSLProxyVerify <em>level</em></syntax>
<default>SSLProxyVerify none</default>
-<contextlist><context>server config</context>
-<context>virtual host</context> </contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
Certificate verification</description>
<syntax>SSLProxyVerifyDepth <em>number</em></syntax>
<default>SSLProxyVerifyDepth 1</default>
-<contextlist><context>server config</context>
-<context>virtual host</context> </contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
</description>
<syntax>SSLProxyCheckPeerExpire on|off</syntax>
<default>SSLProxyCheckPeerExpire on</default>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
</description>
<syntax>SSLProxyCheckPeerCN on|off</syntax>
<default>SSLProxyCheckPeerCN on</default>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
</description>
<syntax>SSLProxyCheckPeerName on|off</syntax>
<default>SSLProxyCheckPeerName on</default>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<compatibility>Apache HTTP Server 2.4.5 and later</compatibility>
<usage>
<description>SSL Proxy Engine Operation Switch</description>
<syntax>SSLProxyEngine on|off</syntax>
<default>SSLProxyEngine off</default>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
<description>Configure usable SSL protocol flavors for proxy usage</description>
<syntax>SSLProxyProtocol [+|-]<em>protocol</em> ...</syntax>
<default>SSLProxyProtocol all -SSLv3 (up to 2.4.16: all)</default>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
-<override>Options</override>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<!-- XXX Why does this have an override and not .htaccess context? -->
proxy handshake</description>
<syntax>SSLProxyCipherSuite <em>cipher-spec</em></syntax>
<default>SSLProxyCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP</default>
-<contextlist><context>server config</context>
-<context>virtual host</context>
-<context>directory</context>
-<context>.htaccess</context></contextlist>
-<override>AuthConfig</override>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
+
<usage>
<p>Equivalent to <directive module="mod_ssl">SSLCipherSuite</directive>, but
for the proxy connection.
<description>Directory of PEM-encoded CA Certificates for
Remote Server Auth</description>
<syntax>SSLProxyCACertificatePath <em>directory-path</em></syntax>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
<description>File of concatenated PEM-encoded CA Certificates
for Remote Server Auth</description>
<syntax>SSLProxyCACertificateFile <em>file-path</em></syntax>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
<description>Directory of PEM-encoded CA CRLs for
Remote Server Auth</description>
<syntax>SSLProxyCARevocationPath <em>directory-path</em></syntax>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
<description>File of concatenated PEM-encoded CA CRLs for
Remote Server Auth</description>
<syntax>SSLProxyCARevocationFile <em>file-path</em></syntax>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
<description>Enable CRL-based revocation checking for Remote Server Auth</description>
<syntax>SSLProxyCARevocationCheck chain|leaf|none</syntax>
<default>SSLProxyCARevocationCheck none</default>
-<contextlist><context>server config</context>
-<context>virtual host</context></contextlist>
+<contextlist><context>server config</context> <context>virtual host</context>
+<context>proxy section</context></contextlist>
+<override>Not applicable</override>
<usage>
<p>
<message id="virtualhost" letter="v">virtual host</message>
<message id="directory" letter="d">directory</message>
<message id="htaccess" letter="h">.htaccess</message>
+ <message id="proxy" letter="p">proxy section</message>
<!-- Used for directive lists -->
<message id="directives">Directives</message>
[normalize-space(.)='.htaccess']">
<xsl:value-of select="$message[@id='htaccess']/@letter"/>
</xsl:if>
+ <xsl:if test="contextlist/context
+ [normalize-space(.)='proxy section']">
+ <xsl:value-of select="$message[@id='proxy']/@letter"/>
+ </xsl:if>
<xsl:text>&</xsl:text>
<xsl:variable name="status" select="translate(
<xsl:when test="normalize-space(.) = '.htaccess'">
<xsl:value-of select="$message[@id='htaccess']" />
</xsl:when>
+<xsl:when test="normalize-space(.) = 'proxy section'">
+ <xsl:value-of select="$message[@id='proxy']" />
+</xsl:when>
<xsl:otherwise> <!-- error -->
<xsl:message terminate="yes">
unknown context: <xsl:value-of select="." />
select="$message[@id='htaccess']"/>
</td>
</tr>&lf;
+ <tr>
+ <th>
+ <xsl:value-of
+ select="$message[@id='proxy']/@letter"/>
+ </th>
+ <td>
+ <xsl:value-of
+ select="$message[@id='proxy']"/>
+ </td>
+ </tr>&lf;
</table>
</td>&lf;
<td>
[normalize-space(.)='.htaccess']">
<xsl:value-of select="$message[@id='htaccess']/@letter"/>
</xsl:if>
+ <xsl:if test="$directive/contextlist/context
+ [normalize-space(.)='proxy section']">
+ <xsl:value-of select="$message[@id='proxy']/@letter"/>
+ </xsl:if>
</td>
<td>
<xsl:choose>
<xsl:when test="normalize-space(.) = '.htaccess'">
<xsl:value-of select="$message[@id='htaccess']" />
</xsl:when>
+<xsl:when test="normalize-space(.) = 'proxy section'">
+ <xsl:value-of select="$message[@id='proxy']" />
+</xsl:when>
<xsl:otherwise> <!-- error -->
<xsl:message terminate="yes">
unknown context: <xsl:value-of select="." />
* 20120211.69 (2.4.30-dev) Add ap_update_sb_handle()
* 20120211.70 (2.4.30-dev) Add flags field to module_struct and function
* ap_get_module_flags()
+ * 20120211.71 (2.4.30-dev) Add optional proxy_{hook,run}_section_post_config(),
+ * ap_proxy_connection_create_ex() and section_config
+ * to struct proxy_{worker,balancer} in mod_proxy.h,
+ * and optional ssl_engine_set() to mod_ssl.h.
+ * 20120211.72 (2.4.30-dev) Add NOT_IN_DIR_CONTEXT replacing NOT_IN_DIR_LOC_FILE
+ * semantics
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20120211
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 70 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 72 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
#define NONFATAL_UNKNOWN 1024 /* Unrecognised directive */
#define NONFATAL_ALL (NONFATAL_OVERRIDE|NONFATAL_UNKNOWN)
+#define PROXY_CONF 2048 /**< *.conf inside <Proxy> only */
+
/** this directive can be placed anywhere */
#define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)
#define NOT_IN_LOCATION 0x08 /**< Forbidden in <Location> */
#define NOT_IN_FILES 0x10 /**< Forbidden in <Files> or <If>*/
#define NOT_IN_HTACCESS 0x20 /**< Forbidden in .htaccess files */
+#define NOT_IN_PROXY 0x40 /**< Forbidden in <Proxy> */
/** Forbidden in <Directory>/<Location>/<Files><If>*/
#define NOT_IN_DIR_LOC_FILE (NOT_IN_DIRECTORY|NOT_IN_LOCATION|NOT_IN_FILES)
-/** Forbidden in <VirtualHost>/<Limit>/<Directory>/<Location>/<Files>/<If> */
-#define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE)
+/** Forbidden in <Directory>/<Location>/<Files><If><Proxy>*/
+#define NOT_IN_DIR_CONTEXT (NOT_IN_LIMIT|NOT_IN_DIR_LOC_FILE|NOT_IN_PROXY)
+/** Forbidden in <VirtualHost>/<Limit>/<Directory>/<Location>/<Files>/<If><Proxy>*/
+#define GLOBAL_ONLY (NOT_IN_VIRTUALHOST|NOT_IN_DIR_CONTEXT)
/** @} */
const char *uid, const char *gid)
{
suexec_config_t *cfg = (suexec_config_t *) mconfig;
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
const char *arg)
{
apr_interval_time_t timeout;
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
static const char *set_keep_alive(cmd_parms *cmd, void *dummy,
int arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
static const char *set_keep_alive_max(cmd_parms *cmd, void *dummy,
const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
/*******************************************************************************
* The optional mod_ssl functions we need.
*/
-static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *opt_ssl_engine_disable;
static APR_OPTIONAL_FN_TYPE(ssl_is_https) *opt_ssl_is_https;
static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *opt_ssl_var_lookup;
{
(void)pool;
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, "h2_h2, child_init");
- opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
/* Step Three: Create conn_rec for the socket we have open now. */
if (!ctx->p_conn->connection) {
- if ((status = ap_proxy_connection_create(ctx->proxy_func, ctx->p_conn,
- ctx->owner,
- ctx->server)) != OK) {
+ status = ap_proxy_connection_create_ex(ctx->proxy_func,
+ ctx->p_conn, ctx->rbase);
+ if (status != OK) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, ctx->owner, APLOGNO(03353)
"setup new connection: is_ssl=%d %s %s %s",
ctx->p_conn->is_ssl, ctx->p_conn->ssl_hostname,
/* XXX: real can NOT be relative to DocumentRoot here... compat bug. */
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
#else
APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
+APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *,
+ ap_conf_vector_t *,
+ int proxy, int enable));
APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
(apr_pool_t *, server_rec *,
{
proxy_server_conf *sconf = ap_get_module_config(r->server->module_config,
&proxy_module);
- ap_conf_vector_t *per_dir_defaults = r->server->lookup_defaults;
+ ap_conf_vector_t *per_dir_defaults = r->per_dir_config;
ap_conf_vector_t **sec_proxy = (ap_conf_vector_t **) sconf->sec_proxy->elts;
ap_conf_vector_t *entry_config;
proxy_dir_conf *entry_proxy;
"Sharing worker '%s' instead of creating new worker '%s'",
ap_proxy_worker_name(cmd->pool, worker), name);
}
+ if (!worker->section_config) {
+ worker->section_config = balancer->section_config;
+ }
arr = apr_table_elts(params);
elts = (const apr_table_entry_t *)arr->elts;
proxy_balancer *balancer = NULL;
proxy_worker *worker = NULL;
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
proxy_server_conf *sconf =
(proxy_server_conf *) ap_get_module_config(cmd->server->module_config, &proxy_module);
}
cmd->path = ap_getword_conf(cmd->pool, &arg);
- cmd->override = OR_ALL|ACCESS_CONF;
+ cmd->override = OR_ALL|ACCESS_CONF|PROXY_CONF;
if (!strncasecmp(cmd->path, "proxy:", 6))
cmd->path += 6;
return apr_pstrcat(cmd->temp_pool, thiscmd->name,
" ", err, NULL);
}
+ if (!balancer->section_config) {
+ balancer->section_config = new_dir_conf;
+ }
}
else {
worker = ap_proxy_get_worker(cmd->temp_pool, NULL, sconf,
return apr_pstrcat(cmd->temp_pool, thiscmd->name,
" ", err, NULL);
}
+ if (!worker->section_config) {
+ worker->section_config = new_dir_conf;
+ }
}
if (worker == NULL && balancer == NULL) {
return apr_pstrcat(cmd->pool, thiscmd->name,
static APR_OPTIONAL_FN_TYPE(ssl_proxy_enable) *proxy_ssl_enable = NULL;
static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *proxy_ssl_disable = NULL;
+static APR_OPTIONAL_FN_TYPE(ssl_engine_set) *proxy_ssl_engine = NULL;
static APR_OPTIONAL_FN_TYPE(ssl_is_https) *proxy_is_https = NULL;
static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *proxy_ssl_val = NULL;
return 0;
}
+PROXY_DECLARE(int) ap_proxy_ssl_engine(conn_rec *c,
+ ap_conf_vector_t *per_dir_config,
+ int enable)
+{
+ /*
+ * if c == NULL just check if the optional function was imported
+ * else run the optional function so ssl filters are inserted
+ */
+ if (proxy_ssl_engine) {
+ return c ? proxy_ssl_engine(c, per_dir_config, 1, enable) : 1;
+ }
+
+ if (!per_dir_config) {
+ if (enable) {
+ return ap_proxy_ssl_enable(c);
+ }
+ else {
+ return ap_proxy_ssl_disable(c);
+ }
+ }
+
+ return 0;
+}
+
PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c)
{
if (proxy_is_https) {
}
static int proxy_post_config(apr_pool_t *pconf, apr_pool_t *plog,
- apr_pool_t *ptemp, server_rec *s)
+ apr_pool_t *ptemp, server_rec *main_s)
{
+ server_rec *s = main_s;
apr_status_t rv = ap_global_mutex_create(&proxy_mutex, NULL,
- proxy_id, NULL, s, pconf, 0);
+ proxy_id, NULL, s, pconf, 0);
if (rv != APR_SUCCESS) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, plog, APLOGNO(02478)
"failed to create %s mutex", proxy_id);
proxy_ssl_enable = APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable);
proxy_ssl_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
+ proxy_ssl_engine = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_set);
proxy_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
proxy_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
ap_proxy_strmatch_path = apr_strmatch_precompile(pconf, "path=", 0);
ap_proxy_strmatch_domain = apr_strmatch_precompile(pconf, "domain=", 0);
+ for (; s; s = s->next) {
+ int rc, i;
+ proxy_server_conf *sconf =
+ ap_get_module_config(s->module_config, &proxy_module);
+ ap_conf_vector_t **sections =
+ (ap_conf_vector_t **)sconf->sec_proxy->elts;
+
+ for (i = 0; i < sconf->sec_proxy->nelts; ++i) {
+ rc = proxy_run_section_post_config(pconf, ptemp, plog,
+ s, sections[i]);
+ if (rc != OK && rc != DECLINED) {
+ return rc;
+ }
+ }
+ }
+
return OK;
}
request_rec *r,
proxy_server_conf *conf),(worker,
balancer,r,conf),DECLINED)
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, section_post_config,
+ (apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s,
+ ap_conf_vector_t *section_config),
+ (p, ptemp, plog, s, section_config),
+ OK, DECLINED)
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(proxy, PROXY, int, fixups,
(request_rec *r), (r),
OK, DECLINED)
proxy_balancer *balancer; /* which balancer am I in? */
apr_thread_mutex_t *tmutex; /* Thread lock for updating address cache */
void *context; /* general purpose storage */
+ ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */
};
/* default to health check every 30 seconds */
void *context; /* general purpose storage */
proxy_balancer_shared *s; /* Shared data */
int failontimeout; /* Whether to mark a member in Err if IO timeout occurs */
+ ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */
};
struct proxy_balancer_method {
(apr_pool_t *, server_rec *, proxy_worker *,
const char *, const char *, void *));
-APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r,
- proxy_worker *worker, proxy_server_conf *conf, char *url,
- const char *proxyhost, apr_port_t proxyport))
-APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r,
- char *url))
+APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, section_post_config,
+ (apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s,
+ ap_conf_vector_t *section_config))
+
+APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler,
+ (request_rec *r, proxy_worker *worker,
+ proxy_server_conf *conf, char *url,
+ const char *proxyhost, apr_port_t proxyport))
+APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler,
+ (request_rec *r, char *url))
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, create_req, (request_rec *r, request_rec *pr))
APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, fixups, (request_rec *r))
+
/**
* pre request hook.
* It will return the most suitable worker at the moment
request_rec *r);
PROXY_DECLARE(int) ap_proxy_ssl_enable(conn_rec *c);
PROXY_DECLARE(int) ap_proxy_ssl_disable(conn_rec *c);
+PROXY_DECLARE(int) ap_proxy_ssl_engine(conn_rec *c,
+ ap_conf_vector_t *per_dir_config,
+ int enable);
PROXY_DECLARE(int) ap_proxy_conn_is_https(conn_rec *c);
PROXY_DECLARE(const char *) ap_proxy_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *var);
* Make a connection record for backend connection
* @param proxy_function calling proxy scheme (http, ajp, ...)
* @param conn acquired connection
- * @param c client connection record
+ * @param c client connection record (unused, deprecated)
* @param s current server record
* @return OK or HTTP_XXX error
* @note The function will return immediately if conn->connection
proxy_conn_rec *conn,
conn_rec *c, server_rec *s);
+/**
+ * Make a connection record for backend connection, using request dir config
+ * @param proxy_function calling proxy scheme (http, ajp, ...)
+ * @param conn acquired connection
+ * @param r current request record
+ * @return OK or HTTP_XXX error
+ * @note The function will return immediately if conn->connection
+ * is already set,
+ */
+PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function,
+ proxy_conn_rec *conn,
+ request_rec *r);
/**
* Determine if proxy connection can potentially be reused at the
* end of this request.
apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
- ap_proxy_ssl_disable(backconn);
+ ap_proxy_ssl_engine(backconn, r->per_dir_config, 0);
rc = ap_run_pre_connection(backconn, sock);
if (rc != OK && rc != DONE) {
backconn->aborted = 1;
}
if (!backend->connection) {
- status = ap_proxy_connection_create("FTP", backend, c, r->server);
+ status = ap_proxy_connection_create_ex("FTP", backend, r);
if (status != OK) {
proxy_ftp_cleanup(r, backend);
return status;
* We do not do SSL over the data connection, even if the virtual host we
* are in might have SSL enabled
*/
- ap_proxy_ssl_disable(data);
+ ap_proxy_ssl_engine(data, r->per_dir_config, 0);
/* set up the connection filters */
rc = ap_run_pre_connection(data, data_sock);
if (rc != OK && rc != DONE) {
/* Step Three: Create conn_rec */
if (!backend->connection) {
- if ((status = ap_proxy_connection_create(proxy_function, backend,
- c, r->server)) != OK)
+ if ((status = ap_proxy_connection_create_ex(proxy_function,
+ backend, r)) != OK)
break;
/*
* On SSL connections set a note on the connection what CN is
proxy_conn_rec *backend = NULL;
char *scheme;
int retry;
- conn_rec *c = r->connection;
apr_pool_t *p = r->pool;
apr_uri_t *uri;
int is_ssl = 0;
status = HTTP_SERVICE_UNAVAILABLE;
break;
}
+
/* Step Three: Create conn_rec */
if (!backend->connection) {
- if ((status = ap_proxy_connection_create(scheme, backend,
- c, r->server)) != OK)
+ status = ap_proxy_connection_create_ex(scheme, backend, r);
+ if (status != OK) {
break;
+ }
}
backend->close = 1; /* must be after ap_proxy_determine_connection */
}
-PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
- proxy_conn_rec *conn,
- conn_rec *c,
- server_rec *s)
+static int proxy_connection_create(const char *proxy_function,
+ proxy_conn_rec *conn,
+ request_rec *r, server_rec *s)
{
+ ap_conf_vector_t *per_dir_config = (r) ? r->per_dir_config
+ : conn->worker->section_config;
apr_sockaddr_t *backend_addr = conn->addr;
int rc;
apr_interval_time_t current_timeout;
/* For ssl connection to backend */
if (conn->is_ssl) {
- if (!ap_proxy_ssl_enable(conn->connection)) {
+ if (!ap_proxy_ssl_engine(conn->connection, per_dir_config, 1)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0,
s, APLOGNO(00961) "%s: failed to enable ssl support "
"for %pI (%s)", proxy_function,
}
else {
/* TODO: See if this will break FTP */
- ap_proxy_ssl_disable(conn->connection);
+ ap_proxy_ssl_engine(conn->connection, per_dir_config, 0);
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00962)
return OK;
}
+PROXY_DECLARE(int) ap_proxy_connection_create_ex(const char *proxy_function,
+ proxy_conn_rec *conn,
+ request_rec *r)
+{
+ return proxy_connection_create(proxy_function, conn, r, r->server);
+}
+
+PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
+ proxy_conn_rec *conn,
+ conn_rec *c, server_rec *s)
+{
+ (void) c; /* unused */
+ return proxy_connection_create(proxy_function, conn, NULL, s);
+}
+
int ap_proxy_lb_workers(void)
{
/*
#include "ap_provider.h"
#include "http_config.h"
+#include "mod_proxy.h" /* for proxy_hook_section_post_config() */
+
#include <assert.h>
static int modssl_running_statically = 0;
AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
NULL, RSRC_CONF, desc),
+#define SSL_CMD_PXY(name, args, desc) \
+ AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
+ NULL, RSRC_CONF|PROXY_CONF, desc),
+
#define SSL_CMD_DIR(name, type, args, desc) \
AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
NULL, OR_##type, desc),
/*
* Proxy configuration for remote SSL connections
*/
- SSL_CMD_SRV(ProxyEngine, FLAG,
+ SSL_CMD_PXY(ProxyEngine, FLAG,
"SSL switch for the proxy protocol engine "
"('on', 'off')")
- SSL_CMD_SRV(ProxyProtocol, RAW_ARGS,
+ SSL_CMD_PXY(ProxyProtocol, RAW_ARGS,
"SSL Proxy: enable or disable SSL protocol flavors "
"('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
- SSL_CMD_SRV(ProxyCipherSuite, TAKE1,
+ SSL_CMD_PXY(ProxyCipherSuite, TAKE1,
"SSL Proxy: colon-delimited list of permitted SSL ciphers "
"('XXX:...:XXX' - see manual)")
- SSL_CMD_SRV(ProxyVerify, TAKE1,
+ SSL_CMD_PXY(ProxyVerify, TAKE1,
"SSL Proxy: whether to verify the remote certificate "
"('on' or 'off')")
- SSL_CMD_SRV(ProxyVerifyDepth, TAKE1,
+ SSL_CMD_PXY(ProxyVerifyDepth, TAKE1,
"SSL Proxy: maximum certificate verification depth "
"('N' - number of intermediate certificates)")
- SSL_CMD_SRV(ProxyCACertificateFile, TAKE1,
+ SSL_CMD_PXY(ProxyCACertificateFile, TAKE1,
"SSL Proxy: file containing server certificates "
"('/path/to/file' - PEM encoded certificates)")
- SSL_CMD_SRV(ProxyCACertificatePath, TAKE1,
+ SSL_CMD_PXY(ProxyCACertificatePath, TAKE1,
"SSL Proxy: directory containing server certificates "
"('/path/to/dir' - contains PEM encoded certificates)")
- SSL_CMD_SRV(ProxyCARevocationPath, TAKE1,
+ SSL_CMD_PXY(ProxyCARevocationPath, TAKE1,
"SSL Proxy: CA Certificate Revocation List (CRL) path "
"('/path/to/dir' - contains PEM encoded files)")
- SSL_CMD_SRV(ProxyCARevocationFile, TAKE1,
+ SSL_CMD_PXY(ProxyCARevocationFile, TAKE1,
"SSL Proxy: CA Certificate Revocation List (CRL) file "
"('/path/to/file' - PEM encoded)")
- SSL_CMD_SRV(ProxyCARevocationCheck, RAW_ARGS,
+ SSL_CMD_PXY(ProxyCARevocationCheck, RAW_ARGS,
"SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
- SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1,
+ SSL_CMD_PXY(ProxyMachineCertificateFile, TAKE1,
"SSL Proxy: file containing client certificates "
"('/path/to/file' - PEM encoded certificates)")
- SSL_CMD_SRV(ProxyMachineCertificatePath, TAKE1,
+ SSL_CMD_PXY(ProxyMachineCertificatePath, TAKE1,
"SSL Proxy: directory containing client certificates "
"('/path/to/dir' - contains PEM encoded certificates)")
- SSL_CMD_SRV(ProxyMachineCertificateChainFile, TAKE1,
+ SSL_CMD_PXY(ProxyMachineCertificateChainFile, TAKE1,
"SSL Proxy: file containing issuing certificates "
"of the client certificate "
"(`/path/to/file' - PEM encoded certificates)")
- SSL_CMD_SRV(ProxyCheckPeerExpire, FLAG,
+ SSL_CMD_PXY(ProxyCheckPeerExpire, FLAG,
"SSL Proxy: check the peer certificate's expiration date")
- SSL_CMD_SRV(ProxyCheckPeerCN, FLAG,
+ SSL_CMD_PXY(ProxyCheckPeerCN, FLAG,
"SSL Proxy: check the peer certificate's CN")
- SSL_CMD_SRV(ProxyCheckPeerName, FLAG,
+ SSL_CMD_PXY(ProxyCheckPeerName, FLAG,
"SSL Proxy: check the peer certificate's name "
"(must be present in subjectAltName extension or CN")
return OK;
}
-static SSLConnRec *ssl_init_connection_ctx(conn_rec *c)
+static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
+ ap_conf_vector_t *per_dir_config)
{
SSLConnRec *sslconn = myConnConfig(c);
SSLSrvConfigRec *sc;
sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
+ if (per_dir_config) {
+ sslconn->dc = ap_get_module_config(per_dir_config, &ssl_module);
+ }
+ else {
+ sslconn->dc = ap_get_module_config(c->base_server->lookup_defaults,
+ &ssl_module);
+ }
+
sslconn->server = c->base_server;
sslconn->verify_depth = UNSET;
sc = mySrvConfig(c->base_server);
return sslconn;
}
-int ssl_proxy_enable(conn_rec *c)
+static int ssl_engine_status(conn_rec *c, SSLConnRec *sslconn)
{
- SSLSrvConfigRec *sc;
-
- SSLConnRec *sslconn = ssl_init_connection_ctx(c);
- sc = mySrvConfig(sslconn->server);
-
- if (!sc->proxy_enabled) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01961)
- "SSL Proxy requested for %s but not enabled "
- "[Hint: SSLProxyEngine]", sc->vhost_id);
-
- return 0;
+ if (c->master) {
+ return DECLINED;
}
-
- sslconn->is_proxy = 1;
- sslconn->disabled = 0;
-
- return 1;
+ if (sslconn) {
+ if (sslconn->disabled) {
+ return SUSPENDED;
+ }
+ if (sslconn->is_proxy) {
+ if (!sslconn->dc->proxy_enabled) {
+ return DECLINED;
+ }
+ }
+ else {
+ if (mySrvConfig(sslconn->server)->enabled != SSL_ENABLED_TRUE) {
+ return DECLINED;
+ }
+ }
+ }
+ else {
+ if (mySrvConfig(c->base_server)->enabled != SSL_ENABLED_TRUE) {
+ return DECLINED;
+ }
+ }
+ return OK;
}
-int ssl_engine_disable(conn_rec *c)
+static int ssl_engine_set(conn_rec *c,
+ ap_conf_vector_t *per_dir_config,
+ int proxy, int enable)
{
- SSLSrvConfigRec *sc;
-
- SSLConnRec *sslconn = myConnConfig(c);
-
- if (sslconn) {
- sc = mySrvConfig(sslconn->server);
+ SSLConnRec *sslconn;
+ int status;
+
+ if (proxy) {
+ sslconn = ssl_init_connection_ctx(c, per_dir_config);
+ sslconn->is_proxy = 1;
}
else {
- sc = mySrvConfig(c->base_server);
+ sslconn = myConnConfig(c);
}
- if (sc->enabled == SSL_ENABLED_FALSE) {
- return 0;
+
+ status = ssl_engine_status(c, sslconn);
+
+ if (proxy && status == DECLINED) {
+ if (enable) {
+ SSLSrvConfigRec *sc = mySrvConfig(sslconn->server);
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01961)
+ "SSL Proxy requested for %s but not enabled "
+ "[Hint: SSLProxyEngine]", sc->vhost_id);
+ }
+ sslconn->disabled = 1;
+ }
+ else if (sslconn) {
+ sslconn->disabled = !enable;
}
- sslconn = ssl_init_connection_ctx(c);
+ return status != DECLINED;
+}
- sslconn->disabled = 1;
+static int ssl_proxy_enable(conn_rec *c)
+{
+ return ssl_engine_set(c, NULL, 1, 1);
+}
- return 1;
+static int ssl_engine_disable(conn_rec *c)
+{
+ return ssl_engine_set(c, NULL, 0, 0);
}
int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
{
SSLSrvConfigRec *sc;
SSL *ssl;
- SSLConnRec *sslconn = myConnConfig(c);
+ SSLConnRec *sslconn;
char *vhost_md5;
int rc;
modssl_ctx_t *mctx;
server_rec *server;
- if (!sslconn) {
- sslconn = ssl_init_connection_ctx(c);
- }
+ /*
+ * Create or retrieve SSL context
+ */
+ sslconn = ssl_init_connection_ctx(c, r ? r->per_dir_config : NULL);
server = sslconn->server;
sc = mySrvConfig(server);
/*
* Seed the Pseudo Random Number Generator (PRNG)
*/
- ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT, "");
+ ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT,
+ sslconn->is_proxy ? "Proxy: " : "Server: ");
- mctx = sslconn->is_proxy ? sc->proxy : sc->server;
+ mctx = myCtxConfig(sslconn, sc);
/*
* Create a new SSL connection with the configured server SSL context and
static int ssl_hook_pre_connection(conn_rec *c, void *csd)
{
-
SSLSrvConfigRec *sc;
SSLConnRec *sslconn = myConnConfig(c);
- if (sslconn) {
- sc = mySrvConfig(sslconn->server);
- }
- else {
- sc = mySrvConfig(c->base_server);
- }
/*
* Immediately stop processing if SSL is disabled for this connection
*/
- if (c->master || !(sc && (sc->enabled == SSL_ENABLED_TRUE ||
- (sslconn && sslconn->is_proxy))))
- {
+ if (ssl_engine_status(c, sslconn) != OK) {
return DECLINED;
}
- /*
- * Create SSL context
- */
- if (!sslconn) {
- sslconn = ssl_init_connection_ctx(c);
+ if (sslconn) {
+ sc = mySrvConfig(sslconn->server);
}
-
- if (sslconn->disabled) {
- return DECLINED;
+ else {
+ sc = mySrvConfig(c->base_server);
}
/*
/* ssl_hook_ReadReq needs to use the BrowserMatch settings so must
* run after mod_setenvif's post_read_request hook. */
static const char *pre_prr[] = { "mod_setenvif.c", NULL };
+ /* The ssl_init_Module post_config hook should run before mod_proxy's
+ * for the ssl proxy main configs to be merged with vhosts' before being
+ * themselves merged with mod_proxy's in proxy_hook_section_post_config.
+ */
+ static const char *b_pc[] = { "mod_proxy.c", NULL};
+
ssl_io_filter_register(p);
ap_hook_process_connection(ssl_hook_process_connection,
NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_test_config (ssl_hook_ConfigTest, NULL,NULL, APR_HOOK_MIDDLE);
- ap_hook_post_config (ssl_init_Module, NULL,NULL, APR_HOOK_MIDDLE);
+ ap_hook_post_config (ssl_init_Module, NULL,b_pc, APR_HOOK_MIDDLE);
ap_hook_http_scheme (ssl_hook_http_scheme, NULL,NULL, APR_HOOK_MIDDLE);
ap_hook_default_port (ssl_hook_default_port, NULL,NULL, APR_HOOK_MIDDLE);
ap_hook_pre_config (ssl_hook_pre_config, NULL,NULL, APR_HOOK_MIDDLE);
AP_AUTH_INTERNAL_PER_CONF);
ap_hook_post_read_request(ssl_hook_ReadReq, pre_prr,NULL, APR_HOOK_MIDDLE);
+ APR_OPTIONAL_HOOK(proxy, section_post_config,
+ ssl_proxy_section_post_config, NULL, NULL,
+ APR_HOOK_MIDDLE);
+
ssl_var_register(p);
APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
+ APR_REGISTER_OPTIONAL_FN(ssl_engine_set);
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
AUTHZ_PROVIDER_VERSION,
AUTHZ_PROVIDER_VERSION,
&ssl_authz_provider_verify_client,
AP_AUTH_INTERNAL_PER_CONF);
-
}
module AP_MODULE_DECLARE_DATA ssl_module = {
#define __MOD_SSL_H__
#include "httpd.h"
+#include "http_config.h"
#include "apr_optional.h"
/* Create a set of SSL_DECLARE(type), SSL_DECLARE_NONSTD(type) and
* is using SSL/TLS. */
APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
-/** The ssl_proxy_enable() and ssl_engine_disable() optional functions
- * are used by mod_proxy to enable use of SSL for outgoing
+/** The ssl_proxy_enable() and ssl_engine_{set,disable}() optional
+ * functions are used by mod_proxy to enable use of SSL for outgoing
* connections. */
APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
-
APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
+APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *,
+ ap_conf_vector_t *,
+ int proxy, int enable));
#endif /* __MOD_SSL_H__ */
/** @} */
SSL_CONF_CTX_set_flags(mctx->ssl_ctx_config, SSL_CONF_FLAG_CERTIFICATE);
mctx->ssl_ctx_param = apr_array_make(p, 5, sizeof(ssl_ctx_param_t));
#endif
-}
-
-static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
- apr_pool_t *p)
-{
- modssl_ctx_t *mctx;
-
- mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy));
-
- modssl_ctx_init(mctx, p);
-
- mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
- mctx->pkp->cert_file = NULL;
- mctx->pkp->cert_path = NULL;
- mctx->pkp->ca_cert_file = NULL;
- mctx->pkp->certs = NULL;
- mctx->pkp->ca_certs = NULL;
+ mctx->ssl_check_peer_cn = UNSET;
+ mctx->ssl_check_peer_name = UNSET;
+ mctx->ssl_check_peer_expire = UNSET;
}
static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
sc->mc = NULL;
sc->enabled = SSL_ENABLED_UNSET;
- sc->proxy_enabled = UNSET;
sc->vhost_id = NULL; /* set during module init */
sc->vhost_id_len = 0; /* set during module init */
sc->session_cache_timeout = UNSET;
sc->cipher_server_pref = UNSET;
sc->insecure_reneg = UNSET;
- sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET;
- sc->proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET;
- sc->proxy_ssl_check_peer_name = SSL_ENABLED_UNSET;
#ifdef HAVE_TLSEXT
sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
#endif
#endif
sc->session_tickets = UNSET;
- modssl_ctx_init_proxy(sc, p);
-
modssl_ctx_init_server(sc, p);
return sc;
#define cfgMergeBool(el) cfgMerge(el, UNSET)
#define cfgMergeInt(el) cfgMerge(el, UNSET)
+/*
+ * Merge per-server SSL configurations
+ */
+
static void modssl_ctx_cfg_merge(apr_pool_t *p,
modssl_ctx_t *base,
modssl_ctx_t *add,
#ifdef HAVE_SSL_CONF_CMD
cfgMergeArray(ssl_ctx_param);
#endif
-}
-static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p,
- modssl_ctx_t *base,
- modssl_ctx_t *add,
- modssl_ctx_t *mrg)
-{
- modssl_ctx_cfg_merge(p, base, add, mrg);
-
- cfgMergeString(pkp->cert_file);
- cfgMergeString(pkp->cert_path);
- cfgMergeString(pkp->ca_cert_file);
+ cfgMergeBool(ssl_check_peer_cn);
+ cfgMergeBool(ssl_check_peer_name);
+ cfgMergeBool(ssl_check_peer_expire);
}
static void modssl_ctx_cfg_merge_certkeys_array(apr_pool_t *p,
#endif
}
-/*
- * Merge per-server SSL configurations
- */
void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
{
SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
cfgMerge(mc, NULL);
cfgMerge(enabled, SSL_ENABLED_UNSET);
- cfgMergeBool(proxy_enabled);
cfgMergeInt(session_cache_timeout);
cfgMergeBool(cipher_server_pref);
cfgMergeBool(insecure_reneg);
- cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET);
- cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET);
- cfgMerge(proxy_ssl_check_peer_name, SSL_ENABLED_UNSET);
#ifdef HAVE_TLSEXT
cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
#endif
#endif
cfgMergeBool(session_tickets);
- modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy);
-
modssl_ctx_cfg_merge_server(p, base->server, add->server, mrg->server);
return mrg;
/*
* Create per-directory SSL configuration
*/
+
+static void modssl_ctx_init_proxy(SSLDirConfigRec *dc,
+ apr_pool_t *p)
+{
+ modssl_ctx_t *mctx;
+
+ mctx = dc->proxy = apr_palloc(p, sizeof(*dc->proxy));
+
+ modssl_ctx_init(mctx, p);
+
+ mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
+
+ mctx->pkp->cert_file = NULL;
+ mctx->pkp->cert_path = NULL;
+ mctx->pkp->ca_cert_file = NULL;
+ mctx->pkp->certs = NULL;
+ mctx->pkp->ca_certs = NULL;
+}
+
void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
{
SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
dc->nVerifyClient = SSL_CVERIFY_UNSET;
dc->nVerifyDepth = UNSET;
- dc->szCACertificatePath = NULL;
- dc->szCACertificateFile = NULL;
dc->szUserName = NULL;
dc->nRenegBufferSize = UNSET;
+ dc->proxy_enabled = UNSET;
+ modssl_ctx_init_proxy(dc, p);
+ dc->proxy_post_config = FALSE;
+
return dc;
}
/*
* Merge per-directory SSL configurations
*/
+
+static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p,
+ modssl_ctx_t *base,
+ modssl_ctx_t *add,
+ modssl_ctx_t *mrg)
+{
+ modssl_ctx_cfg_merge(p, base, add, mrg);
+
+ cfgMergeString(pkp->cert_file);
+ cfgMergeString(pkp->cert_path);
+ cfgMergeString(pkp->ca_cert_file);
+}
+
void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
{
SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
cfgMergeInt(nVerifyDepth);
- cfgMergeString(szCACertificatePath);
- cfgMergeString(szCACertificateFile);
cfgMergeString(szUserName);
cfgMergeInt(nRenegBufferSize);
+ mrg->proxy_post_config = add->proxy_post_config;
+ if (!add->proxy_post_config) {
+ cfgMergeBool(proxy_enabled);
+ modssl_ctx_init_proxy(mrg, p);
+ modssl_ctx_cfg_merge_proxy(p, base->proxy, add->proxy, mrg->proxy);
+ }
+ else {
+ /* post_config hook has already merged and initialized the
+ * proxy context, use it.
+ */
+ mrg->proxy_enabled = add->proxy_enabled;
+ mrg->proxy = add->proxy;
+ }
+
return mrg;
}
+/* Simply merge conf with base into conf, no third party. */
+void ssl_config_proxy_merge(apr_pool_t *p,
+ SSLDirConfigRec *base,
+ SSLDirConfigRec *conf)
+{
+ if (conf->proxy_enabled == UNSET) {
+ conf->proxy_enabled = base->proxy_enabled;
+ }
+ modssl_ctx_cfg_merge_proxy(p, base->proxy, conf->proxy, conf->proxy);
+}
+
/*
* Configuration functions for particular directives
*/
{
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
- ssl_verify_t mode;
+ ssl_verify_t mode = SSL_CVERIFY_NONE;
const char *err;
if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- sc->proxy_enabled = flag ? TRUE : FALSE;
+ dc->proxy_enabled = flag ? TRUE : FALSE;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- sc->proxy->protocol_set = 1;
- return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
+ dc->proxy->protocol_set = 1;
+ return ssl_cmd_protocol_parse(cmd, arg, &dc->proxy->protocol);
}
const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
/* always disable null and export ciphers */
arg = apr_pstrcat(cmd->pool, arg, ":!aNULL:!eNULL:!EXP", NULL);
- sc->proxy->auth.cipher_suite = arg;
+ dc->proxy->auth.cipher_suite = arg;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
- ssl_verify_t mode;
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
+ ssl_verify_t mode = SSL_CVERIFY_NONE;
const char *err;
if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
return err;
}
- sc->proxy->auth.verify_mode = mode;
+ dc->proxy->auth.verify_mode = mode;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
int depth;
const char *err;
return err;
}
- sc->proxy->auth.verify_depth = depth;
+ dc->proxy->auth.verify_depth = depth;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
const char *err;
if ((err = ssl_cmd_check_file(cmd, &arg))) {
return err;
}
- sc->proxy->auth.ca_cert_file = arg;
+ dc->proxy->auth.ca_cert_file = arg;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
const char *err;
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
return err;
}
- sc->proxy->auth.ca_cert_path = arg;
+ dc->proxy->auth.ca_cert_path = arg;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
const char *err;
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
return err;
}
- sc->proxy->crl_path = arg;
+ dc->proxy->crl_path = arg;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
const char *err;
if ((err = ssl_cmd_check_file(cmd, &arg))) {
return err;
}
- sc->proxy->crl_file = arg;
+ dc->proxy->crl_file = arg;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mask);
+ return ssl_cmd_crlcheck_parse(cmd, arg, &dc->proxy->crl_check_mask);
}
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
const char *err;
if ((err = ssl_cmd_check_file(cmd, &arg))) {
return err;
}
- sc->proxy->pkp->cert_file = arg;
+ dc->proxy->pkp->cert_file = arg;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
const char *err;
if ((err = ssl_cmd_check_dir(cmd, &arg))) {
return err;
}
- sc->proxy->pkp->cert_path = arg;
+ dc->proxy->pkp->cert_path = arg;
return NULL;
}
void *dcfg,
const char *arg)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
const char *err;
if ((err = ssl_cmd_check_file(cmd, &arg))) {
return err;
}
- sc->proxy->pkp->ca_cert_file = arg;
+ dc->proxy->pkp->ca_cert_file = arg;
return NULL;
}
const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- sc->proxy_ssl_check_peer_expire = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+ dc->proxy->ssl_check_peer_expire = flag ? TRUE : FALSE;
return NULL;
}
const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- sc->proxy_ssl_check_peer_cn = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+ dc->proxy->ssl_check_peer_cn = flag ? TRUE : FALSE;
return NULL;
}
const char *ssl_cmd_SSLProxyCheckPeerName(cmd_parms *cmd, void *dcfg, int flag)
{
- SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- sc->proxy_ssl_check_peer_name = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
+ dc->proxy->ssl_check_peer_name = flag ? TRUE : FALSE;
return NULL;
}
sc->server->sc = sc;
}
- if (sc->proxy) {
- sc->proxy->sc = sc;
- }
-
/*
* Create the server host:port string because we need it a lot
*/
if (sc->enabled == SSL_ENABLED_UNSET) {
sc->enabled = SSL_ENABLED_FALSE;
}
- if (sc->proxy_enabled == UNSET) {
- sc->proxy_enabled = FALSE;
- }
if (sc->session_cache_timeout == UNSET) {
sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
}
for (s = base_server; s; s = s->next) {
- sc = mySrvConfig(s);
+ SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
+ &ssl_module);
+ sc = mySrvConfig(s);
if (sc->enabled == SSL_ENABLED_TRUE || sc->enabled == SSL_ENABLED_OPTIONAL) {
if ((rv = ssl_run_init_server(s, p, 0, sc->server->ssl_ctx)) != APR_SUCCESS) {
return rv;
}
}
- else if (sc->proxy_enabled == SSL_ENABLED_TRUE) {
- if ((rv = ssl_run_init_server(s, p, 1, sc->proxy->ssl_ctx)) != APR_SUCCESS) {
+
+ if (sdc->proxy_enabled) {
+ rv = ssl_run_init_server(s, p, 1, sdc->proxy->ssl_ctx);
+ if (rv != APR_SUCCESS) {
return rv;
}
}
return APR_SUCCESS;
}
+#define MODSSL_CFG_ITEM_FREE(func, item) \
+ if (item) { \
+ func(item); \
+ item = NULL; \
+ }
+
+static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
+{
+ MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
+
+#ifdef HAVE_SRP
+ if (mctx->srp_vbase != NULL) {
+ SRP_VBASE_free(mctx->srp_vbase);
+ mctx->srp_vbase = NULL;
+ }
+#endif
+}
+
+static apr_status_t ssl_cleanup_proxy_ctx(void *data)
+{
+ modssl_ctx_t *mctx = data;
+
+ ssl_init_ctx_cleanup(mctx);
+
+ if (mctx->pkp->certs) {
+ int i = 0;
+ int ncerts = sk_X509_INFO_num(mctx->pkp->certs);
+
+ if (mctx->pkp->ca_certs) {
+ for (i = 0; i < ncerts; i++) {
+ if (mctx->pkp->ca_certs[i] != NULL) {
+ sk_X509_pop_free(mctx->pkp->ca_certs[i], X509_free);
+ }
+ }
+ }
+
+ sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
+ mctx->pkp->certs = NULL;
+ }
+
+ return APR_SUCCESS;
+}
+
static apr_status_t ssl_init_proxy_ctx(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
- SSLSrvConfigRec *sc)
+ modssl_ctx_t *proxy)
{
apr_status_t rv;
- if ((rv = ssl_init_ctx(s, p, ptemp, sc->proxy)) != APR_SUCCESS) {
+ if (proxy->ssl_ctx) {
+ /* Merged/initialized already */
+ return APR_SUCCESS;
+ }
+
+ apr_pool_cleanup_register(p, proxy,
+ ssl_cleanup_proxy_ctx,
+ apr_pool_cleanup_null);
+
+ if ((rv = ssl_init_ctx(s, p, ptemp, proxy)) != APR_SUCCESS) {
return rv;
}
- if ((rv = ssl_init_proxy_certs(s, p, ptemp, sc->proxy)) != APR_SUCCESS) {
+ if ((rv = ssl_init_proxy_certs(s, p, ptemp, proxy)) != APR_SUCCESS) {
return rv;
}
SSLSrvConfigRec *sc,
apr_array_header_t *pphrases)
{
+ SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
+ &ssl_module);
apr_status_t rv;
/* Initialize the server if SSL is enabled or optional.
}
- if (sc->proxy_enabled) {
- if ((rv = ssl_init_proxy_ctx(s, p, ptemp, sc)) != APR_SUCCESS) {
+ sdc->proxy->sc = sc;
+ if (sdc->proxy_enabled == TRUE) {
+ rv = ssl_init_proxy_ctx(s, p, ptemp, sdc->proxy);
+ if (rv != APR_SUCCESS) {
return rv;
}
}
+ else {
+ sdc->proxy_enabled = FALSE;
+ }
+ sdc->proxy_post_config = 1;
return APR_SUCCESS;
}
return APR_SUCCESS;
}
+int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s,
+ ap_conf_vector_t *section_config)
+{
+ SSLDirConfigRec *sdc = ap_get_module_config(s->lookup_defaults,
+ &ssl_module);
+ SSLDirConfigRec *pdc = ap_get_module_config(section_config,
+ &ssl_module);
+ if (pdc) {
+ pdc->proxy->sc = mySrvConfig(s);
+ ssl_config_proxy_merge(p, sdc, pdc);
+ if (pdc->proxy_enabled) {
+ apr_status_t rv;
+
+ rv = ssl_init_proxy_ctx(s, p, ptemp, pdc->proxy);
+ if (rv != APR_SUCCESS) {
+ return !OK;
+ }
+
+ rv = ssl_run_init_server(s, p, 1, pdc->proxy->ssl_ctx);
+ if (rv != APR_SUCCESS) {
+ return !OK;
+ }
+ }
+ pdc->proxy_post_config = 1;
+ }
+ return OK;
+}
+
static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
const X509_NAME * const *b)
{
#endif
}
-#define MODSSL_CFG_ITEM_FREE(func, item) \
- if (item) { \
- func(item); \
- item = NULL; \
- }
-
-static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
-{
- MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
-
-#ifdef HAVE_SRP
- if (mctx->srp_vbase != NULL) {
- SRP_VBASE_free(mctx->srp_vbase);
- mctx->srp_vbase = NULL;
- }
-#endif
-}
-
-static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx)
-{
- ssl_init_ctx_cleanup(mctx);
-
- if (mctx->pkp->certs) {
- int i = 0;
- int ncerts = sk_X509_INFO_num(mctx->pkp->certs);
-
- if (mctx->pkp->ca_certs) {
- for (i = 0; i < ncerts; i++) {
- if (mctx->pkp->ca_certs[i] != NULL) {
- sk_X509_pop_free(mctx->pkp->ca_certs[i], X509_free);
- }
- }
- }
-
- sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
- mctx->pkp->certs = NULL;
- }
-}
-
apr_status_t ssl_init_ModuleKill(void *data)
{
SSLSrvConfigRec *sc;
for (s = base_server; s; s = s->next) {
sc = mySrvConfig(s);
- ssl_init_ctx_cleanup_proxy(sc->proxy);
-
ssl_init_ctx_cleanup(sc->server);
/* Not Sure but possibly clear X509 trusted cert file */
"proxy-request-hostname");
BOOL proxy_ssl_check_peer_ok = TRUE;
int post_handshake_rc = OK;
+ SSLDirConfigRec *dc;
+ dc = sslconn->dc;
sc = mySrvConfig(server);
#ifdef HAVE_TLSEXT
*/
if (hostname_note &&
#ifndef OPENSSL_NO_SSL3
- sc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&
+ dc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&
#endif
apr_ipsubnet_create(&ip, hostname_note, NULL,
c->pool) != APR_SUCCESS) {
cert = SSL_get_peer_certificate(filter_ctx->pssl);
- if (sc->proxy_ssl_check_peer_expire != SSL_ENABLED_FALSE) {
+ if (dc->proxy->ssl_check_peer_expire != FALSE) {
if (!cert
|| (X509_cmp_current_time(
X509_get_notBefore(cert)) >= 0)
"SSL Proxy: Peer certificate is expired");
}
}
- if ((sc->proxy_ssl_check_peer_name != SSL_ENABLED_FALSE) &&
- ((sc->proxy_ssl_check_peer_cn != SSL_ENABLED_FALSE) ||
- (sc->proxy_ssl_check_peer_name == SSL_ENABLED_TRUE)) &&
+ if ((dc->proxy->ssl_check_peer_name != FALSE) &&
+ ((dc->proxy->ssl_check_peer_cn != FALSE) ||
+ (dc->proxy->ssl_check_peer_name == TRUE)) &&
hostname_note) {
apr_table_unset(c->notes, "proxy-request-hostname");
if (!cert
"for hostname %s", hostname_note);
}
}
- else if ((sc->proxy_ssl_check_peer_cn == SSL_ENABLED_TRUE) &&
+ else if ((dc->proxy->ssl_check_peer_cn == TRUE) &&
hostname_note) {
const char *hostname;
int match = 0;
server_rec *s = r ? r->server : mySrvFromConn(conn);
SSLSrvConfigRec *sc = mySrvConfig(s);
- SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL;
SSLConnRec *sslconn = myConnConfig(conn);
+ SSLDirConfigRec *dc = r ? myDirConfig(r) : sslconn->dc;
modssl_ctx_t *mctx = myCtxConfig(sslconn, sc);
int crl_check_mode = mctx->crl_check_mask & ~SSL_CRLCHECK_FLAGS;
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
server_rec *s = mySrvFromConn(c);
SSLSrvConfigRec *sc = mySrvConfig(s);
+ SSLDirConfigRec *dc = myDirConfigFromConn(c);
X509_NAME *ca_name, *issuer, *ca_issuer;
X509_INFO *info;
X509 *ca_cert;
STACK_OF(X509_NAME) *ca_list;
- STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
+ STACK_OF(X509_INFO) *certs;
STACK_OF(X509) *ca_certs;
STACK_OF(X509) **ca_cert_chains;
int i, j, k;
SSLPROXY_CERT_CB_LOG_FMT "entered",
sc->vhost_id);
+ certs = (dc && dc->proxy) ? dc->proxy->pkp->certs : NULL;
if (!certs || (sk_X509_INFO_num(certs) <= 0)) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02268)
SSLPROXY_CERT_CB_LOG_FMT
return TRUE;
}
- ca_cert_chains = sc->proxy->pkp->ca_certs;
+ ca_cert_chains = dc->proxy->pkp->ca_certs;
for (i = 0; i < sk_X509_NAME_num(ca_list); i++) {
ca_name = sk_X509_NAME_value(ca_list, i);
#define strIsEmpty(s) (s == NULL || s[0] == NUL)
#define myConnConfig(c) \
-(SSLConnRec *)ap_get_module_config(c->conn_config, &ssl_module)
-#define myCtxConfig(sslconn, sc) (sslconn->is_proxy ? sc->proxy : sc->server)
+ ((SSLConnRec *)ap_get_module_config(c->conn_config, &ssl_module))
#define myConnConfigSet(c, val) \
-ap_set_module_config(c->conn_config, &ssl_module, val)
-#define mySrvConfig(srv) (SSLSrvConfigRec *)ap_get_module_config(srv->module_config, &ssl_module)
-#define myDirConfig(req) (SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module)
-#define myModConfig(srv) (mySrvConfig((srv)))->mc
-#define mySrvFromConn(c) (myConnConfig(c))->server
+ ap_set_module_config(c->conn_config, &ssl_module, val)
+#define mySrvConfig(srv) \
+ ((SSLSrvConfigRec *)ap_get_module_config(srv->module_config, &ssl_module))
+#define myDirConfig(req) \
+ ((SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module))
+#define myCtxConfig(sslconn, sc) \
+ (sslconn->is_proxy ? sslconn->dc->proxy : sc->server)
+#define myModConfig(srv) mySrvConfig((srv))->mc
+#define mySrvFromConn(c) myConnConfig(c)->server
+#define myDirConfigFromConn(c) myConnConfig(c)->dc
#define mySrvConfigFromConn(c) mySrvConfig(mySrvFromConn(c))
#define myModConfigFromConn(c) myModConfig(mySrvFromConn(c))
* (i.e. the global configuration for each httpd process)
*/
+typedef struct SSLSrvConfigRec SSLSrvConfigRec;
+typedef struct SSLDirConfigRec SSLDirConfigRec;
+
typedef enum {
SSL_SHUTDOWN_TYPE_UNSET,
SSL_SHUTDOWN_TYPE_STANDARD,
} reneg_state;
server_rec *server;
+ SSLDirConfigRec *dc;
const char *cipher_suite; /* cipher suite used in last reneg */
int service_unavailable; /* thouugh we negotiate SSL, no requests will be served */
} ssl_ctx_param_t;
#endif
-typedef struct SSLSrvConfigRec SSLSrvConfigRec;
-
typedef struct {
SSLSrvConfigRec *sc; /** pointer back to server config */
SSL_CTX *ssl_ctx;
SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */
apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */
#endif
+
+ BOOL ssl_check_peer_cn;
+ BOOL ssl_check_peer_name;
+ BOOL ssl_check_peer_expire;
} modssl_ctx_t;
struct SSLSrvConfigRec {
SSLModConfigRec *mc;
ssl_enabled_t enabled;
- BOOL proxy_enabled;
const char *vhost_id;
int vhost_id_len;
int session_cache_timeout;
BOOL cipher_server_pref;
BOOL insecure_reneg;
modssl_ctx_t *server;
- modssl_ctx_t *proxy;
- ssl_enabled_t proxy_ssl_check_peer_expire;
- ssl_enabled_t proxy_ssl_check_peer_cn;
- ssl_enabled_t proxy_ssl_check_peer_name;
#ifdef HAVE_TLSEXT
ssl_enabled_t strict_sni_vhost_check;
#endif
* (i.e. the local configuration for all <Directory>
* and .htaccess contexts)
*/
-typedef struct {
+struct SSLDirConfigRec {
BOOL bSSLRequired;
apr_array_header_t *aRequirement;
ssl_opt_t nOptions;
const char *szCipherSuite;
ssl_verify_t nVerifyClient;
int nVerifyDepth;
- const char *szCACertificatePath;
- const char *szCACertificateFile;
const char *szUserName;
apr_size_t nRenegBufferSize;
-} SSLDirConfigRec;
+
+ modssl_ctx_t *proxy;
+ BOOL proxy_enabled;
+ BOOL proxy_post_config;
+};
/**
* function prototypes
void *ssl_config_server_merge(apr_pool_t *, void *, void *);
void *ssl_config_perdir_create(apr_pool_t *, char *);
void *ssl_config_perdir_merge(apr_pool_t *, void *, void *);
+void ssl_config_proxy_merge(apr_pool_t *,
+ SSLDirConfigRec *, SSLDirConfigRec *);
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 *);
apr_status_t ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *,
apr_array_header_t *);
apr_status_t ssl_init_CheckServers(server_rec *, apr_pool_t *);
+int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s,
+ ap_conf_vector_t *section_config);
STACK_OF(X509_NAME)
*ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *);
void ssl_init_Child(apr_pool_t *, server_rec *);
void ssl_scache_remove(server_rec *, IDCONST UCHAR *, int,
apr_pool_t *);
-/** Proxy Support */
-int ssl_proxy_enable(conn_rec *c);
-int ssl_engine_disable(conn_rec *c);
-
/** OCSP Stapling Support */
#ifdef HAVE_OCSP_STAPLING
const char *ssl_cmd_SSLStaplingCache(cmd_parms *, void *, const char *);
cmd->name);
return NULL;
}
+ else if (parms->directive && parms->directive->parent) {
+ return apr_pstrcat(parms->pool, cmd->name, " not allowed in ",
+ parms->directive->parent->directive, ">",
+ " context", NULL);
+ }
else {
return apr_pstrcat(parms->pool, cmd->name,
" not allowed here", NULL);
" cannot occur within <VirtualHost> section", NULL);
}
- if ((forbidden & (NOT_IN_LIMIT | NOT_IN_DIR_LOC_FILE))
- && cmd->limited != -1) {
+ if ((forbidden & NOT_IN_DIR_CONTEXT) && cmd->limited != -1) {
return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
" cannot occur within <Limit> or <LimitExcept> "
"section", NULL);
if ((forbidden & NOT_IN_DIR_LOC_FILE) == NOT_IN_DIR_LOC_FILE) {
if (cmd->path != NULL) {
return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
- " cannot occur within <Directory/Location/Files> "
- "section", NULL);
+ " cannot occur within directory context", NULL);
}
if (cmd->cmd->req_override & EXEC_ON_READ) {
/* EXEC_ON_READ must be NOT_IN_DIR_LOC_FILE, if not, it will
|| (found = find_parent(cmd->directive, "<FilesMatch"))
|| (found = find_parent(cmd->directive, "<If"))
|| (found = find_parent(cmd->directive, "<ElseIf"))
- || (found = find_parent(cmd->directive, "<Else"))))) {
+ || (found = find_parent(cmd->directive, "<Else"))))
+ || ((forbidden & NOT_IN_PROXY)
+ && ((found = find_parent(cmd->directive, "<Proxy"))
+ || (found = find_parent(cmd->directive, "<ProxyMatch"))))) {
return apr_pstrcat(cmd->pool, cmd->cmd->name, gt,
" cannot occur within ", found->directive,
"> section", NULL);
void *sconf = cmd->server->module_config;
core_server_config *conf = ap_get_core_module_config(sconf);
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
void *sconf = cmd->server->module_config;
core_server_config *conf = ap_get_core_module_config(sconf);
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
void *sconf = cmd->server->module_config;
core_server_config *conf = ap_get_core_module_config(sconf);
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
ap_regex_t *r = NULL;
const command_rec *thiscmd = cmd->cmd;
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
ap_regex_t *r = NULL;
const command_rec *thiscmd = cmd->cmd;
ap_conf_vector_t *new_url_conf = ap_create_per_dir_config(cmd->pool);
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
static const char *set_protocol(cmd_parms *cmd, void *dummy,
const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
core_server_config *conf =
ap_get_core_module_config(cmd->server->module_config);
char* proto;
int offset = (int)(long)cmd->info;
char *struct_ptr = (char *)cmd->server;
- const char *err = ap_check_cmd_context(cmd,
- NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
}
static const char *server_hostname_port(cmd_parms *cmd, void *dummy, const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
const char *portstr, *part;
char *scheme;
int port;
static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
static const char *set_serverpath(cmd_parms *cmd, void *dummy,
const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err != NULL) {
return err;
static const char *set_limit_req_line(cmd_parms *cmd, void *dummy,
const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
int lim;
if (err != NULL) {
static const char *set_limit_req_fieldsize(cmd_parms *cmd, void *dummy,
const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
int lim;
if (err != NULL) {
static const char *set_limit_req_fields(cmd_parms *cmd, void *dummy,
const char *arg)
{
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
int lim;
if (err != NULL) {
core_server_config *conf =
ap_get_core_module_config(cmd->server->module_config);
const char **np;
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err) {
return err;
{
core_server_config *conf =
ap_get_core_module_config(cmd->server->module_config);
- const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
+ const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
if (err) {
return err;