You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modules-dev@httpd.apache.org by "Thomas, Peter" <pt...@HPTI.com> on 2010/03/24 21:54:16 UTC
In-progress review: adding "AuthType Certificate" to integrate Apache web server's mod_ssl & mod_authnz_ldap modules
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)