RE: Improved AuthType Certificate provider [enhancement #48780]

2010-04-09 Thread Thomas, Peter
> [...] There's an old thread on this same 
> subject, and a module, that you can find at 
> https://sourceforge.net/projects/modauthcertific/

That's one of the prior examples I looked at in coming up with this
approach.  IIRC, it depended on a rigidly defined LDAP schema.
Dictating the schema is often not an option for existing environments. 

> I would suggest collecting the design decisions, and the 
> interactions with authn/authz/access control in trunk 
> somewhere so people can follow without too much investment.  
> Include config examples/use cases.

Will do.  I definitely haven't addressed documentation of any of this
yet.  Is there a template or pattern for config examples and use cases?
A pointer to one or more "well-done" use cases would suffice.

> The contentious parts for these things are usually:
> How does the cert map to r->user?

I stayed with the spirit of mod_ssl here. By default r->user becomes the
certificate subject DN ( SSL_CLIENT_S_DN ).  If the SSLUserName
directive is employed, use that instead.  The advantage of this approach
is that it should work with almost every LDAP implementation--those
where the certificate subject is also the LDAP object's DN, and those
where a component of the subject--such as the CN--must be matched to an
attribute of the LDAP object. 

As I noted in the bugzilla entry, though, I had to "tweak" mod_ssl to
return the DN in RFC2253 format.  The backwards compatible thing to do
is to configure mod_ssl to optionally return the DN in RFC2253 syntax OR
add a new SSL variable that has the LDAP-formatted DN, and then use
SSLUserName to select that variable when needed.  [The current behavior
in mod_ssl used to retrieve the subject or issuer DN uses a method
formally deprecated in OpenSSL--of course, it's not likely that it'll be
going away any time soon.]

Examples:

1)
   # Find the user's entry in LDAP by matching a component of the
subject certificate to an attribute in LDAP
   SSLUserName SSL_CLIENT_S_DN_UID

   AuthLLDAPUrl
ldaps://ldap.example.com/dc=example,dc=com?uid,fullname?sub
   # For AuthType Certificate, mod_authnz_ldap will do a subtree search 
   # from dc=example,dc=com for (&(uid=)(objectclass=*))

2)
   # Find the user's entry in LDAP by the full certificate subject DN 
   AuthLDAPUrl ldaps://ldap.example.com/dc=example,dc=com?fullname?sub

   AuthLDAPRemoteUserIsDN
   # Currently, I'm overloading the semantics of AuthLDAPRemoteUserIsDN:
   #   when AuthType is Certificate this directive causes us to do an 
   #   LDAP_SCOPE_BASE search for r->user, expected to be the full DN in
RFC2253
   #   this is guaranteed to return either 0 or 1 directory objects.
   # In this scenario fullname is still retrieved and placed in the
AUTHENTICATE_FULLNAME
   # environment variable; it is not used to search for the LDAP object.
Likewise the
   # scope parameter of the LDAP URL is ignored for authentication.

> How does one express that basic-auth-if-no-certificate 
> (AuthType foo bar, or does the cert module pre-empty basic 
> auth via some other config mechanism) What if anything 
> changes in authorization providers (hopefully nothing)

In effect, nothing changes in the auhorization providers.  "AuthType
Certificate Basic" does exactly what you would hope, for example:

  AuthType Certificate Basic
  AuthName "Certificate authentication with Basic fallback"
  AuthCertificateProvider ldap 
  AuthBasicProvider file
  
  # Allow fallback from mod_authnz_ldap if user is not found in LDAP;
compare to AuthBasicAuthoritative
  AuthCertificateAuthoritative off

I say "in effect," because to simplify implementation, I reused the
existing method.  For Basic auth, there's no logical change.  For
Certificate auth, I update behavior as appropriate. 
  
> Unfortunately, doing this right in trunk probably makes it 
> unbackportable.  Getting it by hook or by crook in a 

I have a working 2.2 implementation; I guess I'm signing up to distinct
changes per-branch, rather than a trunk commit and a 2.2 backport.  I'm
hoping that's not as bad as one might think at first blush--where I've
made changes to the single authorization method in 2.2, I'd just have to
distribute those changes appropriately to each distinct Require ldap-*
directive method in the trunk.

> standalone 2.2 module might mean making it look like basic 
> auth internally and would probably not be suitable for the 
> base distribution.

I'm not sure what you mean; I definitely want to avoid doing anything
unsuitable.  What do I need to guard against?


Re: Improved AuthType Certificate provider [enhancement #48780]

2010-04-09 Thread Eric Covener
On Tue, Apr 6, 2010 at 7:51 PM, Thomas, Peter  wrote:
>I 'm not sure this is
> the sort of feature we should be adding directly to 2.2.x,

Seems like a stretch.  There's an old thread on this same subject, and
a module, that you can find at
https://sourceforge.net/projects/modauthcertific/

I would suggest collecting the design decisions, and the interactions
with authn/authz/access control in trunk somewhere so people can
follow without too much investment.  Include config examples/use
cases.

The contentious parts for these things are usually:

How does the cert map to r->user?
How does one express that basic-auth-if-no-certificate (AuthType foo
bar, or does the cert module pre-empty basic auth via some other
config mechanism)
What if anything changes in authorization providers (hopefully nothing)

Unfortunately, doing this right in trunk probably makes it
unbackportable.  Getting it by hook or by crook in a standalone 2.2
module might mean making it look like basic auth internally and would
probably not be suitable for the base distribution.

-- 
Eric Covener
cove...@gmail.com


Improved AuthType Certificate provider [enhancement #48780]

2010-04-06 Thread Thomas, Peter
As promised in my note last week, I've created an updated patch attached
to my suggested feature in
https://issues.apache.org/bugzilla/show_bug.cgi?id=48780 .

This patch works in my integration environment, tested with all Require
ldap-* directives.  

Notes:

1) When using certificates we can often expect that the DN of the user
matches the subject DN of the certificate.  For that reason I made a
slight overloading of AuthLDAPRemoteUserIsDN.  This new behavior is only
active in the proposed patch if AuthType is Certificate and
AuthLDAPRemoteUserIsDN is on. In those circumstances, LDAP authn will do
an LDAP_SCOPE_BASE search for the user at the DN specified in the
certificate.  I updated the corresponding authz methods to make sure
that we are always searching for the user's DN in a consistent way.
When the special circumstances do not apply, you continue using the
first attribute in the LDAP URL's attribute list compared with the
username to find the user [the legacy behavior].

2) I updated ssl_engine_vars.c in mod_ssl.  The current SSL_CLIENT_S_DN
uses  X509_NAME_oneline(xsname, NULL, 0) which is a) deprecated and b)
not in an LDAP-friendly (RFC2253-compliant) form.  I updated the code to
use X509_NAME_print_ex(bio, xsname, 0, XN_FLAG_RFC2253).

Since the vast majority of the use of SSL_CLIENT_S_DN is cosmetic
[logging, etc.] I don't foresee this causing a substantial problem.
That said, if someone wants to take a stab at making this configurable
before we move forward, I'm amenable.

3) The only added directives in all this are:

AuthCertificateProvider and
AuthCertificateAuthoritative

They behave exactly as their counterparts from mod_auth_basic...So far
only mod_authnz_ldap is supported [by this patch], as in:

AuthType Certificate
AuthName "SSL Certificate-Based Authentication"
AuthCertificateProvider ldap
[...followed by AuthLDAP settings, &c.]

I have not sought out commt privileges on the project.  I'm not sure
this is the sort of feature we should be adding directly to 2.2.x, even
if I was able to.  What I would like is for other people with interest
in the problem space to try this patch out in their own environments and
get back to me and the community and with suggestions and observations.

--Pete