From ba0d6156c9c88c0432f5fd69dc34067fe44a0418 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Wed, 22 Aug 2001 19:37:03 +0000 Subject: [PATCH] Enable ssl client authentication at SSL_accept time PR: Obtained from: Submitted by: Madhusudan Mathihalli Reviewed by: dougm git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90503 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 2 ++ modules/ssl/mod_ssl.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/CHANGES b/CHANGES index 67acc9021e..204999a9af 100644 --- 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 ] *) Fix a segfault in mod_include when the original request has no associated filename (e.g., we're filtering the error document for diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c index ba476e4e71..1839c46398 100644 --- a/modules/ssl/mod_ssl.c +++ b/modules/ssl/mod_ssl.c @@ -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; } -- 2.50.1