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
*/
}
}
+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,
/* 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,
}
}
+#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
"Init: You should not use name-based "
"virtual hosts in conjunction with SSL!!");
}
+#endif
}
#ifdef SSLC_VERSION_NUMBER
* 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
*
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;
/* 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, "SSL_TLS_SNI", servername);
+ }
+#endif
+
/* standard SSL environment variables */
if (dc->nOptions & SSL_OPT_STDENVVARS) {
for (i = 0; ssl_hook_Fixup_vars[i]; i++) {