]> granicus.if.org Git - apache/commitdiff
Enable ssl client authentication at SSL_accept time
authorDoug MacEachern <dougm@apache.org>
Wed, 22 Aug 2001 19:37:03 +0000 (19:37 +0000)
committerDoug MacEachern <dougm@apache.org>
Wed, 22 Aug 2001 19:37:03 +0000 (19:37 +0000)
PR:
Obtained from:
Submitted by: Madhusudan Mathihalli <madhusudan_mathihalli@hp.com>
Reviewed by: dougm

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90503 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/ssl/mod_ssl.c

diff --git a/CHANGES b/CHANGES
index 67acc9021e83bc53ea121a420a395f72782a1def..204999a9af73e24dcf42d9232b0ff4f6fdd93289 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,6 @@
 Changes with Apache 2.0.25-dev
+  *) Enable ssl client authentication at SSL_accept time
+     [Madhusudan Mathihalli <madhusudan_mathihalli@hp.com>]
 
   *) Fix a segfault in mod_include when the original request has no
      associated filename (e.g., we're filtering the error document for
index ba476e4e71ada350fe2a81e23b9c11168b4593be..1839c4639819e8c92ac28b80ac47ebb05f6e33de 100644 (file)
@@ -316,7 +316,10 @@ static int ssl_hook_pre_connection(conn_rec *c)
 int ssl_hook_process_connection(SSLFilterRec *pRec)
 {
     int n, err;
+    X509 *xs;
+    char *cp;
     conn_rec *c = (conn_rec*)SSL_get_app_data (pRec->pssl);
+    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
 
     if (!SSL_is_init_finished(pRec->pssl))
     {
@@ -426,6 +429,48 @@ int ssl_hook_process_connection(SSLFilterRec *pRec)
             c->aborted = 1;
             return APR_EGENERAL;
         }
+
+        /*
+         * Check for failed client authentication
+         */
+        if (   SSL_get_verify_result(pRec->pssl) != X509_V_OK
+            || apr_table_get (c->notes, "ssl::verify::error") != NULL) {
+            cp = (char *)apr_table_get(c->notes, "ssl::verify::error");
+            ssl_log(c->base_server, SSL_LOG_ERROR|SSL_ADD_SSLERR,
+                    "SSL client authentication failed: %s",
+                    cp != NULL ? cp : "unknown reason");
+            SSL_set_shutdown(pRec->pssl, SSL_RECEIVED_SHUTDOWN);
+            SSL_smart_shutdown(pRec->pssl);
+            SSL_free(pRec->pssl);
+            apr_table_setn(c->notes, "ssl", NULL);
+            c->aborted = 1;
+            return APR_EGENERAL;
+        }
+
+        /*
+         * Remember the peer certificate's DN
+         */
+        if ((xs = SSL_get_peer_certificate(pRec->pssl)) != NULL) {
+            cp = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0);
+            apr_table_setn(c->notes,"ssl::client::dn",apr_pstrdup(c->pool, cp));
+            free(cp);
+        }
+
+        /*
+         * Make really sure that when a peer certificate
+         * is required we really got one... (be paranoid)
+         */
+        if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE
+            && apr_table_get(c->notes, "ssl::client::dn") == NULL) {
+            ssl_log(c->base_server, SSL_LOG_ERROR,
+                    "No acceptable peer certificate available");
+            SSL_set_shutdown(pRec->pssl, SSL_RECEIVED_SHUTDOWN);
+            SSL_smart_shutdown(pRec->pssl);
+            SSL_free(pRec->pssl);
+            apr_table_setn(c->notes, "ssl", NULL);
+            c->aborted = 1;
+            return APR_EGENERAL;
+        }
     }
     return APR_SUCCESS;
 }