httpd-bugs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject DO NOT REPLY [Bug 48780] Enable mod_authnz_ldap to accept valid client certificates as sufficient authentication
Date Wed, 24 Mar 2010 20:55:11 GMT

--- Comment #7 from Peter Thomas <> 2010-03-24 20:55:07 UTC ---
The following is an e-mail sent to modules-dev on the subject.


I've been working on integrating mod_ssl and mod_authnz_ldap for
non-password-based environments.  I contemplate "AuthType Certificate" in .  This enhancement is
targeted for environments where the user is authenticated if they:

1) present a valid SSL client certificate, and
2) a single object corresponding[*1] to that user's certificate exists at the
targeted LDAP server.

To take advantage of the flexibility and utility of the existing module, I'm
extending mod_authnz_ldap instead of writing a separate handler. For example,
once authenticated one can then leverage the "Require ldap-*" directives in
mod_authnz_ldap.  mod_authnz_ldap also populates the environment with all
requested LDAP attributes in AUTHENTICATE_* environment variables. These can be
used in subsequent request processing [such as fine-grained access control or
other logic within request handlers].

To implement the initial "DN matching" approach, I had to make a change to
mod_ssl.c to pull out an RFC2253 compliant representation of the subject DN. 
My debugging so far suggests this may be causing me problems--I've included the
patch diff at the end of this e-mail for review and suggestions.

I hope to have a comprehensive prototype patch available shortly for others
that want to test this out.  A summary of the changes made to date follows:


* provider module defining AuthType Certificate based
* registers check user hook "authenticate_certificate_user"
* TODO:  (from [*1], above) matching certificate subject DN to LDAP object DN
is overly restrictive; someday implement a more general approach which might be
based on creating a filter expression to match DN components, certificate
attributes, &c.

* appended check_certificate member to authn_provider struct

* add "APACHE_MODULE(auth_cert, X.509 certificate authentication, , , most)"

* added authn_ldap_check_certificate, a wrapper for authn_ldap_check_password
after testing for certificate auth pre-conditions
* changed authn_ldap_check_password to use util_ldap_cache_getuserdn instead of
..._checkuserid if AuthType is Certificate
* registered authn_ldap_check_certificate as the check_certificate function for 

* TODO:  Make the following item configurable, defaulting to original behavior
[ I need RFC2253 format because that is how DNs are stored in our LDAP server ]
* changed ssl_var_lookup(…, "SSL_CLIENT_S_DN") to return RFC2253-compliant DN
instead of using deprecated X509_NAME_oneline 

Issues/other TODO items:

* TODO: enhance APR-Util & mod_ldap to support two-way SSL and ldap_sasl_bind_s
for environments that support SASL EXTERNAL authentication based on the LDAP
client's certificate; right now mod_ldap only supports simple
binding--anonymous, or with a binddn and password.
* ssl_var_lookup(…, "SSL_CLIENT_S_DN") bails out unexpectedly when called from
  [I know it works elsewhere, because I can get the user name logged in
access_log by using SSLUserName SSL_CLIENT_S_DN]

Here's the diff fragment if anyone wants to take a stab at helping me puzzle
out what I've done wrong:

--- http-2.2.15-baseline/modules/ssl//ssl_engine_vars.c Sat Feb 27 16:00:58
--- http-2.2.15/modules/ssl//ssl_engine_vars.c  Tue Mar 23 14:22:53 2010
@@ -367,10 +367,20 @@
     else if (strcEQ(var, "S_DN")) {
         xsname = X509_get_subject_name(xs);
-        cp = X509_NAME_oneline(xsname, NULL, 0);
-        result = apr_pstrdup(p, cp);
-        modssl_free(cp);
-        resdup = FALSO;
+        BIO *bio;
+        int n;
+        if ((bio = BIO_new(BIO_s_mem())) == NULL) {
+            result = NULL;
+        } else {
+            X509_NAME_print_ex(bio, xsname, 0, XN_FLAG_RFC2253);
+            n = BIO_pending(bio);
+            result = apr_pcalloc(p, n+1);
+            n = BIO_read(bio, result, n);
+            result[n] = NUL;
+            BIO_free(bio);
+            resdup = FALSE;
+        }
     else if (strlen(var) > 5 && strcEQn(var, "S_DN_", 5)) {
         xsname = X509_get_subject_name(xs)

Configure bugmail:
------- You are receiving this mail because: -------
You are the assignee for the bug.
To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message