summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenedikt Boehm <hollow@gentoo.org>2007-10-25 01:36:27 +0000
committerBenedikt Boehm <hollow@gentoo.org>2007-10-25 01:36:27 +0000
commitba8f3b8cea8bbef98f1caa383a24adf3abb0dd13 (patch)
tree428affed0ee4a97b52674b48ab909ef6ec2eee3e /2.2/patches
parentfix #82311, #194546, #195792 (diff)
downloadapache-ba8f3b8cea8bbef98f1caa383a24adf3abb0dd13.tar.gz
apache-ba8f3b8cea8bbef98f1caa383a24adf3abb0dd13.tar.bz2
apache-ba8f3b8cea8bbef98f1caa383a24adf3abb0dd13.zip
add TLS Server Name Indication (SNI) patch
Diffstat (limited to '2.2/patches')
-rw-r--r--2.2/patches/04_all_mod_ssl_tls_sni.patch217
1 files changed, 217 insertions, 0 deletions
diff --git a/2.2/patches/04_all_mod_ssl_tls_sni.patch b/2.2/patches/04_all_mod_ssl_tls_sni.patch
new file mode 100644
index 0000000..99c9ef2
--- /dev/null
+++ b/2.2/patches/04_all_mod_ssl_tls_sni.patch
@@ -0,0 +1,217 @@
+httpd-2.2.x-sni.patch - server name indication support for Apache 2.2 or later
+(cf. RFC 4366, "Transport Layer Security (TLS) Extensions")
+
+Based on a patch from the EdelKey project (http://www.edelweb.fr/EdelKey/),
+which is used with permission from its author.
+
+Index: httpd-2.2.x/modules/ssl/ssl_engine_init.c
+===================================================================
+--- httpd-2.2.x/modules/ssl/ssl_engine_init.c (revision 515465)
++++ httpd-2.2.x/modules/ssl/ssl_engine_init.c (working copy)
+@@ -156,6 +156,87 @@ 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;
++ BOOL found = FALSE;
++ apr_array_header_t *names;
++ int i;
++
++ /* check ServerName */
++ if (!strcasecmp(servername, s->server_hostname))
++ found = TRUE;
++
++ /* if not matched yet, check ServerAlias entries */
++ if (!found) {
++ names = s->names;
++ if (names) {
++ char **name = (char **) names->elts;
++ for (i = 0; i < names->nelts; ++i) {
++ if(!name[i]) continue;
++ if (!strcasecmp(servername, name[i])) {
++ found = TRUE;
++ break;
++ }
++ }
++ }
++ }
++
++ /* if still no match, check ServerAlias entries with wildcards */
++ if (!found) {
++ names = s->wild_names;
++ if (names) {
++ char **name = (char **) names->elts;
++ for (i = 0; i < names->nelts; ++i) {
++ if(!name[i]) continue;
++ if (!ap_strcasecmp_match(servername, name[i])) {
++ found = TRUE;
++ break;
++ }
++ }
++ }
++ }
++
++ /* set SSL_CTX (if matched) */
++ if (found) {
++ 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);
++}
++
++int ssl_servername_cb(SSL *s, int *al, modssl_ctx_t *mctx)
++{
++ 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,6 +457,29 @@ 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,
+@@ -709,6 +813,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,
+@@ -1035,6 +1141,7 @@ void ssl_init_CheckServers(server_rec *b
+ }
+ }
+
++#ifdef OPENSSL_NO_TLSEXT
+ /*
+ * Give out warnings when more than one SSL-aware virtual server uses the
+ * same IP:port. This doesn't work because mod_ssl then will always use
+@@ -1079,6 +1186,7 @@ void ssl_init_CheckServers(server_rec *b
+ "Init: You should not use name-based "
+ "virtual hosts in conjunction with SSL!!");
+ }
++#endif
+ }
+
+ #ifdef SSLC_VERSION_NUMBER
+Index: httpd-2.2.x/modules/ssl/ssl_engine_kernel.c
+===================================================================
+--- httpd-2.2.x/modules/ssl/ssl_engine_kernel.c (revision 515465)
++++ httpd-2.2.x/modules/ssl/ssl_engine_kernel.c (working copy)
+@@ -231,6 +231,19 @@ 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_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) {
++ SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
++ if (ssl_set_vhost_ctx(ssl,(char *)r->hostname) &&
++ ctx != SSL_get_SSL_CTX(ssl))
++ renegotiate = TRUE;
++ }
++#endif
++
+ /*
+ * Override of SSLCipherSuite
+ *
+@@ -997,6 +1010,9 @@ int ssl_hook_Fixup(request_rec *r)
+ SSLDirConfigRec *dc = myDirConfig(r);
+ apr_table_t *env = r->subprocess_env;
+ char *var, *val = "";
++#ifndef OPENSSL_NO_TLSEXT
++ const char* servername;
++#endif
+ STACK_OF(X509) *peer_certs;
+ SSL *ssl;
+ int i;
+@@ -1018,6 +1034,12 @@ int ssl_hook_Fixup(request_rec *r)
+ /* the always present HTTPS (=HTTP over SSL) flag! */
+ apr_table_setn(env, "HTTPS", "on");
+
++#ifndef OPENSSL_NO_TLSEXT
++ /* add content of SNI TLS extension (if supplied with ClientHello) */
++ if (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
++ apr_table_set(env, "TLS_SNI", servername);
++#endif
++
+ /* standard SSL environment variables */
+ if (dc->nOptions & SSL_OPT_STDENVVARS) {
+ for (i = 0; ssl_hook_Fixup_vars[i]; i++) {
+Index: httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h
+===================================================================
+--- httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h (revision 515465)
++++ httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h (working copy)
+@@ -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 */
+
+ /** @} */