diff options
author | Michael Tindal <urilith@gentoo.org> | 2004-11-04 08:52:31 +0000 |
---|---|---|
committer | Michael Tindal <urilith@gentoo.org> | 2004-11-04 08:52:31 +0000 |
commit | 62ff256919f0e7a5804f88abb8394280fd93743a (patch) | |
tree | 3c15141f98bc40681fb131e4547dc4531deb8b24 /net-www | |
parent | nls is not optional, and cannot be disabled in orbit-0.5.17, made the depende... (diff) | |
download | historical-62ff256919f0e7a5804f88abb8394280fd93743a.tar.gz historical-62ff256919f0e7a5804f88abb8394280fd93743a.tar.bz2 historical-62ff256919f0e7a5804f88abb8394280fd93743a.zip |
Removed stale patches repoman was complaining about.
Diffstat (limited to 'net-www')
-rw-r--r-- | net-www/apache/ChangeLog | 9 | ||||
-rw-r--r-- | net-www/apache/Manifest | 88 | ||||
-rw-r--r-- | net-www/apache/files/httpd-2.0.49-ssl_engine_kernel.patch | 1842 | ||||
-rw-r--r-- | net-www/apache/files/patches/2.0.49-r1/00_ssl_engine.patch | 41 | ||||
-rw-r--r-- | net-www/apache/files/patches/2.0.49-r1/01_ssl_engine_kernel.patch | 1842 | ||||
-rw-r--r-- | net-www/apache/files/patches/2.0.50-r1/00_ssl_engine.patch | 14 |
6 files changed, 45 insertions, 3791 deletions
diff --git a/net-www/apache/ChangeLog b/net-www/apache/ChangeLog index cf72f6fcc90c..82103ab65b2d 100644 --- a/net-www/apache/ChangeLog +++ b/net-www/apache/ChangeLog @@ -1,6 +1,13 @@ # ChangeLog for net-www/apache # Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/net-www/apache/ChangeLog,v 1.290 2004/10/30 11:39:29 kloeri Exp $ +# $Header: /var/cvsroot/gentoo-x86/net-www/apache/ChangeLog,v 1.291 2004/11/04 08:52:31 urilith Exp $ + + 04 Nov 2004; Michael Tindal <urilith@gentoo.org> + -files/httpd-2.0.49-ssl_engine_kernel.patch, + -files/patches/2.0.49-r1/00_ssl_engine.patch, + -files/patches/2.0.49-r1/01_ssl_engine_kernel.patch, + -files/patches/2.0.50-r1/00_ssl_engine.patch: + Removed old patches repoman was complaining about. 30 Oct 2004; Bryan Ăstergaard <kloeri@gentoo.org> apache-1.3.33.ebuild: Stable on alpha, bug 68564. diff --git a/net-www/apache/Manifest b/net-www/apache/Manifest index 8855f5a2b36a..546b69257f9c 100644 --- a/net-www/apache/Manifest +++ b/net-www/apache/Manifest @@ -1,58 +1,51 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -MD5 16e88640e5ca872feea864a37ef01f18 ChangeLog 49305 +MD5 7ea29b37d5684bef716122df72129cd7 ChangeLog 49609 MD5 e4dc4b093f2d9b8edd137e09ecbb2adf apache-1.3.29-r2.ebuild 7177 -MD5 08b63251db95f14ddbdc4b0368d48702 apache-1.3.31.ebuild 6693 -MD5 c46f4b015504b2b22e0b8a7917ec84bf apache-1.3.31-r2.ebuild 6864 -MD5 c096bf4f3779f9138b631ae00aaa387d apache-2.0.51.ebuild 12827 MD5 1bcfd89028a8f1e39f99a370f39e5ff2 apache-1.3.31-r1.ebuild 6739 -MD5 128233f1d85b4f0171e82ce9ed4b01a4 apache-2.0.50.ebuild 12903 +MD5 c46f4b015504b2b22e0b8a7917ec84bf apache-1.3.31-r2.ebuild 6864 MD5 f71001bc9b282e7eb336570621b54328 apache-1.3.31-r3.ebuild 6872 -MD5 5b6dd438f81019e56fa641841c0c13fe metadata.xml 501 -MD5 e04b2e008169968fe7b6c0775d5fab89 apache-2.0.51-r1.ebuild 12836 -MD5 56042cc49c068fcfbe36d15288ed2182 apache-2.0.52.ebuild 12832 +MD5 08b63251db95f14ddbdc4b0368d48702 apache-1.3.31.ebuild 6693 MD5 28accf25c8782d9af5b71a3b3725969f apache-1.3.32-r1.ebuild 6610 MD5 c4728dbf14f69ec79e3dc9d3636e3f0b apache-1.3.32.ebuild 6616 MD5 e8bbe2a2df8cb230ea39cdd0a9e89224 apache-1.3.33.ebuild 6885 +MD5 128233f1d85b4f0171e82ce9ed4b01a4 apache-2.0.50.ebuild 12903 +MD5 e04b2e008169968fe7b6c0775d5fab89 apache-2.0.51-r1.ebuild 12836 +MD5 c096bf4f3779f9138b631ae00aaa387d apache-2.0.51.ebuild 12827 +MD5 56042cc49c068fcfbe36d15288ed2182 apache-2.0.52.ebuild 12832 +MD5 5b6dd438f81019e56fa641841c0c13fe metadata.xml 501 +MD5 8b12871dd74fcd3f4fdf451c9d8c259e files/00_apache_manual.conf 781 MD5 998b4b7df08eb15641e0b9132443b365 files/apache-1.3.27-apachectl.patch 1328 MD5 37d2c4ea8e1a6725deaca42b6aa22c69 files/apache-1.3.27_db4_gentoo.patch 1006 -MD5 8cb4313e58d7bd5dc369eb92f75daa2b files/httpd-2.0.49-ipv6.patch 788 MD5 c2866f70c91c7c7f718b89d92530d5f2 files/apache-1.3.29-usertrack_bug.patch 2588 -MD5 589e8773eb94f785be510f74b2e39ad0 files/digest-apache-1.3.29-r2 211 +MD5 d4b8a4908870107e15cc1edbd0ec6ebb files/apache-1.3.29_mod_auth_db.patch 729 +MD5 2c7dedfa1c3b2b815d733e90acfa06fc files/apache-2.0.48-export.diff 706 MD5 43283cd264b5b1a6b3e5a4adba5ee2c1 files/apache-2.0.48-gentoo.diff 5905 +MD5 b7c4fabdcb3845c4218b770acb792f73 files/apache-2.0.49-gentoo.diff 6316 MD5 a76e0df0ecc6920d9f4f139e31288155 files/apache-builtin-mods 2467 MD5 1ca7ef45f474a29f599364f2022b4e0f files/apache.confd 994 MD5 2b4457530debe71160f56ae68ea4c9c8 files/apache.rc6 1078 +MD5 8de91cfef98483656aa4ab47f2c2ce8e files/apache2 331 MD5 042973893566b6b09b4dd9755d8f0881 files/apacheaddmod 5979 MD5 ba87ae612a52d75f0109a2aba6cd605b files/apachedelmod 3187 MD5 647bdf060613bdf1fdb840ed5ae51b72 files/apachelogserverstatus 4765 MD5 8b5e7c3c7da4ebb58471f917a693e047 files/apachesplitlogfile 5068 +MD5 589e8773eb94f785be510f74b2e39ad0 files/digest-apache-1.3.29-r2 211 MD5 bb36b429c433a5cbf2712605a76ce8fb files/digest-apache-1.3.31 139 -MD5 d52999376f67a872ee48cbae72db0160 files/httpd-2.0.49-cgi.patch 10319 -MD5 69d40992fa9301ce3198a0115fa1f31c files/digest-apache-2.0.51 137 MD5 7d4cec8690cb2c6406b84990d8365587 files/digest-apache-1.3.31-r1 139 -MD5 8b12871dd74fcd3f4fdf451c9d8c259e files/00_apache_manual.conf 781 -MD5 64670c349a80e98fc61da8e32b44a913 files/httpd-2.0.49-ssl_engine_kernel.patch 66330 -MD5 0551c76a9171a3af1d0ad6aa2ef4572c files/digest-apache-2.0.50 137 MD5 7d4cec8690cb2c6406b84990d8365587 files/digest-apache-1.3.31-r2 139 MD5 8cc0834ac7a8afa694ddb3f9f9be2cc8 files/digest-apache-1.3.31-r3 139 -MD5 59a6ba7dcde461f5350af41e6aff92b1 files/robots.txt 342 -MD5 d3626a1e31a675c60d066c111d552adf files/suexec.pam 59 -MD5 161245c7aa1eb785db53b34d6a10be43 files/suexec_pam_gentoo.patch 2149 -MD5 8de91cfef98483656aa4ab47f2c2ce8e files/apache2 331 -MD5 2c7dedfa1c3b2b815d733e90acfa06fc files/apache-2.0.48-export.diff 706 -MD5 b7c4fabdcb3845c4218b770acb792f73 files/apache-2.0.49-gentoo.diff 6316 -MD5 d4b8a4908870107e15cc1edbd0ec6ebb files/apache-1.3.29_mod_auth_db.patch 729 -MD5 b9ff3534313dae1b8ac96df0e3e01373 files/httpd-2.0.48-ipv6.patch 865 -MD5 0eb9067bb4f2c2495069deaa9d7fce1b files/digest-apache-2.0.51-r1 140 -MD5 d0934aedd71114be3cd0ba557fe07eb6 files/digest-apache-2.0.52 137 MD5 da8dfe2134d7e30dc95e77e0c5f472e1 files/digest-apache-1.3.32 212 MD5 c560ade7dafffbfdd05ec6deb125280b files/digest-apache-1.3.32-r1 215 MD5 189cfb35b6320ae3ab57a32dbadd18f2 files/digest-apache-1.3.33 212 -MD5 54c0546fa2b1985686cf22c9efa2c7dc files/common/apr-config.layout 434 -MD5 fe80b29c20bb6794eb7f4a0875588306 files/common/apr-util-config.layout 437 -MD5 5a7b58d54689d6e9d8f8214b5150d18f files/common/config.layout 741 +MD5 0551c76a9171a3af1d0ad6aa2ef4572c files/digest-apache-2.0.50 137 +MD5 69d40992fa9301ce3198a0115fa1f31c files/digest-apache-2.0.51 137 +MD5 0eb9067bb4f2c2495069deaa9d7fce1b files/digest-apache-2.0.51-r1 140 +MD5 d0934aedd71114be3cd0ba557fe07eb6 files/digest-apache-2.0.52 137 +MD5 b9ff3534313dae1b8ac96df0e3e01373 files/httpd-2.0.48-ipv6.patch 865 +MD5 d52999376f67a872ee48cbae72db0160 files/httpd-2.0.49-cgi.patch 10319 +MD5 8cb4313e58d7bd5dc369eb92f75daa2b files/httpd-2.0.49-ipv6.patch 788 +MD5 59a6ba7dcde461f5350af41e6aff92b1 files/robots.txt 342 +MD5 d3626a1e31a675c60d066c111d552adf files/suexec.pam 59 +MD5 161245c7aa1eb785db53b34d6a10be43 files/suexec_pam_gentoo.patch 2149 MD5 869ec17a0417518aa1d9d9566a958fb5 files/2.0.40/40_mod_ssl.conf 3185 MD5 1d10cc98714a34ddc38525743c2989f9 files/2.0.40/41_mod_ssl.default-vhost.conf 8053 MD5 819ee444395cf42ccc8009529a94af37 files/2.0.40/45_mod_dav.conf 583 @@ -71,11 +64,6 @@ MD5 5c47dec8c730edf1cb755b581327bd49 files/2.0.40/httpd.conf 35481 MD5 0055923f696c9ba3be7eeb5518603d40 files/2.0.40/ssl.conf 11082 MD5 d9e0ecfbc1591486a698494a388b091c files/2.0.40/vhosts.conf 1695 MD5 b69bf7c3126e471a2abff013e716367f files/2.0.40/virtual-homepages.conf 780 -MD5 162afe15726e298774bc36b586ae070a files/conf/DynamicVhosts.conf 965 -MD5 139f5b0d5e2bf3525464a336ed2e1f83 files/conf/Vhosts.conf 1910 -MD5 9c606730ea7cc37417109915b2fbe522 files/conf/VirtualHomePages.conf 909 -MD5 a7f15bdba3786353deb7bfaf8de0efb9 files/conf/apache.conf 8115 -MD5 c70dc2c9a5e56660f3f120fcb822fadc files/conf/commonapache.conf 22216 MD5 e8f5a440ea77613b7908872b6ef7cf88 files/2.0.48-r1/apache2.conf 7659 MD5 ed99e515857e9055a046ef407bf87864 files/2.0.48-r1/apache2.confd 1947 MD5 64a65b7880a67acb5b64c64af1d1eabd files/2.0.48-r1/apache2.initd 2410 @@ -95,18 +83,19 @@ MD5 23416b00cbdc46b67e672f272e49ba40 files/2.0.49/dynamic-vhosts.conf 840 MD5 8a234c8eb9cc840fe2d3cfbcdfedc315 files/2.0.49/gentestcrt.sh 8807 MD5 d9e0ecfbc1591486a698494a388b091c files/2.0.49/vhosts.conf 1695 MD5 b69bf7c3126e471a2abff013e716367f files/2.0.49/virtual-homepages.conf 780 +MD5 54c0546fa2b1985686cf22c9efa2c7dc files/common/apr-config.layout 434 +MD5 fe80b29c20bb6794eb7f4a0875588306 files/common/apr-util-config.layout 437 +MD5 5a7b58d54689d6e9d8f8214b5150d18f files/common/config.layout 741 +MD5 162afe15726e298774bc36b586ae070a files/conf/DynamicVhosts.conf 965 +MD5 139f5b0d5e2bf3525464a336ed2e1f83 files/conf/Vhosts.conf 1910 +MD5 9c606730ea7cc37417109915b2fbe522 files/conf/VirtualHomePages.conf 909 +MD5 a7f15bdba3786353deb7bfaf8de0efb9 files/conf/apache.conf 8115 +MD5 c70dc2c9a5e56660f3f120fcb822fadc files/conf/commonapache.conf 22216 MD5 61df284cb67dfde3085aec5543eeb03c files/patches/1.3.31/00_gentoo_apachectl.patch 32836 MD5 3c0dfc9f2dc93ae46eb6382cf9533f18 files/patches/1.3.31/00_gentoo_base.patch 27799 MD5 a63b9472904d3500cf72b370a9ee3200 files/patches/1.3.31/00_gentoo_db4_detect.patch 1304 MD5 161245c7aa1eb785db53b34d6a10be43 files/patches/1.3.31/00_gentoo_suexec_pam.patch 2149 MD5 28272b16a4f701f29eb73d932fd81101 files/patches/1.3.31/Readme.PATCHES 747 -MD5 fc31be76ad482038fa9019ea59067473 files/patches/2.0.49-r1/00_ssl_engine.patch 1364 -MD5 59deb12158a55cc2259cd79c245eb00d files/patches/2.0.49-r1/00_ssl_verify_client.patch 6671 -MD5 21a6ee55341125140e40c0f48144277d files/patches/2.0.49-r1/Readme.PATCHES 507 -MD5 b30d264a0cfb08b2ce2300132abbe654 files/patches/2.0.49-r1/01_apache_ldap_fixes.patch 18048 -MD5 64670c349a80e98fc61da8e32b44a913 files/patches/2.0.49-r1/01_ssl_engine_kernel.patch 66330 -MD5 30add456de1ed8fab4bc473a4afda161 files/patches/2.0.49-r1/04_ssl_makefile.patch 619 -MD5 d52999376f67a872ee48cbae72db0160 files/patches/2.0.49-r2/01_gentoo_cgi.patch 10319 MD5 61df284cb67dfde3085aec5543eeb03c files/patches/1.3.31-r1/00_gentoo_apachectl.patch 32836 MD5 3c0dfc9f2dc93ae46eb6382cf9533f18 files/patches/1.3.31-r1/00_gentoo_base.patch 27799 MD5 a63b9472904d3500cf72b370a9ee3200 files/patches/1.3.31-r1/00_gentoo_db4_detect.patch 1304 @@ -116,12 +105,9 @@ MD5 61df284cb67dfde3085aec5543eeb03c files/patches/1.3.31-r2/00_gentoo_apachectl MD5 3c0dfc9f2dc93ae46eb6382cf9533f18 files/patches/1.3.31-r2/00_gentoo_base.patch 27799 MD5 a63b9472904d3500cf72b370a9ee3200 files/patches/1.3.31-r2/00_gentoo_db4_detect.patch 1304 MD5 161245c7aa1eb785db53b34d6a10be43 files/patches/1.3.31-r2/00_gentoo_suexec_pam.patch 2149 -MD5 a6fbf43cb7c6827f046f7b1df65932c2 files/patches/2.0.50-r1/00_ssl_engine.patch 414 +MD5 59deb12158a55cc2259cd79c245eb00d files/patches/2.0.49-r1/00_ssl_verify_client.patch 6671 +MD5 b30d264a0cfb08b2ce2300132abbe654 files/patches/2.0.49-r1/01_apache_ldap_fixes.patch 18048 +MD5 30add456de1ed8fab4bc473a4afda161 files/patches/2.0.49-r1/04_ssl_makefile.patch 619 +MD5 21a6ee55341125140e40c0f48144277d files/patches/2.0.49-r1/Readme.PATCHES 507 +MD5 d52999376f67a872ee48cbae72db0160 files/patches/2.0.49-r2/01_gentoo_cgi.patch 10319 MD5 5d45e2b46965e7c6866b259df4efe4b2 files/patches/2.0.50-r1/Readme.PATCHES 357 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.9.10 (GNU/Linux) - -iD8DBQFBhZGrHTu7gpaalycRAuJmAJ4oUuPw7fiB4U6ipjU/KrjMyxRLdwCg2HuF -zkhHsrDeCvrR9J/P51DsAnE= -=rPIZ ------END PGP SIGNATURE----- diff --git a/net-www/apache/files/httpd-2.0.49-ssl_engine_kernel.patch b/net-www/apache/files/httpd-2.0.49-ssl_engine_kernel.patch deleted file mode 100644 index 4caf45f2041f..000000000000 --- a/net-www/apache/files/httpd-2.0.49-ssl_engine_kernel.patch +++ /dev/null @@ -1,1842 +0,0 @@ -diff -Naur httpd-2.0.49/modules/ssl/ssl_engine_kernel.c httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c ---- httpd-2.0.49/modules/ssl/ssl_engine_kernel.c 2004-02-09 20:53:20.000000000 +0000 -+++ httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c 2004-05-29 09:39:18.605535640 +0000 -@@ -793,7 +793,6 @@ - SSLConnRec *sslconn = myConnConfig(r->connection); - SSLSrvConfigRec *sc = mySrvConfig(r->server); - SSLDirConfigRec *dc = myDirConfig(r); -- char buf1[MAX_STRING_LEN], buf2[MAX_STRING_LEN]; - char *clientdn; - const char *auth_line, *username, *password; - -@@ -872,14 +871,16 @@ - * adding the string "xxj31ZMTZzkVA" as the password in the user file. - * This is just the crypted variant of the word "password" ;-) - */ -- apr_snprintf(buf1, sizeof(buf1), "%s:password", clientdn); -- ssl_util_uuencode(buf2, buf1, FALSE); -- -- apr_snprintf(buf1, sizeof(buf1), "Basic %s", buf2); -- apr_table_set(r->headers_in, "Authorization", buf1); -+ auth_line = apr_pstrcat(r->pool, "Basic ", -+ ap_pbase64encode(r->pool, -+ apr_pstrcat(r->pool, clientdn, -+ ":password", NULL)), -+ NULL); -+ apr_table_set(r->headers_in, "Authorization", auth_line); - - ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -- "Faking HTTP Basic Auth header: \"Authorization: %s\"", buf1); -+ "Faking HTTP Basic Auth header: \"Authorization: %s\"", -+ auth_line); - - return DECLINED; - } -diff -Naur httpd-2.0.49/modules/ssl/ssl_engine_kernel.c.orig httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c.orig ---- httpd-2.0.49/modules/ssl/ssl_engine_kernel.c.orig 1970-01-01 00:00:00.000000000 +0000 -+++ httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c.orig 2004-02-09 20:53:20.000000000 +0000 -@@ -0,0 +1,1804 @@ -+/* Copyright 2001-2004 The Apache Software Foundation -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* _ _ -+ * _ __ ___ ___ __| | ___ ___| | mod_ssl -+ * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL -+ * | | | | | | (_) | (_| | \__ \__ \ | -+ * |_| |_| |_|\___/ \__,_|___|___/___/_| -+ * |_____| -+ * ssl_engine_kernel.c -+ * The SSL engine kernel -+ */ -+ /* ``It took me fifteen years to discover -+ I had no talent for programming, but -+ I couldn't give it up because by that -+ time I was too famous.'' -+ -- Unknown */ -+#include "mod_ssl.h" -+ -+/* -+ * Post Read Request Handler -+ */ -+int ssl_hook_ReadReq(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSL *ssl; -+ -+ if (!sslconn) { -+ return DECLINED; -+ } -+ -+ if (sslconn->non_ssl_request) { -+ const char *errmsg; -+ char *thisurl; -+ char *thisport = ""; -+ int port = ap_get_server_port(r); -+ -+ if (!ap_is_default_port(port, r)) { -+ thisport = apr_psprintf(r->pool, ":%u", port); -+ } -+ -+ thisurl = ap_escape_html(r->pool, -+ apr_psprintf(r->pool, "https://%s%s/", -+ ap_get_server_name(r), -+ thisport)); -+ -+ errmsg = apr_psprintf(r->pool, -+ "Reason: You're speaking plain HTTP " -+ "to an SSL-enabled server port.<br />\n" -+ "Instead use the HTTPS scheme to access " -+ "this URL, please.<br />\n" -+ "<blockquote>Hint: " -+ "<a href=\"%s\"><b>%s</b></a></blockquote>", -+ thisurl, thisurl); -+ -+ apr_table_setn(r->notes, "error-notes", errmsg); -+ -+ /* Now that we have caught this error, forget it. we are done -+ * with using SSL on this request. -+ */ -+ sslconn->non_ssl_request = 0; -+ -+ -+ return HTTP_BAD_REQUEST; -+ } -+ -+ /* -+ * Get the SSL connection structure and perform the -+ * delayed interlinking from SSL back to request_rec -+ */ -+ if ((ssl = sslconn->ssl)) { -+ SSL_set_app_data2(ssl, r); -+ } -+ -+ return DECLINED; -+} -+ -+/* -+ * Move SetEnvIf information from request_rec to conn_rec/BUFF -+ * to allow the close connection handler to use them. -+ */ -+ -+static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn) -+{ -+ int i; -+ const apr_array_header_t *arr = apr_table_elts(r->subprocess_env); -+ const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; -+ -+ sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD; -+ -+ for (i = 0; i < arr->nelts; i++) { -+ const char *key = elts[i].key; -+ -+ switch (*key) { -+ case 's': -+ /* being case-sensitive here. -+ * and not checking for the -shutdown since these are the only -+ * SetEnvIf "flags" we support -+ */ -+ if (!strncmp(key+1, "sl-", 3)) { -+ key += 4; -+ if (!strncmp(key, "unclean", 7)) { -+ sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; -+ } -+ else if (!strncmp(key, "accurate", 8)) { -+ sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_ACCURATE; -+ } -+ return; /* should only ever be one ssl-*-shutdown */ -+ } -+ break; -+ } -+ } -+} -+ -+/* -+ * URL Translation Handler -+ */ -+int ssl_hook_Translate(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ -+ if (!(sslconn && sslconn->ssl)) { -+ return DECLINED; -+ } -+ -+ /* -+ * Log information about incoming HTTPS requests -+ */ -+ if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "%s HTTPS request received for child %ld (server %s)", -+ (r->connection->keepalives <= 0 ? -+ "Initial (No.1)" : -+ apr_psprintf(r->pool, "Subsequent (No.%d)", -+ r->connection->keepalives+1)), -+ r->connection->id, -+ ssl_util_vhostid(r->pool, r->server)); -+ } -+ -+ /* SetEnvIf ssl-*-shutdown flags can only be per-server, -+ * so they won't change across keepalive requests -+ */ -+ if (sslconn->shutdown_type == SSL_SHUTDOWN_TYPE_UNSET) { -+ ssl_configure_env(r, sslconn); -+ } -+ -+ return DECLINED; -+} -+ -+/* -+ * Access Handler -+ */ -+int ssl_hook_Access(request_rec *r) -+{ -+ SSLDirConfigRec *dc = myDirConfig(r); -+ SSLSrvConfigRec *sc = mySrvConfig(r->server); -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSL *ssl = sslconn ? sslconn->ssl : NULL; -+ SSL_CTX *ctx = NULL; -+ apr_array_header_t *requires; -+ ssl_require_t *ssl_requires; -+ char *cp; -+ int ok, i; -+ BOOL renegotiate = FALSE, renegotiate_quick = FALSE; -+ X509 *cert; -+ X509 *peercert; -+ X509_STORE *cert_store = NULL; -+ X509_STORE_CTX cert_store_ctx; -+ STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL; -+ SSL_CIPHER *cipher = NULL; -+ int depth, verify_old, verify, n; -+ -+ if (ssl) { -+ ctx = SSL_get_SSL_CTX(ssl); -+ } -+ -+ /* -+ * Support for SSLRequireSSL directive -+ */ -+ if (dc->bSSLRequired && !ssl) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "access to %s failed, reason: %s", -+ r->filename, "SSL connection required"); -+ -+ /* remember forbidden access for strict require option */ -+ apr_table_setn(r->notes, "ssl-access-forbidden", "1"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* -+ * Check to see if SSL protocol is on -+ */ -+ if (!(sc->enabled || ssl)) { -+ return DECLINED; -+ } -+ /* -+ * Support for per-directory reconfigured SSL connection parameters. -+ * -+ * This is implemented by forcing an SSL renegotiation with the -+ * reconfigured parameter suite. But Apache's internal API processing -+ * makes our life very hard here, because when internal sub-requests occur -+ * we nevertheless should avoid multiple unnecessary SSL handshakes (they -+ * require extra network I/O and especially time to perform). -+ * -+ * But the optimization for filtering out the unnecessary handshakes isn't -+ * obvious and trivial. Especially because while Apache is in its -+ * sub-request processing the client could force additional handshakes, -+ * too. And these take place perhaps without our notice. So the only -+ * possibility is to explicitly _ask_ OpenSSL whether the renegotiation -+ * has to be performed or not. It has to performed when some parameters -+ * which were previously known (by us) are not those we've now -+ * reconfigured (as known by OpenSSL) or (in optimized way) at least when -+ * the reconfigured parameter suite is stronger (more restrictions) than -+ * the currently active one. -+ */ -+ -+ /* -+ * Override of SSLCipherSuite -+ * -+ * We provide two options here: -+ * -+ * o The paranoid and default approach where we force a renegotiation when -+ * the cipher suite changed in _any_ way (which is straight-forward but -+ * often forces renegotiations too often and is perhaps not what the -+ * user actually wanted). -+ * -+ * o The optimized and still secure way where we force a renegotiation -+ * only if the currently active cipher is no longer contained in the -+ * reconfigured/new cipher suite. Any other changes are not important -+ * because it's the servers choice to select a cipher from the ones the -+ * client supports. So as long as the current cipher is still in the new -+ * cipher suite we're happy. Because we can assume we would have -+ * selected it again even when other (better) ciphers exists now in the -+ * new cipher suite. This approach is fine because the user explicitly -+ * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no -+ * implicit optimizations. -+ */ -+ if (dc->szCipherSuite) { -+ /* remember old state */ -+ -+ if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { -+ cipher = SSL_get_current_cipher(ssl); -+ } -+ else { -+ cipher_list_old = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl); -+ -+ if (cipher_list_old) { -+ cipher_list_old = sk_SSL_CIPHER_dup(cipher_list_old); -+ } -+ } -+ -+ /* configure new state */ -+ if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, -+ r->server, -+ "Unable to reconfigure (per-directory) " -+ "permitted SSL ciphers"); -+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); -+ -+ if (cipher_list_old) { -+ sk_SSL_CIPHER_free(cipher_list_old); -+ } -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* determine whether a renegotiation has to be forced */ -+ cipher_list = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl); -+ -+ if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { -+ /* optimized way */ -+ if ((!cipher && cipher_list) || -+ (cipher && !cipher_list)) -+ { -+ renegotiate = TRUE; -+ } -+ else if (cipher && cipher_list && -+ (sk_SSL_CIPHER_find(cipher_list, cipher) < 0)) -+ { -+ renegotiate = TRUE; -+ } -+ } -+ else { -+ /* paranoid way */ -+ if ((!cipher_list_old && cipher_list) || -+ (cipher_list_old && !cipher_list)) -+ { -+ renegotiate = TRUE; -+ } -+ else if (cipher_list_old && cipher_list) { -+ for (n = 0; -+ !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list)); -+ n++) -+ { -+ SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n); -+ -+ if (sk_SSL_CIPHER_find(cipher_list_old, value) < 0) { -+ renegotiate = TRUE; -+ } -+ } -+ -+ for (n = 0; -+ !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list_old)); -+ n++) -+ { -+ SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n); -+ -+ if (sk_SSL_CIPHER_find(cipher_list, value) < 0) { -+ renegotiate = TRUE; -+ } -+ } -+ } -+ } -+ -+ /* cleanup */ -+ if (cipher_list_old) { -+ sk_SSL_CIPHER_free(cipher_list_old); -+ } -+ -+ /* tracing */ -+ if (renegotiate) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Reconfigured cipher suite will force renegotiation"); -+ } -+ } -+ -+ /* -+ * override of SSLVerifyDepth -+ * -+ * The depth checks are handled by us manually inside the verify callback -+ * function and not by OpenSSL internally (and our function is aware of -+ * both the per-server and per-directory contexts). So we cannot ask -+ * OpenSSL about the currently verify depth. Instead we remember it in our -+ * ap_ctx attached to the SSL* of OpenSSL. We've to force the -+ * renegotiation if the reconfigured/new verify depth is less than the -+ * currently active/remembered verify depth (because this means more -+ * restriction on the certificate chain). -+ */ -+ if (dc->nVerifyDepth != UNSET) { -+ /* XXX: doesnt look like sslconn->verify_depth is actually used */ -+ if (!(n = sslconn->verify_depth)) { -+ sslconn->verify_depth = n = sc->server->auth.verify_depth; -+ } -+ -+ /* determine whether a renegotiation has to be forced */ -+ if (dc->nVerifyDepth < n) { -+ renegotiate = TRUE; -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Reduced client verification depth will force " -+ "renegotiation"); -+ } -+ } -+ -+ /* -+ * override of SSLVerifyClient -+ * -+ * We force a renegotiation if the reconfigured/new verify type is -+ * stronger than the currently active verify type. -+ * -+ * The order is: none << optional_no_ca << optional << require -+ * -+ * Additionally the following optimization is possible here: When the -+ * currently active verify type is "none" but a client certificate is -+ * already known/present, it's enough to manually force a client -+ * verification but at least skip the I/O-intensive renegotation -+ * handshake. -+ */ -+ if (dc->nVerifyClient != SSL_CVERIFY_UNSET) { -+ /* remember old state */ -+ verify_old = SSL_get_verify_mode(ssl); -+ /* configure new state */ -+ verify = SSL_VERIFY_NONE; -+ -+ if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) { -+ verify |= SSL_VERIFY_PEER_STRICT; -+ } -+ -+ if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) || -+ (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA)) -+ { -+ verify |= SSL_VERIFY_PEER; -+ } -+ -+ modssl_set_verify(ssl, verify, ssl_callback_SSLVerify); -+ SSL_set_verify_result(ssl, X509_V_OK); -+ -+ /* determine whether we've to force a renegotiation */ -+ if (!renegotiate && verify != verify_old) { -+ if (((verify_old == SSL_VERIFY_NONE) && -+ (verify != SSL_VERIFY_NONE)) || -+ -+ (!(verify_old & SSL_VERIFY_PEER) && -+ (verify & SSL_VERIFY_PEER)) || -+ -+ (!(verify_old & SSL_VERIFY_PEER_STRICT) && -+ (verify & SSL_VERIFY_PEER_STRICT))) -+ { -+ renegotiate = TRUE; -+ /* optimization */ -+ -+ if ((dc->nOptions & SSL_OPT_OPTRENEGOTIATE) && -+ (verify_old == SSL_VERIFY_NONE) && -+ ((peercert = SSL_get_peer_certificate(ssl)) != NULL)) -+ { -+ renegotiate_quick = TRUE; -+ X509_free(peercert); -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, -+ r->server, -+ "Changed client verification type will force " -+ "%srenegotiation", -+ renegotiate_quick ? "quick " : ""); -+ } -+ } -+ } -+ -+ /* -+ * override SSLCACertificateFile & SSLCACertificatePath -+ * This is only enabled if the SSL_set_cert_store() function -+ * is available in the ssl library. the 1.x based mod_ssl -+ * used SSL_CTX_set_cert_store which is not thread safe. -+ */ -+ -+#ifdef HAVE_SSL_SET_CERT_STORE -+ /* -+ * check if per-dir and per-server config field are not the same. -+ * if f is defined in per-dir and not defined in per-server -+ * or f is defined in both but not the equal ... -+ */ -+#define MODSSL_CFG_NE(f) \ -+ (dc->f && (!sc->f || (sc->f && strNE(dc->f, sc->f)))) -+ -+#define MODSSL_CFG_CA(f) \ -+ (dc->f ? dc->f : sc->f) -+ -+ if (MODSSL_CFG_NE(szCACertificateFile) || -+ MODSSL_CFG_NE(szCACertificatePath)) -+ { -+ STACK_OF(X509_NAME) *ca_list; -+ const char *ca_file = MODSSL_CFG_CA(szCACertificateFile); -+ const char *ca_path = MODSSL_CFG_CA(szCACertificatePath); -+ -+ cert_store = X509_STORE_new(); -+ -+ if (!X509_STORE_load_locations(cert_store, ca_file, ca_path)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Unable to reconfigure verify locations " -+ "for client authentication"); -+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); -+ -+ X509_STORE_free(cert_store); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* SSL_free will free cert_store */ -+ SSL_set_cert_store(ssl, cert_store); -+ -+ if (!(ca_list = ssl_init_FindCAList(r->server, r->pool, -+ ca_file, ca_path))) -+ { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Unable to determine list of available " -+ "CA certificates for client authentication"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ SSL_set_client_CA_list(ssl, ca_list); -+ renegotiate = TRUE; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Changed client verification locations will force " -+ "renegotiation"); -+ } -+#endif /* HAVE_SSL_SET_CERT_STORE */ -+ -+ /* -+ * SSL renegotiations in conjunction with HTTP -+ * requests using the POST method are not supported. -+ * -+ * Background: -+ * -+ * 1. When the client sends a HTTP/HTTPS request, Apache's core code -+ * reads only the request line ("METHOD /path HTTP/x.y") and the -+ * attached MIME headers ("Foo: bar") up to the terminating line ("CR -+ * LF"). An attached request body (for instance the data of a POST -+ * method) is _NOT_ read. Instead it is read by mod_cgi's content -+ * handler and directly passed to the CGI script. -+ * -+ * 2. mod_ssl supports per-directory re-configuration of SSL parameters. -+ * This is implemented by performing an SSL renegotiation of the -+ * re-configured parameters after the request is read, but before the -+ * response is sent. In more detail: the renegotiation happens after the -+ * request line and MIME headers were read, but _before_ the attached -+ * request body is read. The reason simply is that in the HTTP protocol -+ * usually there is no acknowledgment step between the headers and the -+ * body (there is the 100-continue feature and the chunking facility -+ * only), so Apache has no API hook for this step. -+ * -+ * 3. the problem now occurs when the client sends a POST request for -+ * URL /foo via HTTPS the server and the server has SSL parameters -+ * re-configured on a per-URL basis for /foo. Then mod_ssl has to -+ * perform an SSL renegotiation after the request was read and before -+ * the response is sent. But the problem is the pending POST body data -+ * in the receive buffer of SSL (which Apache still has not read - it's -+ * pending until mod_cgi sucks it in). When mod_ssl now tries to perform -+ * the renegotiation the pending data leads to an I/O error. -+ * -+ * Solution Idea: -+ * -+ * There are only two solutions: Either to simply state that POST -+ * requests to URLs with SSL re-configurations are not allowed, or to -+ * renegotiate really after the _complete_ request (i.e. including -+ * the POST body) was read. Obviously the latter would be preferred, -+ * but it cannot be done easily inside Apache, because as already -+ * mentioned, there is no API step between the body reading and the body -+ * processing. And even when we mod_ssl would hook directly into the -+ * loop of mod_cgi, we wouldn't solve the problem for other handlers, of -+ * course. So the only general solution is to suck in the pending data -+ * of the request body from the OpenSSL BIO into the Apache BUFF. Then -+ * the renegotiation can be done and after this step Apache can proceed -+ * processing the request as before. -+ * -+ * Solution Implementation: -+ * -+ * We cannot simply suck in the data via an SSL_read-based loop because of -+ * HTTP chunking. Instead we _have_ to use the Apache API for this step which -+ * is aware of HTTP chunking. So the trick is to suck in the pending request -+ * data via the Apache API (which uses Apache's BUFF code and in the -+ * background mod_ssl's I/O glue code) and re-inject it later into the Apache -+ * BUFF code again. This way the data flows twice through the Apache BUFF, of -+ * course. But this way the solution doesn't depend on any Apache specifics -+ * and is fully transparent to Apache modules. -+ * -+ * !! BUT ALL THIS IS STILL NOT RE-IMPLEMENTED FOR APACHE 2.0 !! -+ */ -+ if (renegotiate && !renegotiate_quick && (r->method_number == M_POST)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "SSL Re-negotiation in conjunction " -+ "with POST method not supported!\n" -+ "hint: try SSLOptions +OptRenegotiate"); -+ -+ return HTTP_METHOD_NOT_ALLOWED; -+ } -+ -+ /* -+ * now do the renegotiation if anything was actually reconfigured -+ */ -+ if (renegotiate) { -+ /* -+ * Now we force the SSL renegotation by sending the Hello Request -+ * message to the client. Here we have to do a workaround: Actually -+ * OpenSSL returns immediately after sending the Hello Request (the -+ * intent AFAIK is because the SSL/TLS protocol says it's not a must -+ * that the client replies to a Hello Request). But because we insist -+ * on a reply (anything else is an error for us) we have to go to the -+ * ACCEPT state manually. Using SSL_set_accept_state() doesn't work -+ * here because it resets too much of the connection. So we set the -+ * state explicitly and continue the handshake manually. -+ */ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Requesting connection re-negotiation"); -+ -+ if (renegotiate_quick) { -+ STACK_OF(X509) *cert_stack; -+ -+ /* perform just a manual re-verification of the peer */ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Performing quick renegotiation: " -+ "just re-verifying the peer"); -+ -+ cert_stack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl); -+ -+ cert = SSL_get_peer_certificate(ssl); -+ -+ if (!cert_stack && cert) { -+ /* client cert is in the session cache, but there is -+ * no chain, since ssl3_get_client_certificate() -+ * sk_X509_shift-ed the peer cert out of the chain. -+ * we put it back here for the purpose of quick_renegotiation. -+ */ -+ cert_stack = sk_new_null(); -+ sk_X509_push(cert_stack, MODSSL_PCHAR_CAST cert); -+ } -+ -+ if (!cert_stack || (sk_X509_num(cert_stack) == 0)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Cannot find peer certificate chain"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (!(cert_store || -+ (cert_store = SSL_CTX_get_cert_store(ctx)))) -+ { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Cannot find certificate storage"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (!cert) { -+ cert = sk_X509_value(cert_stack, 0); -+ } -+ -+ X509_STORE_CTX_init(&cert_store_ctx, cert_store, cert, cert_stack); -+ depth = SSL_get_verify_depth(ssl); -+ -+ if (depth >= 0) { -+ X509_STORE_CTX_set_depth(&cert_store_ctx, depth); -+ } -+ -+ X509_STORE_CTX_set_ex_data(&cert_store_ctx, -+ SSL_get_ex_data_X509_STORE_CTX_idx(), -+ (char *)ssl); -+ -+ if (!modssl_X509_verify_cert(&cert_store_ctx)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation verification step failed"); -+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); -+ } -+ -+ SSL_set_verify_result(ssl, cert_store_ctx.error); -+ X509_STORE_CTX_cleanup(&cert_store_ctx); -+ -+ if (cert_stack != SSL_get_peer_cert_chain(ssl)) { -+ /* we created this ourselves, so free it */ -+ sk_X509_pop_free(cert_stack, X509_free); -+ } -+ } -+ else { -+ request_rec *id = r->main ? r->main : r; -+ -+ /* do a full renegotiation */ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Performing full renegotiation: " -+ "complete handshake protocol"); -+ -+ SSL_set_session_id_context(ssl, -+ (unsigned char *)&id, -+ sizeof(id)); -+ -+ SSL_renegotiate(ssl); -+ SSL_do_handshake(ssl); -+ -+ if (SSL_get_state(ssl) != SSL_ST_OK) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation request failed"); -+ -+ r->connection->aborted = 1; -+ return HTTP_FORBIDDEN; -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Awaiting re-negotiation handshake"); -+ -+ SSL_set_state(ssl, SSL_ST_ACCEPT); -+ SSL_do_handshake(ssl); -+ -+ if (SSL_get_state(ssl) != SSL_ST_OK) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation handshake failed: " -+ "Not accepted by client!?"); -+ -+ r->connection->aborted = 1; -+ return HTTP_FORBIDDEN; -+ } -+ } -+ -+ /* -+ * Remember the peer certificate's DN -+ */ -+ if ((cert = SSL_get_peer_certificate(ssl))) { -+ if (sslconn->client_cert) { -+ X509_free(sslconn->client_cert); -+ } -+ sslconn->client_cert = cert; -+ sslconn->client_dn = NULL; -+ } -+ -+ /* -+ * Finally check for acceptable renegotiation results -+ */ -+ if (dc->nVerifyClient != SSL_CVERIFY_NONE) { -+ BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE); -+ -+ if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation handshake failed: " -+ "Client verification failed"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (do_verify) { -+ if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation handshake failed: " -+ "Client certificate missing"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ X509_free(peercert); -+ } -+ } -+ } -+ -+ /* -+ * Check SSLRequire boolean expressions -+ */ -+ requires = dc->aRequirement; -+ ssl_requires = (ssl_require_t *)requires->elts; -+ -+ for (i = 0; i < requires->nelts; i++) { -+ ssl_require_t *req = &ssl_requires[i]; -+ ok = ssl_expr_exec(r, req->mpExpr); -+ -+ if (ok < 0) { -+ cp = apr_psprintf(r->pool, -+ "Failed to execute " -+ "SSL requirement expression: %s", -+ ssl_expr_get_error()); -+ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "access to %s failed, reason: %s", -+ r->filename, cp); -+ -+ /* remember forbidden access for strict require option */ -+ apr_table_setn(r->notes, "ssl-access-forbidden", "1"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (ok != 1) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Access to %s denied for %s " -+ "(requirement expression not fulfilled)", -+ r->filename, r->connection->remote_ip); -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Failed expression: %s", req->cpExpr); -+ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "access to %s failed, reason: %s", -+ r->filename, -+ "SSL requirement expression not fulfilled " -+ "(see SSL logfile for more details)"); -+ -+ /* remember forbidden access for strict require option */ -+ apr_table_setn(r->notes, "ssl-access-forbidden", "1"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ } -+ -+ /* -+ * Else access is granted from our point of view (except vendor -+ * handlers override). But we have to return DECLINED here instead -+ * of OK, because mod_auth and other modules still might want to -+ * deny access. -+ */ -+ -+ return DECLINED; -+} -+ -+/* -+ * Authentication Handler: -+ * Fake a Basic authentication from the X509 client certificate. -+ * -+ * This must be run fairly early on to prevent a real authentication from -+ * occuring, in particular it must be run before anything else that -+ * authenticates a user. This means that the Module statement for this -+ * module should be LAST in the Configuration file. -+ */ -+int ssl_hook_UserCheck(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSLSrvConfigRec *sc = mySrvConfig(r->server); -+ SSLDirConfigRec *dc = myDirConfig(r); -+ char buf1[MAX_STRING_LEN], buf2[MAX_STRING_LEN]; -+ char *clientdn; -+ const char *auth_line, *username, *password; -+ -+ /* -+ * Additionally forbid access (again) -+ * when strict require option is used. -+ */ -+ if ((dc->nOptions & SSL_OPT_STRICTREQUIRE) && -+ (apr_table_get(r->notes, "ssl-access-forbidden"))) -+ { -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* -+ * We decline when we are in a subrequest. The Authorization header -+ * would already be present if it was added in the main request. -+ */ -+ if (!ap_is_initial_req(r)) { -+ return DECLINED; -+ } -+ -+ /* -+ * Make sure the user is not able to fake the client certificate -+ * based authentication by just entering an X.509 Subject DN -+ * ("/XX=YYY/XX=YYY/..") as the username and "password" as the -+ * password. -+ */ -+ if ((auth_line = apr_table_get(r->headers_in, "Authorization"))) { -+ if (strcEQ(ap_getword(r->pool, &auth_line, ' '), "Basic")) { -+ while ((*auth_line == ' ') || (*auth_line == '\t')) { -+ auth_line++; -+ } -+ -+ auth_line = ap_pbase64decode(r->pool, auth_line); -+ username = ap_getword_nulls(r->pool, &auth_line, ':'); -+ password = auth_line; -+ -+ if ((username[0] == '/') && strEQ(password, "password")) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "Encountered FakeBasicAuth spoof: %s", username); -+ return HTTP_FORBIDDEN; -+ } -+ } -+ } -+ -+ /* -+ * We decline operation in various situations... -+ * - SSLOptions +FakeBasicAuth not configured -+ * - r->user already authenticated -+ * - ssl not enabled -+ * - client did not present a certificate -+ */ -+ if (!(sc->enabled && sslconn->ssl && sslconn->client_cert) || -+ !(dc->nOptions & SSL_OPT_FAKEBASICAUTH) || r->user) -+ { -+ return DECLINED; -+ } -+ -+ if (!sslconn->client_dn) { -+ X509_NAME *name = X509_get_subject_name(sslconn->client_cert); -+ char *cp = X509_NAME_oneline(name, NULL, 0); -+ sslconn->client_dn = apr_pstrdup(r->connection->pool, cp); -+ modssl_free(cp); -+ } -+ -+ clientdn = (char *)sslconn->client_dn; -+ -+ /* -+ * Fake a password - which one would be immaterial, as, it seems, an empty -+ * password in the users file would match ALL incoming passwords, if only -+ * we were using the standard crypt library routine. Unfortunately, OpenSSL -+ * "fixes" a "bug" in crypt and thus prevents blank passwords from -+ * working. (IMHO what they really fix is a bug in the users of the code -+ * - failing to program correctly for shadow passwords). We need, -+ * therefore, to provide a password. This password can be matched by -+ * adding the string "xxj31ZMTZzkVA" as the password in the user file. -+ * This is just the crypted variant of the word "password" ;-) -+ */ -+ apr_snprintf(buf1, sizeof(buf1), "%s:password", clientdn); -+ ssl_util_uuencode(buf2, buf1, FALSE); -+ -+ apr_snprintf(buf1, sizeof(buf1), "Basic %s", buf2); -+ apr_table_set(r->headers_in, "Authorization", buf1); -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Faking HTTP Basic Auth header: \"Authorization: %s\"", buf1); -+ -+ return DECLINED; -+} -+ -+/* authorization phase */ -+int ssl_hook_Auth(request_rec *r) -+{ -+ SSLDirConfigRec *dc = myDirConfig(r); -+ -+ /* -+ * Additionally forbid access (again) -+ * when strict require option is used. -+ */ -+ if ((dc->nOptions & SSL_OPT_STRICTREQUIRE) && -+ (apr_table_get(r->notes, "ssl-access-forbidden"))) -+ { -+ return HTTP_FORBIDDEN; -+ } -+ -+ return DECLINED; -+} -+ -+/* -+ * Fixup Handler -+ */ -+ -+static const char *ssl_hook_Fixup_vars[] = { -+ "SSL_VERSION_INTERFACE", -+ "SSL_VERSION_LIBRARY", -+ "SSL_PROTOCOL", -+ "SSL_CIPHER", -+ "SSL_CIPHER_EXPORT", -+ "SSL_CIPHER_USEKEYSIZE", -+ "SSL_CIPHER_ALGKEYSIZE", -+ "SSL_CLIENT_VERIFY", -+ "SSL_CLIENT_M_VERSION", -+ "SSL_CLIENT_M_SERIAL", -+ "SSL_CLIENT_V_START", -+ "SSL_CLIENT_V_END", -+ "SSL_CLIENT_S_DN", -+ "SSL_CLIENT_S_DN_C", -+ "SSL_CLIENT_S_DN_ST", -+ "SSL_CLIENT_S_DN_L", -+ "SSL_CLIENT_S_DN_O", -+ "SSL_CLIENT_S_DN_OU", -+ "SSL_CLIENT_S_DN_CN", -+ "SSL_CLIENT_S_DN_T", -+ "SSL_CLIENT_S_DN_I", -+ "SSL_CLIENT_S_DN_G", -+ "SSL_CLIENT_S_DN_S", -+ "SSL_CLIENT_S_DN_D", -+ "SSL_CLIENT_S_DN_UID", -+ "SSL_CLIENT_S_DN_Email", -+ "SSL_CLIENT_I_DN", -+ "SSL_CLIENT_I_DN_C", -+ "SSL_CLIENT_I_DN_ST", -+ "SSL_CLIENT_I_DN_L", -+ "SSL_CLIENT_I_DN_O", -+ "SSL_CLIENT_I_DN_OU", -+ "SSL_CLIENT_I_DN_CN", -+ "SSL_CLIENT_I_DN_T", -+ "SSL_CLIENT_I_DN_I", -+ "SSL_CLIENT_I_DN_G", -+ "SSL_CLIENT_I_DN_S", -+ "SSL_CLIENT_I_DN_D", -+ "SSL_CLIENT_I_DN_UID", -+ "SSL_CLIENT_I_DN_Email", -+ "SSL_CLIENT_A_KEY", -+ "SSL_CLIENT_A_SIG", -+ "SSL_SERVER_M_VERSION", -+ "SSL_SERVER_M_SERIAL", -+ "SSL_SERVER_V_START", -+ "SSL_SERVER_V_END", -+ "SSL_SERVER_S_DN", -+ "SSL_SERVER_S_DN_C", -+ "SSL_SERVER_S_DN_ST", -+ "SSL_SERVER_S_DN_L", -+ "SSL_SERVER_S_DN_O", -+ "SSL_SERVER_S_DN_OU", -+ "SSL_SERVER_S_DN_CN", -+ "SSL_SERVER_S_DN_T", -+ "SSL_SERVER_S_DN_I", -+ "SSL_SERVER_S_DN_G", -+ "SSL_SERVER_S_DN_S", -+ "SSL_SERVER_S_DN_D", -+ "SSL_SERVER_S_DN_UID", -+ "SSL_SERVER_S_DN_Email", -+ "SSL_SERVER_I_DN", -+ "SSL_SERVER_I_DN_C", -+ "SSL_SERVER_I_DN_ST", -+ "SSL_SERVER_I_DN_L", -+ "SSL_SERVER_I_DN_O", -+ "SSL_SERVER_I_DN_OU", -+ "SSL_SERVER_I_DN_CN", -+ "SSL_SERVER_I_DN_T", -+ "SSL_SERVER_I_DN_I", -+ "SSL_SERVER_I_DN_G", -+ "SSL_SERVER_I_DN_S", -+ "SSL_SERVER_I_DN_D", -+ "SSL_SERVER_I_DN_UID", -+ "SSL_SERVER_I_DN_Email", -+ "SSL_SERVER_A_KEY", -+ "SSL_SERVER_A_SIG", -+ "SSL_SESSION_ID", -+ NULL -+}; -+ -+int ssl_hook_Fixup(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSLSrvConfigRec *sc = mySrvConfig(r->server); -+ SSLDirConfigRec *dc = myDirConfig(r); -+ apr_table_t *env = r->subprocess_env; -+ char *var, *val = ""; -+ STACK_OF(X509) *peer_certs; -+ SSL *ssl; -+ int i; -+ -+ /* -+ * Check to see if SSL is on -+ */ -+ if (!(sc->enabled && sslconn && (ssl = sslconn->ssl))) { -+ return DECLINED; -+ } -+ -+ /* -+ * Annotate the SSI/CGI environment with standard SSL information -+ */ -+ /* the always present HTTPS (=HTTP over SSL) flag! */ -+ apr_table_setn(env, "HTTPS", "on"); -+ -+ /* standard SSL environment variables */ -+ if (dc->nOptions & SSL_OPT_STDENVVARS) { -+ for (i = 0; ssl_hook_Fixup_vars[i]; i++) { -+ var = (char *)ssl_hook_Fixup_vars[i]; -+ val = ssl_var_lookup(r->pool, r->server, r->connection, r, var); -+ if (!strIsEmpty(val)) { -+ apr_table_setn(env, var, val); -+ } -+ } -+ } -+ -+ /* -+ * On-demand bloat up the SSI/CGI environment with certificate data -+ */ -+ if (dc->nOptions & SSL_OPT_EXPORTCERTDATA) { -+ val = ssl_var_lookup(r->pool, r->server, r->connection, -+ r, "SSL_SERVER_CERT"); -+ -+ apr_table_setn(env, "SSL_SERVER_CERT", val); -+ -+ val = ssl_var_lookup(r->pool, r->server, r->connection, -+ r, "SSL_CLIENT_CERT"); -+ -+ apr_table_setn(env, "SSL_CLIENT_CERT", val); -+ -+ if ((peer_certs = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl))) { -+ for (i = 0; i < sk_X509_num(peer_certs); i++) { -+ var = apr_psprintf(r->pool, "SSL_CLIENT_CERT_CHAIN_%d", i); -+ val = ssl_var_lookup(r->pool, r->server, r->connection, -+ r, var); -+ if (val) { -+ apr_table_setn(env, var, val); -+ } -+ } -+ } -+ } -+ -+ return DECLINED; -+} -+ -+/* _________________________________________________________________ -+** -+** OpenSSL Callback Functions -+** _________________________________________________________________ -+*/ -+ -+/* -+ * Handle out temporary RSA private keys on demand -+ * -+ * The background of this as the TLSv1 standard explains it: -+ * -+ * | D.1. Temporary RSA keys -+ * | -+ * | US Export restrictions limit RSA keys used for encryption to 512 -+ * | bits, but do not place any limit on lengths of RSA keys used for -+ * | signing operations. Certificates often need to be larger than 512 -+ * | bits, since 512-bit RSA keys are not secure enough for high-value -+ * | transactions or for applications requiring long-term security. Some -+ * | certificates are also designated signing-only, in which case they -+ * | cannot be used for key exchange. -+ * | -+ * | When the public key in the certificate cannot be used for encryption, -+ * | the server signs a temporary RSA key, which is then exchanged. In -+ * | exportable applications, the temporary RSA key should be the maximum -+ * | allowable length (i.e., 512 bits). Because 512-bit RSA keys are -+ * | relatively insecure, they should be changed often. For typical -+ * | electronic commerce applications, it is suggested that keys be -+ * | changed daily or every 500 transactions, and more often if possible. -+ * | Note that while it is acceptable to use the same temporary key for -+ * | multiple transactions, it must be signed each time it is used. -+ * | -+ * | RSA key generation is a time-consuming process. In many cases, a -+ * | low-priority process can be assigned the task of key generation. -+ * | Whenever a new key is completed, the existing temporary key can be -+ * | replaced with the new one. -+ * -+ * XXX: base on comment above, if thread support is enabled, -+ * we should spawn a low-priority thread to generate new keys -+ * on the fly. -+ * -+ * So we generated 512 and 1024 bit temporary keys on startup -+ * which we now just hand out on demand.... -+ */ -+ -+RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen) -+{ -+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -+ SSLModConfigRec *mc = myModConfig(c->base_server); -+ int idx; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, -+ "handing out temporary %d bit RSA key", keylen); -+ -+ /* doesn't matter if export flag is on, -+ * we won't be asked for keylen > 512 in that case. -+ * if we are asked for a keylen > 1024, it is too expensive -+ * to generate on the fly. -+ * XXX: any reason not to generate 2048 bit keys at startup? -+ */ -+ -+ switch (keylen) { -+ case 512: -+ idx = SSL_TMP_KEY_RSA_512; -+ break; -+ -+ case 1024: -+ default: -+ idx = SSL_TMP_KEY_RSA_1024; -+ } -+ -+ return (RSA *)mc->pTmpKeys[idx]; -+} -+ -+/* -+ * Hand out the already generated DH parameters... -+ */ -+DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) -+{ -+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -+ SSLModConfigRec *mc = myModConfig(c->base_server); -+ int idx; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, -+ "handing out temporary %d bit DH key", keylen); -+ -+ switch (keylen) { -+ case 512: -+ idx = SSL_TMP_KEY_DH_512; -+ break; -+ -+ case 1024: -+ default: -+ idx = SSL_TMP_KEY_DH_1024; -+ } -+ -+ return (DH *)mc->pTmpKeys[idx]; -+} -+ -+/* -+ * This OpenSSL callback function is called when OpenSSL -+ * does client authentication and verifies the certificate chain. -+ */ -+int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) -+{ -+ /* Get Apache context back through OpenSSL context */ -+ SSL *ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx); -+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = conn->base_server; -+ request_rec *r = (request_rec *)SSL_get_app_data2(ssl); -+ -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; -+ SSLConnRec *sslconn = myConnConfig(conn); -+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); -+ -+ /* Get verify ingredients */ -+ int errnum = X509_STORE_CTX_get_error(ctx); -+ int errdepth = X509_STORE_CTX_get_error_depth(ctx); -+ int depth, verify; -+ -+ /* -+ * Log verification information -+ */ -+ if (s->loglevel >= APLOG_DEBUG) { -+ X509 *cert = X509_STORE_CTX_get_current_cert(ctx); -+ char *sname = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); -+ char *iname = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "Certificate Verification: " -+ "depth: %d, subject: %s, issuer: %s", -+ errdepth, -+ sname ? sname : "-unknown-", -+ iname ? iname : "-unknown-"); -+ -+ if (sname) { -+ modssl_free(sname); -+ } -+ -+ if (iname) { -+ modssl_free(iname); -+ } -+ } -+ -+ /* -+ * Check for optionally acceptable non-verifiable issuer situation -+ */ -+ if (dc && (dc->nVerifyClient != SSL_CVERIFY_UNSET)) { -+ verify = dc->nVerifyClient; -+ } -+ else { -+ verify = mctx->auth.verify_mode; -+ } -+ -+ if (verify == SSL_CVERIFY_NONE) { -+ /* -+ * SSLProxyVerify is either not configured or set to "none". -+ * (this callback doesn't happen in the server context if SSLVerify -+ * is not configured or set to "none") -+ */ -+ return TRUE; -+ } -+ -+ if (ssl_verify_error_is_optional(errnum) && -+ (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) -+ { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "Certificate Verification: Verifiable Issuer is " -+ "configured as optional, therefore we're accepting " -+ "the certificate"); -+ -+ sslconn->verify_info = "GENEROUS"; -+ ok = TRUE; -+ } -+ -+ /* -+ * Additionally perform CRL-based revocation checks -+ */ -+ if (ok) { -+ if (!(ok = ssl_callback_SSLVerify_CRL(ok, ctx, conn))) { -+ errnum = X509_STORE_CTX_get_error(ctx); -+ } -+ } -+ -+ /* -+ * If we already know it's not ok, log the real reason -+ */ -+ if (!ok) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, -+ "Certificate Verification: Error (%d): %s", -+ errnum, X509_verify_cert_error_string(errnum)); -+ -+ if (sslconn->client_cert) { -+ X509_free(sslconn->client_cert); -+ sslconn->client_cert = NULL; -+ } -+ sslconn->client_dn = NULL; -+ sslconn->verify_error = X509_verify_cert_error_string(errnum); -+ } -+ -+ /* -+ * Finally check the depth of the certificate verification -+ */ -+ if (dc && (dc->nVerifyDepth != UNSET)) { -+ depth = dc->nVerifyDepth; -+ } -+ else { -+ depth = mctx->auth.verify_depth; -+ } -+ -+ if (errdepth > depth) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, -+ "Certificate Verification: Certificate Chain too long " -+ "(chain has %d certificates, but maximum allowed are " -+ "only %d)", -+ errdepth, depth); -+ -+ errnum = X509_V_ERR_CERT_CHAIN_TOO_LONG; -+ sslconn->verify_error = X509_verify_cert_error_string(errnum); -+ -+ ok = FALSE; -+ } -+ -+ /* -+ * And finally signal OpenSSL the (perhaps changed) state -+ */ -+ return ok; -+} -+ -+int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c) -+{ -+ server_rec *s = c->base_server; -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ SSLConnRec *sslconn = myConnConfig(c); -+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); -+ X509_OBJECT obj; -+ X509_NAME *subject, *issuer; -+ X509 *cert; -+ X509_CRL *crl; -+ EVP_PKEY *pubkey; -+ int i, n, rc; -+ -+ /* -+ * Unless a revocation store for CRLs was created we -+ * cannot do any CRL-based verification, of course. -+ */ -+ if (!mctx->crl) { -+ return ok; -+ } -+ -+ /* -+ * Determine certificate ingredients in advance -+ */ -+ cert = X509_STORE_CTX_get_current_cert(ctx); -+ subject = X509_get_subject_name(cert); -+ issuer = X509_get_issuer_name(cert); -+ -+ /* -+ * OpenSSL provides the general mechanism to deal with CRLs but does not -+ * use them automatically when verifying certificates, so we do it -+ * explicitly here. We will check the CRL for the currently checked -+ * certificate, if there is such a CRL in the store. -+ * -+ * We come through this procedure for each certificate in the certificate -+ * chain, starting with the root-CA's certificate. At each step we've to -+ * both verify the signature on the CRL (to make sure it's a valid CRL) -+ * and it's revocation list (to make sure the current certificate isn't -+ * revoked). But because to check the signature on the CRL we need the -+ * public key of the issuing CA certificate (which was already processed -+ * one round before), we've a little problem. But we can both solve it and -+ * at the same time optimize the processing by using the following -+ * verification scheme (idea and code snippets borrowed from the GLOBUS -+ * project): -+ * -+ * 1. We'll check the signature of a CRL in each step when we find a CRL -+ * through the _subject_ name of the current certificate. This CRL -+ * itself will be needed the first time in the next round, of course. -+ * But we do the signature processing one round before this where the -+ * public key of the CA is available. -+ * -+ * 2. We'll check the revocation list of a CRL in each step when -+ * we find a CRL through the _issuer_ name of the current certificate. -+ * This CRLs signature was then already verified one round before. -+ * -+ * This verification scheme allows a CA to revoke its own certificate as -+ * well, of course. -+ */ -+ -+ /* -+ * Try to retrieve a CRL corresponding to the _subject_ of -+ * the current certificate in order to verify it's integrity. -+ */ -+ memset((char *)&obj, 0, sizeof(obj)); -+ rc = SSL_X509_STORE_lookup(mctx->crl, -+ X509_LU_CRL, subject, &obj); -+ crl = obj.data.crl; -+ -+ if ((rc > 0) && crl) { -+ /* -+ * Log information about CRL -+ * (A little bit complicated because of ASN.1 and BIOs...) -+ */ -+ if (s->loglevel >= APLOG_DEBUG) { -+ char buff[512]; /* should be plenty */ -+ BIO *bio = BIO_new(BIO_s_mem()); -+ -+ BIO_printf(bio, "CA CRL: Issuer: "); -+ X509_NAME_print(bio, issuer, 0); -+ -+ BIO_printf(bio, ", lastUpdate: "); -+ ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl)); -+ -+ BIO_printf(bio, ", nextUpdate: "); -+ ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl)); -+ -+ n = BIO_read(bio, buff, sizeof(buff)); -+ buff[n] = '\0'; -+ -+ BIO_free(bio); -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, buff); -+ } -+ -+ /* -+ * Verify the signature on this CRL -+ */ -+ pubkey = X509_get_pubkey(cert); -+ rc = X509_CRL_verify(crl, pubkey); -+#ifdef OPENSSL_VERSION_NUMBER -+ /* Only refcounted in OpenSSL */ -+ if (pubkey) -+ EVP_PKEY_free(pubkey); -+#endif -+ if (rc <= 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ "Invalid signature on CRL"); -+ -+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); -+ X509_OBJECT_free_contents(&obj); -+ return FALSE; -+ } -+ -+ /* -+ * Check date of CRL to make sure it's not expired -+ */ -+ i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); -+ -+ if (i == 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ "Found CRL has invalid nextUpdate field"); -+ -+ X509_STORE_CTX_set_error(ctx, -+ X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); -+ X509_OBJECT_free_contents(&obj); -+ -+ return FALSE; -+ } -+ -+ if (i < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ "Found CRL is expired - " -+ "revoking all certificates until you get updated CRL"); -+ -+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); -+ X509_OBJECT_free_contents(&obj); -+ -+ return FALSE; -+ } -+ -+ X509_OBJECT_free_contents(&obj); -+ } -+ -+ /* -+ * Try to retrieve a CRL corresponding to the _issuer_ of -+ * the current certificate in order to check for revocation. -+ */ -+ memset((char *)&obj, 0, sizeof(obj)); -+ rc = SSL_X509_STORE_lookup(mctx->crl, -+ X509_LU_CRL, issuer, &obj); -+ -+ crl = obj.data.crl; -+ if ((rc > 0) && crl) { -+ /* -+ * Check if the current certificate is revoked by this CRL -+ */ -+ n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); -+ -+ for (i = 0; i < n; i++) { -+ X509_REVOKED *revoked = -+ sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); -+ -+ ASN1_INTEGER *sn = X509_REVOKED_get_serialNumber(revoked); -+ -+ if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) { -+ if (s->loglevel >= APLOG_DEBUG) { -+ char *cp = X509_NAME_oneline(issuer, NULL, 0); -+ long serial = ASN1_INTEGER_get(sn); -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, -+ "Certificate with serial %ld (0x%lX) " -+ "revoked per CRL from issuer %s", -+ serial, serial, cp); -+ modssl_free(cp); -+ } -+ -+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); -+ X509_OBJECT_free_contents(&obj); -+ -+ return FALSE; -+ } -+ } -+ -+ X509_OBJECT_free_contents(&obj); -+ } -+ -+ return ok; -+} -+ -+#define SSLPROXY_CERT_CB_LOG_FMT \ -+ "Proxy client certificate callback: (%s) " -+ -+static void modssl_proxy_info_log(server_rec *s, -+ X509_INFO *info, -+ const char *msg) -+{ -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ char name_buf[256]; -+ X509_NAME *name; -+ char *dn; -+ -+ if (s->loglevel < APLOG_DEBUG) { -+ return; -+ } -+ -+ name = X509_get_subject_name(info->x509); -+ dn = X509_NAME_oneline(name, name_buf, sizeof(name_buf)); -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT "%s, sending %s", -+ sc->vhost_id, msg, dn ? dn : "-uknown-"); -+} -+ -+/* -+ * caller will decrement the cert and key reference -+ * so we need to increment here to prevent them from -+ * being freed. -+ */ -+#define modssl_set_cert_info(info, cert, pkey) \ -+ *cert = info->x509; \ -+ X509_reference_inc(*cert); \ -+ *pkey = info->x_pkey->dec_pkey; \ -+ EVP_PKEY_reference_inc(*pkey) -+ -+int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey) -+{ -+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = c->base_server; -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ X509_NAME *ca_name, *issuer; -+ X509_INFO *info; -+ STACK_OF(X509_NAME) *ca_list; -+ STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs; -+ int i, j; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT "entered", -+ sc->vhost_id); -+ -+ if (!certs || (sk_X509_INFO_num(certs) <= 0)) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT -+ "downstream server wanted client certificate " -+ "but none are configured", sc->vhost_id); -+ return FALSE; -+ } -+ -+ ca_list = SSL_get_client_CA_list(ssl); -+ -+ if (!ca_list || (sk_X509_NAME_num(ca_list) <= 0)) { -+ /* -+ * downstream server didn't send us a list of acceptable CA certs, -+ * so we send the first client cert in the list. -+ */ -+ info = sk_X509_INFO_value(certs, 0); -+ -+ modssl_proxy_info_log(s, info, "no acceptable CA list"); -+ -+ modssl_set_cert_info(info, x509, pkey); -+ -+ return TRUE; -+ } -+ -+ for (i = 0; i < sk_X509_NAME_num(ca_list); i++) { -+ ca_name = sk_X509_NAME_value(ca_list, i); -+ -+ for (j = 0; j < sk_X509_INFO_num(certs); j++) { -+ info = sk_X509_INFO_value(certs, j); -+ issuer = X509_get_issuer_name(info->x509); -+ -+ if (X509_NAME_cmp(issuer, ca_name) == 0) { -+ modssl_proxy_info_log(s, info, "found acceptable cert"); -+ -+ modssl_set_cert_info(info, x509, pkey); -+ -+ return TRUE; -+ } -+ } -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT -+ "no client certificate found!?", sc->vhost_id); -+ -+ return FALSE; -+} -+ -+static void ssl_session_log(server_rec *s, -+ const char *request, -+ unsigned char *id, -+ unsigned int idlen, -+ const char *status, -+ const char *result, -+ long timeout) -+{ -+ char buf[SSL_SESSION_ID_STRING_LEN]; -+ char timeout_str[56] = {'\0'}; -+ -+ if (s->loglevel < APLOG_DEBUG) { -+ return; -+ } -+ -+ if (timeout) { -+ apr_snprintf(timeout_str, sizeof(timeout_str), -+ "timeout=%lds ", (timeout - time(NULL))); -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "Inter-Process Session Cache: " -+ "request=%s status=%s id=%s %s(session %s)", -+ request, status, -+ SSL_SESSION_id2sz(id, idlen, buf, sizeof(buf)), -+ timeout_str, result); -+} -+ -+/* -+ * This callback function is executed by OpenSSL whenever a new SSL_SESSION is -+ * added to the internal OpenSSL session cache. We use this hook to spread the -+ * SSL_SESSION also to the inter-process disk-cache to make share it with our -+ * other Apache pre-forked server processes. -+ */ -+int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *session) -+{ -+ /* Get Apache context back through OpenSSL context */ -+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = conn->base_server; -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ long timeout = sc->session_cache_timeout; -+ BOOL rc; -+ unsigned char *id; -+ unsigned int idlen; -+ -+ /* -+ * Set the timeout also for the internal OpenSSL cache, because this way -+ * our inter-process cache is consulted only when it's really necessary. -+ */ -+ SSL_set_timeout(session, timeout); -+ -+ /* -+ * Store the SSL_SESSION in the inter-process cache with the -+ * same expire time, so it expires automatically there, too. -+ */ -+ id = SSL_SESSION_get_session_id(session); -+ idlen = SSL_SESSION_get_session_id_length(session); -+ -+ timeout += modssl_session_get_time(session); -+ -+ rc = ssl_scache_store(s, id, idlen, timeout, session); -+ -+ ssl_session_log(s, "SET", id, idlen, -+ rc == TRUE ? "OK" : "BAD", -+ "caching", timeout); -+ -+ /* -+ * return 0 which means to OpenSSL that the session is still -+ * valid and was not freed by us with SSL_SESSION_free(). -+ */ -+ return 0; -+} -+ -+/* -+ * This callback function is executed by OpenSSL whenever a -+ * SSL_SESSION is looked up in the internal OpenSSL cache and it -+ * was not found. We use this to lookup the SSL_SESSION in the -+ * inter-process disk-cache where it was perhaps stored by one -+ * of our other Apache pre-forked server processes. -+ */ -+SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *ssl, -+ unsigned char *id, -+ int idlen, int *do_copy) -+{ -+ /* Get Apache context back through OpenSSL context */ -+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = conn->base_server; -+ SSL_SESSION *session; -+ -+ /* -+ * Try to retrieve the SSL_SESSION from the inter-process cache -+ */ -+ session = ssl_scache_retrieve(s, id, idlen); -+ -+ ssl_session_log(s, "GET", id, idlen, -+ session ? "FOUND" : "MISSED", -+ session ? "reuse" : "renewal", 0); -+ -+ /* -+ * Return NULL or the retrieved SSL_SESSION. But indicate (by -+ * setting do_copy to 0) that the reference count on the -+ * SSL_SESSION should not be incremented by the SSL library, -+ * because we will no longer hold a reference to it ourself. -+ */ -+ *do_copy = 0; -+ -+ return session; -+} -+ -+/* -+ * This callback function is executed by OpenSSL whenever a -+ * SSL_SESSION is removed from the the internal OpenSSL cache. -+ * We use this to remove the SSL_SESSION in the inter-process -+ * disk-cache, too. -+ */ -+void ssl_callback_DelSessionCacheEntry(SSL_CTX *ctx, -+ SSL_SESSION *session) -+{ -+ server_rec *s; -+ SSLSrvConfigRec *sc; -+ unsigned char *id; -+ unsigned int idlen; -+ -+ /* -+ * Get Apache context back through OpenSSL context -+ */ -+ if (!(s = (server_rec *)SSL_CTX_get_app_data(ctx))) { -+ return; /* on server shutdown Apache is already gone */ -+ } -+ -+ sc = mySrvConfig(s); -+ -+ /* -+ * Remove the SSL_SESSION from the inter-process cache -+ */ -+ id = SSL_SESSION_get_session_id(session); -+ idlen = SSL_SESSION_get_session_id_length(session); -+ -+ ssl_scache_remove(s, id, idlen); -+ -+ ssl_session_log(s, "REM", id, idlen, -+ "OK", "dead", 0); -+ -+ return; -+} -+ -+/* -+ * This callback function is executed while OpenSSL processes the -+ * SSL handshake and does SSL record layer stuff. We use it to -+ * trace OpenSSL's processing in out SSL logfile. -+ */ -+void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) -+{ -+ conn_rec *c; -+ server_rec *s; -+ SSLSrvConfigRec *sc; -+ -+ /* -+ * find corresponding server -+ */ -+ if (!(c = (conn_rec *)SSL_get_app_data((SSL *)ssl))) { -+ return; -+ } -+ -+ s = c->base_server; -+ if (!(sc = mySrvConfig(s))) { -+ return; -+ } -+ -+ /* -+ * create the various trace messages -+ */ -+ if (s->loglevel >= APLOG_DEBUG) { -+ if (where & SSL_CB_HANDSHAKE_START) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Handshake: start", SSL_LIBRARY_NAME); -+ } -+ else if (where & SSL_CB_HANDSHAKE_DONE) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Handshake: done", SSL_LIBRARY_NAME); -+ } -+ else if (where & SSL_CB_LOOP) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Loop: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_READ) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Read: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_WRITE) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Write: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_ALERT) { -+ char *str = (where & SSL_CB_READ) ? "read" : "write"; -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Alert: %s:%s:%s\n", -+ SSL_LIBRARY_NAME, str, -+ SSL_alert_type_string_long(rc), -+ SSL_alert_desc_string_long(rc)); -+ } -+ else if (where & SSL_CB_EXIT) { -+ if (rc == 0) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Exit: failed in %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (rc < 0) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Exit: error in %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ } -+ } -+ -+ /* -+ * Because SSL renegotations can happen at any time (not only after -+ * SSL_accept()), the best way to log the current connection details is -+ * right after a finished handshake. -+ */ -+ if (where & SSL_CB_HANDSHAKE_DONE) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, -+ "Connection: Client IP: %s, Protocol: %s, " -+ "Cipher: %s (%s/%s bits)", -+ ssl_var_lookup(NULL, s, c, NULL, "REMOTE_ADDR"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_PROTOCOL"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_USEKEYSIZE"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_ALGKEYSIZE")); -+ } -+} -+ diff --git a/net-www/apache/files/patches/2.0.49-r1/00_ssl_engine.patch b/net-www/apache/files/patches/2.0.49-r1/00_ssl_engine.patch deleted file mode 100644 index f0014ace6a19..000000000000 --- a/net-www/apache/files/patches/2.0.49-r1/00_ssl_engine.patch +++ /dev/null @@ -1,41 +0,0 @@ -=================================================================== -RCS file: /home/cvspublic/httpd-2.0/modules/ssl/ssl_engine_io.c,v -retrieving revision 1.121 -retrieving revision 1.122 -diff -u -r1.121 -r1.122 ---- httpd-2.0/modules/ssl/ssl_engine_io.c 2004/02/29 00:29:20 1.121 -+++ httpd-2.0/modules/ssl/ssl_engine_io.c 2004/03/25 19:36:32 1.122 -@@ -984,22 +984,20 @@ - - static apr_status_t ssl_io_filter_cleanup(void *data) - { -- apr_status_t ret; -- ssl_filter_ctx_t *filter_ctx = (ssl_filter_ctx_t *)data; -- conn_rec *c; -+ ssl_filter_ctx_t *filter_ctx = data; - -- if (!filter_ctx->pssl) { -- /* already been shutdown */ -- return APR_SUCCESS; -- } -+ if (filter_ctx->pssl) { -+ conn_rec *c = (conn_rec *)SSL_get_app_data(filter_ctx->pssl); -+ SSLConnRec *sslconn = myConnConfig(c); - -- c = (conn_rec *)SSL_get_app_data(filter_ctx->pssl); -- if ((ret = ssl_filter_io_shutdown(filter_ctx, c, 0)) != APR_SUCCESS) { -- ap_log_error(APLOG_MARK, APLOG_INFO, ret, NULL, -- "SSL filter error shutting down I/O"); -- } -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, -+ "SSL connection destroyed without being closed"); - -- return ret; -+ SSL_free(filter_ctx->pssl); -+ sslconn->ssl = filter_ctx->pssl = NULL; -+ } -+ -+ return APR_SUCCESS; - } - - /* diff --git a/net-www/apache/files/patches/2.0.49-r1/01_ssl_engine_kernel.patch b/net-www/apache/files/patches/2.0.49-r1/01_ssl_engine_kernel.patch deleted file mode 100644 index 4caf45f2041f..000000000000 --- a/net-www/apache/files/patches/2.0.49-r1/01_ssl_engine_kernel.patch +++ /dev/null @@ -1,1842 +0,0 @@ -diff -Naur httpd-2.0.49/modules/ssl/ssl_engine_kernel.c httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c ---- httpd-2.0.49/modules/ssl/ssl_engine_kernel.c 2004-02-09 20:53:20.000000000 +0000 -+++ httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c 2004-05-29 09:39:18.605535640 +0000 -@@ -793,7 +793,6 @@ - SSLConnRec *sslconn = myConnConfig(r->connection); - SSLSrvConfigRec *sc = mySrvConfig(r->server); - SSLDirConfigRec *dc = myDirConfig(r); -- char buf1[MAX_STRING_LEN], buf2[MAX_STRING_LEN]; - char *clientdn; - const char *auth_line, *username, *password; - -@@ -872,14 +871,16 @@ - * adding the string "xxj31ZMTZzkVA" as the password in the user file. - * This is just the crypted variant of the word "password" ;-) - */ -- apr_snprintf(buf1, sizeof(buf1), "%s:password", clientdn); -- ssl_util_uuencode(buf2, buf1, FALSE); -- -- apr_snprintf(buf1, sizeof(buf1), "Basic %s", buf2); -- apr_table_set(r->headers_in, "Authorization", buf1); -+ auth_line = apr_pstrcat(r->pool, "Basic ", -+ ap_pbase64encode(r->pool, -+ apr_pstrcat(r->pool, clientdn, -+ ":password", NULL)), -+ NULL); -+ apr_table_set(r->headers_in, "Authorization", auth_line); - - ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -- "Faking HTTP Basic Auth header: \"Authorization: %s\"", buf1); -+ "Faking HTTP Basic Auth header: \"Authorization: %s\"", -+ auth_line); - - return DECLINED; - } -diff -Naur httpd-2.0.49/modules/ssl/ssl_engine_kernel.c.orig httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c.orig ---- httpd-2.0.49/modules/ssl/ssl_engine_kernel.c.orig 1970-01-01 00:00:00.000000000 +0000 -+++ httpd-2.0.49-gentoo/modules/ssl/ssl_engine_kernel.c.orig 2004-02-09 20:53:20.000000000 +0000 -@@ -0,0 +1,1804 @@ -+/* Copyright 2001-2004 The Apache Software Foundation -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+/* _ _ -+ * _ __ ___ ___ __| | ___ ___| | mod_ssl -+ * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL -+ * | | | | | | (_) | (_| | \__ \__ \ | -+ * |_| |_| |_|\___/ \__,_|___|___/___/_| -+ * |_____| -+ * ssl_engine_kernel.c -+ * The SSL engine kernel -+ */ -+ /* ``It took me fifteen years to discover -+ I had no talent for programming, but -+ I couldn't give it up because by that -+ time I was too famous.'' -+ -- Unknown */ -+#include "mod_ssl.h" -+ -+/* -+ * Post Read Request Handler -+ */ -+int ssl_hook_ReadReq(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSL *ssl; -+ -+ if (!sslconn) { -+ return DECLINED; -+ } -+ -+ if (sslconn->non_ssl_request) { -+ const char *errmsg; -+ char *thisurl; -+ char *thisport = ""; -+ int port = ap_get_server_port(r); -+ -+ if (!ap_is_default_port(port, r)) { -+ thisport = apr_psprintf(r->pool, ":%u", port); -+ } -+ -+ thisurl = ap_escape_html(r->pool, -+ apr_psprintf(r->pool, "https://%s%s/", -+ ap_get_server_name(r), -+ thisport)); -+ -+ errmsg = apr_psprintf(r->pool, -+ "Reason: You're speaking plain HTTP " -+ "to an SSL-enabled server port.<br />\n" -+ "Instead use the HTTPS scheme to access " -+ "this URL, please.<br />\n" -+ "<blockquote>Hint: " -+ "<a href=\"%s\"><b>%s</b></a></blockquote>", -+ thisurl, thisurl); -+ -+ apr_table_setn(r->notes, "error-notes", errmsg); -+ -+ /* Now that we have caught this error, forget it. we are done -+ * with using SSL on this request. -+ */ -+ sslconn->non_ssl_request = 0; -+ -+ -+ return HTTP_BAD_REQUEST; -+ } -+ -+ /* -+ * Get the SSL connection structure and perform the -+ * delayed interlinking from SSL back to request_rec -+ */ -+ if ((ssl = sslconn->ssl)) { -+ SSL_set_app_data2(ssl, r); -+ } -+ -+ return DECLINED; -+} -+ -+/* -+ * Move SetEnvIf information from request_rec to conn_rec/BUFF -+ * to allow the close connection handler to use them. -+ */ -+ -+static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn) -+{ -+ int i; -+ const apr_array_header_t *arr = apr_table_elts(r->subprocess_env); -+ const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; -+ -+ sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD; -+ -+ for (i = 0; i < arr->nelts; i++) { -+ const char *key = elts[i].key; -+ -+ switch (*key) { -+ case 's': -+ /* being case-sensitive here. -+ * and not checking for the -shutdown since these are the only -+ * SetEnvIf "flags" we support -+ */ -+ if (!strncmp(key+1, "sl-", 3)) { -+ key += 4; -+ if (!strncmp(key, "unclean", 7)) { -+ sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN; -+ } -+ else if (!strncmp(key, "accurate", 8)) { -+ sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_ACCURATE; -+ } -+ return; /* should only ever be one ssl-*-shutdown */ -+ } -+ break; -+ } -+ } -+} -+ -+/* -+ * URL Translation Handler -+ */ -+int ssl_hook_Translate(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ -+ if (!(sslconn && sslconn->ssl)) { -+ return DECLINED; -+ } -+ -+ /* -+ * Log information about incoming HTTPS requests -+ */ -+ if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "%s HTTPS request received for child %ld (server %s)", -+ (r->connection->keepalives <= 0 ? -+ "Initial (No.1)" : -+ apr_psprintf(r->pool, "Subsequent (No.%d)", -+ r->connection->keepalives+1)), -+ r->connection->id, -+ ssl_util_vhostid(r->pool, r->server)); -+ } -+ -+ /* SetEnvIf ssl-*-shutdown flags can only be per-server, -+ * so they won't change across keepalive requests -+ */ -+ if (sslconn->shutdown_type == SSL_SHUTDOWN_TYPE_UNSET) { -+ ssl_configure_env(r, sslconn); -+ } -+ -+ return DECLINED; -+} -+ -+/* -+ * Access Handler -+ */ -+int ssl_hook_Access(request_rec *r) -+{ -+ SSLDirConfigRec *dc = myDirConfig(r); -+ SSLSrvConfigRec *sc = mySrvConfig(r->server); -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSL *ssl = sslconn ? sslconn->ssl : NULL; -+ SSL_CTX *ctx = NULL; -+ apr_array_header_t *requires; -+ ssl_require_t *ssl_requires; -+ char *cp; -+ int ok, i; -+ BOOL renegotiate = FALSE, renegotiate_quick = FALSE; -+ X509 *cert; -+ X509 *peercert; -+ X509_STORE *cert_store = NULL; -+ X509_STORE_CTX cert_store_ctx; -+ STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL; -+ SSL_CIPHER *cipher = NULL; -+ int depth, verify_old, verify, n; -+ -+ if (ssl) { -+ ctx = SSL_get_SSL_CTX(ssl); -+ } -+ -+ /* -+ * Support for SSLRequireSSL directive -+ */ -+ if (dc->bSSLRequired && !ssl) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "access to %s failed, reason: %s", -+ r->filename, "SSL connection required"); -+ -+ /* remember forbidden access for strict require option */ -+ apr_table_setn(r->notes, "ssl-access-forbidden", "1"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* -+ * Check to see if SSL protocol is on -+ */ -+ if (!(sc->enabled || ssl)) { -+ return DECLINED; -+ } -+ /* -+ * Support for per-directory reconfigured SSL connection parameters. -+ * -+ * This is implemented by forcing an SSL renegotiation with the -+ * reconfigured parameter suite. But Apache's internal API processing -+ * makes our life very hard here, because when internal sub-requests occur -+ * we nevertheless should avoid multiple unnecessary SSL handshakes (they -+ * require extra network I/O and especially time to perform). -+ * -+ * But the optimization for filtering out the unnecessary handshakes isn't -+ * obvious and trivial. Especially because while Apache is in its -+ * sub-request processing the client could force additional handshakes, -+ * too. And these take place perhaps without our notice. So the only -+ * possibility is to explicitly _ask_ OpenSSL whether the renegotiation -+ * has to be performed or not. It has to performed when some parameters -+ * which were previously known (by us) are not those we've now -+ * reconfigured (as known by OpenSSL) or (in optimized way) at least when -+ * the reconfigured parameter suite is stronger (more restrictions) than -+ * the currently active one. -+ */ -+ -+ /* -+ * Override of SSLCipherSuite -+ * -+ * We provide two options here: -+ * -+ * o The paranoid and default approach where we force a renegotiation when -+ * the cipher suite changed in _any_ way (which is straight-forward but -+ * often forces renegotiations too often and is perhaps not what the -+ * user actually wanted). -+ * -+ * o The optimized and still secure way where we force a renegotiation -+ * only if the currently active cipher is no longer contained in the -+ * reconfigured/new cipher suite. Any other changes are not important -+ * because it's the servers choice to select a cipher from the ones the -+ * client supports. So as long as the current cipher is still in the new -+ * cipher suite we're happy. Because we can assume we would have -+ * selected it again even when other (better) ciphers exists now in the -+ * new cipher suite. This approach is fine because the user explicitly -+ * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no -+ * implicit optimizations. -+ */ -+ if (dc->szCipherSuite) { -+ /* remember old state */ -+ -+ if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { -+ cipher = SSL_get_current_cipher(ssl); -+ } -+ else { -+ cipher_list_old = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl); -+ -+ if (cipher_list_old) { -+ cipher_list_old = sk_SSL_CIPHER_dup(cipher_list_old); -+ } -+ } -+ -+ /* configure new state */ -+ if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, -+ r->server, -+ "Unable to reconfigure (per-directory) " -+ "permitted SSL ciphers"); -+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); -+ -+ if (cipher_list_old) { -+ sk_SSL_CIPHER_free(cipher_list_old); -+ } -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* determine whether a renegotiation has to be forced */ -+ cipher_list = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl); -+ -+ if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { -+ /* optimized way */ -+ if ((!cipher && cipher_list) || -+ (cipher && !cipher_list)) -+ { -+ renegotiate = TRUE; -+ } -+ else if (cipher && cipher_list && -+ (sk_SSL_CIPHER_find(cipher_list, cipher) < 0)) -+ { -+ renegotiate = TRUE; -+ } -+ } -+ else { -+ /* paranoid way */ -+ if ((!cipher_list_old && cipher_list) || -+ (cipher_list_old && !cipher_list)) -+ { -+ renegotiate = TRUE; -+ } -+ else if (cipher_list_old && cipher_list) { -+ for (n = 0; -+ !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list)); -+ n++) -+ { -+ SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n); -+ -+ if (sk_SSL_CIPHER_find(cipher_list_old, value) < 0) { -+ renegotiate = TRUE; -+ } -+ } -+ -+ for (n = 0; -+ !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list_old)); -+ n++) -+ { -+ SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n); -+ -+ if (sk_SSL_CIPHER_find(cipher_list, value) < 0) { -+ renegotiate = TRUE; -+ } -+ } -+ } -+ } -+ -+ /* cleanup */ -+ if (cipher_list_old) { -+ sk_SSL_CIPHER_free(cipher_list_old); -+ } -+ -+ /* tracing */ -+ if (renegotiate) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Reconfigured cipher suite will force renegotiation"); -+ } -+ } -+ -+ /* -+ * override of SSLVerifyDepth -+ * -+ * The depth checks are handled by us manually inside the verify callback -+ * function and not by OpenSSL internally (and our function is aware of -+ * both the per-server and per-directory contexts). So we cannot ask -+ * OpenSSL about the currently verify depth. Instead we remember it in our -+ * ap_ctx attached to the SSL* of OpenSSL. We've to force the -+ * renegotiation if the reconfigured/new verify depth is less than the -+ * currently active/remembered verify depth (because this means more -+ * restriction on the certificate chain). -+ */ -+ if (dc->nVerifyDepth != UNSET) { -+ /* XXX: doesnt look like sslconn->verify_depth is actually used */ -+ if (!(n = sslconn->verify_depth)) { -+ sslconn->verify_depth = n = sc->server->auth.verify_depth; -+ } -+ -+ /* determine whether a renegotiation has to be forced */ -+ if (dc->nVerifyDepth < n) { -+ renegotiate = TRUE; -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Reduced client verification depth will force " -+ "renegotiation"); -+ } -+ } -+ -+ /* -+ * override of SSLVerifyClient -+ * -+ * We force a renegotiation if the reconfigured/new verify type is -+ * stronger than the currently active verify type. -+ * -+ * The order is: none << optional_no_ca << optional << require -+ * -+ * Additionally the following optimization is possible here: When the -+ * currently active verify type is "none" but a client certificate is -+ * already known/present, it's enough to manually force a client -+ * verification but at least skip the I/O-intensive renegotation -+ * handshake. -+ */ -+ if (dc->nVerifyClient != SSL_CVERIFY_UNSET) { -+ /* remember old state */ -+ verify_old = SSL_get_verify_mode(ssl); -+ /* configure new state */ -+ verify = SSL_VERIFY_NONE; -+ -+ if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) { -+ verify |= SSL_VERIFY_PEER_STRICT; -+ } -+ -+ if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) || -+ (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA)) -+ { -+ verify |= SSL_VERIFY_PEER; -+ } -+ -+ modssl_set_verify(ssl, verify, ssl_callback_SSLVerify); -+ SSL_set_verify_result(ssl, X509_V_OK); -+ -+ /* determine whether we've to force a renegotiation */ -+ if (!renegotiate && verify != verify_old) { -+ if (((verify_old == SSL_VERIFY_NONE) && -+ (verify != SSL_VERIFY_NONE)) || -+ -+ (!(verify_old & SSL_VERIFY_PEER) && -+ (verify & SSL_VERIFY_PEER)) || -+ -+ (!(verify_old & SSL_VERIFY_PEER_STRICT) && -+ (verify & SSL_VERIFY_PEER_STRICT))) -+ { -+ renegotiate = TRUE; -+ /* optimization */ -+ -+ if ((dc->nOptions & SSL_OPT_OPTRENEGOTIATE) && -+ (verify_old == SSL_VERIFY_NONE) && -+ ((peercert = SSL_get_peer_certificate(ssl)) != NULL)) -+ { -+ renegotiate_quick = TRUE; -+ X509_free(peercert); -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, -+ r->server, -+ "Changed client verification type will force " -+ "%srenegotiation", -+ renegotiate_quick ? "quick " : ""); -+ } -+ } -+ } -+ -+ /* -+ * override SSLCACertificateFile & SSLCACertificatePath -+ * This is only enabled if the SSL_set_cert_store() function -+ * is available in the ssl library. the 1.x based mod_ssl -+ * used SSL_CTX_set_cert_store which is not thread safe. -+ */ -+ -+#ifdef HAVE_SSL_SET_CERT_STORE -+ /* -+ * check if per-dir and per-server config field are not the same. -+ * if f is defined in per-dir and not defined in per-server -+ * or f is defined in both but not the equal ... -+ */ -+#define MODSSL_CFG_NE(f) \ -+ (dc->f && (!sc->f || (sc->f && strNE(dc->f, sc->f)))) -+ -+#define MODSSL_CFG_CA(f) \ -+ (dc->f ? dc->f : sc->f) -+ -+ if (MODSSL_CFG_NE(szCACertificateFile) || -+ MODSSL_CFG_NE(szCACertificatePath)) -+ { -+ STACK_OF(X509_NAME) *ca_list; -+ const char *ca_file = MODSSL_CFG_CA(szCACertificateFile); -+ const char *ca_path = MODSSL_CFG_CA(szCACertificatePath); -+ -+ cert_store = X509_STORE_new(); -+ -+ if (!X509_STORE_load_locations(cert_store, ca_file, ca_path)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Unable to reconfigure verify locations " -+ "for client authentication"); -+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); -+ -+ X509_STORE_free(cert_store); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* SSL_free will free cert_store */ -+ SSL_set_cert_store(ssl, cert_store); -+ -+ if (!(ca_list = ssl_init_FindCAList(r->server, r->pool, -+ ca_file, ca_path))) -+ { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Unable to determine list of available " -+ "CA certificates for client authentication"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ SSL_set_client_CA_list(ssl, ca_list); -+ renegotiate = TRUE; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Changed client verification locations will force " -+ "renegotiation"); -+ } -+#endif /* HAVE_SSL_SET_CERT_STORE */ -+ -+ /* -+ * SSL renegotiations in conjunction with HTTP -+ * requests using the POST method are not supported. -+ * -+ * Background: -+ * -+ * 1. When the client sends a HTTP/HTTPS request, Apache's core code -+ * reads only the request line ("METHOD /path HTTP/x.y") and the -+ * attached MIME headers ("Foo: bar") up to the terminating line ("CR -+ * LF"). An attached request body (for instance the data of a POST -+ * method) is _NOT_ read. Instead it is read by mod_cgi's content -+ * handler and directly passed to the CGI script. -+ * -+ * 2. mod_ssl supports per-directory re-configuration of SSL parameters. -+ * This is implemented by performing an SSL renegotiation of the -+ * re-configured parameters after the request is read, but before the -+ * response is sent. In more detail: the renegotiation happens after the -+ * request line and MIME headers were read, but _before_ the attached -+ * request body is read. The reason simply is that in the HTTP protocol -+ * usually there is no acknowledgment step between the headers and the -+ * body (there is the 100-continue feature and the chunking facility -+ * only), so Apache has no API hook for this step. -+ * -+ * 3. the problem now occurs when the client sends a POST request for -+ * URL /foo via HTTPS the server and the server has SSL parameters -+ * re-configured on a per-URL basis for /foo. Then mod_ssl has to -+ * perform an SSL renegotiation after the request was read and before -+ * the response is sent. But the problem is the pending POST body data -+ * in the receive buffer of SSL (which Apache still has not read - it's -+ * pending until mod_cgi sucks it in). When mod_ssl now tries to perform -+ * the renegotiation the pending data leads to an I/O error. -+ * -+ * Solution Idea: -+ * -+ * There are only two solutions: Either to simply state that POST -+ * requests to URLs with SSL re-configurations are not allowed, or to -+ * renegotiate really after the _complete_ request (i.e. including -+ * the POST body) was read. Obviously the latter would be preferred, -+ * but it cannot be done easily inside Apache, because as already -+ * mentioned, there is no API step between the body reading and the body -+ * processing. And even when we mod_ssl would hook directly into the -+ * loop of mod_cgi, we wouldn't solve the problem for other handlers, of -+ * course. So the only general solution is to suck in the pending data -+ * of the request body from the OpenSSL BIO into the Apache BUFF. Then -+ * the renegotiation can be done and after this step Apache can proceed -+ * processing the request as before. -+ * -+ * Solution Implementation: -+ * -+ * We cannot simply suck in the data via an SSL_read-based loop because of -+ * HTTP chunking. Instead we _have_ to use the Apache API for this step which -+ * is aware of HTTP chunking. So the trick is to suck in the pending request -+ * data via the Apache API (which uses Apache's BUFF code and in the -+ * background mod_ssl's I/O glue code) and re-inject it later into the Apache -+ * BUFF code again. This way the data flows twice through the Apache BUFF, of -+ * course. But this way the solution doesn't depend on any Apache specifics -+ * and is fully transparent to Apache modules. -+ * -+ * !! BUT ALL THIS IS STILL NOT RE-IMPLEMENTED FOR APACHE 2.0 !! -+ */ -+ if (renegotiate && !renegotiate_quick && (r->method_number == M_POST)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "SSL Re-negotiation in conjunction " -+ "with POST method not supported!\n" -+ "hint: try SSLOptions +OptRenegotiate"); -+ -+ return HTTP_METHOD_NOT_ALLOWED; -+ } -+ -+ /* -+ * now do the renegotiation if anything was actually reconfigured -+ */ -+ if (renegotiate) { -+ /* -+ * Now we force the SSL renegotation by sending the Hello Request -+ * message to the client. Here we have to do a workaround: Actually -+ * OpenSSL returns immediately after sending the Hello Request (the -+ * intent AFAIK is because the SSL/TLS protocol says it's not a must -+ * that the client replies to a Hello Request). But because we insist -+ * on a reply (anything else is an error for us) we have to go to the -+ * ACCEPT state manually. Using SSL_set_accept_state() doesn't work -+ * here because it resets too much of the connection. So we set the -+ * state explicitly and continue the handshake manually. -+ */ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Requesting connection re-negotiation"); -+ -+ if (renegotiate_quick) { -+ STACK_OF(X509) *cert_stack; -+ -+ /* perform just a manual re-verification of the peer */ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Performing quick renegotiation: " -+ "just re-verifying the peer"); -+ -+ cert_stack = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl); -+ -+ cert = SSL_get_peer_certificate(ssl); -+ -+ if (!cert_stack && cert) { -+ /* client cert is in the session cache, but there is -+ * no chain, since ssl3_get_client_certificate() -+ * sk_X509_shift-ed the peer cert out of the chain. -+ * we put it back here for the purpose of quick_renegotiation. -+ */ -+ cert_stack = sk_new_null(); -+ sk_X509_push(cert_stack, MODSSL_PCHAR_CAST cert); -+ } -+ -+ if (!cert_stack || (sk_X509_num(cert_stack) == 0)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Cannot find peer certificate chain"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (!(cert_store || -+ (cert_store = SSL_CTX_get_cert_store(ctx)))) -+ { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Cannot find certificate storage"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (!cert) { -+ cert = sk_X509_value(cert_stack, 0); -+ } -+ -+ X509_STORE_CTX_init(&cert_store_ctx, cert_store, cert, cert_stack); -+ depth = SSL_get_verify_depth(ssl); -+ -+ if (depth >= 0) { -+ X509_STORE_CTX_set_depth(&cert_store_ctx, depth); -+ } -+ -+ X509_STORE_CTX_set_ex_data(&cert_store_ctx, -+ SSL_get_ex_data_X509_STORE_CTX_idx(), -+ (char *)ssl); -+ -+ if (!modssl_X509_verify_cert(&cert_store_ctx)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation verification step failed"); -+ ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server); -+ } -+ -+ SSL_set_verify_result(ssl, cert_store_ctx.error); -+ X509_STORE_CTX_cleanup(&cert_store_ctx); -+ -+ if (cert_stack != SSL_get_peer_cert_chain(ssl)) { -+ /* we created this ourselves, so free it */ -+ sk_X509_pop_free(cert_stack, X509_free); -+ } -+ } -+ else { -+ request_rec *id = r->main ? r->main : r; -+ -+ /* do a full renegotiation */ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, -+ "Performing full renegotiation: " -+ "complete handshake protocol"); -+ -+ SSL_set_session_id_context(ssl, -+ (unsigned char *)&id, -+ sizeof(id)); -+ -+ SSL_renegotiate(ssl); -+ SSL_do_handshake(ssl); -+ -+ if (SSL_get_state(ssl) != SSL_ST_OK) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation request failed"); -+ -+ r->connection->aborted = 1; -+ return HTTP_FORBIDDEN; -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Awaiting re-negotiation handshake"); -+ -+ SSL_set_state(ssl, SSL_ST_ACCEPT); -+ SSL_do_handshake(ssl); -+ -+ if (SSL_get_state(ssl) != SSL_ST_OK) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation handshake failed: " -+ "Not accepted by client!?"); -+ -+ r->connection->aborted = 1; -+ return HTTP_FORBIDDEN; -+ } -+ } -+ -+ /* -+ * Remember the peer certificate's DN -+ */ -+ if ((cert = SSL_get_peer_certificate(ssl))) { -+ if (sslconn->client_cert) { -+ X509_free(sslconn->client_cert); -+ } -+ sslconn->client_cert = cert; -+ sslconn->client_dn = NULL; -+ } -+ -+ /* -+ * Finally check for acceptable renegotiation results -+ */ -+ if (dc->nVerifyClient != SSL_CVERIFY_NONE) { -+ BOOL do_verify = (dc->nVerifyClient == SSL_CVERIFY_REQUIRE); -+ -+ if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation handshake failed: " -+ "Client verification failed"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (do_verify) { -+ if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, -+ "Re-negotiation handshake failed: " -+ "Client certificate missing"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ X509_free(peercert); -+ } -+ } -+ } -+ -+ /* -+ * Check SSLRequire boolean expressions -+ */ -+ requires = dc->aRequirement; -+ ssl_requires = (ssl_require_t *)requires->elts; -+ -+ for (i = 0; i < requires->nelts; i++) { -+ ssl_require_t *req = &ssl_requires[i]; -+ ok = ssl_expr_exec(r, req->mpExpr); -+ -+ if (ok < 0) { -+ cp = apr_psprintf(r->pool, -+ "Failed to execute " -+ "SSL requirement expression: %s", -+ ssl_expr_get_error()); -+ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "access to %s failed, reason: %s", -+ r->filename, cp); -+ -+ /* remember forbidden access for strict require option */ -+ apr_table_setn(r->notes, "ssl-access-forbidden", "1"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ -+ if (ok != 1) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Access to %s denied for %s " -+ "(requirement expression not fulfilled)", -+ r->filename, r->connection->remote_ip); -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Failed expression: %s", req->cpExpr); -+ -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "access to %s failed, reason: %s", -+ r->filename, -+ "SSL requirement expression not fulfilled " -+ "(see SSL logfile for more details)"); -+ -+ /* remember forbidden access for strict require option */ -+ apr_table_setn(r->notes, "ssl-access-forbidden", "1"); -+ -+ return HTTP_FORBIDDEN; -+ } -+ } -+ -+ /* -+ * Else access is granted from our point of view (except vendor -+ * handlers override). But we have to return DECLINED here instead -+ * of OK, because mod_auth and other modules still might want to -+ * deny access. -+ */ -+ -+ return DECLINED; -+} -+ -+/* -+ * Authentication Handler: -+ * Fake a Basic authentication from the X509 client certificate. -+ * -+ * This must be run fairly early on to prevent a real authentication from -+ * occuring, in particular it must be run before anything else that -+ * authenticates a user. This means that the Module statement for this -+ * module should be LAST in the Configuration file. -+ */ -+int ssl_hook_UserCheck(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSLSrvConfigRec *sc = mySrvConfig(r->server); -+ SSLDirConfigRec *dc = myDirConfig(r); -+ char buf1[MAX_STRING_LEN], buf2[MAX_STRING_LEN]; -+ char *clientdn; -+ const char *auth_line, *username, *password; -+ -+ /* -+ * Additionally forbid access (again) -+ * when strict require option is used. -+ */ -+ if ((dc->nOptions & SSL_OPT_STRICTREQUIRE) && -+ (apr_table_get(r->notes, "ssl-access-forbidden"))) -+ { -+ return HTTP_FORBIDDEN; -+ } -+ -+ /* -+ * We decline when we are in a subrequest. The Authorization header -+ * would already be present if it was added in the main request. -+ */ -+ if (!ap_is_initial_req(r)) { -+ return DECLINED; -+ } -+ -+ /* -+ * Make sure the user is not able to fake the client certificate -+ * based authentication by just entering an X.509 Subject DN -+ * ("/XX=YYY/XX=YYY/..") as the username and "password" as the -+ * password. -+ */ -+ if ((auth_line = apr_table_get(r->headers_in, "Authorization"))) { -+ if (strcEQ(ap_getword(r->pool, &auth_line, ' '), "Basic")) { -+ while ((*auth_line == ' ') || (*auth_line == '\t')) { -+ auth_line++; -+ } -+ -+ auth_line = ap_pbase64decode(r->pool, auth_line); -+ username = ap_getword_nulls(r->pool, &auth_line, ':'); -+ password = auth_line; -+ -+ if ((username[0] == '/') && strEQ(password, "password")) { -+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, -+ "Encountered FakeBasicAuth spoof: %s", username); -+ return HTTP_FORBIDDEN; -+ } -+ } -+ } -+ -+ /* -+ * We decline operation in various situations... -+ * - SSLOptions +FakeBasicAuth not configured -+ * - r->user already authenticated -+ * - ssl not enabled -+ * - client did not present a certificate -+ */ -+ if (!(sc->enabled && sslconn->ssl && sslconn->client_cert) || -+ !(dc->nOptions & SSL_OPT_FAKEBASICAUTH) || r->user) -+ { -+ return DECLINED; -+ } -+ -+ if (!sslconn->client_dn) { -+ X509_NAME *name = X509_get_subject_name(sslconn->client_cert); -+ char *cp = X509_NAME_oneline(name, NULL, 0); -+ sslconn->client_dn = apr_pstrdup(r->connection->pool, cp); -+ modssl_free(cp); -+ } -+ -+ clientdn = (char *)sslconn->client_dn; -+ -+ /* -+ * Fake a password - which one would be immaterial, as, it seems, an empty -+ * password in the users file would match ALL incoming passwords, if only -+ * we were using the standard crypt library routine. Unfortunately, OpenSSL -+ * "fixes" a "bug" in crypt and thus prevents blank passwords from -+ * working. (IMHO what they really fix is a bug in the users of the code -+ * - failing to program correctly for shadow passwords). We need, -+ * therefore, to provide a password. This password can be matched by -+ * adding the string "xxj31ZMTZzkVA" as the password in the user file. -+ * This is just the crypted variant of the word "password" ;-) -+ */ -+ apr_snprintf(buf1, sizeof(buf1), "%s:password", clientdn); -+ ssl_util_uuencode(buf2, buf1, FALSE); -+ -+ apr_snprintf(buf1, sizeof(buf1), "Basic %s", buf2); -+ apr_table_set(r->headers_in, "Authorization", buf1); -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, -+ "Faking HTTP Basic Auth header: \"Authorization: %s\"", buf1); -+ -+ return DECLINED; -+} -+ -+/* authorization phase */ -+int ssl_hook_Auth(request_rec *r) -+{ -+ SSLDirConfigRec *dc = myDirConfig(r); -+ -+ /* -+ * Additionally forbid access (again) -+ * when strict require option is used. -+ */ -+ if ((dc->nOptions & SSL_OPT_STRICTREQUIRE) && -+ (apr_table_get(r->notes, "ssl-access-forbidden"))) -+ { -+ return HTTP_FORBIDDEN; -+ } -+ -+ return DECLINED; -+} -+ -+/* -+ * Fixup Handler -+ */ -+ -+static const char *ssl_hook_Fixup_vars[] = { -+ "SSL_VERSION_INTERFACE", -+ "SSL_VERSION_LIBRARY", -+ "SSL_PROTOCOL", -+ "SSL_CIPHER", -+ "SSL_CIPHER_EXPORT", -+ "SSL_CIPHER_USEKEYSIZE", -+ "SSL_CIPHER_ALGKEYSIZE", -+ "SSL_CLIENT_VERIFY", -+ "SSL_CLIENT_M_VERSION", -+ "SSL_CLIENT_M_SERIAL", -+ "SSL_CLIENT_V_START", -+ "SSL_CLIENT_V_END", -+ "SSL_CLIENT_S_DN", -+ "SSL_CLIENT_S_DN_C", -+ "SSL_CLIENT_S_DN_ST", -+ "SSL_CLIENT_S_DN_L", -+ "SSL_CLIENT_S_DN_O", -+ "SSL_CLIENT_S_DN_OU", -+ "SSL_CLIENT_S_DN_CN", -+ "SSL_CLIENT_S_DN_T", -+ "SSL_CLIENT_S_DN_I", -+ "SSL_CLIENT_S_DN_G", -+ "SSL_CLIENT_S_DN_S", -+ "SSL_CLIENT_S_DN_D", -+ "SSL_CLIENT_S_DN_UID", -+ "SSL_CLIENT_S_DN_Email", -+ "SSL_CLIENT_I_DN", -+ "SSL_CLIENT_I_DN_C", -+ "SSL_CLIENT_I_DN_ST", -+ "SSL_CLIENT_I_DN_L", -+ "SSL_CLIENT_I_DN_O", -+ "SSL_CLIENT_I_DN_OU", -+ "SSL_CLIENT_I_DN_CN", -+ "SSL_CLIENT_I_DN_T", -+ "SSL_CLIENT_I_DN_I", -+ "SSL_CLIENT_I_DN_G", -+ "SSL_CLIENT_I_DN_S", -+ "SSL_CLIENT_I_DN_D", -+ "SSL_CLIENT_I_DN_UID", -+ "SSL_CLIENT_I_DN_Email", -+ "SSL_CLIENT_A_KEY", -+ "SSL_CLIENT_A_SIG", -+ "SSL_SERVER_M_VERSION", -+ "SSL_SERVER_M_SERIAL", -+ "SSL_SERVER_V_START", -+ "SSL_SERVER_V_END", -+ "SSL_SERVER_S_DN", -+ "SSL_SERVER_S_DN_C", -+ "SSL_SERVER_S_DN_ST", -+ "SSL_SERVER_S_DN_L", -+ "SSL_SERVER_S_DN_O", -+ "SSL_SERVER_S_DN_OU", -+ "SSL_SERVER_S_DN_CN", -+ "SSL_SERVER_S_DN_T", -+ "SSL_SERVER_S_DN_I", -+ "SSL_SERVER_S_DN_G", -+ "SSL_SERVER_S_DN_S", -+ "SSL_SERVER_S_DN_D", -+ "SSL_SERVER_S_DN_UID", -+ "SSL_SERVER_S_DN_Email", -+ "SSL_SERVER_I_DN", -+ "SSL_SERVER_I_DN_C", -+ "SSL_SERVER_I_DN_ST", -+ "SSL_SERVER_I_DN_L", -+ "SSL_SERVER_I_DN_O", -+ "SSL_SERVER_I_DN_OU", -+ "SSL_SERVER_I_DN_CN", -+ "SSL_SERVER_I_DN_T", -+ "SSL_SERVER_I_DN_I", -+ "SSL_SERVER_I_DN_G", -+ "SSL_SERVER_I_DN_S", -+ "SSL_SERVER_I_DN_D", -+ "SSL_SERVER_I_DN_UID", -+ "SSL_SERVER_I_DN_Email", -+ "SSL_SERVER_A_KEY", -+ "SSL_SERVER_A_SIG", -+ "SSL_SESSION_ID", -+ NULL -+}; -+ -+int ssl_hook_Fixup(request_rec *r) -+{ -+ SSLConnRec *sslconn = myConnConfig(r->connection); -+ SSLSrvConfigRec *sc = mySrvConfig(r->server); -+ SSLDirConfigRec *dc = myDirConfig(r); -+ apr_table_t *env = r->subprocess_env; -+ char *var, *val = ""; -+ STACK_OF(X509) *peer_certs; -+ SSL *ssl; -+ int i; -+ -+ /* -+ * Check to see if SSL is on -+ */ -+ if (!(sc->enabled && sslconn && (ssl = sslconn->ssl))) { -+ return DECLINED; -+ } -+ -+ /* -+ * Annotate the SSI/CGI environment with standard SSL information -+ */ -+ /* the always present HTTPS (=HTTP over SSL) flag! */ -+ apr_table_setn(env, "HTTPS", "on"); -+ -+ /* standard SSL environment variables */ -+ if (dc->nOptions & SSL_OPT_STDENVVARS) { -+ for (i = 0; ssl_hook_Fixup_vars[i]; i++) { -+ var = (char *)ssl_hook_Fixup_vars[i]; -+ val = ssl_var_lookup(r->pool, r->server, r->connection, r, var); -+ if (!strIsEmpty(val)) { -+ apr_table_setn(env, var, val); -+ } -+ } -+ } -+ -+ /* -+ * On-demand bloat up the SSI/CGI environment with certificate data -+ */ -+ if (dc->nOptions & SSL_OPT_EXPORTCERTDATA) { -+ val = ssl_var_lookup(r->pool, r->server, r->connection, -+ r, "SSL_SERVER_CERT"); -+ -+ apr_table_setn(env, "SSL_SERVER_CERT", val); -+ -+ val = ssl_var_lookup(r->pool, r->server, r->connection, -+ r, "SSL_CLIENT_CERT"); -+ -+ apr_table_setn(env, "SSL_CLIENT_CERT", val); -+ -+ if ((peer_certs = (STACK_OF(X509) *)SSL_get_peer_cert_chain(ssl))) { -+ for (i = 0; i < sk_X509_num(peer_certs); i++) { -+ var = apr_psprintf(r->pool, "SSL_CLIENT_CERT_CHAIN_%d", i); -+ val = ssl_var_lookup(r->pool, r->server, r->connection, -+ r, var); -+ if (val) { -+ apr_table_setn(env, var, val); -+ } -+ } -+ } -+ } -+ -+ return DECLINED; -+} -+ -+/* _________________________________________________________________ -+** -+** OpenSSL Callback Functions -+** _________________________________________________________________ -+*/ -+ -+/* -+ * Handle out temporary RSA private keys on demand -+ * -+ * The background of this as the TLSv1 standard explains it: -+ * -+ * | D.1. Temporary RSA keys -+ * | -+ * | US Export restrictions limit RSA keys used for encryption to 512 -+ * | bits, but do not place any limit on lengths of RSA keys used for -+ * | signing operations. Certificates often need to be larger than 512 -+ * | bits, since 512-bit RSA keys are not secure enough for high-value -+ * | transactions or for applications requiring long-term security. Some -+ * | certificates are also designated signing-only, in which case they -+ * | cannot be used for key exchange. -+ * | -+ * | When the public key in the certificate cannot be used for encryption, -+ * | the server signs a temporary RSA key, which is then exchanged. In -+ * | exportable applications, the temporary RSA key should be the maximum -+ * | allowable length (i.e., 512 bits). Because 512-bit RSA keys are -+ * | relatively insecure, they should be changed often. For typical -+ * | electronic commerce applications, it is suggested that keys be -+ * | changed daily or every 500 transactions, and more often if possible. -+ * | Note that while it is acceptable to use the same temporary key for -+ * | multiple transactions, it must be signed each time it is used. -+ * | -+ * | RSA key generation is a time-consuming process. In many cases, a -+ * | low-priority process can be assigned the task of key generation. -+ * | Whenever a new key is completed, the existing temporary key can be -+ * | replaced with the new one. -+ * -+ * XXX: base on comment above, if thread support is enabled, -+ * we should spawn a low-priority thread to generate new keys -+ * on the fly. -+ * -+ * So we generated 512 and 1024 bit temporary keys on startup -+ * which we now just hand out on demand.... -+ */ -+ -+RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen) -+{ -+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -+ SSLModConfigRec *mc = myModConfig(c->base_server); -+ int idx; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, -+ "handing out temporary %d bit RSA key", keylen); -+ -+ /* doesn't matter if export flag is on, -+ * we won't be asked for keylen > 512 in that case. -+ * if we are asked for a keylen > 1024, it is too expensive -+ * to generate on the fly. -+ * XXX: any reason not to generate 2048 bit keys at startup? -+ */ -+ -+ switch (keylen) { -+ case 512: -+ idx = SSL_TMP_KEY_RSA_512; -+ break; -+ -+ case 1024: -+ default: -+ idx = SSL_TMP_KEY_RSA_1024; -+ } -+ -+ return (RSA *)mc->pTmpKeys[idx]; -+} -+ -+/* -+ * Hand out the already generated DH parameters... -+ */ -+DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) -+{ -+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -+ SSLModConfigRec *mc = myModConfig(c->base_server); -+ int idx; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, -+ "handing out temporary %d bit DH key", keylen); -+ -+ switch (keylen) { -+ case 512: -+ idx = SSL_TMP_KEY_DH_512; -+ break; -+ -+ case 1024: -+ default: -+ idx = SSL_TMP_KEY_DH_1024; -+ } -+ -+ return (DH *)mc->pTmpKeys[idx]; -+} -+ -+/* -+ * This OpenSSL callback function is called when OpenSSL -+ * does client authentication and verifies the certificate chain. -+ */ -+int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) -+{ -+ /* Get Apache context back through OpenSSL context */ -+ SSL *ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx); -+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = conn->base_server; -+ request_rec *r = (request_rec *)SSL_get_app_data2(ssl); -+ -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ SSLDirConfigRec *dc = r ? myDirConfig(r) : NULL; -+ SSLConnRec *sslconn = myConnConfig(conn); -+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); -+ -+ /* Get verify ingredients */ -+ int errnum = X509_STORE_CTX_get_error(ctx); -+ int errdepth = X509_STORE_CTX_get_error_depth(ctx); -+ int depth, verify; -+ -+ /* -+ * Log verification information -+ */ -+ if (s->loglevel >= APLOG_DEBUG) { -+ X509 *cert = X509_STORE_CTX_get_current_cert(ctx); -+ char *sname = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); -+ char *iname = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "Certificate Verification: " -+ "depth: %d, subject: %s, issuer: %s", -+ errdepth, -+ sname ? sname : "-unknown-", -+ iname ? iname : "-unknown-"); -+ -+ if (sname) { -+ modssl_free(sname); -+ } -+ -+ if (iname) { -+ modssl_free(iname); -+ } -+ } -+ -+ /* -+ * Check for optionally acceptable non-verifiable issuer situation -+ */ -+ if (dc && (dc->nVerifyClient != SSL_CVERIFY_UNSET)) { -+ verify = dc->nVerifyClient; -+ } -+ else { -+ verify = mctx->auth.verify_mode; -+ } -+ -+ if (verify == SSL_CVERIFY_NONE) { -+ /* -+ * SSLProxyVerify is either not configured or set to "none". -+ * (this callback doesn't happen in the server context if SSLVerify -+ * is not configured or set to "none") -+ */ -+ return TRUE; -+ } -+ -+ if (ssl_verify_error_is_optional(errnum) && -+ (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) -+ { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "Certificate Verification: Verifiable Issuer is " -+ "configured as optional, therefore we're accepting " -+ "the certificate"); -+ -+ sslconn->verify_info = "GENEROUS"; -+ ok = TRUE; -+ } -+ -+ /* -+ * Additionally perform CRL-based revocation checks -+ */ -+ if (ok) { -+ if (!(ok = ssl_callback_SSLVerify_CRL(ok, ctx, conn))) { -+ errnum = X509_STORE_CTX_get_error(ctx); -+ } -+ } -+ -+ /* -+ * If we already know it's not ok, log the real reason -+ */ -+ if (!ok) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, -+ "Certificate Verification: Error (%d): %s", -+ errnum, X509_verify_cert_error_string(errnum)); -+ -+ if (sslconn->client_cert) { -+ X509_free(sslconn->client_cert); -+ sslconn->client_cert = NULL; -+ } -+ sslconn->client_dn = NULL; -+ sslconn->verify_error = X509_verify_cert_error_string(errnum); -+ } -+ -+ /* -+ * Finally check the depth of the certificate verification -+ */ -+ if (dc && (dc->nVerifyDepth != UNSET)) { -+ depth = dc->nVerifyDepth; -+ } -+ else { -+ depth = mctx->auth.verify_depth; -+ } -+ -+ if (errdepth > depth) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, -+ "Certificate Verification: Certificate Chain too long " -+ "(chain has %d certificates, but maximum allowed are " -+ "only %d)", -+ errdepth, depth); -+ -+ errnum = X509_V_ERR_CERT_CHAIN_TOO_LONG; -+ sslconn->verify_error = X509_verify_cert_error_string(errnum); -+ -+ ok = FALSE; -+ } -+ -+ /* -+ * And finally signal OpenSSL the (perhaps changed) state -+ */ -+ return ok; -+} -+ -+int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c) -+{ -+ server_rec *s = c->base_server; -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ SSLConnRec *sslconn = myConnConfig(c); -+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc); -+ X509_OBJECT obj; -+ X509_NAME *subject, *issuer; -+ X509 *cert; -+ X509_CRL *crl; -+ EVP_PKEY *pubkey; -+ int i, n, rc; -+ -+ /* -+ * Unless a revocation store for CRLs was created we -+ * cannot do any CRL-based verification, of course. -+ */ -+ if (!mctx->crl) { -+ return ok; -+ } -+ -+ /* -+ * Determine certificate ingredients in advance -+ */ -+ cert = X509_STORE_CTX_get_current_cert(ctx); -+ subject = X509_get_subject_name(cert); -+ issuer = X509_get_issuer_name(cert); -+ -+ /* -+ * OpenSSL provides the general mechanism to deal with CRLs but does not -+ * use them automatically when verifying certificates, so we do it -+ * explicitly here. We will check the CRL for the currently checked -+ * certificate, if there is such a CRL in the store. -+ * -+ * We come through this procedure for each certificate in the certificate -+ * chain, starting with the root-CA's certificate. At each step we've to -+ * both verify the signature on the CRL (to make sure it's a valid CRL) -+ * and it's revocation list (to make sure the current certificate isn't -+ * revoked). But because to check the signature on the CRL we need the -+ * public key of the issuing CA certificate (which was already processed -+ * one round before), we've a little problem. But we can both solve it and -+ * at the same time optimize the processing by using the following -+ * verification scheme (idea and code snippets borrowed from the GLOBUS -+ * project): -+ * -+ * 1. We'll check the signature of a CRL in each step when we find a CRL -+ * through the _subject_ name of the current certificate. This CRL -+ * itself will be needed the first time in the next round, of course. -+ * But we do the signature processing one round before this where the -+ * public key of the CA is available. -+ * -+ * 2. We'll check the revocation list of a CRL in each step when -+ * we find a CRL through the _issuer_ name of the current certificate. -+ * This CRLs signature was then already verified one round before. -+ * -+ * This verification scheme allows a CA to revoke its own certificate as -+ * well, of course. -+ */ -+ -+ /* -+ * Try to retrieve a CRL corresponding to the _subject_ of -+ * the current certificate in order to verify it's integrity. -+ */ -+ memset((char *)&obj, 0, sizeof(obj)); -+ rc = SSL_X509_STORE_lookup(mctx->crl, -+ X509_LU_CRL, subject, &obj); -+ crl = obj.data.crl; -+ -+ if ((rc > 0) && crl) { -+ /* -+ * Log information about CRL -+ * (A little bit complicated because of ASN.1 and BIOs...) -+ */ -+ if (s->loglevel >= APLOG_DEBUG) { -+ char buff[512]; /* should be plenty */ -+ BIO *bio = BIO_new(BIO_s_mem()); -+ -+ BIO_printf(bio, "CA CRL: Issuer: "); -+ X509_NAME_print(bio, issuer, 0); -+ -+ BIO_printf(bio, ", lastUpdate: "); -+ ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl)); -+ -+ BIO_printf(bio, ", nextUpdate: "); -+ ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl)); -+ -+ n = BIO_read(bio, buff, sizeof(buff)); -+ buff[n] = '\0'; -+ -+ BIO_free(bio); -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, buff); -+ } -+ -+ /* -+ * Verify the signature on this CRL -+ */ -+ pubkey = X509_get_pubkey(cert); -+ rc = X509_CRL_verify(crl, pubkey); -+#ifdef OPENSSL_VERSION_NUMBER -+ /* Only refcounted in OpenSSL */ -+ if (pubkey) -+ EVP_PKEY_free(pubkey); -+#endif -+ if (rc <= 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ "Invalid signature on CRL"); -+ -+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); -+ X509_OBJECT_free_contents(&obj); -+ return FALSE; -+ } -+ -+ /* -+ * Check date of CRL to make sure it's not expired -+ */ -+ i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); -+ -+ if (i == 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ "Found CRL has invalid nextUpdate field"); -+ -+ X509_STORE_CTX_set_error(ctx, -+ X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); -+ X509_OBJECT_free_contents(&obj); -+ -+ return FALSE; -+ } -+ -+ if (i < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ "Found CRL is expired - " -+ "revoking all certificates until you get updated CRL"); -+ -+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); -+ X509_OBJECT_free_contents(&obj); -+ -+ return FALSE; -+ } -+ -+ X509_OBJECT_free_contents(&obj); -+ } -+ -+ /* -+ * Try to retrieve a CRL corresponding to the _issuer_ of -+ * the current certificate in order to check for revocation. -+ */ -+ memset((char *)&obj, 0, sizeof(obj)); -+ rc = SSL_X509_STORE_lookup(mctx->crl, -+ X509_LU_CRL, issuer, &obj); -+ -+ crl = obj.data.crl; -+ if ((rc > 0) && crl) { -+ /* -+ * Check if the current certificate is revoked by this CRL -+ */ -+ n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); -+ -+ for (i = 0; i < n; i++) { -+ X509_REVOKED *revoked = -+ sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); -+ -+ ASN1_INTEGER *sn = X509_REVOKED_get_serialNumber(revoked); -+ -+ if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) { -+ if (s->loglevel >= APLOG_DEBUG) { -+ char *cp = X509_NAME_oneline(issuer, NULL, 0); -+ long serial = ASN1_INTEGER_get(sn); -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, -+ "Certificate with serial %ld (0x%lX) " -+ "revoked per CRL from issuer %s", -+ serial, serial, cp); -+ modssl_free(cp); -+ } -+ -+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); -+ X509_OBJECT_free_contents(&obj); -+ -+ return FALSE; -+ } -+ } -+ -+ X509_OBJECT_free_contents(&obj); -+ } -+ -+ return ok; -+} -+ -+#define SSLPROXY_CERT_CB_LOG_FMT \ -+ "Proxy client certificate callback: (%s) " -+ -+static void modssl_proxy_info_log(server_rec *s, -+ X509_INFO *info, -+ const char *msg) -+{ -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ char name_buf[256]; -+ X509_NAME *name; -+ char *dn; -+ -+ if (s->loglevel < APLOG_DEBUG) { -+ return; -+ } -+ -+ name = X509_get_subject_name(info->x509); -+ dn = X509_NAME_oneline(name, name_buf, sizeof(name_buf)); -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT "%s, sending %s", -+ sc->vhost_id, msg, dn ? dn : "-uknown-"); -+} -+ -+/* -+ * caller will decrement the cert and key reference -+ * so we need to increment here to prevent them from -+ * being freed. -+ */ -+#define modssl_set_cert_info(info, cert, pkey) \ -+ *cert = info->x509; \ -+ X509_reference_inc(*cert); \ -+ *pkey = info->x_pkey->dec_pkey; \ -+ EVP_PKEY_reference_inc(*pkey) -+ -+int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey) -+{ -+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = c->base_server; -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ X509_NAME *ca_name, *issuer; -+ X509_INFO *info; -+ STACK_OF(X509_NAME) *ca_list; -+ STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs; -+ int i, j; -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT "entered", -+ sc->vhost_id); -+ -+ if (!certs || (sk_X509_INFO_num(certs) <= 0)) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT -+ "downstream server wanted client certificate " -+ "but none are configured", sc->vhost_id); -+ return FALSE; -+ } -+ -+ ca_list = SSL_get_client_CA_list(ssl); -+ -+ if (!ca_list || (sk_X509_NAME_num(ca_list) <= 0)) { -+ /* -+ * downstream server didn't send us a list of acceptable CA certs, -+ * so we send the first client cert in the list. -+ */ -+ info = sk_X509_INFO_value(certs, 0); -+ -+ modssl_proxy_info_log(s, info, "no acceptable CA list"); -+ -+ modssl_set_cert_info(info, x509, pkey); -+ -+ return TRUE; -+ } -+ -+ for (i = 0; i < sk_X509_NAME_num(ca_list); i++) { -+ ca_name = sk_X509_NAME_value(ca_list, i); -+ -+ for (j = 0; j < sk_X509_INFO_num(certs); j++) { -+ info = sk_X509_INFO_value(certs, j); -+ issuer = X509_get_issuer_name(info->x509); -+ -+ if (X509_NAME_cmp(issuer, ca_name) == 0) { -+ modssl_proxy_info_log(s, info, "found acceptable cert"); -+ -+ modssl_set_cert_info(info, x509, pkey); -+ -+ return TRUE; -+ } -+ } -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ SSLPROXY_CERT_CB_LOG_FMT -+ "no client certificate found!?", sc->vhost_id); -+ -+ return FALSE; -+} -+ -+static void ssl_session_log(server_rec *s, -+ const char *request, -+ unsigned char *id, -+ unsigned int idlen, -+ const char *status, -+ const char *result, -+ long timeout) -+{ -+ char buf[SSL_SESSION_ID_STRING_LEN]; -+ char timeout_str[56] = {'\0'}; -+ -+ if (s->loglevel < APLOG_DEBUG) { -+ return; -+ } -+ -+ if (timeout) { -+ apr_snprintf(timeout_str, sizeof(timeout_str), -+ "timeout=%lds ", (timeout - time(NULL))); -+ } -+ -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "Inter-Process Session Cache: " -+ "request=%s status=%s id=%s %s(session %s)", -+ request, status, -+ SSL_SESSION_id2sz(id, idlen, buf, sizeof(buf)), -+ timeout_str, result); -+} -+ -+/* -+ * This callback function is executed by OpenSSL whenever a new SSL_SESSION is -+ * added to the internal OpenSSL session cache. We use this hook to spread the -+ * SSL_SESSION also to the inter-process disk-cache to make share it with our -+ * other Apache pre-forked server processes. -+ */ -+int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *session) -+{ -+ /* Get Apache context back through OpenSSL context */ -+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = conn->base_server; -+ SSLSrvConfigRec *sc = mySrvConfig(s); -+ long timeout = sc->session_cache_timeout; -+ BOOL rc; -+ unsigned char *id; -+ unsigned int idlen; -+ -+ /* -+ * Set the timeout also for the internal OpenSSL cache, because this way -+ * our inter-process cache is consulted only when it's really necessary. -+ */ -+ SSL_set_timeout(session, timeout); -+ -+ /* -+ * Store the SSL_SESSION in the inter-process cache with the -+ * same expire time, so it expires automatically there, too. -+ */ -+ id = SSL_SESSION_get_session_id(session); -+ idlen = SSL_SESSION_get_session_id_length(session); -+ -+ timeout += modssl_session_get_time(session); -+ -+ rc = ssl_scache_store(s, id, idlen, timeout, session); -+ -+ ssl_session_log(s, "SET", id, idlen, -+ rc == TRUE ? "OK" : "BAD", -+ "caching", timeout); -+ -+ /* -+ * return 0 which means to OpenSSL that the session is still -+ * valid and was not freed by us with SSL_SESSION_free(). -+ */ -+ return 0; -+} -+ -+/* -+ * This callback function is executed by OpenSSL whenever a -+ * SSL_SESSION is looked up in the internal OpenSSL cache and it -+ * was not found. We use this to lookup the SSL_SESSION in the -+ * inter-process disk-cache where it was perhaps stored by one -+ * of our other Apache pre-forked server processes. -+ */ -+SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *ssl, -+ unsigned char *id, -+ int idlen, int *do_copy) -+{ -+ /* Get Apache context back through OpenSSL context */ -+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl); -+ server_rec *s = conn->base_server; -+ SSL_SESSION *session; -+ -+ /* -+ * Try to retrieve the SSL_SESSION from the inter-process cache -+ */ -+ session = ssl_scache_retrieve(s, id, idlen); -+ -+ ssl_session_log(s, "GET", id, idlen, -+ session ? "FOUND" : "MISSED", -+ session ? "reuse" : "renewal", 0); -+ -+ /* -+ * Return NULL or the retrieved SSL_SESSION. But indicate (by -+ * setting do_copy to 0) that the reference count on the -+ * SSL_SESSION should not be incremented by the SSL library, -+ * because we will no longer hold a reference to it ourself. -+ */ -+ *do_copy = 0; -+ -+ return session; -+} -+ -+/* -+ * This callback function is executed by OpenSSL whenever a -+ * SSL_SESSION is removed from the the internal OpenSSL cache. -+ * We use this to remove the SSL_SESSION in the inter-process -+ * disk-cache, too. -+ */ -+void ssl_callback_DelSessionCacheEntry(SSL_CTX *ctx, -+ SSL_SESSION *session) -+{ -+ server_rec *s; -+ SSLSrvConfigRec *sc; -+ unsigned char *id; -+ unsigned int idlen; -+ -+ /* -+ * Get Apache context back through OpenSSL context -+ */ -+ if (!(s = (server_rec *)SSL_CTX_get_app_data(ctx))) { -+ return; /* on server shutdown Apache is already gone */ -+ } -+ -+ sc = mySrvConfig(s); -+ -+ /* -+ * Remove the SSL_SESSION from the inter-process cache -+ */ -+ id = SSL_SESSION_get_session_id(session); -+ idlen = SSL_SESSION_get_session_id_length(session); -+ -+ ssl_scache_remove(s, id, idlen); -+ -+ ssl_session_log(s, "REM", id, idlen, -+ "OK", "dead", 0); -+ -+ return; -+} -+ -+/* -+ * This callback function is executed while OpenSSL processes the -+ * SSL handshake and does SSL record layer stuff. We use it to -+ * trace OpenSSL's processing in out SSL logfile. -+ */ -+void ssl_callback_LogTracingState(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc) -+{ -+ conn_rec *c; -+ server_rec *s; -+ SSLSrvConfigRec *sc; -+ -+ /* -+ * find corresponding server -+ */ -+ if (!(c = (conn_rec *)SSL_get_app_data((SSL *)ssl))) { -+ return; -+ } -+ -+ s = c->base_server; -+ if (!(sc = mySrvConfig(s))) { -+ return; -+ } -+ -+ /* -+ * create the various trace messages -+ */ -+ if (s->loglevel >= APLOG_DEBUG) { -+ if (where & SSL_CB_HANDSHAKE_START) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Handshake: start", SSL_LIBRARY_NAME); -+ } -+ else if (where & SSL_CB_HANDSHAKE_DONE) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Handshake: done", SSL_LIBRARY_NAME); -+ } -+ else if (where & SSL_CB_LOOP) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Loop: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_READ) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Read: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_WRITE) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Write: %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (where & SSL_CB_ALERT) { -+ char *str = (where & SSL_CB_READ) ? "read" : "write"; -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Alert: %s:%s:%s\n", -+ SSL_LIBRARY_NAME, str, -+ SSL_alert_type_string_long(rc), -+ SSL_alert_desc_string_long(rc)); -+ } -+ else if (where & SSL_CB_EXIT) { -+ if (rc == 0) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Exit: failed in %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ else if (rc < 0) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, -+ "%s: Exit: error in %s", -+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); -+ } -+ } -+ } -+ -+ /* -+ * Because SSL renegotations can happen at any time (not only after -+ * SSL_accept()), the best way to log the current connection details is -+ * right after a finished handshake. -+ */ -+ if (where & SSL_CB_HANDSHAKE_DONE) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, -+ "Connection: Client IP: %s, Protocol: %s, " -+ "Cipher: %s (%s/%s bits)", -+ ssl_var_lookup(NULL, s, c, NULL, "REMOTE_ADDR"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_PROTOCOL"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_USEKEYSIZE"), -+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_ALGKEYSIZE")); -+ } -+} -+ diff --git a/net-www/apache/files/patches/2.0.50-r1/00_ssl_engine.patch b/net-www/apache/files/patches/2.0.50-r1/00_ssl_engine.patch deleted file mode 100644 index 15360e8119e9..000000000000 --- a/net-www/apache/files/patches/2.0.50-r1/00_ssl_engine.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- httpd-2.0/modules/ssl/ssl_engine_io.c 2004/07/13 18:11:22 1.124 -+++ httpd-2.0/modules/ssl/ssl_engine_io.c 2004/08/11 13:19:24 1.125 -@@ -589,6 +589,10 @@ - while (1) { - - if (!inctx->filter_ctx->pssl) { -+ /* Ensure a non-zero error code is returned */ -+ if (inctx->rc == APR_SUCCESS) { -+ inctx->rc = APR_EGENERAL; -+ } - break; - } - - |