source: server/common/patches/httpd-2.2.8-sni.patch @ 760

Last change on this file since 760 was 683, checked in by andersk, 15 years ago
Add SNI support to the httpd package.
File size: 11.7 KB
  • httpd-2.2.x/modules/ssl/ssl_private.h

    httpd-2.2.8-sni.patch - server name indication support for Apache 2.2
    (see RFC 4366, "Transport Layer Security (TLS) Extensions")
    
    based on a patch from the EdelKey project
    (http://www.edelweb.fr/EdelKey/files/apache-2.2.0+0.9.9+servername.patch)
    
    Needs openssl-SNAP-20060330 / OpenSSL 0.9.8f or later
    to work properly (ftp://ftp.openssl.org/snapshot/). The 0.9.8 versions
    must be configured explicitly for TLS extension support at compile time
    ("./config enable-tlsext").
    
     
    3535#include "http_connection.h"
    3636#include "http_request.h"
    3737#include "http_protocol.h"
     38#include "http_vhost.h"
    3839#include "util_script.h"
    3940#include "util_filter.h"
    4041#include "util_ebcdic.h"
     
    555556SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *);
    556557void         ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
    557558void         ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int);
     559#ifndef OPENSSL_NO_TLSEXT
     560int          ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
     561#endif
    558562
    559563/**  Session Cache Support  */
    560564void         ssl_scache_init(server_rec *, apr_pool_t *);
  • httpd-2.2.x/modules/ssl/ssl_engine_init.c

     
    355355    }
    356356}
    357357
     358#ifndef OPENSSL_NO_TLSEXT
     359static void ssl_init_ctx_tls_extensions(server_rec *s,
     360                                        apr_pool_t *p,
     361                                        apr_pool_t *ptemp,
     362                                        modssl_ctx_t *mctx)
     363{
     364    /*
     365     * Configure TLS extensions support
     366     */
     367    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
     368                 "Configuring TLS extension handling");
     369
     370    /*
     371     * Server name indication (SNI)
     372     */
     373    if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
     374                          ssl_callback_ServerNameIndication) ||
     375        !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
     376        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
     377                     "Unable to initialize TLS servername extension "
     378                     "callback (incompatible OpenSSL version?)");
     379        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
     380        ssl_die();
     381    }
     382}
     383#endif
     384
    358385static void ssl_init_ctx_protocol(server_rec *s,
    359386                                  apr_pool_t *p,
    360387                                  apr_pool_t *ptemp,
     
    687714    if (mctx->pks) {
    688715        /* XXX: proxy support? */
    689716        ssl_init_ctx_cert_chain(s, p, ptemp, mctx);
     717#ifndef OPENSSL_NO_TLSEXT
     718        ssl_init_ctx_tls_extensions(s, p, ptemp, mctx);
     719#endif
    690720    }
    691721}
    692722
     
    10381068        if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
    10391069            ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
    10401070                         base_server,
     1071#ifdef OPENSSL_NO_TLSEXT
    10411072                         "Init: SSL server IP/port conflict: "
     1073#else
     1074                         "Init: SSL server IP/port overlap: "
     1075#endif
    10421076                         "%s (%s:%d) vs. %s (%s:%d)",
    10431077                         ssl_util_vhostid(p, s),
    10441078                         (s->defn_name ? s->defn_name : "unknown"),
     
    10551089
    10561090    if (conflict) {
    10571091        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
     1092#ifdef OPENSSL_NO_TLSEXT
    10581093                     "Init: You should not use name-based "
    10591094                     "virtual hosts in conjunction with SSL!!");
     1095#else
     1096                     "Init: Name-based SSL virtual hosts only "
     1097                     "work for clients with TLS server name indication "
     1098                     "support (RFC 4366)");
     1099#endif
    10601100    }
    10611101}
    10621102
  • httpd-2.2.x/modules/ssl/ssl_engine_vars.c

     
    320320    else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) {
    321321        result = ssl_var_lookup_ssl_compress_meth(ssl);
    322322    }
     323#ifndef OPENSSL_NO_TLSEXT
     324    else if (ssl != NULL && strcEQ(var, "TLS_SNI")) {
     325        result = apr_pstrdup(p, SSL_get_servername(ssl,
     326                                                   TLSEXT_NAMETYPE_host_name));
     327    }
     328#endif
    323329    return result;
    324330}
    325331
  • httpd-2.2.x/modules/ssl/ssl_engine_kernel.c

     
    3131#include "ssl_private.h"
    3232
    3333static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
     34#ifndef OPENSSL_NO_TLSEXT
     35static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s);
     36#endif
    3437
    3538/*
    3639 *  Post Read Request Handler
     
    3942{
    4043    SSLConnRec *sslconn = myConnConfig(r->connection);
    4144    SSL *ssl;
     45#ifndef OPENSSL_NO_TLSEXT
     46    const char *servername;
     47#endif
    4248
    4349    if (!sslconn) {
    4450        return DECLINED;
     
    8793    if (!ssl) {
    8894        return DECLINED;
    8995    }
     96#ifndef OPENSSL_NO_TLSEXT
     97    if (!r->hostname &&
     98        (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
     99        /* Use the SNI extension as the hostname if no Host: header was sent */
     100        r->hostname = apr_pstrdup(r->pool, servername);
     101        ap_update_vhost_from_headers(r);
     102    }
     103#endif
    90104    SSL_set_app_data2(ssl, r);
    91105
    92106    /*
     
    9971011    SSLDirConfigRec *dc = myDirConfig(r);
    9981012    apr_table_t *env = r->subprocess_env;
    9991013    char *var, *val = "";
     1014#ifndef OPENSSL_NO_TLSEXT
     1015    const char *servername;
     1016#endif
    10001017    STACK_OF(X509) *peer_certs;
    10011018    SSL *ssl;
    10021019    int i;
     
    10181035    /* the always present HTTPS (=HTTP over SSL) flag! */
    10191036    apr_table_setn(env, "HTTPS", "on");
    10201037
     1038#ifndef OPENSSL_NO_TLSEXT
     1039    /* add content of SNI TLS extension (if supplied with ClientHello) */
     1040    if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) {
     1041        apr_table_set(env, "SSL_TLS_SNI", servername);
     1042    }
     1043#endif
     1044
    10211045    /* standard SSL environment variables */
    10221046    if (dc->nOptions & SSL_OPT_STDENVVARS) {
    10231047        for (i = 0; ssl_hook_Fixup_vars[i]; i++) {
     
    18101834    }
    18111835}
    18121836
     1837#ifndef OPENSSL_NO_TLSEXT
     1838/*
     1839 * This callback function is executed when OpenSSL encounters an extended
     1840 * client hello with a server name indication extension ("SNI", cf. RFC 4366).
     1841 */
     1842int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
     1843{
     1844    const char *servername =
     1845                SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
     1846
     1847    if (servername) {
     1848        conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
     1849        if (c) {
     1850            if (ap_vhost_iterate_given_conn(c, ssl_find_vhost,
     1851                                            (void *)servername)) {
     1852                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
     1853                              "SSL virtual host for servername %s found",
     1854                              servername);
     1855                return SSL_TLSEXT_ERR_OK;
     1856            }
     1857            else {
     1858                ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
     1859                              "No matching SSL virtual host for servername "
     1860                              "%s found (using default/first virtual host)",
     1861                              servername);
     1862                return SSL_TLSEXT_ERR_ALERT_WARNING;
     1863            }
     1864        }
     1865    }
     1866
     1867    return SSL_TLSEXT_ERR_NOACK;
     1868}
     1869
     1870/*
     1871 * Find a (name-based) SSL virtual host where either the ServerName
     1872 * or one of the ServerAliases matches the supplied name (to be used
     1873 * with ap_vhost_iterate_given_conn())
     1874 */
     1875static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
     1876{
     1877    SSLSrvConfigRec *sc;
     1878    SSL *ssl;
     1879    BOOL found = FALSE;
     1880    apr_array_header_t *names;
     1881    int i;
     1882
     1883    /* check ServerName */
     1884    if (!strcasecmp(servername, s->server_hostname)) {
     1885        found = TRUE;
     1886    }
     1887
     1888    /*
     1889     * if not matched yet, check ServerAlias entries
     1890     * (adapted from vhost.c:matches_aliases())
     1891     */
     1892    if (!found) {
     1893        names = s->names;
     1894        if (names) {
     1895            char **name = (char **)names->elts;
     1896            for (i = 0; i < names->nelts; ++i) {
     1897                if (!name[i])
     1898                    continue;
     1899                if (!strcasecmp(servername, name[i])) {
     1900                    found = TRUE;
     1901                    break;
     1902                }
     1903            }
     1904        }
     1905    }
     1906
     1907    /* if still no match, check ServerAlias entries with wildcards */
     1908    if (!found) {
     1909        names = s->wild_names;
     1910        if (names) {
     1911            char **name = (char **)names->elts;
     1912            for (i = 0; i < names->nelts; ++i) {
     1913                if (!name[i])
     1914                    continue;
     1915                if (!ap_strcasecmp_match(servername, name[i])) {
     1916                    found = TRUE;
     1917                    break;
     1918                }
     1919            }
     1920        }
     1921    }
     1922
     1923    /* set SSL_CTX (if matched) */
     1924    if (found && (ssl = ((SSLConnRec *)myConnConfig(c))->ssl) &&
     1925        (sc = mySrvConfig(s))) {
     1926        SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
     1927        /*
     1928         * SSL_set_SSL_CTX() only deals with the server cert,
     1929         * so we need to duplicate a few additional settings
     1930         * from the ctx by hand
     1931         */
     1932        SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx));
     1933        if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) ||
     1934            (SSL_num_renegotiations(ssl) == 0)) {
     1935           /*
     1936            * Only initialize the verification settings from the ctx
     1937            * if they are not yet set, or if we're called when a new
     1938            * SSL connection is set up (num_renegotiations == 0).
     1939            * Otherwise, we would possibly reset a per-directory
     1940            * configuration which was put into effect by ssl_hook_Access.
     1941            */
     1942            SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx),
     1943                           SSL_CTX_get_verify_callback(ssl->ctx));
     1944        }
     1945
     1946        /*
     1947         * We also need to make sure that the correct mctx is
     1948         * assigned to the connection - the CRL callback e.g.
     1949         * makes use of it for retrieving its store (mctx->crl).
     1950         * Since logging in callbacks uses c->base_server in many
     1951         * cases, it also ensures that these messages are routed
     1952         * to the proper log. And finally, there is one special
     1953         * filter callback, which is set very early depending on the
     1954         * base_server's log level. If this is not the first vhost
     1955         * we're now selecting (and the first vhost doesn't use
     1956         * APLOG_DEBUG), then we need to set that callback here.
     1957         */
     1958        c->base_server = s;
     1959        if (c->base_server->loglevel >= APLOG_DEBUG) {
     1960            BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
     1961            BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
     1962        }
     1963
     1964        return 1;
     1965    }
     1966
     1967    return 0;
     1968}
     1969#endif
  • httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h

     
    264264#define SSL_SESS_CACHE_NO_INTERNAL  SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
    265265#endif
    266266
     267#ifndef OPENSSL_NO_TLSEXT
     268#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
     269#define OPENSSL_NO_TLSEXT
     270#endif
     271#endif
     272
    267273#endif /* SSL_TOOLKIT_COMPAT_H */
    268274
    269275/** @} */
Note: See TracBrowser for help on using the repository browser.