diff -purN httpd-2.2.0/modules/ssl/ssl_engine_init.c httpd-2.2.0-p2/modules/ssl/ssl_engine_init.c --- httpd-2.2.0/modules/ssl/ssl_engine_init.c 2005-11-10 16:20:05.000000000 +0100 +++ httpd-2.2.0-p2/modules/ssl/ssl_engine_init.c 2006-03-27 12:01:04.523694000 +0200 @@ -156,6 +156,52 @@ static int ssl_tmp_keys_init(server_rec return OK; } +#ifndef OPENSSL_NO_TLSEXT + +static int set_ssl_vhost(void * servername, conn_rec *c, server_rec *s) +{ + SSLSrvConfigRec *sc; + SSL *ssl; + + if (!strcasecmp((const char * )servername ,(const char*)s->server_hostname)) { + if ((ssl = ((SSLConnRec *)myConnConfig(c))->ssl) == NULL) + return 0; + if (!(sc = mySrvConfig(s))) + return 0; + SSL_set_SSL_CTX(ssl,sc->server->ssl_ctx); + return 1; + } + return 0; +} + +int ssl_set_vhost_ctx(SSL *ssl, const char * servername) + +{ + conn_rec *c; + + if (servername == NULL) /* should not occur. */ + return 0; + + SSL_set_SSL_CTX(ssl,NULL); + + if (!(c = (conn_rec *) SSL_get_app_data(ssl))) + return 0; + + return ap_vhost_iterate_given_conn(c,set_ssl_vhost,servername); +} + + +static int ssl_servername_cb(SSL *s, int *ad, void *arg) +{ + const char *servername = SSL_get_servername(s,TLSEXT_NAMETYPE_host_name); + + if ( servername ) { + return ssl_set_vhost_ctx(s,servername)?SSL_TLSEXT_ERR_OK:SSL_TLSEXT_ERR_ALERT_FATAL; + } + return SSL_TLSEXT_ERR_NOACK; +} + +#endif /* * Per-module initialization */ @@ -376,13 +422,34 @@ static void ssl_init_server_check(server } } +static void ssl_init_server_extensions(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, + modssl_ctx_t *mctx) +{ + /* + * Configure TLS extensions support + */ + +#ifndef OPENSSL_NO_TLSEXT + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "Configuring TLS extensions facility"); + + if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx, ssl_servername_cb) || + !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "Unable to initialize servername callback, bad openssl version."); + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); + ssl_die(); + } +#endif +} static void ssl_init_ctx_protocol(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx) { SSL_CTX *ctx = NULL; - SSL_METHOD *method = NULL; char *cp; int protocol = mctx->protocol; @@ -406,16 +473,14 @@ static void ssl_init_ctx_protocol(server "Creating new SSL context (protocols: %s)", cp); if (protocol == SSL_PROTOCOL_SSLV2) { - method = mctx->pkp ? + ctx = SSL_CTX_new(mctx->pkp ? SSLv2_client_method() : /* proxy */ - SSLv2_server_method(); /* server */ - ctx = SSL_CTX_new(method); /* only SSLv2 is left */ + SSLv2_server_method()); /* only SSLv2 is left */ } else { - method = mctx->pkp ? + ctx = SSL_CTX_new(mctx->pkp ? SSLv23_client_method() : /* proxy */ - SSLv23_server_method(); /* server */ - ctx = SSL_CTX_new(method); /* be more flexible */ + SSLv23_server_method()); /* be more flexible */ } mctx->ssl_ctx = ctx; @@ -709,6 +774,8 @@ static void ssl_init_ctx(server_rec *s, /* XXX: proxy support? */ ssl_init_ctx_cert_chain(s, p, ptemp, mctx); } + + ssl_init_server_extensions(s, p, ptemp, mctx); } static int ssl_server_import_cert(server_rec *s, diff -purN httpd-2.2.0/modules/ssl/ssl_engine_kernel.c httpd-2.2.0-p2/modules/ssl/ssl_engine_kernel.c --- httpd-2.2.0/modules/ssl/ssl_engine_kernel.c 2005-11-10 16:20:05.000000000 +0100 +++ httpd-2.2.0-p2/modules/ssl/ssl_engine_kernel.c 2006-03-27 12:01:12.693689000 +0200 @@ -228,6 +228,22 @@ int ssl_hook_Access(request_rec *r) * the currently active one. */ +#ifndef OPENSSL_NO_TLSEXT + /* + * We will switch to another virtualhost and to its ssl_ctx + if changed, we will force a renegotiation. + */ + if (r->hostname) + { + SSL_CTX *ctx = SSL_get_SSL_CTX(ssl); + if (!ssl_set_vhost_ctx(ssl,(char*)r->hostname)) + return HTTP_FORBIDDEN; + SSL_set_tlsext_host_name(ssl,(char*)r->hostname); + if (ctx != SSL_get_SSL_CTX(ssl)) + renegotiate = TRUE; + } +#endif + /* * Override of SSLCipherSuite * diff -purN httpd-2.2.0/modules/ssl/ssl_private.h httpd-2.2.0-p2/modules/ssl/ssl_private.h --- httpd-2.2.0/modules/ssl/ssl_private.h 2005-09-29 22:44:53.000000000 +0200 +++ httpd-2.2.0-p2/modules/ssl/ssl_private.h 2006-03-27 12:01:23.863690000 +0200 @@ -602,6 +602,9 @@ int ssl_io_buffer_fill(request_ /* PRNG */ int ssl_rand_seed(server_rec *, apr_pool_t *, ssl_rsctx_t, char *); +/** TLS extension context switch */ +int ssl_find_good_ctx(SSL *ssl, const char * servername) ; + /** Utility Functions */ char *ssl_util_vhostid(apr_pool_t *, server_rec *); apr_file_t *ssl_util_ppopen(server_rec *, apr_pool_t *, const char *, diff -purN httpd-2.2.0/modules/ssl/ssl_toolkit_compat.h httpd-2.2.0-p2/modules/ssl/ssl_toolkit_compat.h --- httpd-2.2.0/modules/ssl/ssl_toolkit_compat.h 2005-09-29 22:44:53.000000000 +0200 +++ httpd-2.2.0-p2/modules/ssl/ssl_toolkit_compat.h 2006-03-27 12:01:42.153686000 +0200 @@ -258,6 +258,12 @@ typedef void (*modssl_popfree_fn)(char * #define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP #endif +#ifndef OPENSSL_NO_TLSEXT +#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME +#define OPENSSL_NO_TLSEXT +#endif +#endif + #endif /* SSL_TOOLKIT_COMPAT_H */ /** @} */