[1115] | 1 | http://sni.velox.ch/httpd-2.2.11-sni.20090427.patch - server name indication |
---|
| 2 | support for mod_ssl / Apache 2.2.11 (RFC 4366, section 3.1) |
---|
[683] | 3 | |
---|
[1115] | 4 | Last updated 2009-04-27, by Kaspar Brand. |
---|
| 5 | Provided AS IS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND. |
---|
[683] | 6 | |
---|
[1115] | 7 | Based on a patch from the EdelKey project (http://www.edelweb.fr/EdelKey/files/), |
---|
| 8 | includes further improvements by Ruediger Pluem (from httpd trunk). |
---|
[683] | 9 | |
---|
[1102] | 10 | Needs openssl-SNAP-20060330 / OpenSSL 0.9.8f or later |
---|
| 11 | to work properly (ftp://ftp.openssl.org/snapshot/). OpenSSL versions |
---|
| 12 | prior to 0.9.8j must be configured explicitly for TLS extension support |
---|
| 13 | at compile time ("./config enable-tlsext"). |
---|
| 14 | |
---|
[1115] | 15 | Index: httpd-2.2.11/modules/ssl/ssl_private.h |
---|
[683] | 16 | =================================================================== |
---|
[1115] | 17 | --- httpd-2.2.11/modules/ssl/ssl_private.h (revision 768863) |
---|
| 18 | +++ httpd-2.2.11/modules/ssl/ssl_private.h (working copy) |
---|
[683] | 19 | @@ -35,6 +35,7 @@ |
---|
| 20 | #include "http_connection.h" |
---|
| 21 | #include "http_request.h" |
---|
| 22 | #include "http_protocol.h" |
---|
| 23 | +#include "http_vhost.h" |
---|
| 24 | #include "util_script.h" |
---|
| 25 | #include "util_filter.h" |
---|
| 26 | #include "util_ebcdic.h" |
---|
[1115] | 27 | @@ -129,6 +130,9 @@ ap_set_module_config(c->conn_config, &ssl_module, |
---|
| 28 | #define mySrvConfig(srv) (SSLSrvConfigRec *)ap_get_module_config(srv->module_config, &ssl_module) |
---|
| 29 | #define myDirConfig(req) (SSLDirConfigRec *)ap_get_module_config(req->per_dir_config, &ssl_module) |
---|
| 30 | #define myModConfig(srv) (mySrvConfig((srv)))->mc |
---|
| 31 | +#define mySrvFromConn(c) (myConnConfig(c))->server |
---|
| 32 | +#define mySrvConfigFromConn(c) mySrvConfig(mySrvFromConn(c)) |
---|
| 33 | +#define myModConfigFromConn(c) myModConfig(mySrvFromConn(c)) |
---|
| 34 | |
---|
| 35 | #define myCtxVarSet(mc,num,val) mc->rCtx.pV##num = val |
---|
| 36 | #define myCtxVarGet(mc,num,type) (type)(mc->rCtx.pV##num) |
---|
| 37 | @@ -347,6 +351,7 @@ typedef struct { |
---|
| 38 | int is_proxy; |
---|
| 39 | int disabled; |
---|
| 40 | int non_ssl_request; |
---|
| 41 | + server_rec *server; |
---|
| 42 | } SSLConnRec; |
---|
| 43 | |
---|
| 44 | typedef struct { |
---|
| 45 | @@ -449,6 +454,9 @@ struct SSLSrvConfigRec { |
---|
| 46 | BOOL cipher_server_pref; |
---|
| 47 | modssl_ctx_t *server; |
---|
| 48 | modssl_ctx_t *proxy; |
---|
| 49 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 50 | + ssl_enabled_t strict_sni_vhost_check; |
---|
| 51 | +#endif |
---|
| 52 | }; |
---|
| 53 | |
---|
| 54 | /** |
---|
| 55 | @@ -513,6 +521,9 @@ const char *ssl_cmd_SSLOptions(cmd_parms *, void |
---|
| 56 | const char *ssl_cmd_SSLRequireSSL(cmd_parms *, void *); |
---|
| 57 | const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *); |
---|
| 58 | const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); |
---|
| 59 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 60 | +const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag); |
---|
| 61 | +#endif |
---|
| 62 | |
---|
| 63 | const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); |
---|
| 64 | const char *ssl_cmd_SSLProxyProtocol(cmd_parms *, void *, const char *); |
---|
| 65 | @@ -555,6 +566,9 @@ int ssl_callback_NewSessionCacheEntry(SSL |
---|
[683] | 66 | SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); |
---|
| 67 | void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); |
---|
| 68 | void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); |
---|
| 69 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 70 | +int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); |
---|
| 71 | +#endif |
---|
| 72 | |
---|
| 73 | /** Session Cache Support */ |
---|
| 74 | void ssl_scache_init(server_rec *, apr_pool_t *); |
---|
[1115] | 75 | Index: httpd-2.2.11/modules/ssl/ssl_engine_init.c |
---|
[683] | 76 | =================================================================== |
---|
[1115] | 77 | --- httpd-2.2.11/modules/ssl/ssl_engine_init.c (revision 768863) |
---|
| 78 | +++ httpd-2.2.11/modules/ssl/ssl_engine_init.c (working copy) |
---|
[1102] | 79 | @@ -358,6 +358,33 @@ static void ssl_init_server_check(server_rec *s, |
---|
[683] | 80 | } |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 84 | +static void ssl_init_ctx_tls_extensions(server_rec *s, |
---|
| 85 | + apr_pool_t *p, |
---|
| 86 | + apr_pool_t *ptemp, |
---|
| 87 | + modssl_ctx_t *mctx) |
---|
| 88 | +{ |
---|
| 89 | + /* |
---|
| 90 | + * Configure TLS extensions support |
---|
| 91 | + */ |
---|
| 92 | + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, |
---|
| 93 | + "Configuring TLS extension handling"); |
---|
| 94 | + |
---|
| 95 | + /* |
---|
| 96 | + * Server name indication (SNI) |
---|
| 97 | + */ |
---|
| 98 | + if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx, |
---|
| 99 | + ssl_callback_ServerNameIndication) || |
---|
| 100 | + !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) { |
---|
| 101 | + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, |
---|
| 102 | + "Unable to initialize TLS servername extension " |
---|
| 103 | + "callback (incompatible OpenSSL version?)"); |
---|
| 104 | + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); |
---|
| 105 | + ssl_die(); |
---|
| 106 | + } |
---|
| 107 | +} |
---|
| 108 | +#endif |
---|
| 109 | + |
---|
| 110 | static void ssl_init_ctx_protocol(server_rec *s, |
---|
| 111 | apr_pool_t *p, |
---|
| 112 | apr_pool_t *ptemp, |
---|
[1102] | 113 | @@ -690,6 +717,9 @@ static void ssl_init_ctx(server_rec *s, |
---|
[683] | 114 | if (mctx->pks) { |
---|
| 115 | /* XXX: proxy support? */ |
---|
| 116 | ssl_init_ctx_cert_chain(s, p, ptemp, mctx); |
---|
| 117 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 118 | + ssl_init_ctx_tls_extensions(s, p, ptemp, mctx); |
---|
| 119 | +#endif |
---|
| 120 | } |
---|
| 121 | } |
---|
| 122 | |
---|
[1102] | 123 | @@ -1039,9 +1069,19 @@ void ssl_init_CheckServers(server_rec *base_server |
---|
[816] | 124 | klen = strlen(key); |
---|
| 125 | |
---|
[683] | 126 | if ((ps = (server_rec *)apr_hash_get(table, key, klen))) { |
---|
[816] | 127 | - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, |
---|
| 128 | + ap_log_error(APLOG_MARK, |
---|
| 129 | +#ifdef OPENSSL_NO_TLSEXT |
---|
| 130 | + APLOG_WARNING, |
---|
| 131 | +#else |
---|
| 132 | + APLOG_DEBUG, |
---|
| 133 | +#endif |
---|
| 134 | + 0, |
---|
[683] | 135 | base_server, |
---|
| 136 | +#ifdef OPENSSL_NO_TLSEXT |
---|
| 137 | "Init: SSL server IP/port conflict: " |
---|
| 138 | +#else |
---|
| 139 | + "Init: SSL server IP/port overlap: " |
---|
| 140 | +#endif |
---|
| 141 | "%s (%s:%d) vs. %s (%s:%d)", |
---|
| 142 | ssl_util_vhostid(p, s), |
---|
| 143 | (s->defn_name ? s->defn_name : "unknown"), |
---|
[1102] | 144 | @@ -1058,8 +1098,14 @@ void ssl_init_CheckServers(server_rec *base_server |
---|
[683] | 145 | |
---|
| 146 | if (conflict) { |
---|
| 147 | ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, |
---|
| 148 | +#ifdef OPENSSL_NO_TLSEXT |
---|
| 149 | "Init: You should not use name-based " |
---|
| 150 | "virtual hosts in conjunction with SSL!!"); |
---|
| 151 | +#else |
---|
| 152 | + "Init: Name-based SSL virtual hosts only " |
---|
| 153 | + "work for clients with TLS server name indication " |
---|
| 154 | + "support (RFC 4366)"); |
---|
| 155 | +#endif |
---|
| 156 | } |
---|
| 157 | } |
---|
| 158 | |
---|
[1115] | 159 | Index: httpd-2.2.11/modules/ssl/ssl_engine_config.c |
---|
[683] | 160 | =================================================================== |
---|
[1115] | 161 | --- httpd-2.2.11/modules/ssl/ssl_engine_config.c (revision 768863) |
---|
| 162 | +++ httpd-2.2.11/modules/ssl/ssl_engine_config.c (working copy) |
---|
| 163 | @@ -169,6 +169,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_ |
---|
| 164 | sc->vhost_id_len = 0; /* set during module init */ |
---|
| 165 | sc->session_cache_timeout = UNSET; |
---|
| 166 | sc->cipher_server_pref = UNSET; |
---|
| 167 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 168 | + sc->strict_sni_vhost_check = SSL_ENABLED_UNSET; |
---|
| 169 | +#endif |
---|
| 170 | |
---|
| 171 | modssl_ctx_init_proxy(sc, p); |
---|
| 172 | |
---|
| 173 | @@ -257,6 +260,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void |
---|
| 174 | cfgMergeBool(proxy_enabled); |
---|
| 175 | cfgMergeInt(session_cache_timeout); |
---|
| 176 | cfgMergeBool(cipher_server_pref); |
---|
| 177 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 178 | + cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET); |
---|
| 179 | +#endif |
---|
| 180 | |
---|
| 181 | modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); |
---|
| 182 | |
---|
| 183 | @@ -1411,6 +1417,17 @@ const char *ssl_cmd_SSLUserName(cmd_parms *cmd, vo |
---|
| 184 | return NULL; |
---|
| 185 | } |
---|
| 186 | |
---|
| 187 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 188 | +const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag) |
---|
| 189 | +{ |
---|
| 190 | + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); |
---|
| 191 | + |
---|
| 192 | + sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE; |
---|
| 193 | + |
---|
| 194 | + return NULL; |
---|
| 195 | +} |
---|
| 196 | +#endif |
---|
| 197 | + |
---|
| 198 | void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) |
---|
| 199 | { |
---|
| 200 | if (!ap_exists_config_define("DUMP_CERTS")) { |
---|
| 201 | Index: httpd-2.2.11/modules/ssl/ssl_engine_io.c |
---|
| 202 | =================================================================== |
---|
| 203 | --- httpd-2.2.11/modules/ssl/ssl_engine_io.c (revision 768863) |
---|
| 204 | +++ httpd-2.2.11/modules/ssl/ssl_engine_io.c (working copy) |
---|
| 205 | @@ -695,7 +695,7 @@ static apr_status_t ssl_io_input_read(bio_filter_i |
---|
| 206 | */ |
---|
| 207 | ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c, |
---|
| 208 | "SSL library error %d reading data", ssl_err); |
---|
| 209 | - ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); |
---|
| 210 | + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c)); |
---|
| 211 | |
---|
| 212 | } |
---|
| 213 | if (inctx->rc == APR_SUCCESS) { |
---|
| 214 | @@ -799,7 +799,7 @@ static apr_status_t ssl_filter_write(ap_filter_t * |
---|
| 215 | */ |
---|
| 216 | ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, |
---|
| 217 | "SSL library error %d writing data", ssl_err); |
---|
| 218 | - ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); |
---|
| 219 | + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c)); |
---|
| 220 | } |
---|
| 221 | if (outctx->rc == APR_SUCCESS) { |
---|
| 222 | outctx->rc = APR_EGENERAL; |
---|
| 223 | @@ -861,7 +861,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_ |
---|
| 224 | ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, |
---|
| 225 | "SSL handshake failed: HTTP spoken on HTTPS port; " |
---|
| 226 | "trying to send HTML error page"); |
---|
| 227 | - ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, f->c->base_server); |
---|
| 228 | + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, sslconn->server); |
---|
| 229 | |
---|
| 230 | sslconn->non_ssl_request = 1; |
---|
| 231 | ssl_io_filter_disable(sslconn, f); |
---|
| 232 | @@ -971,11 +971,11 @@ static apr_status_t ssl_filter_io_shutdown(ssl_fil |
---|
| 233 | SSL_smart_shutdown(ssl); |
---|
| 234 | |
---|
| 235 | /* and finally log the fact that we've closed the connection */ |
---|
| 236 | - if (c->base_server->loglevel >= APLOG_INFO) { |
---|
| 237 | + if (mySrvFromConn(c)->loglevel >= APLOG_INFO) { |
---|
| 238 | ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, |
---|
| 239 | "Connection closed to child %ld with %s shutdown " |
---|
| 240 | "(server %s)", |
---|
| 241 | - c->id, type, ssl_util_vhostid(c->pool, c->base_server)); |
---|
| 242 | + c->id, type, ssl_util_vhostid(c->pool, mySrvFromConn(c))); |
---|
| 243 | } |
---|
| 244 | |
---|
| 245 | /* deallocate the SSL connection */ |
---|
| 246 | @@ -1021,21 +1021,23 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t |
---|
| 247 | { |
---|
| 248 | conn_rec *c = (conn_rec *)SSL_get_app_data(filter_ctx->pssl); |
---|
| 249 | SSLConnRec *sslconn = myConnConfig(c); |
---|
| 250 | - SSLSrvConfigRec *sc = mySrvConfig(c->base_server); |
---|
| 251 | + SSLSrvConfigRec *sc; |
---|
| 252 | X509 *cert; |
---|
| 253 | int n; |
---|
| 254 | int ssl_err; |
---|
| 255 | long verify_result; |
---|
| 256 | + server_rec *server; |
---|
| 257 | |
---|
| 258 | if (SSL_is_init_finished(filter_ctx->pssl)) { |
---|
| 259 | return APR_SUCCESS; |
---|
| 260 | } |
---|
| 261 | |
---|
| 262 | + server = mySrvFromConn(c); |
---|
| 263 | if (sslconn->is_proxy) { |
---|
| 264 | if ((n = SSL_connect(filter_ctx->pssl)) <= 0) { |
---|
| 265 | ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, |
---|
| 266 | "SSL Proxy connect failed"); |
---|
| 267 | - ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); |
---|
| 268 | + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server); |
---|
| 269 | /* ensure that the SSL structures etc are freed, etc: */ |
---|
| 270 | ssl_filter_io_shutdown(filter_ctx, c, 1); |
---|
| 271 | return HTTP_BAD_GATEWAY; |
---|
| 272 | @@ -1092,8 +1094,8 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t |
---|
| 273 | ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, |
---|
| 274 | "SSL library error %d in handshake " |
---|
| 275 | "(server %s)", ssl_err, |
---|
| 276 | - ssl_util_vhostid(c->pool, c->base_server)); |
---|
| 277 | - ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); |
---|
| 278 | + ssl_util_vhostid(c->pool, server)); |
---|
| 279 | + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server); |
---|
| 280 | |
---|
| 281 | } |
---|
| 282 | if (inctx->rc == APR_SUCCESS) { |
---|
| 283 | @@ -1102,6 +1104,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t |
---|
| 284 | |
---|
| 285 | return ssl_filter_io_shutdown(filter_ctx, c, 1); |
---|
| 286 | } |
---|
| 287 | + sc = mySrvConfig(sslconn->server); |
---|
| 288 | |
---|
| 289 | /* |
---|
| 290 | * Check for failed client authentication |
---|
| 291 | @@ -1127,7 +1130,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t |
---|
| 292 | "accepting certificate based on " |
---|
| 293 | "\"SSLVerifyClient optional_no_ca\" " |
---|
| 294 | "configuration"); |
---|
| 295 | - ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); |
---|
| 296 | + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server); |
---|
| 297 | } |
---|
| 298 | else { |
---|
| 299 | const char *error = sslconn->verify_error ? |
---|
| 300 | @@ -1137,7 +1140,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t |
---|
| 301 | ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, |
---|
| 302 | "SSL client authentication failed: %s", |
---|
| 303 | error ? error : "unknown"); |
---|
| 304 | - ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, c->base_server); |
---|
| 305 | + ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server); |
---|
| 306 | |
---|
| 307 | return ssl_filter_io_shutdown(filter_ctx, c, 1); |
---|
| 308 | } |
---|
| 309 | @@ -1809,7 +1812,7 @@ long ssl_io_data_cb(BIO *bio, int cmd, |
---|
| 310 | return rc; |
---|
| 311 | if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL) |
---|
| 312 | return rc; |
---|
| 313 | - s = c->base_server; |
---|
| 314 | + s = mySrvFromConn(c); |
---|
| 315 | |
---|
| 316 | if ( cmd == (BIO_CB_WRITE|BIO_CB_RETURN) |
---|
| 317 | || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) { |
---|
| 318 | Index: httpd-2.2.11/modules/ssl/ssl_engine_vars.c |
---|
| 319 | =================================================================== |
---|
| 320 | --- httpd-2.2.11/modules/ssl/ssl_engine_vars.c (revision 768863) |
---|
| 321 | +++ httpd-2.2.11/modules/ssl/ssl_engine_vars.c (working copy) |
---|
[1102] | 322 | @@ -320,6 +320,12 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, con |
---|
[683] | 323 | else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) { |
---|
| 324 | result = ssl_var_lookup_ssl_compress_meth(ssl); |
---|
| 325 | } |
---|
| 326 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 327 | + else if (ssl != NULL && strcEQ(var, "TLS_SNI")) { |
---|
| 328 | + result = apr_pstrdup(p, SSL_get_servername(ssl, |
---|
| 329 | + TLSEXT_NAMETYPE_host_name)); |
---|
| 330 | + } |
---|
| 331 | +#endif |
---|
| 332 | return result; |
---|
| 333 | } |
---|
| 334 | |
---|
[1115] | 335 | @@ -589,7 +595,7 @@ static char *ssl_var_lookup_ssl_cert_verify(apr_po |
---|
| 336 | vrc = SSL_get_verify_result(ssl); |
---|
| 337 | xs = SSL_get_peer_certificate(ssl); |
---|
| 338 | |
---|
| 339 | - if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs == NULL) |
---|
| 340 | + if (vrc == X509_V_OK && verr == NULL && xs == NULL) |
---|
| 341 | /* no client verification done at all */ |
---|
| 342 | result = "NONE"; |
---|
| 343 | else if (vrc == X509_V_OK && verr == NULL && vinfo == NULL && xs != NULL) |
---|
| 344 | Index: httpd-2.2.11/modules/ssl/ssl_engine_kernel.c |
---|
[683] | 345 | =================================================================== |
---|
[1115] | 346 | --- httpd-2.2.11/modules/ssl/ssl_engine_kernel.c (revision 768863) |
---|
| 347 | +++ httpd-2.2.11/modules/ssl/ssl_engine_kernel.c (working copy) |
---|
[683] | 348 | @@ -31,6 +31,9 @@ |
---|
| 349 | #include "ssl_private.h" |
---|
| 350 | |
---|
| 351 | static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); |
---|
| 352 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 353 | +static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s); |
---|
| 354 | +#endif |
---|
| 355 | |
---|
| 356 | /* |
---|
| 357 | * Post Read Request Handler |
---|
[816] | 358 | @@ -39,6 +42,9 @@ int ssl_hook_ReadReq(request_rec *r) |
---|
[683] | 359 | { |
---|
| 360 | SSLConnRec *sslconn = myConnConfig(r->connection); |
---|
| 361 | SSL *ssl; |
---|
| 362 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 363 | + const char *servername; |
---|
| 364 | +#endif |
---|
| 365 | |
---|
| 366 | if (!sslconn) { |
---|
| 367 | return DECLINED; |
---|
[1115] | 368 | @@ -87,6 +93,51 @@ int ssl_hook_ReadReq(request_rec *r) |
---|
[683] | 369 | if (!ssl) { |
---|
| 370 | return DECLINED; |
---|
| 371 | } |
---|
| 372 | +#ifndef OPENSSL_NO_TLSEXT |
---|
[1102] | 373 | + if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { |
---|
| 374 | + char *host, *scope_id; |
---|
| 375 | + apr_port_t port; |
---|
| 376 | + apr_status_t rv; |
---|
| 377 | + |
---|
| 378 | + /* |
---|
| 379 | + * The SNI extension supplied a hostname. So don't accept requests |
---|
| 380 | + * with either no hostname or a different hostname. |
---|
| 381 | + */ |
---|
| 382 | + if (!r->hostname) { |
---|
| 383 | + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, |
---|
| 384 | + "Hostname %s provided via SNI, but no hostname" |
---|
| 385 | + " provided in HTTP request", servername); |
---|
| 386 | + return HTTP_BAD_REQUEST; |
---|
| 387 | + } |
---|
| 388 | + rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool); |
---|
| 389 | + if (rv != APR_SUCCESS || scope_id) { |
---|
| 390 | + return HTTP_BAD_REQUEST; |
---|
| 391 | + } |
---|
| 392 | + if (strcmp(host, servername)) { |
---|
| 393 | + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, |
---|
| 394 | + "Hostname %s provided via SNI and hostname %s provided" |
---|
| 395 | + " via HTTP are different", servername, host); |
---|
| 396 | + return HTTP_BAD_REQUEST; |
---|
| 397 | + } |
---|
[683] | 398 | + } |
---|
[1115] | 399 | + else if ((((mySrvConfig(r->server))->strict_sni_vhost_check |
---|
| 400 | + == SSL_ENABLED_TRUE) |
---|
| 401 | + || (mySrvConfig(sslconn->server))->strict_sni_vhost_check |
---|
| 402 | + == SSL_ENABLED_TRUE) |
---|
| 403 | + && r->connection->vhost_lookup_data) { |
---|
| 404 | + /* |
---|
| 405 | + * We are using a name based configuration here, but no hostname was |
---|
| 406 | + * provided via SNI. Don't allow that if are requested to do strict |
---|
| 407 | + * checking. Check whether this strict checking was setup either in the |
---|
| 408 | + * server config we used for handshaking or in our current server. |
---|
| 409 | + * This should avoid insecure configuration by accident. |
---|
| 410 | + */ |
---|
| 411 | + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, |
---|
| 412 | + "No hostname was provided via SNI for a name based" |
---|
| 413 | + " virtual host"); |
---|
| 414 | + return HTTP_FORBIDDEN; |
---|
| 415 | + } |
---|
[683] | 416 | +#endif |
---|
| 417 | SSL_set_app_data2(ssl, r); |
---|
| 418 | |
---|
| 419 | /* |
---|
[1115] | 420 | @@ -155,10 +206,11 @@ static void ssl_configure_env(request_rec *r, SSLC |
---|
| 421 | */ |
---|
| 422 | int ssl_hook_Access(request_rec *r) |
---|
| 423 | { |
---|
| 424 | - SSLDirConfigRec *dc = myDirConfig(r); |
---|
| 425 | - SSLSrvConfigRec *sc = mySrvConfig(r->server); |
---|
| 426 | - SSLConnRec *sslconn = myConnConfig(r->connection); |
---|
| 427 | - SSL *ssl = sslconn ? sslconn->ssl : NULL; |
---|
| 428 | + SSLDirConfigRec *dc = myDirConfig(r); |
---|
| 429 | + SSLSrvConfigRec *sc = mySrvConfig(r->server); |
---|
| 430 | + SSLConnRec *sslconn = myConnConfig(r->connection); |
---|
| 431 | + SSL *ssl = sslconn ? sslconn->ssl : NULL; |
---|
| 432 | + server_rec *handshakeserver = sslconn ? sslconn->server : NULL; |
---|
| 433 | SSL_CTX *ctx = NULL; |
---|
| 434 | apr_array_header_t *requires; |
---|
| 435 | ssl_require_t *ssl_requires; |
---|
| 436 | @@ -252,7 +304,7 @@ int ssl_hook_Access(request_rec *r) |
---|
[816] | 437 | * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no |
---|
| 438 | * implicit optimizations. |
---|
| 439 | */ |
---|
| 440 | - if (dc->szCipherSuite) { |
---|
[1115] | 441 | + if (dc->szCipherSuite || (r->server != handshakeserver)) { |
---|
[816] | 442 | /* remember old state */ |
---|
| 443 | |
---|
| 444 | if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { |
---|
[1115] | 445 | @@ -267,7 +319,10 @@ int ssl_hook_Access(request_rec *r) |
---|
[816] | 446 | } |
---|
| 447 | |
---|
| 448 | /* configure new state */ |
---|
| 449 | - if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) { |
---|
[1102] | 450 | + if ((dc->szCipherSuite || sc->server->auth.cipher_suite) && |
---|
| 451 | + !modssl_set_cipher_list(ssl, dc->szCipherSuite ? |
---|
| 452 | + dc->szCipherSuite : |
---|
| 453 | + sc->server->auth.cipher_suite)) { |
---|
[816] | 454 | ap_log_error(APLOG_MARK, APLOG_WARNING, 0, |
---|
| 455 | r->server, |
---|
| 456 | "Unable to reconfigure (per-directory) " |
---|
[1115] | 457 | @@ -334,8 +389,13 @@ int ssl_hook_Access(request_rec *r) |
---|
[816] | 458 | sk_SSL_CIPHER_free(cipher_list_old); |
---|
| 459 | } |
---|
| 460 | |
---|
| 461 | - /* tracing */ |
---|
| 462 | if (renegotiate) { |
---|
| 463 | +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE |
---|
| 464 | + if (sc->cipher_server_pref == TRUE) { |
---|
| 465 | + SSL_set_options(ssl, SSL_OP_CIPHER_SERVER_PREFERENCE); |
---|
| 466 | + } |
---|
| 467 | +#endif |
---|
| 468 | + /* tracing */ |
---|
| 469 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
---|
| 470 | "Reconfigured cipher suite will force renegotiation"); |
---|
| 471 | } |
---|
[1115] | 472 | @@ -348,24 +408,22 @@ int ssl_hook_Access(request_rec *r) |
---|
| 473 | * function and not by OpenSSL internally (and our function is aware of |
---|
| 474 | * both the per-server and per-directory contexts). So we cannot ask |
---|
| 475 | * OpenSSL about the currently verify depth. Instead we remember it in our |
---|
| 476 | - * ap_ctx attached to the SSL* of OpenSSL. We've to force the |
---|
| 477 | + * SSLConnRec attached to the SSL* of OpenSSL. We've to force the |
---|
| 478 | * renegotiation if the reconfigured/new verify depth is less than the |
---|
[816] | 479 | * currently active/remembered verify depth (because this means more |
---|
| 480 | * restriction on the certificate chain). |
---|
| 481 | */ |
---|
| 482 | - if (dc->nVerifyDepth != UNSET) { |
---|
[1102] | 483 | - /* XXX: doesnt look like sslconn->verify_depth is actually used */ |
---|
| 484 | - if (!(n = sslconn->verify_depth)) { |
---|
| 485 | - sslconn->verify_depth = n = sc->server->auth.verify_depth; |
---|
| 486 | - } |
---|
| 487 | - |
---|
| 488 | - /* determine whether a renegotiation has to be forced */ |
---|
| 489 | - if (dc->nVerifyDepth < n) { |
---|
| 490 | - renegotiate = TRUE; |
---|
| 491 | - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
---|
| 492 | - "Reduced client verification depth will force " |
---|
| 493 | - "renegotiation"); |
---|
| 494 | - } |
---|
[1115] | 495 | + n = sslconn->verify_depth ? |
---|
| 496 | + sslconn->verify_depth : |
---|
| 497 | + (mySrvConfig(handshakeserver))->server->auth.verify_depth; |
---|
| 498 | + /* determine the new depth */ |
---|
[1102] | 499 | + sslconn->verify_depth = (dc->nVerifyDepth != UNSET) ? |
---|
| 500 | + dc->nVerifyDepth : sc->server->auth.verify_depth; |
---|
[1115] | 501 | + if (sslconn->verify_depth < n) { |
---|
[1102] | 502 | + renegotiate = TRUE; |
---|
| 503 | + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
---|
| 504 | + "Reduced client verification depth will force " |
---|
| 505 | + "renegotiation"); |
---|
| 506 | } |
---|
[816] | 507 | |
---|
[1102] | 508 | /* |
---|
[1115] | 509 | @@ -382,18 +440,22 @@ int ssl_hook_Access(request_rec *r) |
---|
[816] | 510 | * verification but at least skip the I/O-intensive renegotation |
---|
| 511 | * handshake. |
---|
| 512 | */ |
---|
| 513 | - if (dc->nVerifyClient != SSL_CVERIFY_UNSET) { |
---|
| 514 | + if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) || |
---|
| 515 | + (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) { |
---|
| 516 | /* remember old state */ |
---|
| 517 | verify_old = SSL_get_verify_mode(ssl); |
---|
| 518 | /* configure new state */ |
---|
| 519 | verify = SSL_VERIFY_NONE; |
---|
| 520 | |
---|
| 521 | - if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) { |
---|
| 522 | + if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) || |
---|
| 523 | + (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) { |
---|
| 524 | verify |= SSL_VERIFY_PEER_STRICT; |
---|
| 525 | } |
---|
| 526 | |
---|
| 527 | if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) || |
---|
| 528 | - (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA)) |
---|
| 529 | + (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) || |
---|
| 530 | + (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) || |
---|
| 531 | + (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) |
---|
| 532 | { |
---|
| 533 | verify |= SSL_VERIFY_PEER; |
---|
| 534 | } |
---|
[1115] | 535 | @@ -430,6 +492,45 @@ int ssl_hook_Access(request_rec *r) |
---|
| 536 | renegotiate_quick ? "quick " : ""); |
---|
| 537 | } |
---|
| 538 | } |
---|
| 539 | + /* If we're handling a request for a vhost other than the default one, |
---|
| 540 | + * then we need to make sure that client authentication is properly |
---|
| 541 | + * enforced. For clients supplying an SNI extension, the peer |
---|
| 542 | + * certificate verification has happened in the handshake already |
---|
| 543 | + * (and r->server == handshakeserver). For non-SNI requests, |
---|
| 544 | + * an additional check is needed here. If client authentication |
---|
| 545 | + * is configured as mandatory, then we can only proceed if the |
---|
| 546 | + * CA list doesn't have to be changed (OpenSSL doesn't provide |
---|
| 547 | + * an option to change the list for an existing session). |
---|
| 548 | + */ |
---|
| 549 | + if ((r->server != handshakeserver) |
---|
| 550 | + && renegotiate |
---|
| 551 | + && ((verify & SSL_VERIFY_PEER) || |
---|
| 552 | + (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))) { |
---|
| 553 | + SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver); |
---|
| 554 | + |
---|
[816] | 555 | +#define MODSSL_CFG_CA_NE(f, sc1, sc2) \ |
---|
[1115] | 556 | + (sc1->server->auth.f && \ |
---|
| 557 | + (!sc2->server->auth.f || \ |
---|
| 558 | + strNE(sc1->server->auth.f, sc2->server->auth.f))) |
---|
[816] | 559 | + |
---|
[1115] | 560 | + if (MODSSL_CFG_CA_NE(ca_cert_file, sc, hssc) || |
---|
| 561 | + MODSSL_CFG_CA_NE(ca_cert_path, sc, hssc)) { |
---|
| 562 | + if (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { |
---|
| 563 | + ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
---|
| 564 | + "Non-default virtual host with SSLVerify set to " |
---|
| 565 | + "'require' and VirtualHost-specific CA certificate " |
---|
| 566 | + "list is only available to clients with TLS server " |
---|
| 567 | + "name indication (SNI) support"); |
---|
| 568 | + modssl_set_verify(ssl, verify_old, NULL); |
---|
| 569 | + return HTTP_FORBIDDEN; |
---|
| 570 | + } else |
---|
| 571 | + /* let it pass, possibly with an "incorrect" peer cert, |
---|
| 572 | + * so make sure the SSL_CLIENT_VERIFY environment variable |
---|
| 573 | + * will indicate partial success only, later on. |
---|
| 574 | + */ |
---|
| 575 | + sslconn->verify_info = "GENEROUS"; |
---|
| 576 | + } |
---|
[816] | 577 | + } |
---|
[1115] | 578 | } |
---|
[816] | 579 | |
---|
[1115] | 580 | /* |
---|
| 581 | @@ -666,8 +767,10 @@ int ssl_hook_Access(request_rec *r) |
---|
[816] | 582 | /* |
---|
| 583 | * Finally check for acceptable renegotiation results |
---|
| 584 | */ |
---|
| 585 | - if (dc->nVerifyClient != SSL_CVERIFY_NONE) { |
---|
| 586 | - BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE); |
---|
| 587 | + if ((dc->nVerifyClient != SSL_CVERIFY_NONE) || |
---|
| 588 | + (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) { |
---|
| 589 | + BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) || |
---|
| 590 | + (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)); |
---|
| 591 | |
---|
| 592 | if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) { |
---|
| 593 | ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, |
---|
[1115] | 594 | @@ -997,6 +1100,9 @@ int ssl_hook_Fixup(request_rec *r) |
---|
[683] | 595 | SSLDirConfigRec *dc = myDirConfig(r); |
---|
| 596 | apr_table_t *env = r->subprocess_env; |
---|
| 597 | char *var, *val = ""; |
---|
| 598 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 599 | + const char *servername; |
---|
| 600 | +#endif |
---|
| 601 | STACK_OF(X509) *peer_certs; |
---|
| 602 | SSL *ssl; |
---|
| 603 | int i; |
---|
[1115] | 604 | @@ -1018,6 +1124,13 @@ int ssl_hook_Fixup(request_rec *r) |
---|
[683] | 605 | /* the always present HTTPS (=HTTP over SSL) flag! */ |
---|
| 606 | apr_table_setn(env, "HTTPS", "on"); |
---|
| 607 | |
---|
| 608 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 609 | + /* add content of SNI TLS extension (if supplied with ClientHello) */ |
---|
| 610 | + if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { |
---|
| 611 | + apr_table_set(env, "SSL_TLS_SNI", servername); |
---|
| 612 | + } |
---|
| 613 | +#endif |
---|
| 614 | + |
---|
| 615 | /* standard SSL environment variables */ |
---|
| 616 | if (dc->nOptions & SSL_OPT_STDENVVARS) { |
---|
| 617 | for (i = 0; ssl_hook_Fixup_vars[i]; i++) { |
---|
[1115] | 618 | @@ -1105,7 +1218,7 @@ int ssl_hook_Fixup(request_rec *r) |
---|
| 619 | RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen) |
---|
| 620 | { |
---|
| 621 | conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
---|
| 622 | - SSLModConfigRec *mc = myModConfig(c->base_server); |
---|
| 623 | + SSLModConfigRec *mc = myModConfigFromConn(c); |
---|
| 624 | int idx; |
---|
| 625 | |
---|
| 626 | ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, |
---|
| 627 | @@ -1137,7 +1250,7 @@ RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int |
---|
| 628 | DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) |
---|
| 629 | { |
---|
| 630 | conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
---|
| 631 | - SSLModConfigRec *mc = myModConfig(c->base_server); |
---|
| 632 | + SSLModConfigRec *mc = myModConfigFromConn(c); |
---|
| 633 | int idx; |
---|
| 634 | |
---|
| 635 | ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, |
---|
| 636 | @@ -1166,8 +1279,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX |
---|
[816] | 637 | SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, |
---|
| 638 | SSL_get_ex_data_X509_STORE_CTX_idx()); |
---|
| 639 | conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); |
---|
| 640 | - server_rec *s = conn->base_server; |
---|
| 641 | request_rec *r = (request_rec *)SSL_get_app_data2(ssl); |
---|
[1115] | 642 | + server_rec *s = r ? r->server : mySrvFromConn(conn); |
---|
[816] | 643 | |
---|
| 644 | SSLSrvConfigRec *sc = mySrvConfig(s); |
---|
| 645 | SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; |
---|
[1115] | 646 | @@ -1290,7 +1403,10 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX |
---|
[816] | 647 | |
---|
| 648 | int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c) |
---|
| 649 | { |
---|
| 650 | - server_rec *s = c->base_server; |
---|
| 651 | + SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, |
---|
| 652 | + SSL_get_ex_data_X509_STORE_CTX_idx()); |
---|
| 653 | + request_rec *r = (request_rec *)SSL_get_app_data2(ssl); |
---|
[1115] | 654 | + server_rec *s = r ? r->server : mySrvFromConn(c); |
---|
[816] | 655 | SSLSrvConfigRec *sc = mySrvConfig(s); |
---|
| 656 | SSLConnRec *sslconn = myConnConfig(c); |
---|
| 657 | modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); |
---|
[1115] | 658 | @@ -1515,7 +1631,7 @@ static void modssl_proxy_info_log(server_rec *s, |
---|
| 659 | int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey) |
---|
| 660 | { |
---|
| 661 | conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
---|
| 662 | - server_rec *s = c->base_server; |
---|
| 663 | + server_rec *s = mySrvFromConn(c); |
---|
| 664 | SSLSrvConfigRec *sc = mySrvConfig(s); |
---|
| 665 | X509_NAME *ca_name, *issuer; |
---|
| 666 | X509_INFO *info; |
---|
| 667 | @@ -1613,7 +1729,7 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SS |
---|
| 668 | { |
---|
| 669 | /* Get Apache context back through OpenSSL context */ |
---|
| 670 | conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); |
---|
| 671 | - server_rec *s = conn->base_server; |
---|
| 672 | + server_rec *s = mySrvFromConn(conn); |
---|
| 673 | SSLSrvConfigRec *sc = mySrvConfig(s); |
---|
| 674 | long timeout = sc->session_cache_timeout; |
---|
| 675 | BOOL rc; |
---|
| 676 | @@ -1661,7 +1777,7 @@ SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL |
---|
| 677 | { |
---|
| 678 | /* Get Apache context back through OpenSSL context */ |
---|
| 679 | conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); |
---|
| 680 | - server_rec *s = conn->base_server; |
---|
| 681 | + server_rec *s = mySrvFromConn(conn); |
---|
| 682 | SSL_SESSION *session; |
---|
| 683 | |
---|
| 684 | /* |
---|
| 685 | @@ -1739,7 +1855,7 @@ void ssl_callback_LogTracingState(MODSSL_INFO_CB_A |
---|
| 686 | return; |
---|
[683] | 687 | } |
---|
[1115] | 688 | |
---|
| 689 | - s = c->base_server; |
---|
| 690 | + s = mySrvFromConn(c); |
---|
| 691 | if (!(sc = mySrvConfig(s))) { |
---|
| 692 | return; |
---|
| 693 | } |
---|
| 694 | @@ -1810,3 +1926,138 @@ void ssl_callback_LogTracingState(MODSSL_INFO_CB_A |
---|
| 695 | } |
---|
[683] | 696 | } |
---|
| 697 | |
---|
| 698 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 699 | +/* |
---|
| 700 | + * This callback function is executed when OpenSSL encounters an extended |
---|
| 701 | + * client hello with a server name indication extension ("SNI", cf. RFC 4366). |
---|
| 702 | + */ |
---|
| 703 | +int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx) |
---|
| 704 | +{ |
---|
| 705 | + const char *servername = |
---|
| 706 | + SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); |
---|
| 707 | + |
---|
| 708 | + if (servername) { |
---|
| 709 | + conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
---|
| 710 | + if (c) { |
---|
| 711 | + if (ap_vhost_iterate_given_conn(c, ssl_find_vhost, |
---|
| 712 | + (void *)servername)) { |
---|
| 713 | + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, |
---|
| 714 | + "SSL virtual host for servername %s found", |
---|
| 715 | + servername); |
---|
| 716 | + return SSL_TLSEXT_ERR_OK; |
---|
| 717 | + } |
---|
| 718 | + else { |
---|
| 719 | + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, |
---|
| 720 | + "No matching SSL virtual host for servername " |
---|
| 721 | + "%s found (using default/first virtual host)", |
---|
| 722 | + servername); |
---|
| 723 | + return SSL_TLSEXT_ERR_ALERT_WARNING; |
---|
| 724 | + } |
---|
| 725 | + } |
---|
| 726 | + } |
---|
| 727 | + |
---|
| 728 | + return SSL_TLSEXT_ERR_NOACK; |
---|
| 729 | +} |
---|
| 730 | + |
---|
| 731 | +/* |
---|
| 732 | + * Find a (name-based) SSL virtual host where either the ServerName |
---|
| 733 | + * or one of the ServerAliases matches the supplied name (to be used |
---|
| 734 | + * with ap_vhost_iterate_given_conn()) |
---|
| 735 | + */ |
---|
| 736 | +static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s) |
---|
| 737 | +{ |
---|
| 738 | + SSLSrvConfigRec *sc; |
---|
| 739 | + SSL *ssl; |
---|
| 740 | + BOOL found = FALSE; |
---|
| 741 | + apr_array_header_t *names; |
---|
| 742 | + int i; |
---|
[1115] | 743 | + SSLConnRec *sslcon; |
---|
[683] | 744 | + |
---|
| 745 | + /* check ServerName */ |
---|
| 746 | + if (!strcasecmp(servername, s->server_hostname)) { |
---|
| 747 | + found = TRUE; |
---|
| 748 | + } |
---|
| 749 | + |
---|
| 750 | + /* |
---|
| 751 | + * if not matched yet, check ServerAlias entries |
---|
| 752 | + * (adapted from vhost.c:matches_aliases()) |
---|
| 753 | + */ |
---|
| 754 | + if (!found) { |
---|
| 755 | + names = s->names; |
---|
| 756 | + if (names) { |
---|
| 757 | + char **name = (char **)names->elts; |
---|
| 758 | + for (i = 0; i < names->nelts; ++i) { |
---|
| 759 | + if (!name[i]) |
---|
| 760 | + continue; |
---|
| 761 | + if (!strcasecmp(servername, name[i])) { |
---|
| 762 | + found = TRUE; |
---|
| 763 | + break; |
---|
| 764 | + } |
---|
| 765 | + } |
---|
| 766 | + } |
---|
| 767 | + } |
---|
| 768 | + |
---|
| 769 | + /* if still no match, check ServerAlias entries with wildcards */ |
---|
| 770 | + if (!found) { |
---|
| 771 | + names = s->wild_names; |
---|
| 772 | + if (names) { |
---|
| 773 | + char **name = (char **)names->elts; |
---|
| 774 | + for (i = 0; i < names->nelts; ++i) { |
---|
| 775 | + if (!name[i]) |
---|
| 776 | + continue; |
---|
| 777 | + if (!ap_strcasecmp_match(servername, name[i])) { |
---|
| 778 | + found = TRUE; |
---|
| 779 | + break; |
---|
| 780 | + } |
---|
| 781 | + } |
---|
| 782 | + } |
---|
| 783 | + } |
---|
| 784 | + |
---|
| 785 | + /* set SSL_CTX (if matched) */ |
---|
[1115] | 786 | + sslcon = myConnConfig(c); |
---|
| 787 | + if (found && (ssl = sslcon->ssl) && |
---|
[683] | 788 | + (sc = mySrvConfig(s))) { |
---|
| 789 | + SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx); |
---|
| 790 | + /* |
---|
| 791 | + * SSL_set_SSL_CTX() only deals with the server cert, |
---|
| 792 | + * so we need to duplicate a few additional settings |
---|
| 793 | + * from the ctx by hand |
---|
| 794 | + */ |
---|
| 795 | + SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx)); |
---|
| 796 | + if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) || |
---|
| 797 | + (SSL_num_renegotiations(ssl) == 0)) { |
---|
| 798 | + /* |
---|
| 799 | + * Only initialize the verification settings from the ctx |
---|
| 800 | + * if they are not yet set, or if we're called when a new |
---|
| 801 | + * SSL connection is set up (num_renegotiations == 0). |
---|
| 802 | + * Otherwise, we would possibly reset a per-directory |
---|
| 803 | + * configuration which was put into effect by ssl_hook_Access. |
---|
| 804 | + */ |
---|
| 805 | + SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx), |
---|
| 806 | + SSL_CTX_get_verify_callback(ssl->ctx)); |
---|
| 807 | + } |
---|
| 808 | + |
---|
| 809 | + /* |
---|
[1115] | 810 | + * Save the found server into our SSLConnRec for later |
---|
| 811 | + * retrieval |
---|
[683] | 812 | + */ |
---|
[1115] | 813 | + sslcon->server = s; |
---|
[816] | 814 | + |
---|
| 815 | + /* |
---|
| 816 | + * There is one special filter callback, which is set |
---|
| 817 | + * very early depending on the base_server's log level. |
---|
| 818 | + * If this is not the first vhost we're now selecting |
---|
| 819 | + * (and the first vhost doesn't use APLOG_DEBUG), then |
---|
| 820 | + * we need to set that callback here. |
---|
| 821 | + */ |
---|
[1115] | 822 | + if (s->loglevel >= APLOG_DEBUG) { |
---|
[683] | 823 | + BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb); |
---|
| 824 | + BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl); |
---|
| 825 | + } |
---|
| 826 | + |
---|
| 827 | + return 1; |
---|
| 828 | + } |
---|
| 829 | + |
---|
| 830 | + return 0; |
---|
| 831 | +} |
---|
| 832 | +#endif |
---|
[1115] | 833 | Index: httpd-2.2.11/modules/ssl/mod_ssl.c |
---|
[683] | 834 | =================================================================== |
---|
[1115] | 835 | --- httpd-2.2.11/modules/ssl/mod_ssl.c (revision 768863) |
---|
| 836 | +++ httpd-2.2.11/modules/ssl/mod_ssl.c (working copy) |
---|
| 837 | @@ -145,6 +145,10 @@ static const command_rec ssl_config_cmds[] = { |
---|
| 838 | "Use the server's cipher ordering preference") |
---|
| 839 | SSL_CMD_ALL(UserName, TAKE1, |
---|
| 840 | "Set user name to SSL variable value") |
---|
| 841 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 842 | + SSL_CMD_SRV(StrictSNIVHostCheck, FLAG, |
---|
| 843 | + "Strict SNI virtual host checking") |
---|
| 844 | +#endif |
---|
| 845 | |
---|
| 846 | /* |
---|
| 847 | * Proxy configuration for remote SSL connections |
---|
| 848 | @@ -295,6 +299,8 @@ static SSLConnRec *ssl_init_connection_ctx(conn_re |
---|
| 849 | |
---|
| 850 | sslconn = apr_pcalloc(c->pool, sizeof(*sslconn)); |
---|
| 851 | |
---|
| 852 | + sslconn->server = c->base_server; |
---|
| 853 | + |
---|
| 854 | myConnConfigSet(c, sslconn); |
---|
| 855 | |
---|
| 856 | return sslconn; |
---|
| 857 | @@ -302,9 +308,10 @@ static SSLConnRec *ssl_init_connection_ctx(conn_re |
---|
| 858 | |
---|
| 859 | int ssl_proxy_enable(conn_rec *c) |
---|
| 860 | { |
---|
| 861 | - SSLSrvConfigRec *sc = mySrvConfig(c->base_server); |
---|
| 862 | + SSLSrvConfigRec *sc; |
---|
| 863 | |
---|
| 864 | SSLConnRec *sslconn = ssl_init_connection_ctx(c); |
---|
| 865 | + sc = mySrvConfig(sslconn->server); |
---|
| 866 | |
---|
| 867 | if (!sc->proxy_enabled) { |
---|
| 868 | ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, |
---|
| 869 | @@ -322,10 +329,16 @@ int ssl_proxy_enable(conn_rec *c) |
---|
| 870 | |
---|
| 871 | int ssl_engine_disable(conn_rec *c) |
---|
| 872 | { |
---|
| 873 | - SSLSrvConfigRec *sc = mySrvConfig(c->base_server); |
---|
| 874 | + SSLSrvConfigRec *sc; |
---|
| 875 | |
---|
| 876 | - SSLConnRec *sslconn; |
---|
| 877 | + SSLConnRec *sslconn = myConnConfig(c); |
---|
| 878 | |
---|
| 879 | + if (sslconn) { |
---|
| 880 | + sc = mySrvConfig(sslconn->server); |
---|
| 881 | + } |
---|
| 882 | + else { |
---|
| 883 | + sc = mySrvConfig(c->base_server); |
---|
| 884 | + } |
---|
| 885 | if (sc->enabled == SSL_ENABLED_FALSE) { |
---|
| 886 | return 0; |
---|
| 887 | } |
---|
| 888 | @@ -339,21 +352,24 @@ int ssl_engine_disable(conn_rec *c) |
---|
| 889 | |
---|
| 890 | int ssl_init_ssl_connection(conn_rec *c) |
---|
| 891 | { |
---|
| 892 | - SSLSrvConfigRec *sc = mySrvConfig(c->base_server); |
---|
| 893 | + SSLSrvConfigRec *sc; |
---|
| 894 | SSL *ssl; |
---|
| 895 | SSLConnRec *sslconn = myConnConfig(c); |
---|
| 896 | char *vhost_md5; |
---|
| 897 | modssl_ctx_t *mctx; |
---|
| 898 | + server_rec *server; |
---|
| 899 | |
---|
| 900 | + if (!sslconn) { |
---|
| 901 | + sslconn = ssl_init_connection_ctx(c); |
---|
| 902 | + } |
---|
| 903 | + server = sslconn->server; |
---|
| 904 | + sc = mySrvConfig(server); |
---|
| 905 | + |
---|
| 906 | /* |
---|
| 907 | * Seed the Pseudo Random Number Generator (PRNG) |
---|
| 908 | */ |
---|
| 909 | - ssl_rand_seed(c->base_server, c->pool, SSL_RSCTX_CONNECT, ""); |
---|
| 910 | + ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT, ""); |
---|
| 911 | |
---|
| 912 | - if (!sslconn) { |
---|
| 913 | - sslconn = ssl_init_connection_ctx(c); |
---|
| 914 | - } |
---|
| 915 | - |
---|
| 916 | mctx = sslconn->is_proxy ? sc->proxy : sc->server; |
---|
| 917 | |
---|
| 918 | /* |
---|
| 919 | @@ -365,7 +381,7 @@ int ssl_init_ssl_connection(conn_rec *c) |
---|
| 920 | ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, |
---|
| 921 | "Unable to create a new SSL connection from the SSL " |
---|
| 922 | "context"); |
---|
| 923 | - ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server); |
---|
| 924 | + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server); |
---|
| 925 | |
---|
| 926 | c->aborted = 1; |
---|
| 927 | |
---|
| 928 | @@ -380,7 +396,7 @@ int ssl_init_ssl_connection(conn_rec *c) |
---|
| 929 | { |
---|
| 930 | ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, |
---|
| 931 | "Unable to set session id context to `%s'", vhost_md5); |
---|
| 932 | - ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, c->base_server); |
---|
| 933 | + ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server); |
---|
| 934 | |
---|
| 935 | c->aborted = 1; |
---|
| 936 | |
---|
| 937 | @@ -429,9 +445,15 @@ static apr_port_t ssl_hook_default_port(const requ |
---|
| 938 | |
---|
| 939 | static int ssl_hook_pre_connection(conn_rec *c, void *csd) |
---|
| 940 | { |
---|
| 941 | - SSLSrvConfigRec *sc = mySrvConfig(c->base_server); |
---|
| 942 | + SSLSrvConfigRec *sc; |
---|
| 943 | SSLConnRec *sslconn = myConnConfig(c); |
---|
| 944 | |
---|
| 945 | + if (sslconn) { |
---|
| 946 | + sc = mySrvConfig(sslconn->server); |
---|
| 947 | + } |
---|
| 948 | + else { |
---|
| 949 | + sc = mySrvConfig(c->base_server); |
---|
| 950 | + } |
---|
| 951 | /* |
---|
| 952 | * Immediately stop processing if SSL is disabled for this connection |
---|
| 953 | */ |
---|
| 954 | Index: httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h |
---|
| 955 | =================================================================== |
---|
| 956 | --- httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h (revision 768863) |
---|
| 957 | +++ httpd-2.2.11/modules/ssl/ssl_toolkit_compat.h (working copy) |
---|
[1102] | 958 | @@ -264,6 +264,12 @@ typedef void (*modssl_popfree_fn)(char *data); |
---|
[683] | 959 | #define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP |
---|
| 960 | #endif |
---|
| 961 | |
---|
| 962 | +#ifndef OPENSSL_NO_TLSEXT |
---|
| 963 | +#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME |
---|
| 964 | +#define OPENSSL_NO_TLSEXT |
---|
| 965 | +#endif |
---|
| 966 | +#endif |
---|
| 967 | + |
---|
| 968 | #endif /* SSL_TOOLKIT_COMPAT_H */ |
---|
| 969 | |
---|
| 970 | /** @} */ |
---|
[1115] | 971 | Index: httpd-2.2.11/docs/manual/mod/mod_ssl.html.en |
---|
| 972 | =================================================================== |
---|
[1146] | 973 | --- httpd-2.2.11/docs/manual/mod/mod_ssl.html.en 2008-08-20 19:02:48.000000000 -0400 |
---|
| 974 | +++ httpd-2.2.11/docs/manual/mod/mod_ssl.html.en 2009-06-03 05:33:23.000000000 -0400 |
---|
[1115] | 975 | @@ -75,6 +75,7 @@ to provide the cryptography engine.</p> |
---|
| 976 | <li><img alt="" src="../images/down.gif" /> <a href="#sslrequiressl">SSLRequireSSL</a></li> |
---|
| 977 | <li><img alt="" src="../images/down.gif" /> <a href="#sslsessioncache">SSLSessionCache</a></li> |
---|
| 978 | <li><img alt="" src="../images/down.gif" /> <a href="#sslsessioncachetimeout">SSLSessionCacheTimeout</a></li> |
---|
| 979 | +<li><img alt="" src="../images/down.gif" /> <a href="#sslstrictsnivhostcheck">SSLStrictSNIVHostCheck</a></li> |
---|
| 980 | <li><img alt="" src="../images/down.gif" /> <a href="#sslusername">SSLUserName</a></li> |
---|
| 981 | <li><img alt="" src="../images/down.gif" /> <a href="#sslverifyclient">SSLVerifyClient</a></li> |
---|
| 982 | <li><img alt="" src="../images/down.gif" /> <a href="#sslverifydepth">SSLVerifyDepth</a></li> |
---|
| 983 | @@ -1613,6 +1614,37 @@ SSLSessionCacheTimeout 600 |
---|
| 984 | |
---|
| 985 | </div> |
---|
| 986 | <div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
---|
| 987 | +<div class="directive-section"><h2><a name="SSLStrictSNIVHostCheck" id="SSLStrictSNIVHostCheck">SSLStrictSNIVHostCheck</a> <a name="sslstrictsnivhostcheck" id="sslstrictsnivhostcheck">Directive</a></h2> |
---|
| 988 | +<table class="directive"> |
---|
| 989 | +<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Whether to allow non SNI clients to access a name based virtual |
---|
| 990 | +host. |
---|
| 991 | +</td></tr> |
---|
| 992 | +<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>SSLStrictSNIVHostCheck on|off</code></td></tr> |
---|
| 993 | +<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>SSLStrictSNIVHostCheck off</code></td></tr> |
---|
| 994 | +<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr> |
---|
| 995 | +<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr> |
---|
| 996 | +<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_ssl</td></tr> |
---|
| 997 | +</table> |
---|
| 998 | +<p> |
---|
| 999 | +This directive sets whether a non SNI client is allowed to access a name based |
---|
| 1000 | +virtual host. If set to <code>on</code> in the non default name based virtual |
---|
| 1001 | +host, non SNI clients are not allowed to access this particular virtual host. |
---|
| 1002 | +If set to <code>on</code> in the default name based virtual host, non SNI |
---|
| 1003 | +clients are not allowed to access any name based virtual host belonging to |
---|
| 1004 | +this IP / port combination. |
---|
| 1005 | +</p> |
---|
| 1006 | + |
---|
| 1007 | +<div class="warning"><p> |
---|
| 1008 | +This option is only available if httpd was compiled against an SNI capable |
---|
| 1009 | +version of OpenSSL. |
---|
| 1010 | +</p></div> |
---|
| 1011 | + |
---|
| 1012 | +<div class="example"><h3>Example</h3><p><code> |
---|
| 1013 | +SSLStrictSNIVHostCheck on |
---|
| 1014 | +</code></p></div> |
---|
| 1015 | + |
---|
| 1016 | +</div> |
---|
| 1017 | +<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div> |
---|
| 1018 | <div class="directive-section"><h2><a name="SSLUserName" id="SSLUserName">SSLUserName</a> <a name="sslusername" id="sslusername">Directive</a></h2> |
---|
| 1019 | <table class="directive"> |
---|
| 1020 | <tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Variable name to determine user name</td></tr> |
---|
| 1021 | @@ -1717,6 +1749,6 @@ SSLVerifyDepth 10 |
---|
| 1022 | <div class="bottomlang"> |
---|
| 1023 | <p><span>Available Languages: </span><a href="../en/mod/mod_ssl.html" title="English"> en </a></p> |
---|
| 1024 | </div><div id="footer"> |
---|
| 1025 | -<p class="apache">Copyright 2008 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p> |
---|
| 1026 | +<p class="apache">Copyright 2009 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p> |
---|
| 1027 | <p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div> |
---|
[1146] | 1028 | -</body></html> |
---|
| 1029 | \ No newline at end of file |
---|
| 1030 | +</body></html> |
---|