source: TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/relyingparty/validation.py @ 6276

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg-security/TI12-security/trunk/NDGSecurity/python/ndg_security_server/ndg/security/server/wsgi/openid/relyingparty/validation.py@6276
Revision 6276, 27.5 KB checked in by pjkersha, 11 years ago (diff)
  • ndg.security.server.wsgi.NDGSecurityMiddlewareBase: change code to leave trailing space in path info attribute
  • ndg.security.server.wsgi.openid.provider.OpenIDProviderMiddleware:
    • added properties with type checking
    • added trustedRelyingParties attribute - a list of sites trusted by the Provider for which no decide page interface is invoked.
  • ndg.security.server.wsgi.openid.provider.axinterface.csv: fixed adding of AX attributes for CSV class. Required attributes were being set twice.
  • ndg.security.server.wsgi.openid.relyingparty.OpenIDRelyingParty:
    • changed whitelisting to use ndg.security.server.wsgi.openid.relyingparty.validation.SSLIdPValidationDriver class. FIXME: Fix required in SSL verify callback needed to check only the server certificate in the verification chain and ignore CA certificates.
  • ndg.security.server.wsgi.openid.relyingparty.validation.SSLIdPValidationDriver: changed to init to include keyword option for installing default urllib2 opener and defaulting to OMIT it.
Line 
1"""NDG Security OpenID Relying Party Provider Validation module
2
3Based on the Earth System Grid IdPValidator interface for restricting
4OpenID Providers that a Relying Party may connect to
5
6An Identity Provider (IdP) is equivalent to an OpenID Provider
7
8NERC DataGrid Project
9"""
10__author__ = "P J Kershaw"
11__date__ = "09/06/2009"
12__copyright__ = "(C) 2009 Science and Technology Facilities Council"
13__license__ = "BSD - see top-level directory for LICENSE file"
14__contact__ = "Philip.Kershaw@stfc.ac.uk"
15__revision__ = "$Id: $"
16import logging
17log = logging.getLogger(__name__)
18import os
19import traceback
20import re
21
22from elementtree import ElementTree
23from openid.yadis.manager import Discovery
24
25from ndg.security.common.X509 import X509Cert
26from ndg.security.common.utils.etree import QName
27from ndg.security.common.utils.classfactory import instantiateClass
28
29class _ConfigBase(object):
30    """Base class for IdP Validator and Attribute Provider configuration
31    """
32    def __init__(self):
33        self.__className = None
34        self.__configFile = None
35        self.__parameters = {}
36   
37    def _set_className(self, className):
38        if not isinstance(className, basestring):
39            raise TypeError('Expecting string type for className; got %r' %
40                            type(className))
41        self.__className = className
42   
43    def _get_className(self):
44        return self.__className
45   
46    className = property(fget=_get_className,
47                         fset=_set_className)
48
49    def _get_configFile(self):
50        return self.__configFile
51   
52    def _set_configFile(self, configFile):
53        if not isinstance(configFile, basestring):
54            raise TypeError('Expecting string type for configFile; got %r' %
55                            type(className))
56        self.__configFile = configFile
57
58    configFile = property(fget=_get_configFile,
59                          fset=_set_configFile)
60   
61    def _get_parameters(self):
62        return self.__parameters
63   
64    def _set_parameters(self, parameters):   
65        if not isinstance(parameters, dict):
66            raise TypeError('Expecting string type for parameters; got %r' %
67                            type(parameters))
68        self.__parameters = parameters
69   
70    parameters = property(fget=_get_parameters,
71                          fset=_set_parameters)
72
73class IdPValidatorConfig(_ConfigBase):
74    """Container for IdP validator configuration"""
75   
76class AttributeProviderConfig(_ConfigBase):
77    """Container for Attribute Provider configuration"""
78   
79class XmlConfigReaderError(Exception):
80    """Raise from XmlConfigReader"""
81     
82class XmlConfigReader(object):
83    """Parser for IdP and Attribute Provider config
84    """
85    VALIDATOR_ELEMNAME = "validator"
86    PARAMETER_ELEMNAME = "parameter"
87    ATTRIBUTE_PROVIDER_ELEMNAME = "attributeprovider"
88    NAME_ATTRNAME = "name"
89    VALUE_ATTRNAME = "value"
90   
91    def getValidators(self, source): 
92        """Retrieve IdP Validator objects from XML file
93        @type source: basestring/file
94        @param source: file path to XML file or file object
95        """
96        validators = None
97
98        root = self.__parseConfigFile(source)
99        if root is not None:
100            validators = self.__extractValidatorConfigs(root)
101       
102        return validators
103   
104    def getAttrProviders(self, source):
105        """
106        @type source: basestring/file
107        @param source: file path to XML file or file object
108        """   
109        attrProviders = None
110
111        root = self.__parseConfigFile(source)
112        if root is not None:
113            attrProviders = self.__extractAttrProviderConfigs(root)
114       
115        return attrProviders
116   
117    def __parseConfigFile(self, source):
118        """Read in the XML configuration file
119        @type source: basestring/file
120        @param source: file path to XML file or file object
121        """
122        elem = ElementTree.parse(source)
123        root = elem.getroot()
124       
125        return root
126
127    def __extractValidatorConfigs(self, root):
128        """Parse Validator configuration from the XML config file
129        @type root: ElementTree.Element
130        @param root: root element of parsed XML config file
131        """
132        validators = []
133       
134        for elem in root:
135            localName = QName.getLocalPart(elem.tag).lower()
136            if localName == XmlConfigReader.VALIDATOR_ELEMNAME:   
137                validatorConfig = IdPValidatorConfig()
138               
139                className = elem.attrib.get(XmlConfigReader.NAME_ATTRNAME)
140                if className is None:
141                    raise XmlConfigReaderError('No "%s" attribute found in '
142                                               '"%s" tag' %
143                                              (XmlConfigReader.NAME_ATTRNAME,
144                                               elem.tag))
145                   
146                validatorConfig.className = className
147               
148                parameters = {}
149                for el in elem:
150                    if QName.getLocalPart(
151                       el.tag).lower() == XmlConfigReader.PARAMETER_ELEMNAME:
152                       
153                        nameAttr = el.attrib.get(XmlConfigReader.NAME_ATTRNAME)
154                        if nameAttr is None:
155                            raise XmlConfigReaderError('No "%s" attribute '
156                                                       'found in "%s" tag' %
157                                                (XmlConfigReader.NAME_ATTRNAME,
158                                                 el.tag))
159                        if nameAttr in parameters:
160                            raise XmlConfigReaderError('Duplicate parameter '
161                                                       'name "%s" found' % 
162                                                       el.attrib[
163                                                XmlConfigReader.NAME_ATTRNAME])
164                           
165                        valAttr = el.attrib.get(XmlConfigReader.VALUE_ATTRNAME)
166                        if valAttr is None:
167                            raise XmlConfigReaderError('No "%s" attribute '
168                                                       'found in "%s" tag' %
169                                                (XmlConfigReader.VALUE_ATTRNAME,
170                                                 el.tag))
171                               
172                        parameters[nameAttr] = os.path.expandvars(valAttr)
173           
174                validatorConfig.parameters = parameters
175                validators.append(validatorConfig)
176       
177        return validators
178   
179    def __extractAttrProviderConfigs(self, root):
180        """Parse Attribute Provider configurations from the XML tree
181        @type root: ElementTree.Element
182        @param root: root element of parsed XML config file
183        """
184        attrProviders = []
185        validatorConfig = None
186        parameters = {}
187
188        for elem in root:
189            localName = QName.getLocalPart(elem.tag).lower()
190            if localName == XmlConfigReader.ATTRIBUTE_PROVIDER_ELEMNAME:
191                if validatorConfig is not None:
192                    validatorConfig.parameters = parameters
193                    attrProviders.append(validatorConfig)
194               
195                validatorConfig = AttributeProviderConfig()
196                nameAttr = elem.attrib.get(XmlConfigReader.NAME_ATTRNAME)
197                if nameAttr is None:
198                    raise XmlConfigReaderError('No "%s" attribute '
199                                               'found in "%s" tag' %
200                                               (XmlConfigReader.NAME_ATTRNAME,
201                                                elem.tag))
202                validatorConfig.className(nameAttr)
203           
204            elif localName == XmlConfigReader.PARAMETER_ELEMNAME:
205               
206                nameAttr = elem.attrib.get(XmlConfigReader.NAME_ATTRNAME)
207                if nameAttr is None:
208                    raise XmlConfigReaderError('No "%s" attribute '
209                                               'found in "%s" tag' %
210                                               (XmlConfigReader.NAME_ATTRNAME,
211                                                elem.tag))
212                       
213                if nameAttr in parameters:
214                    raise XmlConfigReaderError('Duplicate parameter name "%s" '
215                                               'found' % nameAttr)
216                   
217                valAttr = elem.attrib.get(XmlConfigReader.VALUE_ATTRNAME)
218                if valAttr is None:
219                    raise XmlConfigReaderError('No "%s" attribute '
220                                               'found in "%s" tag' %
221                                               (XmlConfigReader.VALUE_ATTRNAME,
222                                                elem.tag))
223           
224                parameters[nameAttr] = elem.attrib[valAttr]
225           
226        if validatorConfig != None:
227            validatorConfig.parameters = parameters
228            attrProviders.append(validatorConfig)
229       
230        return attrProviders
231
232
233class IdPValidatorException(Exception):
234    """Base class for IdPValidator exceptions"""
235   
236class IdPInvalidException(IdPValidatorException):
237    """Raise from IdPValidator.validate if the IdP is not acceptable"""
238
239class ConfigException(IdPValidatorException):
240    """Problem with configuration for the IdP Validator class"""
241 
242
243class IdPValidator(object):
244    '''Interface class for implementing OpenID Provider validators for a
245    Relying Party to call'''
246   
247    def __init__(self):
248        raise NotImplementedError()
249
250    def initialize(self, **parameters):
251        '''@raise ConfigException:''' 
252        raise NotImplementedError()
253       
254    def validate(self, idpEndpoint, idpIdentity):
255        '''@raise IdPInvalidException:
256        @raise ConfigException:''' 
257        raise NotImplementedError()
258 
259
260class SSLIdPValidator(object):
261    '''Interface class for implementing OpenID Provider validators for a
262    Relying Party to call'''
263    __slots__ = ()
264   
265    def __init__(self):
266        raise NotImplementedError()
267
268    def initialize(self, **parameters):
269        '''@raise ConfigException:''' 
270        raise NotImplementedError()
271       
272    def validate(self, x509CertCtx):
273        '''@type x509StoreCtx: M2Crypto.X509_Store_Context
274        @param x509StoreCtx: context object containing peer certificate and
275        certificate chain for verification
276 
277        @raise IdPInvalidException:
278        @raise ConfigException:''' 
279        raise NotImplementedError()
280   
281   
282import urllib2
283from M2Crypto import SSL
284from M2Crypto.m2urllib2 import build_opener
285from ndg.security.common.X509 import X500DN
286
287class SSLClientAuthNValidator(SSLIdPValidator):
288    """HTTPS based validation with the addition that this client can provide
289    a certificate to the peer enabling mutual authentication
290    """
291    PARAMETERS = {
292        'configFilePath': basestring,
293        'caCertDirPath': basestring,
294        'certFilePath': basestring,
295        'priKeyFilePath': basestring,
296        'priKeyPwd': basestring
297    }
298    __slots__ = {}
299    __slots__.update(PARAMETERS)
300    __slots__.update({'validIdPNames': []})
301   
302    def __init__(self):
303        """Set-up default SSL context for HTTPS requests"""
304        self.validIdPNames = []
305       
306        for p in SSLClientAuthNValidator.PARAMETERS:
307            setattr(self, p, '')
308
309    def __setattr__(self, name, value):
310        if (name in SSLClientAuthNValidator.PARAMETERS and 
311            not isinstance(value, SSLClientAuthNValidator.PARAMETERS[name])):
312            raise TypeError('Invalid type %r for parameter "%s" expecting '
313                            '%r ' % 
314                            (type(value), 
315                             name, 
316                             SSLClientAuthNValidator.PARAMETERS[name]))
317           
318        super(SSLClientAuthNValidator, self).__setattr__(name, value)
319       
320    def initialize(self, ctx, **parameters):
321        '''@raise ConfigException:''' 
322        for name, val in parameters.items():
323            setattr(self, name, os.path.expandvars(val))
324             
325        ctx.load_verify_locations(capath=self.caCertDirPath)
326        if self.certFilePath is not None and self.priKeyFilePath is not None:
327            ctx.load_cert(self.certFilePath, 
328                          keyfile=self.priKeyFilePath, 
329                          callback=lambda *arg, **kw: self.priKeyPwd)
330           
331        if self.configFilePath is not None:
332            # Simple file format - one IdP server name per line
333            cfgFile = open(self.configFilePath)
334            self.validIdPNames = [l.strip() for l in cfgFile.readlines()
335                                  if not l.startswith('#')]
336                         
337    def validate(self, x509StoreCtx):
338        '''callback function used to control the behaviour when the
339        SSL_VERIFY_PEER flag is set
340       
341        @type x509StoreCtx: M2Crypto.X509_Store_Context
342        @param x509StoreCtx: locate the certificate to be verified and perform
343        additional verification steps as needed
344        @rtype: int
345        @return: controls the strategy of the further verification process.
346        - If verify_callback returns 0, the verification process is immediately
347        stopped with "verification failed" state. If SSL_VERIFY_PEER is set,
348        a verification failure alert is sent to the peer and the TLS/SSL
349        handshake is terminated.
350        - If verify_callback returns 1, the verification process is continued.
351        If verify_callback always returns 1, the TLS/SSL handshake will not be
352        terminated with respect to verification failures and the connection
353        will be established. The calling process can however retrieve the error
354        code of the last verification error using SSL_get_verify_result(3) or
355        by maintaining its own error storage managed by verify_callback.
356        '''
357        x509Cert = X509Cert.fromM2Crypto(x509StoreCtx.get_current_cert())
358        commonName = x509Cert.dn['CN']
359       
360       
361        x509CertChain = x509StoreCtx.get1_chain()
362        for cert in x509CertChain:
363            subject = cert.get_subject()
364            dn = subject.as_text()
365            log.debug("verifyCallback: dn = %r", dn)
366
367        # If all is OK preVerifyOK will be 1.  Return this to the caller to
368        # that it's OK to proceed
369        if commonName not in self.validIdPNames:
370            raise IdPInvalidException("Peer certificate CN=%s is not in list "
371                                      "of valid OpenID Providers" % commonName)
372
373
374class FileBasedIdentityUriValidator(IdPValidator):
375    """Validate OpenID identity URI against a list of regular expressions
376    which specify the allowable identities.  The list is read from a simple
377    flat file - one pattern per line
378    """   
379    PARAMETERS = {
380        'configFilePath': basestring,
381    }
382    CONFIGFILE_COMMENT_CHAR = '#'
383   
384    def __init__(self):
385        self.__configFilePath = None
386        self.__identityUriPatterns = None
387
388    def _setIdentityUriPatterns(self, value):
389        if not isinstance(value, dict):
390            raise TypeError('Expecting a dict of pattern objects keyed by '
391                            'pattern string for "identityUriPatterns" object; '
392                            'got %r' % type(value))
393        self.__identityUriPatterns = value
394
395    identityUriPatterns = property(fget=lambda self:self.__identityUriPatterns, 
396                                   fset=_setIdentityUriPatterns, 
397                                   doc="list of regular expression objects "
398                                       "to match input identity URIs against")
399       
400    def _getConfigFilePath(self):
401        return self.__configFilePath
402
403    def _setConfigFilePath(self, value):
404        if not isinstance(value, basestring):
405            raise TypeError('Expecting string type for "configFilePath"; got '
406                            '%r' % type(value))
407        self.__configFilePath = value
408
409    configFilePath = property(fget=_getConfigFilePath, 
410                              fset=_setConfigFilePath, 
411                              doc="Configuration file path for this validator")
412
413    def initialize(self, **parameters):
414        '''@raise ConfigException:''' 
415        for name, val in parameters.items():
416            if name not in FileBasedIdentityUriValidator.PARAMETERS:
417                raise AttributeError('Invalid parameter name "%s".  Valid '
418                            'names are %r' % (name,
419                            FileBasedIdentityUriValidator.PARAMETERS.keys()))
420               
421            if not isinstance(val, 
422                              FileBasedIdentityUriValidator.PARAMETERS[name]):
423                raise TypeError('Invalid type %r for parameter "%s" expecting '
424                            '%r ' % 
425                            (type(val), 
426                             name, 
427                             FileBasedIdentityUriValidator.PARAMETERS[name]))
428       
429            setattr(self, name, os.path.expandvars(val))
430
431        self._parseConfigFile()
432       
433    def _parseConfigFile(self):
434        """Read the configFile containing identity URI regular expressions
435        """
436        try:
437            configFile = open(self.configFilePath)
438        except IOError, e:
439            raise ConfigException('Error parsing %r configuration file "%s": '
440                                  '%s' % (self.__class__.__name__,
441                                   e.filename, e.strerror))
442       
443        lines = re.split('\s', configFile.read().strip())
444        self.identityUriPatterns = dict([
445            (pat, re.compile(pat))
446            for pat in lines if not pat.startswith(
447                        FileBasedIdentityUriValidator.CONFIGFILE_COMMENT_CHAR)
448        ])
449       
450    def validate(self, idpEndpoint, idpIdentity):
451        '''Match user identity URI against list of acceptable patterns parsed
452        from config file.  The idpEndpoint is ignored
453       
454        @type idpEndpoint: basestring
455        @param idpEndpoint: endpoint for OpenID Provider service being
456        discovered
457        @type idpIdentity: basestring
458        @param idpIdentity: endpoint for OpenID Provider service being
459        @raise IdPInvalidException:
460        ''' 
461        for patStr, pat in self.identityUriPatterns.items():
462            if pat.match(idpIdentity) is not None:
463                log.debug("Identity URI %r matches whitelist pattern %r" %
464                          (idpIdentity, patStr))
465                break # identity matches: return silently
466        else:
467            raise IdPInvalidException("OpenID identity URI %r doesn't match "
468                                      "the whitelisted patterns" %
469                                      idpIdentity)
470   
471   
472class IdPValidationDriver(object):
473    """Parse an XML Validation configuration containing XML Validators and
474    execute these against the Provider (IdP) input"""   
475    IDP_VALIDATOR_BASE_CLASS = IdPValidator
476    IDP_CONFIG_FILEPATH_ENV_VARNAME = "IDP_CONFIG_FILE"
477   
478    def __init__(self):
479        self.__idPValidators = []
480       
481    def _get_idPValidators(self):
482        return self.__idPValidators
483   
484    def _set_idPValidators(self, idPValidators):
485        badValidators = [i for i in idPValidators
486                         if not isinstance(i, 
487                                    self.__class__.IDP_VALIDATOR_BASE_CLASS)]
488        if len(badValidators):
489            raise TypeError("Input validators must be of IdPValidator derived "
490                            "type")
491               
492        self.__idPValidators = idPValidators
493       
494    idPValidators = property(fget=_get_idPValidators,
495                             fset=_set_idPValidators,
496                             doc="list of IdP Validators")
497
498    @classmethod
499    def readConfig(cls, idpConfigFilePath=None):
500        """Read IdP Validation configuration file.  This is an XML document
501        containing a list of validator class names and their initialisation
502        parameters
503        """
504        validators = []
505       
506        if idpConfigFilePath is None:
507            idpConfigFilePath = os.environ.get(
508                        IdPValidationDriver.IDP_CONFIG_FILEPATH_ENV_VARNAME)
509           
510        if idpConfigFilePath is None:
511            log.warning("IdPValidationDriver.readConfig: No IdP "
512                        "Configuration file was set")
513            return validators
514       
515        configReader = XmlConfigReader()
516        validatorConfigs = configReader.getValidators(idpConfigFilePath)
517
518        for validatorConfig in validatorConfigs:
519            try:
520                validator = instantiateClass(validatorConfig.className,
521                                             None, 
522                                             objectType=IdPValidator)
523                validator.initialize(**validatorConfig.parameters)
524                validators.append(validator)
525           
526            except Exception, e: 
527                log.error("Failed to initialise validator %s: %s", 
528                          validatorConfig.className, traceback.format_exc())
529               
530        return validators
531   
532    def performIdPValidation(self, 
533                             identifier, 
534                             discoveries=(Discovery(None, None),)):
535        """Perform all IdPValidation for all configured IdPValidators.  if
536        the setIdPValidator method was used to initialise a list of
537        IdPValidators before this method is called, the configurations
538        are still checked each time this method is called and any valid
539        IdPValidators found are appended to the initial list and run in
540        addition.
541       
542        @param identifier: OpenID identity URL
543        @type identifier: basestring
544        @param discoveries: list of discovery instances.  Default to a single
545        one with a provider URI of None
546        @type discoveries: openid.yadis.discover.Discover
547        """
548        validators = self.readConfig()
549
550        if self.idPValidators is not None:
551            validators += self.idPValidators
552
553        log.info("%d IdPValidators initialised", len(validators))
554
555        # validate the discovered end points
556        if len(validators) > 0:
557       
558            newDiscoveries = []
559            for validator in validators:   
560                for discoveryInfo in discoveries:
561                    try:
562                        validator.validate(discoveryInfo.url, identifier)
563
564                        log.info("Whitelist Validator %r accepting endpoint: "
565                                 "%s", validator, discoveryInfo.url)
566
567                        newDiscoveries.append(discoveryInfo)
568                   
569                    except IdPInvalidException, e:
570                        log.warning("Whitelist Validator %r rejecting "
571                                    "identifier: %s: %s", validator, 
572                                    identifier, e)
573                                               
574                    except Exception, e:       
575                        log.warning("Error with Whitelist Validator %r "
576                                    "rejecting identity: %s: %s", validator, 
577                                    identifier, traceback.format_exc())
578                       
579            if len(newDiscoveries) > 0:
580                discoveries = newDiscoveries
581                log.info("Found %d valid endpoint(s)." % len(discoveries))
582            else:     
583                raise IdPInvalidException("No valid endpoints were found "
584                                          "after validation.")
585        else:
586            log.warning("No IdP validation executed because no validators "
587                        "were set")
588           
589        return discoveries
590
591
592class SSLIdPValidationDriver(IdPValidationDriver):
593    '''Validate an IdP using the certificate it returns from an SSL based
594    request'''
595    IDP_VALIDATOR_BASE_CLASS = SSLIdPValidator
596   
597    def __init__(self, idpConfigFilePath=None, installOpener=False):
598        super(SSLIdPValidationDriver, self).__init__()
599       
600        # Context object determines what validation is applied against the
601        # peer's certificate in the SSL connection
602        self.ctx = SSL.Context()
603       
604        # Enforce peer cert checking via this classes' __call__ method
605        self.ctx.set_verify(SSL.verify_peer|SSL.verify_fail_if_no_peer_cert, 
606                            9, 
607                            callback=self)
608
609        if installOpener:
610            urllib2.install_opener(build_opener(ssl_context=self.ctx))
611       
612        if idpConfigFilePath is not None:
613            self.idPValidators += \
614                self.readConfig(idpConfigFilePath=idpConfigFilePath)
615           
616        log.info("%d IdPValidator(s) initialised", len(self.idPValidators))
617       
618    def readConfig(self, idpConfigFilePath):
619        """Read and initialise validators set in a config file""" 
620        validators = []
621       
622        if idpConfigFilePath is None:
623            idpConfigFilePath = os.environ('SSL_IDP_VALIDATION_CONFIG_FILE')
624           
625        if idpConfigFilePath is None:
626            log.warning("SSLIdPValidationDriver.readConfig: No IdP "
627                        "Configuration file was set")
628            return validators
629       
630        configReader = XmlConfigReader()
631        validatorConfigs = configReader.getValidators(idpConfigFilePath)
632
633        for validatorConfig in validatorConfigs:
634            try:
635                validator = instantiateClass(validatorConfig.className,
636                                             None, 
637                                             objectType=SSLIdPValidator)
638               
639                # Validator has access to the SSL context object in addition
640                # to custom settings set in parameters
641                validator.initialize(self.ctx, **validatorConfig.parameters)
642                validators.append(validator)
643           
644            except Exception, e: 
645                raise ConfigException("Validator class %r initialisation "
646                                      "failed with %s exception: %s" %
647                                      (validatorConfig.className, 
648                                       e.__class__.__name__,
649                                       traceback.format_exc()))
650               
651        return validators
652           
653    def __call__(self, preVerifyOK, x509StoreCtx):
654        '''@type preVerifyOK: int
655        @param preVerifyOK: If a verification error is found, this parameter
656        will be set to 0
657        @type x509StoreCtx: M2Crypto.X509_Store_Context
658        @param x509StoreCtx: context object containing peer certificate and
659        certificate chain for verification
660        '''
661        if preVerifyOK == 0:
662            # Something is wrong with the certificate don't bother proceeding
663            # any further
664            log.info("No custom Validation executed: a previous verification "
665                     "error has occurred")
666            return preVerifyOK
667
668        # validate the discovered end points
669        for validator in self.idPValidators:   
670            try:
671                validator.validate(x509StoreCtx)
672                log.info("Whitelist Validator %s succeeded", 
673                         validator.__class__.__name__)
674           
675            except Exception, e:
676                log.error("Whitelist Validator %r caught %s exception with "
677                          "peer certificate context: %s", 
678                          validator.__class__.__name__, 
679                          e.__class__.__name__,
680                          traceback.format_exc())       
681                return 0
682           
683        if len(self.idPValidators) == 0:
684            log.warning("No IdP validation executed because no validators "
685                        "were set")
686           
687        return 1
688       
Note: See TracBrowser for help on using the repository browser.