source:
server/common/patches/httpd-2.2.x-sni.patch
@
1102
Last change on this file since 1102 was 1102, checked in by mitchb, 15 years ago | |
---|---|
File size: 20.8 KB |
-
httpd-2.2.x/modules/ssl/ssl_private.h
httpd-2.2.x-sni.patch - server name indication support for Apache 2.2 (see RFC 4366, "Transport Layer Security (TLS) Extensions") Last updated 2009-04-08 based on a patch from the EdelKey project (http://www.edelweb.fr/EdelKey/files/apache-2.2.0+0.9.9+servername.patch) Needs openssl-SNAP-20060330 / OpenSSL 0.9.8f or later to work properly (ftp://ftp.openssl.org/snapshot/). OpenSSL versions prior to 0.9.8j must be configured explicitly for TLS extension support at compile time ("./config enable-tlsext").
35 35 #include "http_connection.h" 36 36 #include "http_request.h" 37 37 #include "http_protocol.h" 38 #include "http_vhost.h" 38 39 #include "util_script.h" 39 40 #include "util_filter.h" 40 41 #include "util_ebcdic.h" … … int ssl_callback_NewSessionCacheEntry(SSL 562 563 SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); 563 564 void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); 564 565 void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); 566 #ifndef OPENSSL_NO_TLSEXT 567 int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); 568 #endif 565 569 566 570 /** Session Cache Support */ 567 571 void ssl_scache_init(server_rec *, apr_pool_t *); -
httpd-2.2.x/modules/ssl/ssl_engine_init.c
static void ssl_init_server_check(server_rec *s, 358 358 } 359 359 } 360 360 361 #ifndef OPENSSL_NO_TLSEXT 362 static void ssl_init_ctx_tls_extensions(server_rec *s, 363 apr_pool_t *p, 364 apr_pool_t *ptemp, 365 modssl_ctx_t *mctx) 366 { 367 /* 368 * Configure TLS extensions support 369 */ 370 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 371 "Configuring TLS extension handling"); 372 373 /* 374 * Server name indication (SNI) 375 */ 376 if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx, 377 ssl_callback_ServerNameIndication) || 378 !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) { 379 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 380 "Unable to initialize TLS servername extension " 381 "callback (incompatible OpenSSL version?)"); 382 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); 383 ssl_die(); 384 } 385 } 386 #endif 387 361 388 static void ssl_init_ctx_protocol(server_rec *s, 362 389 apr_pool_t *p, 363 390 apr_pool_t *ptemp, … … static void ssl_init_ctx(server_rec *s, 690 717 if (mctx->pks) { 691 718 /* XXX: proxy support? */ 692 719 ssl_init_ctx_cert_chain(s, p, ptemp, mctx); 720 #ifndef OPENSSL_NO_TLSEXT 721 ssl_init_ctx_tls_extensions(s, p, ptemp, mctx); 722 #endif 693 723 } 694 724 } 695 725 … … void ssl_init_CheckServers(server_rec *base_server 1039 1069 klen = strlen(key); 1040 1070 1041 1071 if ((ps = (server_rec *)apr_hash_get(table, key, klen))) { 1042 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, 1072 ap_log_error(APLOG_MARK, 1073 #ifdef OPENSSL_NO_TLSEXT 1074 APLOG_WARNING, 1075 #else 1076 APLOG_DEBUG, 1077 #endif 1078 0, 1043 1079 base_server, 1080 #ifdef OPENSSL_NO_TLSEXT 1044 1081 "Init: SSL server IP/port conflict: " 1082 #else 1083 "Init: SSL server IP/port overlap: " 1084 #endif 1045 1085 "%s (%s:%d) vs. %s (%s:%d)", 1046 1086 ssl_util_vhostid(p, s), 1047 1087 (s->defn_name ? s->defn_name : "unknown"), … … void ssl_init_CheckServers(server_rec *base_server 1058 1098 1059 1099 if (conflict) { 1060 1100 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, 1101 #ifdef OPENSSL_NO_TLSEXT 1061 1102 "Init: You should not use name-based " 1062 1103 "virtual hosts in conjunction with SSL!!"); 1104 #else 1105 "Init: Name-based SSL virtual hosts only " 1106 "work for clients with TLS server name indication " 1107 "support (RFC 4366)"); 1108 #endif 1063 1109 } 1064 1110 } 1065 1111 -
httpd-2.2.x/modules/ssl/ssl_engine_vars.c
static char *ssl_var_lookup_ssl(apr_pool_t *p, con 320 320 else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) { 321 321 result = ssl_var_lookup_ssl_compress_meth(ssl); 322 322 } 323 #ifndef OPENSSL_NO_TLSEXT 324 else if (ssl != NULL && strcEQ(var, "TLS_SNI")) { 325 result = apr_pstrdup(p, SSL_get_servername(ssl, 326 TLSEXT_NAMETYPE_host_name)); 327 } 328 #endif 323 329 return result; 324 330 } 325 331 -
httpd-2.2.x/modules/ssl/ssl_engine_kernel.c
31 31 #include "ssl_private.h" 32 32 33 33 static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); 34 #ifndef OPENSSL_NO_TLSEXT 35 static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s); 36 #endif 34 37 35 38 /* 36 39 * Post Read Request Handler … … int ssl_hook_ReadReq(request_rec *r) 39 42 { 40 43 SSLConnRec *sslconn = myConnConfig(r->connection); 41 44 SSL *ssl; 45 #ifndef OPENSSL_NO_TLSEXT 46 const char *servername; 47 #endif 42 48 43 49 if (!sslconn) { 44 50 return DECLINED; … … int ssl_hook_ReadReq(request_rec *r) 87 93 if (!ssl) { 88 94 return DECLINED; 89 95 } 96 #ifndef OPENSSL_NO_TLSEXT 97 if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { 98 char *host, *scope_id; 99 apr_port_t port; 100 apr_status_t rv; 101 102 /* 103 * The SNI extension supplied a hostname. So don't accept requests 104 * with either no hostname or a different hostname. 105 */ 106 if (!r->hostname) { 107 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, 108 "Hostname %s provided via SNI, but no hostname" 109 " provided in HTTP request", servername); 110 return HTTP_BAD_REQUEST; 111 } 112 rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool); 113 if (rv != APR_SUCCESS || scope_id) { 114 return HTTP_BAD_REQUEST; 115 } 116 if (strcmp(host, servername)) { 117 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, 118 "Hostname %s provided via SNI and hostname %s provided" 119 " via HTTP are different", servername, host); 120 return HTTP_BAD_REQUEST; 121 } 122 } 123 #endif 90 124 SSL_set_app_data2(ssl, r); 91 125 92 126 /* … … int ssl_hook_Access(request_rec *r) 252 286 * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no 253 287 * implicit optimizations. 254 288 */ 255 if (dc->szCipherSuite ) {289 if (dc->szCipherSuite || (r->server != r->connection->base_server)) { 256 290 /* remember old state */ 257 291 258 292 if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { … … int ssl_hook_Access(request_rec *r) 267 301 } 268 302 269 303 /* configure new state */ 270 if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) { 304 if ((dc->szCipherSuite || sc->server->auth.cipher_suite) && 305 !modssl_set_cipher_list(ssl, dc->szCipherSuite ? 306 dc->szCipherSuite : 307 sc->server->auth.cipher_suite)) { 271 308 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, 272 309 r->server, 273 310 "Unable to reconfigure (per-directory) " … … int ssl_hook_Access(request_rec *r) 334 371 sk_SSL_CIPHER_free(cipher_list_old); 335 372 } 336 373 337 /* tracing */338 374 if (renegotiate) { 375 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE 376 if (sc->cipher_server_pref == TRUE) { 377 SSL_set_options(ssl, SSL_OP_CIPHER_SERVER_PREFERENCE); 378 } 379 #endif 380 /* tracing */ 339 381 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 340 382 "Reconfigured cipher suite will force renegotiation"); 341 383 } … … int ssl_hook_Access(request_rec *r) 353 395 * currently active/remembered verify depth (because this means more 354 396 * restriction on the certificate chain). 355 397 */ 356 if (dc->nVerifyDepth != UNSET) { 357 /* XXX: doesnt look like sslconn->verify_depth is actually used */ 358 if (!(n = sslconn->verify_depth)) { 359 sslconn->verify_depth = n = sc->server->auth.verify_depth; 360 } 361 362 /* determine whether a renegotiation has to be forced */ 363 if (dc->nVerifyDepth < n) { 364 renegotiate = TRUE; 365 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 366 "Reduced client verification depth will force " 367 "renegotiation"); 368 } 398 n = sslconn->verify_depth; 399 sslconn->verify_depth = (dc->nVerifyDepth != UNSET) ? 400 dc->nVerifyDepth : sc->server->auth.verify_depth; 401 if ((sslconn->verify_depth < n) || 402 ((n == 0) && (sc->server->auth.verify_depth == 0))) { 403 renegotiate = TRUE; 404 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 405 "Reduced client verification depth will force " 406 "renegotiation"); 369 407 } 370 408 371 409 /* … … int ssl_hook_Access(request_rec *r) 382 420 * verification but at least skip the I/O-intensive renegotation 383 421 * handshake. 384 422 */ 385 if (dc->nVerifyClient != SSL_CVERIFY_UNSET) { 423 if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) || 424 (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) { 386 425 /* remember old state */ 387 426 verify_old = SSL_get_verify_mode(ssl); 388 427 /* configure new state */ 389 428 verify = SSL_VERIFY_NONE; 390 429 391 if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) { 430 if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) || 431 (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) { 392 432 verify |= SSL_VERIFY_PEER_STRICT; 393 433 } 394 434 395 435 if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) || 396 (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA)) 436 (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) || 437 (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) || 438 (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) 397 439 { 398 440 verify |= SSL_VERIFY_PEER; 399 441 } … … int ssl_hook_Access(request_rec *r) 491 533 "Changed client verification locations will force " 492 534 "renegotiation"); 493 535 } 536 #else 537 #ifndef OPENSSL_NO_TLSEXT 538 #define MODSSL_CFG_CA_NE(f, sc1, sc2) \ 539 (sc1->server->auth.f && \ 540 (!sc2->server->auth.f || \ 541 sc2->server->auth.f && strNE(sc1->server->auth.f, sc2->server->auth.f))) 542 543 /* If we're handling a request for a vhost other than the default one, 544 * then we need to make sure that client authentication is properly 545 * enforced. For clients supplying an SNI extension, the peer certificate 546 * verification has happened in the handshake already (and r->server 547 * has been set to r->connection->base_server). For non-SNI requests, 548 * an additional check is needed here. If client authentication is 549 * configured as mandatory, then we can only proceed if the CA list 550 * doesn't have to be changed (SSL_set_cert_store() would be required 551 * for this). 552 */ 553 if ((r->server != r->connection->base_server) && 554 (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) && 555 renegotiate && 556 !(SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { 557 SSLSrvConfigRec *bssc = mySrvConfig(r->connection->base_server); 558 559 if (MODSSL_CFG_CA_NE(ca_cert_file, sc, bssc) || 560 MODSSL_CFG_CA_NE(ca_cert_path, sc, bssc)) { 561 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 562 "Non-default virtual host with SSLVerify set to 'require' " 563 "and VirtualHost-specific CA certificate list is only " 564 "supported for clients with TLS server name indication " 565 "(SNI) support"); 566 return HTTP_FORBIDDEN; 567 } 568 } 569 #endif /* OPENSSL_NO_TLSEXT */ 494 570 #endif /* HAVE_SSL_SET_CERT_STORE */ 495 571 496 572 /* If a renegotiation is now required for this location, and the … … int ssl_hook_Access(request_rec *r) 675 751 /* 676 752 * Finally check for acceptable renegotiation results 677 753 */ 678 if (dc->nVerifyClient != SSL_CVERIFY_NONE) { 679 BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE); 754 if ((dc->nVerifyClient != SSL_CVERIFY_NONE) || 755 (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) { 756 BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) || 757 (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)); 680 758 681 759 if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) { 682 760 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, … … int ssl_hook_Fixup(request_rec *r) 1006 1084 SSLDirConfigRec *dc = myDirConfig(r); 1007 1085 apr_table_t *env = r->subprocess_env; 1008 1086 char *var, *val = ""; 1087 #ifndef OPENSSL_NO_TLSEXT 1088 const char *servername; 1089 #endif 1009 1090 STACK_OF(X509) *peer_certs; 1010 1091 SSL *ssl; 1011 1092 int i; … … int ssl_hook_Fixup(request_rec *r) 1027 1108 /* the always present HTTPS (=HTTP over SSL) flag! */ 1028 1109 apr_table_setn(env, "HTTPS", "on"); 1029 1110 1111 #ifndef OPENSSL_NO_TLSEXT 1112 /* add content of SNI TLS extension (if supplied with ClientHello) */ 1113 if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { 1114 apr_table_set(env, "SSL_TLS_SNI", servername); 1115 } 1116 #endif 1117 1030 1118 /* standard SSL environment variables */ 1031 1119 if (dc->nOptions & SSL_OPT_STDENVVARS) { 1032 1120 for (i = 0; ssl_hook_Fixup_vars[i]; i++) { … … int ssl_callback_SSLVerify(int ok, X509_STORE_CTX 1175 1263 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, 1176 1264 SSL_get_ex_data_X509_STORE_CTX_idx()); 1177 1265 conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); 1178 server_rec *s = conn->base_server;1179 1266 request_rec *r = (request_rec *)SSL_get_app_data2(ssl); 1267 server_rec *s = r ? r->server : conn->base_server; 1180 1268 1181 1269 SSLSrvConfigRec *sc = mySrvConfig(s); 1182 1270 SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; … … int ssl_callback_SSLVerify(int ok, X509_STORE_CTX 1299 1387 1300 1388 int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c) 1301 1389 { 1302 server_rec *s = c->base_server; 1390 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, 1391 SSL_get_ex_data_X509_STORE_CTX_idx()); 1392 request_rec *r = (request_rec *)SSL_get_app_data2(ssl); 1393 server_rec *s = r ? r->server : c->base_server; 1303 1394 SSLSrvConfigRec *sc = mySrvConfig(s); 1304 1395 SSLConnRec *sslconn = myConnConfig(c); 1305 1396 modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); … … void ssl_callback_LogTracingState(MODSSL_INFO_CB_A 1819 1910 } 1820 1911 } 1821 1912 1913 #ifndef OPENSSL_NO_TLSEXT 1914 /* 1915 * This callback function is executed when OpenSSL encounters an extended 1916 * client hello with a server name indication extension ("SNI", cf. RFC 4366). 1917 */ 1918 int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx) 1919 { 1920 const char *servername = 1921 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); 1922 1923 if (servername) { 1924 conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); 1925 if (c) { 1926 if (ap_vhost_iterate_given_conn(c, ssl_find_vhost, 1927 (void *)servername)) { 1928 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, 1929 "SSL virtual host for servername %s found", 1930 servername); 1931 return SSL_TLSEXT_ERR_OK; 1932 } 1933 else { 1934 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, 1935 "No matching SSL virtual host for servername " 1936 "%s found (using default/first virtual host)", 1937 servername); 1938 return SSL_TLSEXT_ERR_ALERT_WARNING; 1939 } 1940 } 1941 } 1942 1943 return SSL_TLSEXT_ERR_NOACK; 1944 } 1945 1946 /* 1947 * Find a (name-based) SSL virtual host where either the ServerName 1948 * or one of the ServerAliases matches the supplied name (to be used 1949 * with ap_vhost_iterate_given_conn()) 1950 */ 1951 static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s) 1952 { 1953 SSLSrvConfigRec *sc; 1954 SSL *ssl; 1955 BOOL found = FALSE; 1956 apr_array_header_t *names; 1957 int i; 1958 1959 /* check ServerName */ 1960 if (!strcasecmp(servername, s->server_hostname)) { 1961 found = TRUE; 1962 } 1963 1964 /* 1965 * if not matched yet, check ServerAlias entries 1966 * (adapted from vhost.c:matches_aliases()) 1967 */ 1968 if (!found) { 1969 names = s->names; 1970 if (names) { 1971 char **name = (char **)names->elts; 1972 for (i = 0; i < names->nelts; ++i) { 1973 if (!name[i]) 1974 continue; 1975 if (!strcasecmp(servername, name[i])) { 1976 found = TRUE; 1977 break; 1978 } 1979 } 1980 } 1981 } 1982 1983 /* if still no match, check ServerAlias entries with wildcards */ 1984 if (!found) { 1985 names = s->wild_names; 1986 if (names) { 1987 char **name = (char **)names->elts; 1988 for (i = 0; i < names->nelts; ++i) { 1989 if (!name[i]) 1990 continue; 1991 if (!ap_strcasecmp_match(servername, name[i])) { 1992 found = TRUE; 1993 break; 1994 } 1995 } 1996 } 1997 } 1998 1999 /* set SSL_CTX (if matched) */ 2000 if (found && (ssl = ((SSLConnRec *)myConnConfig(c))->ssl) && 2001 (sc = mySrvConfig(s))) { 2002 SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx); 2003 /* 2004 * SSL_set_SSL_CTX() only deals with the server cert, 2005 * so we need to duplicate a few additional settings 2006 * from the ctx by hand 2007 */ 2008 SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx)); 2009 if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) || 2010 (SSL_num_renegotiations(ssl) == 0)) { 2011 /* 2012 * Only initialize the verification settings from the ctx 2013 * if they are not yet set, or if we're called when a new 2014 * SSL connection is set up (num_renegotiations == 0). 2015 * Otherwise, we would possibly reset a per-directory 2016 * configuration which was put into effect by ssl_hook_Access. 2017 */ 2018 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx), 2019 SSL_CTX_get_verify_callback(ssl->ctx)); 2020 } 2021 2022 /* 2023 * We also need to make sure that the correct mctx 2024 * (accessed through the c->base_server->module_config vector) 2025 * is assigned to the connection - the CRL callback e.g. 2026 * makes use of it for retrieving its store (mctx->crl). 2027 * Since logging in callbacks uses c->base_server in many 2028 * cases, it also ensures that these messages are routed 2029 * to the proper log. 2030 */ 2031 c->base_server = s; 2032 2033 /* 2034 * There is one special filter callback, which is set 2035 * very early depending on the base_server's log level. 2036 * If this is not the first vhost we're now selecting 2037 * (and the first vhost doesn't use APLOG_DEBUG), then 2038 * we need to set that callback here. 2039 */ 2040 if (c->base_server->loglevel >= APLOG_DEBUG) { 2041 BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb); 2042 BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl); 2043 } 2044 2045 return 1; 2046 } 2047 2048 return 0; 2049 } 2050 #endif -
httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h
typedef void (*modssl_popfree_fn)(char *data); 264 264 #define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 265 265 #endif 266 266 267 #ifndef OPENSSL_NO_TLSEXT 268 #ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME 269 #define OPENSSL_NO_TLSEXT 270 #endif 271 #endif 272 267 273 #endif /* SSL_TOOLKIT_COMPAT_H */ 268 274 269 275 /** @} */
Note: See TracBrowser
for help on using the repository browser.