1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-07 04:02:58 +03:00

Added server name indication (RFC 4366) support (PR 34607).

Submitted by: Kaspar Brand <asfbugz velox.ch>


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@606190 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Guenter Knauf
2007-12-21 13:16:21 +00:00
parent fa7344eaae
commit b47b9d2718
4 changed files with 140 additions and 0 deletions

View File

@@ -2,6 +2,9 @@
Changes with Apache 2.3.0 Changes with Apache 2.3.0
[ When backported to 2.2.x, remove entry from this file ] [ When backported to 2.2.x, remove entry from this file ]
*) mod_ssl: Added server name indication support (RFC 4366).
PR 34607. [Kaspar Brand <asfbugz velox.ch>]
*) ApacheMonitor.exe: Introduce --kill argument for use by the *) ApacheMonitor.exe: Introduce --kill argument for use by the
installer. This will permit the installation tool to remove installer. This will permit the installation tool to remove
all running instances before attempting to remove the .exe. all running instances before attempting to remove the .exe.

View File

@@ -135,6 +135,87 @@ static int ssl_tmp_keys_init(server_rec *s)
return OK; 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 * Per-module initialization
*/ */
@@ -355,6 +436,29 @@ static void ssl_init_server_check(server_rec *s,
} }
} }
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, static void ssl_init_ctx_protocol(server_rec *s,
apr_pool_t *p, apr_pool_t *p,
apr_pool_t *ptemp, apr_pool_t *ptemp,
@@ -712,6 +816,8 @@ static void ssl_init_ctx(server_rec *s,
/* XXX: proxy support? */ /* XXX: proxy support? */
ssl_init_ctx_cert_chain(s, p, ptemp, mctx); 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, static int ssl_server_import_cert(server_rec *s,
@@ -1038,6 +1144,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
} }
} }
#ifdef OPENSSL_NO_TLSEXT
/* /*
* Give out warnings when more than one SSL-aware virtual server uses the * 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 * same IP:port. This doesn't work because mod_ssl then will always use
@@ -1082,6 +1189,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
"Init: You should not use name-based " "Init: You should not use name-based "
"virtual hosts in conjunction with SSL!!"); "virtual hosts in conjunction with SSL!!");
} }
#endif
} }
#ifdef SSLC_VERSION_NUMBER #ifdef SSLC_VERSION_NUMBER

View File

@@ -297,6 +297,19 @@ int ssl_hook_Access(request_rec *r)
* the currently active one. * 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 * Override of SSLCipherSuite
* *
@@ -1063,6 +1076,9 @@ int ssl_hook_Fixup(request_rec *r)
SSLDirConfigRec *dc = myDirConfig(r); SSLDirConfigRec *dc = myDirConfig(r);
apr_table_t *env = r->subprocess_env; apr_table_t *env = r->subprocess_env;
char *var, *val = ""; char *var, *val = "";
#ifndef OPENSSL_NO_TLSEXT
const char* servername;
#endif
STACK_OF(X509) *peer_certs; STACK_OF(X509) *peer_certs;
SSL *ssl; SSL *ssl;
int i; int i;
@@ -1089,6 +1105,13 @@ int ssl_hook_Fixup(request_rec *r)
/* the always present HTTPS (=HTTP over SSL) flag! */ /* the always present HTTPS (=HTTP over SSL) flag! */
apr_table_setn(env, "HTTPS", "on"); 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, "SSL_TLS_SNI", servername);
}
#endif
/* standard SSL environment variables */ /* standard SSL environment variables */
if (dc->nOptions & SSL_OPT_STDENVVARS) { if (dc->nOptions & SSL_OPT_STDENVVARS) {
for (i = 0; ssl_hook_Fixup_vars[i]; i++) { for (i = 0; ssl_hook_Fixup_vars[i]; i++) {

View File

@@ -270,6 +270,12 @@ typedef void (*modssl_popfree_fn)(char *data);
#define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP #define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
#endif #endif
#ifndef OPENSSL_NO_TLSEXT
#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
#define OPENSSL_NO_TLSEXT
#endif
#endif
#endif /* SSL_TOOLKIT_COMPAT_H */ #endif /* SSL_TOOLKIT_COMPAT_H */
/** @} */ /** @} */