Removed stale patches repoman was complaining about.
authorMichael Tindal <urilith@gentoo.org>
Thu, 4 Nov 2004 08:52:31 +0000 (08:52 +0000)
committerMichael Tindal <urilith@gentoo.org>
Thu, 4 Nov 2004 08:52:31 +0000 (08:52 +0000)
net-www/apache/ChangeLog
net-www/apache/Manifest
net-www/apache/files/httpd-2.0.49-ssl_engine_kernel.patch [deleted file]
net-www/apache/files/patches/2.0.49-r1/00_ssl_engine.patch [deleted file]
net-www/apache/files/patches/2.0.49-r1/01_ssl_engine_kernel.patch [deleted file]
net-www/apache/files/patches/2.0.50-r1/00_ssl_engine.patch [deleted file]

index cf72f6fcc90c3533d05fd98d12abadb0eebcff23..82103ab65b2d3e35bdda8fc8caf2dff30eb2f486 100644 (file)
@@ -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.
index 8855f5a2b36a90753170626db888eef1a4a3e1b7..546b69257f9c96571aa737b4527b782bd3befb47 100644 (file)
@@ -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 (file)
index 4caf45f..0000000
+++ /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 (file)
index f0014ac..0000000
+++ /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 (file)
index 4caf45f..0000000
+++ /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 (file)
index 15360e8..0000000
+++ /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;
-         }
- 
-