source:
server/common/patches/httpd-2.2.x-sni.patch
@
884
Last change on this file since 884 was 836, checked in by andersk, 16 years ago | |
---|---|
File size: 19.5 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") # 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/). The 0.9.8 versions # 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_NewSessionCach 555 556 SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); 556 557 void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); 557 558 void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE, int, int); 559 #ifndef OPENSSL_NO_TLSEXT 560 int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); 561 #endif 558 562 559 563 /** Session Cache Support */ 560 564 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 355 355 } 356 356 } 357 357 358 #ifndef OPENSSL_NO_TLSEXT 359 static void ssl_init_ctx_tls_extensions(server_rec *s, 360 apr_pool_t *p, 361 apr_pool_t *ptemp, 362 modssl_ctx_t *mctx) 363 { 364 /* 365 * Configure TLS extensions support 366 */ 367 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, 368 "Configuring TLS extension handling"); 369 370 /* 371 * Server name indication (SNI) 372 */ 373 if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx, 374 ssl_callback_ServerNameIndication) || 375 !SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) { 376 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, 377 "Unable to initialize TLS servername extension " 378 "callback (incompatible OpenSSL version?)"); 379 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); 380 ssl_die(); 381 } 382 } 383 #endif 384 358 385 static void ssl_init_ctx_protocol(server_rec *s, 359 386 apr_pool_t *p, 360 387 apr_pool_t *ptemp, … … static void ssl_init_ctx(server_rec *s, 687 714 if (mctx->pks) { 688 715 /* XXX: proxy support? */ 689 716 ssl_init_ctx_cert_chain(s, p, ptemp, mctx); 717 #ifndef OPENSSL_NO_TLSEXT 718 ssl_init_ctx_tls_extensions(s, p, ptemp, mctx); 719 #endif 690 720 } 691 721 } 692 722 … … void ssl_init_CheckServers(server_rec *b 1036 1066 klen = strlen(key); 1037 1067 1038 1068 if ((ps = (server_rec *)apr_hash_get(table, key, klen))) { 1039 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, 1069 ap_log_error(APLOG_MARK, 1070 #ifdef OPENSSL_NO_TLSEXT 1071 APLOG_WARNING, 1072 #else 1073 APLOG_DEBUG, 1074 #endif 1075 0, 1040 1076 base_server, 1077 #ifdef OPENSSL_NO_TLSEXT 1041 1078 "Init: SSL server IP/port conflict: " 1079 #else 1080 "Init: SSL server IP/port overlap: " 1081 #endif 1042 1082 "%s (%s:%d) vs. %s (%s:%d)", 1043 1083 ssl_util_vhostid(p, s), 1044 1084 (s->defn_name ? s->defn_name : "unknown"), … … void ssl_init_CheckServers(server_rec *b 1055 1095 1056 1096 if (conflict) { 1057 1097 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, 1098 #ifdef OPENSSL_NO_TLSEXT 1058 1099 "Init: You should not use name-based " 1059 1100 "virtual hosts in conjunction with SSL!!"); 1101 #else 1102 "Init: Name-based SSL virtual hosts only " 1103 "work for clients with TLS server name indication " 1104 "support (RFC 4366)"); 1105 #endif 1060 1106 } 1061 1107 } 1062 1108 -
httpd-2.2.x/modules/ssl/ssl_engine_vars.c
static char *ssl_var_lookup_ssl(apr_pool 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 (!r->hostname && 98 (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { 99 /* Use the SNI extension as the hostname if no Host: header was sent */ 100 r->hostname = apr_pstrdup(r->pool, servername); 101 ap_update_vhost_from_headers(r); 102 } 103 #endif 90 104 SSL_set_app_data2(ssl, r); 91 105 92 106 /* … … int ssl_hook_Access(request_rec *r) 252 266 * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no 253 267 * implicit optimizations. 254 268 */ 255 if (dc->szCipherSuite ) {269 if (dc->szCipherSuite || (r->server != r->connection->base_server)) { 256 270 /* remember old state */ 257 271 258 272 if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { … … int ssl_hook_Access(request_rec *r) 267 281 } 268 282 269 283 /* configure new state */ 270 if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) { 284 if ((dc->szCipherSuite && 285 !modssl_set_cipher_list(ssl, dc->szCipherSuite)) || 286 (sc->server->auth.cipher_suite && 287 !modssl_set_cipher_list(ssl, sc->server->auth.cipher_suite))) { 271 288 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, 272 289 r->server, 273 290 "Unable to reconfigure (per-directory) " … … int ssl_hook_Access(request_rec *r) 334 351 sk_SSL_CIPHER_free(cipher_list_old); 335 352 } 336 353 337 /* tracing */338 354 if (renegotiate) { 355 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE 356 if (sc->cipher_server_pref == TRUE) { 357 SSL_set_options(ssl, SSL_OP_CIPHER_SERVER_PREFERENCE); 358 } 359 #endif 360 /* tracing */ 339 361 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 340 362 "Reconfigured cipher suite will force renegotiation"); 341 363 } … … int ssl_hook_Access(request_rec *r) 353 375 * currently active/remembered verify depth (because this means more 354 376 * restriction on the certificate chain). 355 377 */ 356 if (dc->nVerifyDepth != UNSET) { 378 if ((dc->nVerifyDepth != UNSET) || 379 (sc->server->auth.verify_depth != 1)) { 357 380 /* XXX: doesnt look like sslconn->verify_depth is actually used */ 358 381 if (!(n = sslconn->verify_depth)) { 359 382 sslconn->verify_depth = n = sc->server->auth.verify_depth; 360 383 } 361 384 362 385 /* determine whether a renegotiation has to be forced */ 363 if (dc->nVerifyDepth < n) { 386 if ((dc->nVerifyDepth < n) || 387 (sc->server->auth.verify_depth < n)) { 364 388 renegotiate = TRUE; 365 389 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 366 390 "Reduced client verification depth will force " … … int ssl_hook_Access(request_rec *r) 382 406 * verification but at least skip the I/O-intensive renegotation 383 407 * handshake. 384 408 */ 385 if (dc->nVerifyClient != SSL_CVERIFY_UNSET) { 409 if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) || 410 (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) { 386 411 /* remember old state */ 387 412 verify_old = SSL_get_verify_mode(ssl); 388 413 /* configure new state */ 389 414 verify = SSL_VERIFY_NONE; 390 415 391 if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) { 416 if ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) || 417 (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)) { 392 418 verify |= SSL_VERIFY_PEER_STRICT; 393 419 } 394 420 395 421 if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) || 396 (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA)) 422 (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) || 423 (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL) || 424 (sc->server->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA)) 397 425 { 398 426 verify |= SSL_VERIFY_PEER; 399 427 } … … int ssl_hook_Access(request_rec *r) 491 519 "Changed client verification locations will force " 492 520 "renegotiation"); 493 521 } 522 #else 523 #ifndef OPENSSL_NO_TLSEXT 524 #define MODSSL_CFG_CA_NE(f, sc1, sc2) \ 525 (sc1->server->auth.f && \ 526 (!sc2->server->auth.f || \ 527 sc2->server->auth.f && strNE(sc1->server->auth.f, sc2->server->auth.f))) 528 529 /* If we're handling a request for a vhost other than the default one, 530 * then we need to make sure that client authentication is properly 531 * enforced. For clients supplying an SNI extension, the peer certificate 532 * verification has happened in the handshake already (and r->server 533 * has been set to r->connection->base_server). For non-SNI requests, 534 * an additional check is needed here. If client authentication is 535 * configured as mandatory, then we can only proceed if the CA list 536 * doesn't have to be changed (SSL_set_cert_store() would be required 537 * for this). 538 */ 539 if ((r->server != r->connection->base_server) && 540 (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) && 541 renegotiate && 542 !(SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { 543 SSLSrvConfigRec *bssc = mySrvConfig(r->connection->base_server); 544 545 if (MODSSL_CFG_CA_NE(ca_cert_file, sc, bssc) || 546 MODSSL_CFG_CA_NE(ca_cert_path, sc, bssc)) { 547 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 548 "Non-default virtual host with SSLVerify set to 'require' " 549 "and VirtualHost-specific CA certificate list is only " 550 "supported for clients with TLS server name indication " 551 "(SNI) support"); 552 return HTTP_FORBIDDEN; 553 } 554 } 555 #endif /* OPENSSL_NO_TLSEXT */ 494 556 #endif /* HAVE_SSL_SET_CERT_STORE */ 495 557 496 558 /* If a renegotiation is now required for this location, and the … … int ssl_hook_Access(request_rec *r) 666 728 /* 667 729 * Finally check for acceptable renegotiation results 668 730 */ 669 if (dc->nVerifyClient != SSL_CVERIFY_NONE) { 670 BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE); 731 if ((dc->nVerifyClient != SSL_CVERIFY_NONE) || 732 (sc->server->auth.verify_mode != SSL_CVERIFY_NONE)) { 733 BOOL do_verify = ((dc->nVerifyClient == SSL_CVERIFY_REQUIRE) || 734 (sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE)); 671 735 672 736 if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) { 673 737 ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, … … int ssl_hook_Fixup(request_rec *r) 997 1061 SSLDirConfigRec *dc = myDirConfig(r); 998 1062 apr_table_t *env = r->subprocess_env; 999 1063 char *var, *val = ""; 1064 #ifndef OPENSSL_NO_TLSEXT 1065 const char *servername; 1066 #endif 1000 1067 STACK_OF(X509) *peer_certs; 1001 1068 SSL *ssl; 1002 1069 int i; … … int ssl_hook_Fixup(request_rec *r) 1018 1085 /* the always present HTTPS (=HTTP over SSL) flag! */ 1019 1086 apr_table_setn(env, "HTTPS", "on"); 1020 1087 1088 #ifndef OPENSSL_NO_TLSEXT 1089 /* add content of SNI TLS extension (if supplied with ClientHello) */ 1090 if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { 1091 apr_table_set(env, "SSL_TLS_SNI", servername); 1092 } 1093 #endif 1094 1021 1095 /* standard SSL environment variables */ 1022 1096 if (dc->nOptions & SSL_OPT_STDENVVARS) { 1023 1097 for (i = 0; ssl_hook_Fixup_vars[i]; i++) { … … int ssl_callback_SSLVerify(int ok, X509_ 1166 1240 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, 1167 1241 SSL_get_ex_data_X509_STORE_CTX_idx()); 1168 1242 conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); 1169 server_rec *s = conn->base_server;1170 1243 request_rec *r = (request_rec *)SSL_get_app_data2(ssl); 1244 server_rec *s = r ? r->server : conn->base_server; 1171 1245 1172 1246 SSLSrvConfigRec *sc = mySrvConfig(s); 1173 1247 SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; … … int ssl_callback_SSLVerify(int ok, X509_ 1290 1364 1291 1365 int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c) 1292 1366 { 1293 server_rec *s = c->base_server; 1367 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, 1368 SSL_get_ex_data_X509_STORE_CTX_idx()); 1369 request_rec *r = (request_rec *)SSL_get_app_data2(ssl); 1370 server_rec *s = r ? r->server : c->base_server; 1294 1371 SSLSrvConfigRec *sc = mySrvConfig(s); 1295 1372 SSLConnRec *sslconn = myConnConfig(c); 1296 1373 modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); … … void ssl_callback_LogTracingState(MODSSL 1810 1887 } 1811 1888 } 1812 1889 1890 #ifndef OPENSSL_NO_TLSEXT 1891 /* 1892 * This callback function is executed when OpenSSL encounters an extended 1893 * client hello with a server name indication extension ("SNI", cf. RFC 4366). 1894 */ 1895 int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx) 1896 { 1897 const char *servername = 1898 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); 1899 1900 if (servername) { 1901 conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); 1902 if (c) { 1903 if (ap_vhost_iterate_given_conn(c, ssl_find_vhost, 1904 (void *)servername)) { 1905 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, 1906 "SSL virtual host for servername %s found", 1907 servername); 1908 return SSL_TLSEXT_ERR_OK; 1909 } 1910 else { 1911 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, 1912 "No matching SSL virtual host for servername " 1913 "%s found (using default/first virtual host)", 1914 servername); 1915 return SSL_TLSEXT_ERR_ALERT_WARNING; 1916 } 1917 } 1918 } 1919 1920 return SSL_TLSEXT_ERR_NOACK; 1921 } 1922 1923 /* 1924 * Find a (name-based) SSL virtual host where either the ServerName 1925 * or one of the ServerAliases matches the supplied name (to be used 1926 * with ap_vhost_iterate_given_conn()) 1927 */ 1928 static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s) 1929 { 1930 SSLSrvConfigRec *sc; 1931 SSL *ssl; 1932 BOOL found = FALSE; 1933 apr_array_header_t *names; 1934 int i; 1935 1936 /* check ServerName */ 1937 if (!strcasecmp(servername, s->server_hostname)) { 1938 found = TRUE; 1939 } 1940 1941 /* 1942 * if not matched yet, check ServerAlias entries 1943 * (adapted from vhost.c:matches_aliases()) 1944 */ 1945 if (!found) { 1946 names = s->names; 1947 if (names) { 1948 char **name = (char **)names->elts; 1949 for (i = 0; i < names->nelts; ++i) { 1950 if (!name[i]) 1951 continue; 1952 if (!strcasecmp(servername, name[i])) { 1953 found = TRUE; 1954 break; 1955 } 1956 } 1957 } 1958 } 1959 1960 /* if still no match, check ServerAlias entries with wildcards */ 1961 if (!found) { 1962 names = s->wild_names; 1963 if (names) { 1964 char **name = (char **)names->elts; 1965 for (i = 0; i < names->nelts; ++i) { 1966 if (!name[i]) 1967 continue; 1968 if (!ap_strcasecmp_match(servername, name[i])) { 1969 found = TRUE; 1970 break; 1971 } 1972 } 1973 } 1974 } 1975 1976 /* set SSL_CTX (if matched) */ 1977 if (found && (ssl = ((SSLConnRec *)myConnConfig(c))->ssl) && 1978 (sc = mySrvConfig(s))) { 1979 SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx); 1980 /* 1981 * SSL_set_SSL_CTX() only deals with the server cert, 1982 * so we need to duplicate a few additional settings 1983 * from the ctx by hand 1984 */ 1985 SSL_set_options(ssl, SSL_CTX_get_options(ssl->ctx)); 1986 if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) || 1987 (SSL_num_renegotiations(ssl) == 0)) { 1988 /* 1989 * Only initialize the verification settings from the ctx 1990 * if they are not yet set, or if we're called when a new 1991 * SSL connection is set up (num_renegotiations == 0). 1992 * Otherwise, we would possibly reset a per-directory 1993 * configuration which was put into effect by ssl_hook_Access. 1994 */ 1995 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ssl->ctx), 1996 SSL_CTX_get_verify_callback(ssl->ctx)); 1997 } 1998 1999 /* 2000 * We also need to make sure that the correct mctx 2001 * (accessed through the c->base_server->module_config vector) 2002 * is assigned to the connection - the CRL callback e.g. 2003 * makes use of it for retrieving its store (mctx->crl). 2004 * Since logging in callbacks uses c->base_server in many 2005 * cases, it also ensures that these messages are routed 2006 * to the proper log. 2007 */ 2008 c->base_server = s; 2009 2010 /* 2011 * There is one special filter callback, which is set 2012 * very early depending on the base_server's log level. 2013 * If this is not the first vhost we're now selecting 2014 * (and the first vhost doesn't use APLOG_DEBUG), then 2015 * we need to set that callback here. 2016 */ 2017 if (c->base_server->loglevel >= APLOG_DEBUG) { 2018 BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb); 2019 BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl); 2020 } 2021 2022 return 1; 2023 } 2024 2025 return 0; 2026 } 2027 #endif -
httpd-2.2.x/modules/ssl/ssl_toolkit_compat.h
typedef void (*modssl_popfree_fn)(char * 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.