All: I've been working on integrating mod_ssl and mod_authnz_ldap for non-password-based environments. I contemplate "AuthType Certificate" in https://issues.apache.org/bugzilla/show_bug.cgi?id=48780 . 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: ----- Added: modules/aaa/mod_auth_cert.c * 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. ----- Modified: Modouls/aaa/mod_auth.h: * appended check_certificate member to authn_provider struct modules/aaa/config.m4: * add "APACHE_MODULE(auth_cert, X.509 certificate authentication, , , most)" modules/aaa/mod_authnz_ldap.c: * 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 Modules/ssl/mod_ssl.h: * 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 mod_auth_cert.c:authenticate_certificate_user [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 puzzling out anything I've done wrong: --- http-2.2.15-baseline/modules/ssl//ssl_engine_vars.c Sat Feb 27 16:00:58 2010 --- 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)