thanks a lot gustavo.

i were far away from this source of information.

but this should help if i want to authenticate the client in apache, and i 
wanted to do this in paste SecureHTTPServer. the way to go with the underlying 
pyopenssl is setting a callback function that will be called for each 
certificate the client has. when the relevant match occurs, the client's 
certificate userid will just be looked up in the users' table, and the password 
shoud not be checked.

that's why i wanted to be able to set the verify callback function on the 
server.ssl_context, at some early point before the first request, like 
config.app_cfg.py.

On Wed, Apr 29, 2009 at 17:41, Gustavo Narea <[email protected]> wrote:

Hello, Alex.

On Wednesday April 29, 2009 01:28:31 [email protected] wrote:
i'm sorry i don't understand yet where to look in.
in the request.environ i have the key paste.httpserver.threadpool that
seems promising, but i don't see how to get to the server object yet.

since you're the repoze man too, i'd need to find the server before the
first request, in order to install a callback function in
securehttpserver.ssl_context. this callback will do the repoze.who work.

No, you don't have to do anything of that. The solution is simpler.

You just need to authenticate the X.509 certificate based on some of its
attributes, which should be available as items of the WSGI environ dictionary
[1]. In this context, "authenticate" means check that the certificate is valid
(against its CA's root certificate) and that it hasn't expired.

That plugin should look like this:
"""
from repoze.who.interfaces import IAuthenticator
from zope.interface import implements

class X509AuthenticatorPlugin(object):
   implements(IAuthenticator)

   def __init__(self, root_certs_of_cas):
       self.root_certs_of_cas = root_certs_of_cas

   def authenticate(self, environ, identity):
       cert_body = environ.get('SSL_CLIENT_CERT')
       if not cert_body:
           # There's no X.509 certificate to validate:
           return None

       ca = get_cert_ca(cert_body)
       if ca not in self.root_certs_of_cas:
           # We dont have the root certificate for this CA:
           return None

       this_ca = self.root_certs_of_cas[ca]
       if not validate_cert(this_ca, cert_body):
           # The certificate is invalid!
           return None

       if environ['SSL_CLIENT_V_END'] < now:
           # The certificate has expired
           return None

       # At this point, the cert is just perfect.
       return environ.get('SSL_CLIENT_S_DN')
"""

Cheers.

[1] Here's a sample vendor-specific list:
http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#envvars
--
Gustavo Narea <xri://=Gustavo>.
| Tech blog: =Gustavo/(+blog)/tech  ~  About me: =Gustavo/about |

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---





--
alex

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply via email to