Ignore:
Timestamp:
04/03/10 15:16:09 (10 years ago)
Author:
pjkersha
Message:

Fixes to SAML timestamp checking

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/saml_utils/binding/soap/subjectquery.py

    r6615 r6675  
    5151                        doc="SAML Response associated with this exception") 
    5252     
    53      
     53 
     54class IssueInstantInvalid(SubjectQueryResponseError): 
     55    """Issue instant of SAML artifact is invalid""" 
     56 
     57   
     58class ResponseIssueInstantInvalid(IssueInstantInvalid): 
     59    """Issue instant of a response is after the current time""" 
     60 
     61     
     62class AssertionIssueInstantInvalid(IssueInstantInvalid): 
     63    """Issue instant of an assertion is after the current time""" 
     64 
     65 
     66class AssertionConditionNotBeforeInvalid(SubjectQueryResponseError): 
     67    """An assertion condition notBefore time is set after the current clock 
     68    time""" 
     69     
     70 
     71class AssertionConditionNotOnOrAfterInvalid(SubjectQueryResponseError): 
     72    """An assertion condition notOnOrAfter time is set before the current clock 
     73    time""" 
     74 
     75    
    5476class SubjectQuerySOAPBinding(SOAPBinding):  
    5577    """SAML Subject Query SOAP Binding 
     
    237259        self.__query.issueInstant = datetime.utcnow() 
    238260 
     261    def _verifyTimeConditions(self, response): 
     262        """Verify time conditions set in a response 
     263        @param response: SAML Response returned from remote service 
     264        @type response: ndg.saml.saml2.core.Response 
     265        @raise SubjectQueryResponseError: if a timestamp is invalid 
     266        """ 
     267         
     268        if not self.verifyTimeConditions: 
     269            log.debug("Skipping verification of SAML Response time conditions") 
     270             
     271        utcNow = datetime.utcnow()  
     272        nowMinusSkew = utcNow - self.clockSkewTolerance 
     273        nowPlusSkew = utcNow + self.clockSkewTolerance 
     274         
     275        if response.issueInstant > nowPlusSkew: 
     276            msg = ('SAML Attribute Response issueInstant [%s] is after ' 
     277                   'the clock time [%s] (skewed +%s)' %  
     278                   (response.issueInstant,  
     279                    SAMLDateTime.toString(nowPlusSkew), 
     280                    self.clockSkewTolerance)) 
     281              
     282            samlRespError = ResponseIssueInstantInvalid(msg) 
     283            samlRespError.response = response 
     284            raise samlRespError 
     285         
     286        for assertion in response.assertions: 
     287            if assertion.issueInstant is None: 
     288                samlRespError = AssertionIssueInstantInvalid("No issueInstant " 
     289                                                             "set in response " 
     290                                                             "assertion") 
     291                samlRespError.response = response 
     292                raise samlRespError 
     293             
     294            elif nowPlusSkew < assertion.issueInstant: 
     295                msg = ('The clock time [%s] (skewed +%s) is before the ' 
     296                       'SAML Attribute Response assertion issue instant [%s]' %  
     297                       (SAMLDateTime.toString(utcNow), 
     298                        self.clockSkewTolerance, 
     299                        assertion.issueInstant)) 
     300                samlRespError = AssertionIssueInstantInvalid(msg) 
     301                samlRespError.response = response 
     302                raise samlRespError 
     303             
     304            if assertion.conditions is not None: 
     305                if nowPlusSkew < assertion.conditions.notBefore:             
     306                    msg = ('The clock time [%s] (skewed +%s) is before the ' 
     307                           'SAML Attribute Response assertion conditions not ' 
     308                           'before time [%s]' %  
     309                           (SAMLDateTime.toString(utcNow), 
     310                            self.clockSkewTolerance, 
     311                            assertion.conditions.notBefore)) 
     312                               
     313                    samlRespError = AssertionConditionNotBeforeInvalid(msg) 
     314                    samlRespError.response = response 
     315                    raise samlRespError 
     316                  
     317                if nowMinusSkew >= assertion.conditions.notOnOrAfter:            
     318                    msg = ('The clock time [%s] (skewed -%s) is on or after ' 
     319                           'the SAML Attribute Response assertion conditions ' 
     320                           'not on or after time [%s]' %  
     321                           (SAMLDateTime.toString(utcNow), 
     322                            self.clockSkewTolerance, 
     323                            assertion.conditions.notOnOrAfter)) 
     324                     
     325                    samlRespError = AssertionConditionNotOnOrAfterInvalid(msg)  
     326                    samlRespError.response = response 
     327                    raise samlRespError 
     328                 
    239329    def send(self, **kw): 
    240330        '''Make an attribute query to a remote SAML service 
     
    270360            raise samlRespError 
    271361         
    272         utcNow = datetime.utcnow() + self.clockSkewTolerance 
    273         if response.issueInstant > utcNow: 
    274             msg = ('SAML Attribute Response issueInstant [%s] is after ' 
    275                    'the current clock time [%s]' %  
    276                    (self.query.issueInstant, SAMLDateTime.toString(utcNow))) 
    277              
    278             samlRespError = SubjectQueryResponseError(msg)                   
    279             samlRespError.response = response 
    280             raise samlRespError 
    281          
    282         for assertion in response.assertions: 
    283             if self.verifyTimeConditions and assertion.conditions is not None: 
    284                 if utcNow < assertion.conditions.notBefore:             
    285                     msg = ('The current clock time [%s] is before the SAML ' 
    286                            'Attribute Response assertion conditions not before ' 
    287                            'time [%s]' %  
    288                            (SAMLDateTime.toString(utcNow), 
    289                             assertion.conditions.notBefore)) 
    290                                
    291                     samlRespError = SubjectQueryResponseError(msg) 
    292                     samlRespError.response = response 
    293                     raise samlRespError 
    294                   
    295                 if utcNow >= assertion.conditions.notOnOrAfter:            
    296                     msg = ('The current clock time [%s] is on or after the ' 
    297                            'SAML Attribute Response assertion conditions not ' 
    298                            'on or after time [%s]' %  
    299                            (SAMLDateTime.toString(utcNow), 
    300                             response.assertion.conditions.notOnOrAfter)) 
    301                      
    302                     samlRespError = SubjectQueryResponseError(msg)  
    303                     samlRespError.response = response 
    304                     raise samlRespError    
     362        self._verifyTimeConditions(response) 
    305363             
    306364        return response  
Note: See TracChangeset for help on using the changeset viewer.