Changeset 6790 for TI12-security/trunk


Ignore:
Timestamp:
30/03/10 17:16:31 (10 years ago)
Author:
pjkersha
Message:
  • Added marshalling function for condition <Apply> to marshall inputs for given functionId.
  • implemented string-at-least-one-member-of function.
Location:
TI12-security/trunk/NDG_XACML/ndg/xacml
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/__init__.py

    r6783 r6790  
    9393class XacmlPolicyBase(XacmlCoreBase): 
    9494    """Base class for policy types""" 
    95     XACML_2_0_POLICY_NS = XACML_2_0_NS_PREFIX + ":policy:schema:os" 
     95    XACML_2_0_POLICY_NS = (XacmlCoreBase.XACML_2_0_NS_PREFIX + 
     96                           ":policy:schema:os") 
     97     
    9698    def __init__(self): 
    9799        super(XacmlPolicyBase, self).__init__() 
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/attributedesignator.py

    r6770 r6790  
    1010__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1111__revision__ = "$Id: $" 
    12  
    1312from ndg.xacml.core.expression import Expression 
    1413 
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/__init__.py

    r6783 r6790  
    1212__revision__ = "$Id: $" 
    1313from ndg.xacml.utils import TypedList 
    14 from ndg.xacml.core import XacmlContextBase 
     14from ndg.xacml.core import XacmlCoreBase 
    1515from ndg.xacml.core.attribute import Attribute 
    1616 
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/pdp.py

    r6783 r6790  
    2121from ndg.xacml.core.attributevalue import AttributeValue 
    2222from ndg.xacml.core.variablereference import VariableReference 
    23 from ndg.xacml.core.attributedesignator import AttributeDesignator 
     23from ndg.xacml.core.attributedesignator import (AttributeDesignator, 
     24                                                SubjectAttributeDesignator, 
     25                                                ResourceAttributeDesignator, 
     26                                                ActionAttributeDesignator, 
     27                                                EnvironmentAttributeDesignator) 
    2428from ndg.xacml.core.attributeselector import AttributeSelector 
    2529from ndg.xacml.core.context.request import Request 
     
    3741        self.__response.results.append(Result.createInitialised()) 
    3842         
     43        self.__response.results[0].decision = Decision.INDETERMINATE 
    3944        if len(arg) > 0: 
    4045            self.__response.results[0].status.statusMessage = arg[0] 
     
    7580 
    7681class UnsupportedStdElementError(UnsupportedElementError): 
    77     """Element type is part of the XACML spec but is not suppored in this  
     82    """Element type is part of the XACML spec. but is not supported in this  
    7883    implementation"""   
     84     
     85 
     86class MissingAttributeError(PDPError): 
     87    """AttributeDesignator or AttributeSelector has specified MustBePresent 
     88    but the request context contains no match for required attribute XPath 
     89    respectively 
     90    """ 
    7991     
    8092     
     
    8395    single policy but not policy sets 
    8496    """ 
    85     __slots__ = ('__policy',) 
     97    __slots__ = ('__policy', '__functionMap', '__request') 
    8698    TARGET_CHILD_ATTRS = ('subjects', 'resources', 'actions', 'environments') 
    8799     
     
    96108            self.policy = policy 
    97109             
    98         self.functionMap = FunctionMap.withLoadedMap() 
    99  
    100          
     110        self.__functionMap = FunctionMap.withLoadedMap() 
     111        self.__request = None 
     112 
    101113    @classmethod 
    102114    def fromPolicySource(cls, source, readerFactory): 
     
    125137                            '%r instead' % (Policy, type(value))) 
    126138        self.__policy = value 
    127                      
     139     
     140    @property 
     141    def functionMap(self): 
     142        """functionMap object for PDP to retrieve functions from given XACML 
     143        function URNs""" 
     144        return self.__functionMap 
     145     
     146    @functionMap.setter 
     147    def functionMap(self, value): 
     148        '''functionMap object for PDP to retrieve functions from given XACML 
     149        function URNs''' 
     150        if not isinstance(value, FunctionMap): 
     151            raise TypeError('Expecting %r derived type for "functionMap" ' 
     152                            'input; got %r instead' % (FunctionMap,  
     153                                                       type(value))) 
     154        self.__functionMap = value 
     155 
     156     
     157    @property 
     158    def request(self): 
     159        """request context""" 
     160        return self.__request 
     161     
     162    @request.setter 
     163    def request(self, value): 
     164        '''request context''' 
     165        if not isinstance(value, Request): 
     166            raise TypeError('Expecting %r derived type for "request" ' 
     167                            'input; got %r instead' % (Request,  
     168                                                       type(value))) 
     169        self.__request = value 
     170                                         
    128171    def evaluate(self, request): 
    129172        """Make an access control decision for the given request based on the 
     
    136179        """ 
    137180        response = Response() 
    138         result = Result() 
     181        result = Result.createInitialised(decision=Decision.NOT_APPLICABLE) 
    139182        response.results.append(result) 
    140         result.decision = Decision.NOT_APPLICABLE 
    141          
    142         if not isinstance(request, Request): 
    143             log.error('Expecting %r derived type for "reader" input; got ' 
    144                       '%r instead' % Request, type(request)) 
     183         
     184        try: 
     185            self.request = request 
     186             
     187        except AttributeError, e: 
     188            log.error(str(e)) 
    145189            result.decision = Decision.INDETERMINATE 
    146190            return response 
     
    151195            log.debug('Checking policy target for match with request...') 
    152196             
     197             
    153198            if not self.matchTarget(self.policy.target, request): 
    154199                log.debug('No match for policy target setting %r decision', 
     
    161206             
    162207            # Check rules 
    163             ruleEffects = [Effect()]*len(self.policy.rules) 
    164             for rule, effect in zip(self.policy.rules, ruleEffects): 
     208            ruleStatusValues = [False]*len(self.policy.rules) 
     209            for i, rule in enumerate(self.policy.rules): 
    165210                log.debug('Checking policy rule %r for match...', rule.id) 
    166211                if not self.matchTarget(rule.target, request): 
    167212                    log.debug('No match to request context for target in rule ' 
    168213                              '%r', rule.id) 
    169                     effect.value = Effect.PERMIT_STR 
     214                    ruleStatusValues[i] = True 
    170215                    continue    
    171216                 
    172217                # Apply the condition 
    173                 effect = self.applyCondition(rule.condition)  
     218                ruleStatusValues[i] = self.evaluateCondition(rule.condition)  
    174219                      
    175220        except PDPError, e: 
    176221            log.error('Exception raised evaluating request context, returning ' 
    177222                      '%r decision:%s',  
    178                       Decision.INDETERMINATE_STR,  
     223                      e.response.results[0].decision,  
    179224                      traceback.format_exc()) 
    180225             
    181             result.decision = Decision.INDETERMINATE 
    182             result.status.statusCode = e.response.results[0].status.statusCode 
     226            result = e.response.results[0] 
    183227             
    184228        except Exception: 
     
    191235                        
    192236            result.decision = Decision.INDETERMINATE 
    193             result.status.statusCode = StatusCode.PROCESSING_ERROR 
     237            result.status.statusCode.value = StatusCode.PROCESSING_ERROR 
    194238             
    195239        return response 
     
    226270        # Iterate for target subjects, resources, actions and environments  
    227271        # elements 
    228         for i, status in zip(self.__class__.TARGET_CHILD_ATTRS, statusValues): 
     272        for i, attrName in enumerate(self.__class__.TARGET_CHILD_ATTRS): 
    229273            # If any one of the <Target> children is missing then it counts as 
    230274            # a match e.g. for <Subjects> child element - Section 5.5: 
     
    233277            # attributes in the context. If this element is missing, 
    234278            # then the target SHALL match all subjects. 
    235             targetElem = getattr(target, i) 
     279            targetElem = getattr(target, attrName) 
    236280            if len(targetElem) == 0: 
    237                 status = True 
     281                statusValues[i] = True 
    238282                continue 
    239283             
     
    248292            #          </Subject> 
    249293            #     ... 
    250             # or for example, resource in the list of resources and so on 
     294            # or resource in the list of resources and so on 
    251295            for targetSubElem in targetElem: 
    252296                 
    253297                # For the given subject/resource/action/environment check for a 
    254298                # match with the equivalent in the request 
    255                 requestElem = getattr(request, i)  
     299                requestElem = getattr(request, attrName)  
    256300                for requestSubElem in requestElem: 
    257301                    if self.matchTargetChild(targetSubElem, requestSubElem): 
     
    259303                        # matches then this counts as a subject match overall  
    260304                        # for this target 
    261                         status = True 
     305                        statusValues[i] = True 
    262306  
    263307        # Target matches if all the children (i.e. subjects, resources, actions 
     
    287331        is not supported by this implementation 
    288332        """ 
    289          
    290333        if targetChild is None: 
    291334            # Default if target child is not set is to match all children 
    292335            return True 
    293          
    294336         
    295337        matchStatusValues = [True]*len(targetChild.matches) 
     
    322364            # AttributeDesignator or AttributeSelector 
    323365            if childMatch.attributeDesignator is not None: 
    324                 attributeId = childMatch.attributeDesignator.attributeId 
    325                 dataType = childMatch.attributeDesignator.dataType 
    326                  
    327                 # Issuer is an optional match - see core spec. 7.2.4 
    328                 issuer = childMatch.attributeDesignator.issuer 
    329                 if issuer is not None: 
    330                     # Issuer found - set lambda to match this against the  
    331                     # issuer setting in the request 
    332                     _issuerMatch = lambda requestChildIssuer: (issuer ==  
    333                                                             requestChildIssuer) 
    334                 else: 
    335                     # No issuer set - lambda returns True regardless 
    336                     _issuerMatch = lambda requestChildIssuer: True 
    337                      
    338                      
    339                 _attributeMatch = lambda requestChildAttribute: ( 
    340                     matchFunc.evaluate(matchAttributeValue,  
    341                               requestChildAttribute.attributeValue.value) and 
    342                     requestChildAttribute.attributeId == attributeId and 
    343                     requestChildAttribute.dataType == dataType and 
    344                     _issuerMatch(requestChildAttribute.issuer) 
    345                 ) 
     366                _attributeMatch = self.attributeDesignatorMatchFuncFactory( 
     367                                                matchFunc, 
     368                                                childMatch.attributeValue.value, 
     369                                                childMatch.attributeDesignator) 
    346370                 
    347371            elif childMatch.attributeSelector is not None: 
     
    384408        # Any match => overall match       
    385409        return any(matchStatusValues) 
    386  
     410                 
     411    def attributeDesignatorMatchFuncFactory(self, 
     412                                            matchFunc, 
     413                                            matchAttributeValue,  
     414                                            attributeDesignator): 
     415        """Define a match function to match a given request attribute against  
     416        the input attribute value and AttributeDesignator defined in a policy  
     417        target 
     418        """             
     419        attributeId = attributeDesignator.attributeId 
     420        dataType = attributeDesignator.dataType 
     421         
     422        # Issuer is an optional match - see core spec. 7.2.4 
     423        issuer = attributeDesignator.issuer 
     424        if issuer is not None: 
     425            # Issuer found - set lambda to match this against the  
     426            # issuer setting in the request 
     427            _issuerMatch = lambda requestChildIssuer: ( 
     428                                                issuer == requestChildIssuer) 
     429        else: 
     430            # No issuer set - lambda returns True regardless 
     431            _issuerMatch = lambda requestChildIssuer: True 
     432         
     433         
     434        _attributeMatch = lambda attribute: ( 
     435            matchFunc.evaluate(matchAttributeValue,  
     436                               attribute.attributeValue.value) and 
     437            attribute.attributeId == attributeId and 
     438            attribute.dataType == dataType and 
     439            _issuerMatch(attribute.issuer) 
     440        ) 
     441         
     442        return _attributeMatch 
     443     
    387444    def evaluateCondition(self, condition): 
    388         """Evaluate a rule condition""" 
     445        """Evaluate a rule condition 
     446        @param condition: rule condition 
     447        @type condition: ndg.xacml.core.condition.Condition 
     448        @return: True/False status for whether the rule condition matched or 
     449        not 
     450        @rtype: bool 
     451        """ 
    389452         
    390453        # Spec:  
     
    420483            Apply: self.evaluateApplyStatement, 
    421484            AttributeValue: self.evaluateAttributeValueStatement, 
    422             AttributeDesignator: self.evaluateAttributeDesignator, 
     485            SubjectAttributeDesignator: self.evaluateAttributeDesignator, 
    423486            AttributeSelector: NotImplemented, 
    424487            VariableReference: NotImplemented 
     
    426489         
    427490        # Marshall inputs 
    428         funcInputs = ()*len(applyElem.expressions) 
     491        funcInputs = ('',)*len(applyElem.expressions) 
    429492        for i, expression in enumerate(applyElem.expressions): 
    430493            marshaller = inputMarshallerMap.get(expression.__class__) 
     
    440503                                              expression) 
    441504             
    442             funcInputs[i] = marshaller(self, expression) 
     505            funcInputs[i] = marshaller(expression) 
    443506             
    444507        # Execute function on the retrieved inputs 
     
    448511        return result 
    449512             
    450     def evaluateAttributeValueStatement(self, attributeValue): 
    451         return  
    452      
    453     def evaluateAttributeDesignator(self): 
    454         pass 
    455  
     513    evaluateAttributeValueStatement = lambda self, attributeValue: ( 
     514        attributeValue.value 
     515    ) 
     516     
     517    def evaluateAttributeDesignator(self, attributeDesignator): 
     518        '''Retrieve string attribute bag for a given attribute designator 
     519        TODO: possible refactor as AttributeDesignator or ContextHandler method 
     520        ''' 
     521        attributeValues = [] 
     522        dataType = attributeDesignator.dataType 
     523         
     524        if isinstance(attributeDesignator, SubjectAttributeDesignator): 
     525            for i in self.request.subjects: 
     526                attributeValues.extend( 
     527                    [j.attributeValue for j in i.attributes 
     528                     if j.attributeValue.dataType == dataType]) 
     529 
     530        elif isinstance(attributeDesignator, ResourceAttributeDesignator): 
     531            for i in self.request.resources: 
     532                attributeValues.extend( 
     533                    [j.attributeValue for j in i.attributes 
     534                     if j.attributeValue.dataType == dataType]) 
     535 
     536        elif isinstance(attributeDesignator, ActionAttributeDesignator): 
     537            attributeValues.append([j.attributeValue for j in i.attributes 
     538                                    if j.attributeValue.dataType == dataType]) 
     539             
     540        elif isinstance(attributeDesignator, EnvironmentAttributeDesignator): 
     541            attributeValues.append([j.attributeValue for j in i.attributes 
     542                                    if j.attributeValue.dataType == dataType]) 
     543        else: 
     544            raise TypeError('Expecting %r derived type got %r' % 
     545                            (AttributeDesignator, type(attributeDesignator))) 
     546                
     547        if len(attributeValues) == 0 and attributeDesignator.mustBePresent: 
     548            raise MissingAttributeError('No match for AttributeDesignator ' 
     549                                        'attributeId=%r, dataType=%r and ' 
     550                                        'issuer=%r' %  
     551                                        (attributeDesignator.attributeId, 
     552                                         attributeDesignator.dataType, 
     553                                         attributeDesignator.issuer))  
     554                         
     555        return attributeValues 
     556 
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/result.py

    r6783 r6790  
    1313log = logging.getLogger(__name__) 
    1414 
    15 from ndg.xacml.core import XacmlBase 
    1615from ndg.xacml.core.context import XacmlContextBase 
    1716from ndg.xacml.core.obligation import Obligation 
     
    6564            raise TypeError("\"value\" must be a basestring derived type, " 
    6665                            "got %r" % value.__class__) 
    67              
     66         
     67        if value not in self.__class__.CODES: 
     68            raise AttributeError('Status code expected values are %r; got %r' % 
     69                                 (self.__class__.CODES, value)) 
     70                 
    6871        self.__value = value 
    6972 
     
    98101        status.statusCode = StatusCode() 
    99102        status.statusCode.value = code 
    100         status.statusCode.statusMessage = message 
    101         status.statusCode.statusDetail = detail 
     103        status.statusMessage = message 
     104        status.statusDetail = detail 
    102105         
    103106        return status 
     
    190193    __slots__ = ('__value',) 
    191194     
    192     def __init__(self, decisionType): 
     195    def __init__(self, decision=INDETERMINATE_STR): 
    193196        self.__value = None 
    194         self.value = decisionType 
     197        self.value = decision 
    195198 
    196199    def __getstate__(self): 
     
    323326                          decision=Decision.NOT_APPLICABLE, 
    324327                          resourceId='',  
    325                           obligations=None 
     328                          obligations=None, 
    326329                          **kw): 
    327330        """Create a result object populated with all it's child elements 
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/functions/__init__.py

    r6780 r6790  
    286286        """Force function entries to derive from AbstractFunction and IDs to 
    287287        be string type 
    288         """ 
    289         def keyFilter(key): 
    290             """Enforce string type keys""" 
    291             if not isinstance(key, basestring): 
    292                 raise TypeError('Expecting %r type for key; got %r' %  
    293                                 (basestring, type(key)))  
    294             return True  
    295          
    296         def valueFilter(value): 
    297             """Enforce AbstractFunction derived types for match functions""" 
    298  
    299             if not isinstance(value,  
    300                               (AbstractFunction, NotImplemented.__class__)): 
    301                 raise TypeError('Expecting %r derived type for value; got %r' %  
    302                                 (AbstractFunction, type(value)))  
    303             return True  
    304                       
    305         super(FunctionMap, self).__init__(keyFilter, valueFilter) 
    306          
     288        """         
     289        # Filters are defined as staticmethods but reference via self here to  
     290        # enable derived class to override them as standard methods without 
     291        # needing to redefine this __init__ method             
     292        super(FunctionMap, self).__init__(self.keyFilter, self.valueFilter) 
     293         
     294    @staticmethod 
     295    def keyFilter(key): 
     296        """Enforce string type keys""" 
     297        if not isinstance(key, basestring): 
     298            raise TypeError('Expecting %r type for key; got %r' %  
     299                            (basestring, type(key)))  
     300        return True  
     301     
     302    @staticmethod 
     303    def valueFilter(value): 
     304        """Enforce AbstractFunction derived types for match functions""" 
     305 
     306        if not isinstance(value,  
     307                          (AbstractFunction, NotImplemented.__class__)): 
     308            raise TypeError('Expecting %r derived type for value; got %r' %  
     309                            (AbstractFunction, type(value)))  
     310        return True  
     311            
    307312    def load(self): 
    308313        """Load function map with implementations from the relevant function 
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/functions/v1/anyuri_equal.py

    r6782 r6790  
    1414 
    1515 
    16 class AnyuriEqual(AbstractFunction): 
     16class AnyURIEqual(AbstractFunction): 
    1717    """Any URI equal matching function - 
    1818     
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/rule.py

    r6783 r6790  
    2323    __slots__ = ('__value',) 
    2424     
    25     def __init__(self): 
    26         self.__value = Effect.DENY_STR 
     25    def __init__(self, effect=DENY_STR): 
     26        self.__value = None 
     27        self.value = effect 
    2728 
    2829    def __getstate__(self): 
     
    176177        if not isinstance(value, Effect): 
    177178            raise TypeError('Expecting %r type for "effect" ' 
    178                             'attribute; got %r' % (basestring, type(value))) 
     179                            'attribute; got %r' % (Effect, type(value))) 
    179180             
    180181        self.__effect = value    
  • TI12-security/trunk/NDG_XACML/ndg/xacml/parsers/etree/rulereader.py

    r6753 r6790  
    1010__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1111__revision__ = "$Id: $" 
    12 from ndg.xacml.core.rule import Rule 
     12from ndg.xacml.core.rule import Rule, Effect 
    1313from ndg.xacml.core.condition import Condition 
    1414from ndg.xacml.core.target import Target 
     
    5151                 
    5252            attributeValues.append(attributeValue)  
    53                     
    54         rule.id, rule.effect = attributeValues 
     53         
     54        rule.effect = Effect()         
     55        rule.id, rule.effect.value = attributeValues 
    5556             
    5657        # Parse sub-elements 
  • TI12-security/trunk/NDG_XACML/ndg/xacml/test/ndg1.xml

    r6783 r6790  
    6969                <SubjectAttributeDesignator  
    7070                    AttributeId="urn:siteA:security:authz:1.0:attr"  
    71                     MustBePresent="false"  
    72                     DataType="http://www.w3.org/2001/XMLSchema#string" 
    73                     Issuer="https://localhost:7443/AttributeAuthority"/> 
     71                    DataType="http://www.w3.org/2001/XMLSchema#string"/> 
    7472                <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> 
    7573                    <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string"> 
Note: See TracChangeset for help on using the changeset viewer.