Changeset 6783 for TI12-security/trunk/NDG_XACML
- Timestamp:
- 29/03/10 17:07:31 (10 years ago)
- Location:
- TI12-security/trunk/NDG_XACML/ndg/xacml
- Files:
-
- 1 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
TI12-security/trunk/NDG_XACML/ndg/xacml/core/__init__.py
r6774 r6783 14 14 15 15 class XacmlCoreBase(object): 16 """Base class for Policy and Policy subelements""" 17 XACML_2_0_XMLNS = "urn:oasis:names:tc:xacml:2.0:policy:schema:os" 16 """Base class for all XACML types""" 17 XACML_1_0_NS_PREFIX = "urn:oasis:names:tc:xacml:1.0" 18 XACML_2_0_NS_PREFIX = "urn:oasis:names:tc:xacml:2.0" 18 19 19 20 __slots__ = ('__xmlns', '__reader', '__writer', '__elem') … … 22 23 23 24 def __init__(self): 24 self.__xmlns = XacmlCoreBase.XACML_2_0_XMLNS25 self.__xmlns = None 25 26 self.__reader = None 26 27 self.__writer = None … … 32 33 33 34 def _getXmlns(self): 35 """XML Namespace for this XACML type""" 34 36 return self.__xmlns 35 37 36 38 def _setXmlns(self, value): 39 """XML Namespace for this XACML type""" 37 40 if not isinstance(value, basestring): 38 41 raise TypeError('Expecting string type for "xmlns" ' … … 87 90 self.__elem = value 88 91 92 93 class XacmlPolicyBase(XacmlCoreBase): 94 """Base class for policy types""" 95 XACML_2_0_POLICY_NS = XACML_2_0_NS_PREFIX + ":policy:schema:os" 96 def __init__(self): 97 super(XacmlPolicyBase, self).__init__() 98 self.xmlns = XacmlPolicyBase.XACML_2_0_POLICY_NS 89 99 90 class TargetChildBase(XacmlCoreBase): 100 101 class TargetChildBase(XacmlPolicyBase): 91 102 """Base type for XACML Policy Subject, Resource, Action and Environment 92 103 types""" … … 96 107 97 108 def __init__(self): 109 super(TargetChildBase, self).__init__() 110 98 111 # Derived types can specify the type for matches via the MATCH_TYPE 99 112 # class variable -
TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/__init__.py
r6776 r6783 12 12 __revision__ = "$Id: $" 13 13 from ndg.xacml.utils import TypedList 14 from ndg.xacml.core import XacmlContextBase 14 15 from ndg.xacml.core.attribute import Attribute 15 16 16 17 17 class XacmlContextBase( object):18 class XacmlContextBase(XacmlCoreBase): 18 19 """Base class for XACML Request and Response types""" 19 20 ELEMENT_LOCAL_NAME = None -
TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/pdp.py
r6782 r6783 16 16 17 17 from ndg.xacml.core.context.pdpinterface import PDPInterface 18 from ndg.xacml.core.rule import Effect 18 19 from ndg.xacml.core.policy import Policy 20 from ndg.xacml.core.apply import Apply 21 from ndg.xacml.core.attributevalue import AttributeValue 22 from ndg.xacml.core.variablereference import VariableReference 23 from ndg.xacml.core.attributedesignator import AttributeDesignator 24 from ndg.xacml.core.attributeselector import AttributeSelector 19 25 from ndg.xacml.core.context.request import Request 20 26 from ndg.xacml.core.context.response import Response 21 27 from ndg.xacml.core.context.result import Result, Decision 28 from ndg.xacml.core.context.result import StatusCode 22 29 from ndg.xacml.core.functions import FunctionMap 23 from ndg.xacml.parsers import AbstractReader24 30 25 31 32 class PDPError(Exception): 33 """Base class for PDP class exceptions""" 34 def __init__(self, *arg, **kw): 35 super(PDPError, self).__init__(*arg, **kw) 36 self.__response = Response() 37 self.__response.results.append(Result.createInitialised()) 38 39 if len(arg) > 0: 40 self.__response.results[0].status.statusMessage = arg[0] 41 42 @property 43 def response(self): 44 """Context response object associated with this exception 45 """ 46 return self.__response 47 48 @response.setter 49 def response(self, value): 50 if not isinstance(value, Response): 51 raise TypeError('Expecting %r type for "response" attribute; got ' 52 '%r instead' % (Response, type(Response))) 53 self.__response = value 54 55 56 class UnsupportedFunctionError(PDPError): 57 """Encountered a function type that is not supported in this implementation 58 """ 59 def __init__(self, *arg, **kw): 60 super(UnsupportedFunctionError, self).__init__(*arg, **kw) 61 self.response.results[0].status.statusCode = StatusCode.PROCESSING_ERROR 62 63 64 class UnsupportedStdFunctionError(UnsupportedFunctionError): 65 """Encountered a function type that is not supported even though it is part 66 of the XACML spec.""" 67 68 69 class UnsupportedElementError(PDPError): 70 """Element type is not supported in this implementation""" 71 def __init__(self, *arg, **kw): 72 super(UnsupportedElementError, self).__init__(*arg, **kw) 73 self.response.results[0].status.statusCode = StatusCode.SYNTAX_ERROR 74 75 76 class UnsupportedStdElementError(UnsupportedElementError): 77 """Element type is part of the XACML spec but is not suppored in this 78 implementation""" 79 80 26 81 class PDP(PDPInterface): 27 82 """A XACML Policy Decision Point implementation. It supports the use of a … … 41 96 self.policy = policy 42 97 43 self. matchFunc= FunctionMap.withLoadedMap()98 self.functionMap = FunctionMap.withLoadedMap() 44 99 45 100 … … 97 152 98 153 if not self.matchTarget(self.policy.target, request): 99 log.debug('No match for policy target setting Decision=%s',154 log.debug('No match for policy target setting %r decision', 100 155 Decision.NOT_APPLICABLE_STR) 101 156 … … 106 161 107 162 # Check rules 108 for rule in self.policy.rules: 163 ruleEffects = [Effect()]*len(self.policy.rules) 164 for rule, effect in zip(self.policy.rules, ruleEffects): 109 165 log.debug('Checking policy rule %r for match...', rule.id) 110 166 if not self.matchTarget(rule.target, request): 111 167 log.debug('No match to request context for target in rule ' 112 168 '%r', rule.id) 169 effect.value = Effect.PERMIT_STR 113 170 continue 114 171 115 172 # Apply the condition 116 self.appyCondition(rule.condition) 117 except: 173 effect = self.applyCondition(rule.condition) 174 175 except PDPError, e: 118 176 log.error('Exception raised evaluating request context, returning ' 119 ' Decision=%s:%s',177 '%r decision:%s', 120 178 Decision.INDETERMINATE_STR, 121 179 traceback.format_exc()) 180 122 181 result.decision = Decision.INDETERMINATE 182 result.status.statusCode = e.response.results[0].status.statusCode 183 184 except Exception: 185 # Catch all so that nothing is handled from within the scope of this 186 # method 187 log.error('No PDPError type exception raised evaluating request ' 188 'context, returning %r decision:%s', 189 Decision.INDETERMINATE_STR, 190 traceback.format_exc()) 191 192 result.decision = Decision.INDETERMINATE 193 result.status.statusCode = StatusCode.PROCESSING_ERROR 123 194 124 195 return response … … 167 238 continue 168 239 169 # Iterate over each for example, subject in the list of subjects or 170 # for example, resource in the list of resources and so on 240 # Iterate over each for example, subject in the list of subjects: 241 # <Target> 242 # <Subjects> 243 # <Subject> 244 # ... 245 # </Subject> 246 # <Subject> 247 # ... 248 # </Subject> 249 # ... 250 # or for example, resource in the list of resources and so on 171 251 for targetSubElem in targetElem: 172 252 … … 187 267 188 268 def matchTargetChild(self, targetChild, requestChild): 189 """Match a child (Subject, Resource, Action or Environment) from the 190 request context with a given target's child 269 """Match a request child element (a <Subject>, <Resource>, <Action> or 270 <Environment>) with the corresponding target's <Subject>, <Resource>, 271 <Action> or <Environment>. 191 272 192 273 @param targetChild: Target Subject, Resource, Action or Environment … … 198 279 @return: True if request context matches something in the target 199 280 @rtype: bool 200 @raise NotImplementedError: AttributeSelector processing is not281 @raise UnsupportedElementError: AttributeSelector processing is not 201 282 currently supported. If an AttributeSelector is found in the policy, 202 283 this exception will be raised. 203 """ 204 matchStatus = True 284 @raise UnsupportedStdFunctionError: policy references a function type 285 which is in the XACML spec. but is not supported by this implementation 286 @raise UnsupportedFunctionError: policy references a function type which 287 is not supported by this implementation 288 """ 205 289 206 290 if targetChild is None: … … 208 292 return True 209 293 294 295 matchStatusValues = [True]*len(targetChild.matches) 210 296 211 297 # Section 7.6 … … 214 300 # request context if the value of all its <SubjectMatch>, 215 301 # <ResourceMatch>, <ActionMatch> or <EnvironmentMatch> elements, 216 # respectively, are âTrueâ. 217 for childMatch in targetChild.matches: 302 # respectively, are "True". 303 # 304 # e.g. for <SubjectMatch>es in <Subject> ... 305 for childMatch, matchStatus in zip(targetChild.matches, 306 matchStatusValues): 307 218 308 # Get the match function from the Match ID 219 matchFunc = self. matchFunc.get(childMatch.matchId)309 matchFunc = self.functionMap.get(childMatch.matchId) 220 310 if matchFunc is NotImplemented: 221 raise NotImplementedError('No match function implemented for ' 222 'MatchId="%s"' % childMatch.matchId) 223 224 if matchFunc is None: 225 raise Exception('Match function namespace %r is not recognised' 226 % childMatch.matchId) 311 raise UnsupportedStdFunctionError('No match function ' 312 'implemented for MatchId="%s"' 313 % childMatch.matchId) 314 elif matchFunc is None: 315 raise UnsupportedFunctionError('Match function namespace %r is ' 316 'not recognised' % 317 childMatch.matchId) 227 318 228 319 matchAttributeValue = childMatch.attributeValue.value … … 234 325 dataType = childMatch.attributeDesignator.dataType 235 326 236 # Issuer is an optional match - see core spec 7.2.4327 # Issuer is an optional match - see core spec. 7.2.4 237 328 issuer = childMatch.attributeDesignator.issuer 238 329 if issuer is not None: … … 258 349 # it's XML representation and an abstraction of the XML parser 259 350 # for executing XPath searches into that representation 260 raise NotImplementedError('This PDP implementation does not'261 'support <AttributeSelector> '262 'elements')351 raise UnsupportedElementError('This PDP implementation does ' 352 'not support <AttributeSelector> ' 353 'elements') 263 354 else: 264 355 _attributeMatch = lambda requestChildAttribute: ( … … 266 357 requestChildAttribute.attributeValue.value) 267 358 ) 268 269 for attribute in requestChild.attributes: 270 if _attributeMatch(attribute) == True: 359 360 # Iterate through each attribute in the request in turn matching it 361 # against the target using the generated _attributeMatch function 362 # 363 # Any Match element NOT matching will result in an overall status of 364 # no match. 365 # 366 # Continue iterating through the whole list even if a False status 367 # is found. The other attributes need to be checked in case an 368 # error occurs. In this case the top-level PDP exception handling 369 # block will catch it and set an overall decision of INDETERMINATE 370 attrMatchStatusValues = [False]*len(requestChild.attributes) 371 372 for attribute, attrMatchStatus in zip(requestChild.attributes, 373 attrMatchStatusValues): 374 attrMatchStatus = _attributeMatch(attribute) 375 if attrMatchStatus == True: 271 376 if log.getEffectiveLevel() <= logging.DEBUG: 272 377 log.debug('Request attribute %r set to %r matches ' … … 275 380 attribute.attributeValue.value) 276 381 277 # Default status is True - any *Match element NOT matching 278 # will result in an overall status of no match 279 else: 280 # Don't return here but set the status to False. The other 281 # attributes need to be checked in case an error occurs. 282 # In this case the top-level PDP exception handling block 283 # will catch it and set an overall decision of INDETERMINATE 284 matchStatus = False 285 286 return matchStatus 287 288 def applyCondition(self, condition): 289 """Apply a rule condition""" 290 382 matchStatus = all(attrMatchStatusValues) 383 384 # Any match => overall match 385 return any(matchStatusValues) 386 387 def evaluateCondition(self, condition): 388 """Evaluate a rule condition""" 389 390 # Spec: 391 # 392 # "The condition value SHALL be "True" if the <Condition> element is 393 # absent" 394 if condition is None: 395 return True 396 397 applyElem = condition.expression 398 if not isinstance(applyElem, Apply): 399 raise UnsupportedElementError('%r type <Condition> sub-element ' 400 'processing is not supported in this ' 401 'implementation' % applyElem) 402 403 result = self.evaluateApplyStatement(applyElem) 404 405 def evaluateApplyStatement(self, applyElem): 406 """Evaluate a given Condition <Apply> statement""" 407 408 # Get function for this <Apply> statement 409 func = self.functionMap.get(applyElem.functionId) 410 if func is NotImplemented: 411 raise UnsupportedStdFunctionError('No match function ' 412 'implemented for MatchId="%s"' 413 % applyElem.functionId) 414 elif func is None: 415 raise UnsupportedFunctionError('<Apply> function namespace %r is ' 416 'not recognised' % 417 applyElem.functionId) 418 419 inputMarshallerMap = { 420 Apply: self.evaluateApplyStatement, 421 AttributeValue: self.evaluateAttributeValueStatement, 422 AttributeDesignator: self.evaluateAttributeDesignator, 423 AttributeSelector: NotImplemented, 424 VariableReference: NotImplemented 425 } 426 427 # Marshall inputs 428 funcInputs = ()*len(applyElem.expressions) 429 for i, expression in enumerate(applyElem.expressions): 430 marshaller = inputMarshallerMap.get(expression.__class__) 431 if marshaller is NotImplemented: 432 raise UnsupportedStdElementError('%r type <Apply> sub-element ' 433 'processing is not supported ' 434 'in this implementation' % 435 expression) 436 elif marshaller is None: 437 raise UnsupportedElementError('%r type <Apply> sub-element ' 438 'processing is not supported in ' 439 'this implementation' % 440 expression) 441 442 funcInputs[i] = marshaller(self, expression) 443 444 # Execute function on the retrieved inputs 445 result = func(*funcInputs) 446 447 # Pass the result back to the parent <Apply> element 448 return result 449 450 def evaluateAttributeValueStatement(self, attributeValue): 451 return 452 453 def evaluateAttributeDesignator(self): 454 pass 455 -
TI12-security/trunk/NDG_XACML/ndg/xacml/core/context/result.py
r6777 r6783 13 13 log = logging.getLogger(__name__) 14 14 15 from ndg.xacml.core import XacmlBase 15 16 from ndg.xacml.core.context import XacmlContextBase 16 17 from ndg.xacml.core.obligation import Obligation … … 23 24 ELEMENT_LOCAL_NAME = "StatusCode" 24 25 25 26 IDENTIFIER_PREFIX = XacmlContextBase.XACML_1_0_NS_PREFIX + ':status' 27 28 OK = IDENTIFIER_PREFIX + ":ok" 29 MISSING_ATTRIBUTE = IDENTIFIER_PREFIX + ":missing-attribute" 30 PROCESSING_ERROR = IDENTIFIER_PREFIX + ":processing-error" 31 SYNTAX_ERROR = IDENTIFIER_PREFIX + ":syntax-error" 32 33 CODES = (OK, MISSING_ATTRIBUTE, PROCESSING_ERROR, SYNTAX_ERROR) 34 26 35 __slots__ = ('__value', '__childStatusCode',) 27 36 … … 82 91 self.__statusDetail = None 83 92 93 @classmethod 94 def createInitialised(cls, code=StatusCode.OK, message='', detail=''): 95 """Create with an empty StatusCode object set 96 """ 97 status = cls() 98 status.statusCode = StatusCode() 99 status.statusCode.value = code 100 status.statusCode.statusMessage = message 101 status.statusCode.statusDetail = detail 102 103 return status 104 84 105 def _getStatusCode(self): 85 106 ''' … … 298 319 self.__obligations = None 299 320 321 @classmethod 322 def createInitialised(cls, 323 decision=Decision.NOT_APPLICABLE, 324 resourceId='', 325 obligations=None 326 **kw): 327 """Create a result object populated with all it's child elements 328 rather than set to None as is the default from __init__ 329 @return: new result object with all its child attributes created 330 @rtype: ndg.xacml.core.context.result.Result 331 """ 332 result = cls() 333 result.decision = Decision() 334 result.decision.value = decision 335 result.status = Status.createInitialised(**kw) 336 337 if obligations is not None: 338 result.obligations = obligations 339 340 return result 341 300 342 @property 301 343 def resourceId(self): -
TI12-security/trunk/NDG_XACML/ndg/xacml/core/rule.py
r6770 r6783 14 14 from ndg.xacml.core.target import Target 15 15 from ndg.xacml.core.condition import Condition 16 17 18 class Effect(object): 19 """Rule Effect""" 20 DENY_STR = 'Deny' 21 PERMIT_STR = 'Permit' 22 TYPES = (DENY_STR, PERMIT_STR) 23 __slots__ = ('__value',) 24 25 def __init__(self): 26 self.__value = Effect.DENY_STR 27 28 def __getstate__(self): 29 '''Enable pickling''' 30 _dict = {} 31 for attrName in Effect.__slots__: 32 # Ugly hack to allow for derived classes setting private member 33 # variables 34 if attrName.startswith('__'): 35 attrName = "_Effect" + attrName 36 37 _dict[attrName] = getattr(self, attrName) 38 39 return _dict 40 41 def __setstate__(self, attrDict): 42 '''Enable pickling''' 43 for attrName, val in attrDict.items(): 44 setattr(self, attrName, val) 45 46 def _setValue(self, value): 47 if isinstance(value, Effect): 48 # Cast to string 49 value = str(value) 50 51 elif not isinstance(value, basestring): 52 raise TypeError('Expecting string or Effect instance for ' 53 '"value" attribute; got %r instead' % type(value)) 54 55 if value not in self.__class__.TYPES: 56 raise AttributeError('Permissable effect types are %r; got ' 57 '%r instead' % (Effect.TYPES, value)) 58 self.__value = value 59 60 def _getValue(self): 61 return self.__value 62 63 value = property(fget=_getValue, fset=_setValue, doc="Effect value") 64 65 def __str__(self): 66 return self.__value 67 68 def __eq__(self, effect): 69 if isinstance(effect, Effect): 70 # Cast to string 71 value = effect.value 72 73 elif isinstance(effect, basestring): 74 value = effect 75 76 else: 77 raise TypeError('Expecting string or Effect instance for ' 78 'input effect value; got %r instead' % type(value)) 79 80 if value not in self.__class__.TYPES: 81 raise AttributeError('Permissable effect types are %r; got ' 82 '%r instead' % (Effect.TYPES, value)) 83 84 return self.__value == value 85 86 87 class PermitEffect(Effect): 88 """Permit authorisation Effect""" 89 __slots__ = () 90 91 def __init__(self): 92 super(PermitEffect, self).__init__(Effect.PERMIT_STR) 93 94 def _setValue(self): 95 raise AttributeError("can't set attribute") 96 97 98 class DenyEffect(Effect): 99 """Deny authorisation Effect""" 100 __slots__ = () 101 102 def __init__(self): 103 super(DenyEffect, self).__init__(Effect.DENY_STR) 104 105 def _setValue(self, value): 106 raise AttributeError("can't set attribute") 107 108 # Add instances of each for convenience 109 Effect.PERMIT = PermitEffect() 110 Effect.DENY = DenyEffect() 16 111 17 112 … … 79 174 80 175 def _set_effect(self, value): 81 if not isinstance(value, basestring):176 if not isinstance(value, Effect): 82 177 raise TypeError('Expecting %r type for "effect" ' 83 178 'attribute; got %r' % (basestring, type(value))) -
TI12-security/trunk/NDG_XACML/ndg/xacml/core/variabledefinition.py
r6745 r6783 10 10 __contact__ = "Philip.Kershaw@stfc.ac.uk" 11 11 __revision__ = "$Id: $" 12 from ndg.xacml.core import XacmlPolicyBase 12 13 13 class VariableDefinition(object): 14 ''' 15 classdocs14 15 class VariableDefinition(XacmlPolicyBase): 16 '''XACML Variable Definition Type 16 17 ''' 17 18 ELEMENT_LOCAL_NAME = "VariableDefinition" … … 20 21 21 22 def __init__(self): 22 ''' 23 Constructor 24 ''' 23 '''This class not needed yet''' 24 raise NotImplementedError() 25 25 -
TI12-security/trunk/NDG_XACML/ndg/xacml/parsers/etree/applyreader.py
r6774 r6783 15 15 from ndg.xacml.core.apply import Apply 16 16 from ndg.xacml.core.attributevalue import AttributeValue 17 from ndg.xacml.core.variablereference import VariableReference 17 18 from ndg.xacml.core.attributeselector import AttributeSelector 18 19 from ndg.xacml.core.attributedesignator import (SubjectAttributeDesignator, … … 114 115 'implemented', localName) 115 116 116 elif (localName == 117 self.__class__.VARIABLE_REFERENCE_ELEMENT_LOCAL_NAME): 117 elif (localName == VariableReference.ELEMENT_LOCAL_NAME): 118 118 raise NotImplementedError('%r Apply sub-element not ' 119 119 'implemented', localName) -
TI12-security/trunk/NDG_XACML/ndg/xacml/parsers/etree/reader.py
r6770 r6783 15 15 from xml.etree import ElementTree 16 16 17 from ndg.xacml.core import Xacml CoreBase17 from ndg.xacml.core import XacmlPolicyBase 18 18 from ndg.xacml.parsers import AbstractReader 19 19 … … 32 32 33 33 self.__namespace_map_backup = ElementTree._namespace_map.copy() 34 ElementTree._namespace_map[''] = Xacml CoreBase.XACML_2_0_XMLNS34 ElementTree._namespace_map[''] = XacmlPolicyBase.XACML_2_0_POLICY_NS 35 35 36 36 def __del__(self): -
TI12-security/trunk/NDG_XACML/ndg/xacml/test/ndg1.xml
r6782 r6783 61 61 something more specific 62 62 --> 63 <Condition FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">63 <Condition> 64 64 <!-- 65 65 The user must have at least one of the roles set - in this … … 73 73 Issuer="https://localhost:7443/AttributeAuthority"/> 74 74 <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> 75 <!--76 A custom attribute type is used for NDG Security because77 the PDP needs to ask the PIP to retrieve user attributes78 from the applicable issuing attribute authority79 -->80 75 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string"> 81 urn:siteA:security:authz:1.0:attr:staff 76 staff 77 </AttributeValue> 78 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string"> 79 admin 80 </AttributeValue> 81 <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string"> 82 postdoc 82 83 </AttributeValue> 83 84 </Apply> -
TI12-security/trunk/NDG_XACML/ndg/xacml/test/rule2.xml
r6754 r6783 8 8 PolicyId="urn:oasis:names:tc:xacml:2.0:example:policyid:2" 9 9 RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:deny-overrides"> 10 <!-- 10 11 11 <PolicyDefaults> 12 12 <XPathVersion>http://www.w3.org/TR/1999/Rec-xpath-19991116</XPathVersion> 13 13 </PolicyDefaults> 14 --> 14 15 15 <Target/> 16 <!-- 16 <!-- VariableDefinition is not currently implemented 29/03/10 17 17 <VariableDefinition VariableId="17590035"> 18 18 <Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:date-less-or-equal"> -
TI12-security/trunk/NDG_XACML/ndg/xacml/test/test_context.py
r6782 r6783 106 106 result = Result() 107 107 response.results.append(result) 108 result.decision = Decision.value = Decision.NOT_APPLICABLE 108 result.decision = Decision() 109 result.decision.value = Decision.NOT_APPLICABLE 109 110 110 111 def test03AbstractCtxHandler(self):
Note: See TracChangeset
for help on using the changeset viewer.