Commit b74651db authored by Doug MacEachern's avatar Doug MacEachern
Browse files

Enable ssl client authentication at SSL_accept time

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
parent 861d0c17
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
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
+45 −0
Original line number Diff line number Diff line
@@ -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;
}