Commit d6bda3aa authored by Stefan Eissing's avatar Stefan Eissing
Browse files

On the trunk:

mod_ssl: Extending SSLEngine to alternatively get a list of add:port spec as used in VirtualHost.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1807709 13f79535-47bb-0310-9956-ffa450edef68
parent 29afdd25
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
                                                         -*- coding: utf-8 -*-
Changes with Apache 2.5.0

  *) mod_ssl: Adding option to set a list of addr:port specs, as used in VirtualHosts
     to enable SSLEngine for all matching hosts. Updated documentation. [Stefan Eissing]
  
  *) core: Disallow Methods' registration at runtime (.htaccess), they may be
     used only if registered at init time (httpd.conf).  [Yann Ylavic]

+15 −3
Original line number Diff line number Diff line
@@ -550,15 +550,15 @@ SSLSessionCacheTimeout 600
<directivesynopsis>
<name>SSLEngine</name>
<description>SSL Engine Operation Switch</description>
<syntax>SSLEngine on|off|optional</syntax>
<syntax>SSLEngine on|off|optional|addr[:port] [addr[:port]] ...</syntax>
<default>SSLEngine off</default>
<contextlist><context>server config</context>
<context>virtual host</context></contextlist>

<usage>
<p>
This directive toggles the usage of the SSL/TLS Protocol Engine. This
is should be used inside a <directive module="core"
This directive toggles the usage of the SSL/TLS Protocol Engine. Values 'on',
'off' and 'optional' should be used inside a <directive module="core"
type="section">VirtualHost</directive> section to enable SSL/TLS for a
that virtual host. By default the SSL/TLS Protocol Engine is
disabled for both the main server and all configured virtual hosts.</p>
@@ -570,6 +570,18 @@ SSLEngine on
&lt;/VirtualHost&gt;
</highlight>
</example>
<p>In Apache 2.4 and later, addr:port values should be used in the 
global server to enable the SSL/TLS Protocol Engine for <em>all</em> 
<directive module="core" type="section">VirtualHost</directive>s 
that match one of the addresses in the list.</p>
<example><title>Example</title>
<highlight language="config">
SSLEngine *:443
&lt;VirtualHost *:443&gt;
#...
&lt;/VirtualHost&gt;
</highlight>
</example>
<p>In Apache 2.1 and later, <directive>SSLEngine</directive> can be set to
<code>optional</code>. This enables support for
<a href="http://www.ietf.org/rfc/rfc2817.txt">RFC 2817</a>, Upgrading to TLS
+89 −21
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ static const command_rec ssl_config_cmds[] = {
    /*
     * Per-server context configuration directives
     */
    SSL_CMD_SRV(Engine, TAKE1,
    SSL_CMD_SRV(Engine, RAW_ARGS,
                "SSL switch for the protocol engine "
                "('on', 'off')")
    SSL_CMD_SRV(FIPS, FLAG,
@@ -490,6 +490,75 @@ static SSLConnRec *ssl_init_connection_ctx(conn_rec *c,
    return sslconn;
}

static int ssl_server_addr_matches(server_addr_rec *sar, apr_sockaddr_t *sa)
{
    /* Determine if the list of server_addr_rec's matches the given socket address.
     * IP Address/port may be wilcard/0 for a match to occur. */
    while (sar) {
        if (apr_sockaddr_is_wildcard(sar->host_addr)
            || apr_sockaddr_equal(sar->host_addr, sa)) {
            if (sar->host_addr->port == sa->port 
                || sar->host_addr->port == 0
                || sa->port == 0) {
                return 1;
            }
        }
        sar = sar->next;
    }
    return 0;
}

int ssl_server_addr_overlap(server_addr_rec *sar1, server_addr_rec *sar2)
{
    if (sar1) {
        while (sar2) {
            if (ssl_server_addr_matches(sar1, sar2->host_addr)) {
                return 1;
            }
            sar2 = sar2->next;
        }
    }
    return 0;
}

static ssl_enabled_t ssl_srv_enabled_on(server_rec *s, apr_sockaddr_t *sa)
{
    SSLSrvConfigRec *sc = mySrvConfig(s);
    if (sc->enabled == SSL_ENABLED_TRUE && sc->enabled_on) {
        if (!ssl_server_addr_matches(sc->enabled_on, sa)) {
            return SSL_ENABLED_FALSE;
        }
    }
    return sc->enabled;
}

static ssl_enabled_t ssl_conn_enabled(conn_rec *c)
{
    if (c->master) {
        return ssl_conn_enabled(c->master);
    }
    else {
        SSLConnRec *sslconn = myConnConfig(c);
        if (sslconn) {
            if (sslconn->disabled) {
                return SSL_ENABLED_FALSE;
            }
            if (sslconn->is_proxy) {
                if (!sslconn->dc->proxy_enabled) {
                    return SSL_ENABLED_FALSE;
                }
            }
            else {
                return ssl_srv_enabled_on(sslconn->server, c->local_addr);
            }
        }
        else {
            return ssl_srv_enabled_on(c->base_server, c->local_addr);
        }
    }
    return SSL_ENABLED_TRUE;
}

static int ssl_engine_status(conn_rec *c, SSLConnRec *sslconn)
{
    if (c->master) {
@@ -504,17 +573,13 @@ static int ssl_engine_status(conn_rec *c, SSLConnRec *sslconn)
                return DECLINED;
            }
        }
        else {
            if (mySrvConfig(sslconn->server)->enabled != SSL_ENABLED_TRUE) {
        else if (ssl_srv_enabled_on(sslconn->server, c->local_addr) != SSL_ENABLED_TRUE) {
            return DECLINED;
        }
    }
    }
    else {
        if (mySrvConfig(c->base_server)->enabled != SSL_ENABLED_TRUE) {
    else if (ssl_srv_enabled_on(c->base_server, c->local_addr) != SSL_ENABLED_TRUE) {
        return DECLINED;
    }
    }
    return OK;
}

@@ -632,27 +697,30 @@ int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
    return APR_SUCCESS;
}

/* FIXME: if we ever want to server http: requests over TLS, this 
 * needs to change. We probably need the scheme in request_rec and
 * return that iff it is set. */
static const char *ssl_hook_http_scheme(const request_rec *r)
{
    SSLSrvConfigRec *sc = mySrvConfig(r->server);

    if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
    switch (ssl_conn_enabled(r->connection)) {
        case SSL_ENABLED_FALSE:
        case SSL_ENABLED_OPTIONAL:
            return NULL;
    }

        default:
            return "https";
    }
}

static apr_port_t ssl_hook_default_port(const request_rec *r)
{
    SSLSrvConfigRec *sc = mySrvConfig(r->server);

    if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
    switch (ssl_conn_enabled(r->connection)) {
        case SSL_ENABLED_FALSE:
        case SSL_ENABLED_OPTIONAL:
            return 0;
    }

        default:
            return 443;
    }
}

static int ssl_hook_pre_connection(conn_rec *c, void *csd)
{
+45 −12
Original line number Diff line number Diff line
@@ -231,6 +231,7 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
    sc->session_tickets        = UNSET;
    sc->policies               = NULL;
    sc->error_policy           = NULL;
    sc->enabled_on             = NULL;

    modssl_ctx_init_server(sc, p);

@@ -376,6 +377,8 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
    mrg->policies = NULL;
    cfgMergeString(error_policy);

    mrg->enabled_on = (add->enabled == SSL_ENABLED_UNSET)? base->enabled_on : add->enabled_on;
                         
    modssl_ctx_cfg_merge_server(p, base->server, add->server, mrg->server);

    return mrg;
@@ -1010,24 +1013,54 @@ const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
    return NULL;
}

const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *args)
{
    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
    const char *w, *err;
    server_addr_rec **psar;
    server_rec s;
        
    w = ap_getword_conf(cmd->pool, &args);

    if (*w == '\0') {
        return "SSLEngine takes at least one argument";
    }
    
    if (!strcasecmp(arg, "On")) {
    if (*args == 0) {
        if (!strcasecmp(w, "On")) {
            sc->enabled = SSL_ENABLED_TRUE;
            sc->enabled_on = NULL;
            return NULL;
        }
    else if (!strcasecmp(arg, "Off")) {
        else if (!strcasecmp(w, "Off")) {
            sc->enabled = SSL_ENABLED_FALSE;
            sc->enabled_on = NULL;
            return NULL;
        }
    else if (!strcasecmp(arg, "Optional")) {
        else if (!strcasecmp(w, "Optional")) {
            sc->enabled = SSL_ENABLED_OPTIONAL;
            sc->enabled_on = NULL;
            return NULL;
        }
    }
    
    return "Argument must be On, Off, or Optional";
    memset(&s, 0, sizeof(s));
    err = ap_parse_vhost_addrs(cmd->pool, w, &s);
    sc->enabled_on = s.addrs;
    sc->enabled = SSL_ENABLED_TRUE;
    
    if (!err && *args) {
        s.addrs = NULL;
        err = ap_parse_vhost_addrs(cmd->pool, args, &s);
        if (!err && s.addrs) {
            psar = &sc->enabled_on;
            while (*psar) {
                psar = &(*psar)->next;
            }
            *psar = s.addrs;
        }
    }
    return err;
}

const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
+7 −0
Original line number Diff line number Diff line
@@ -269,6 +269,13 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
        if (sc->enabled == SSL_ENABLED_UNSET) {
            sc->enabled = SSL_ENABLED_FALSE;
        }
        /* Check if conditions to enable apply to this server at all. Conditions
         * might be inherited from base server and never match a vhost. */
        if (sc->enabled_on && sc->enabled == SSL_ENABLED_TRUE) {
            if (!ssl_server_addr_overlap(sc->enabled_on, s->addrs)) {
                sc->enabled = SSL_ENABLED_FALSE;
            }
        }

        if (sc->session_cache_timeout == UNSET) {
            sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
Loading