Changeset 6391


Ignore:
Timestamp:
25/01/10 10:10:02 (9 years ago)
Author:
pjkersha
Message:

refactored config file parsing

Location:
TI12-security/trunk/WSSecurity/ndg/wssecurity/common
Files:
1 added
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/WSSecurity/ndg/wssecurity/common/signaturehandler/__init__.py

    r6387 r6391  
    44NERC DataGrid Project 
    55""" 
    6 __author__ = "C Byrom" 
     6__author__ = "C Byrom, Philip Kershaw" 
    77__date__ = "18/08/08" 
    88__copyright__ = "" 
     
    1010__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1111__revision__ = '$Id: $' 
    12  
     12import logging 
     13log = logging.getLogger(__name__) 
     14 
     15import os 
    1316import re 
     17import base64 
     18from datetime import datetime, timedelta 
    1419 
    1520# Digest and signature/verify 
    1621from sha import sha 
     22 
    1723from M2Crypto import X509, BIO, RSA 
    18 import base64 
    19  
    20 import os 
    2124 
    2225import ZSI 
     
    2528from ConfigParser import RawConfigParser 
    2629 
    27 # Enable settings from a config file 
    28 from ndg.security.common.wssecurity import WSSecurityConfig, WSSecurityError 
    29  
    30 from ndg.security.common.X509 import X509Cert, X509CertParse, X509CertRead, \ 
    31 X509Stack, X509StackParseFromDER 
    32  
    33 from datetime import datetime, timedelta 
    34 import logging 
    35 log = logging.getLogger(__name__) 
     30from ndg.wssecurity.common import WSSecurityConfigError, WSSecurityError 
     31from ndg.wssecurity.utils.configfileparsers import CaseSensitiveConfigParser 
     32from ndg.wssecurity.utils.pki import (X509Cert, X509CertParse, X509CertRead,  
     33                                      X509Stack, X509StackParseFromDER) 
    3634 
    3735 
     
    4139    UTILITY = ("http://docs.oasis-open.org/wss/2004/01/" 
    4240               "oasis-200401-wss-wssecurity-utility-1.0.xsd") 
     41 
    4342 
    4443class OASIS(_OASIS): 
     
    5554    verify a signature is not from a known CA""" 
    5655     
     56     
    5757class VerifyError(WSSecurityError): 
    5858    """Raised from SignatureHandler.verify if an error occurs in the signature 
    5959    verification""" 
    6060  
     61  
    6162class TimestampError(WSSecurityError): 
    6263    """Raised from SignatureHandler._verifyTimestamp if there is a problem with 
    6364    the created or expiry times in an input message Timestamp""" 
     65 
    6466 
    6567class MessageExpired(TimestampError): 
     
    6870    order to set a wsu:MessageExpired fault code""" 
    6971     
     72     
    7073class InvalidSignature(WSSecurityError): 
    7174    """Raised from verify method for an invalid signature""" 
    7275 
     76 
    7377class SignatureError(WSSecurityError): 
    7478    """Flag if an error occurs during signature generation""" 
     79 
    7580 
    7681class NoSignatureFound(WSSecurityError): 
     
    8287    WS-Security 
    8388     
    84     @cvar BINARY_SECURITY_TOK_VAL_TYPE: supported ValueTypes for BinarySecurityToken 
     89    @cvar BINARY_SECURITY_TOK_VAL_TYPE: supported ValueTypes for  
     90    BinarySecurityToken 
    8591    element in WSSE header 
    8692    @type BINARY_SECURITY_TOK_VAL_TYPE: dict 
     
    109115    } 
    110116 
     117    # keyword used with ZSI.wstools.Utility.Canonicalization 
     118    ZSI_C14N_KEYWORD_NAME = 'inclusive_namespaces' 
     119     
     120    CFG_PARSER_CLASS = CaseSensitiveConfigParser 
    111121    PROPERTY_DEFAULTS = dict( 
    112         reqBINARY_SECURITY_TOK_VAL_TYPE=(OASIS.X509TOKEN.X509,), 
     122        reqBinarySecurityTokValType=(OASIS.X509TOKEN.X509,), 
    113123        verifyingCert=(None,), 
    114124        verifyingCertFilePath=(None,), 
     
    129139        refC14nInclNS=([],), 
    130140        signedInfoC14nInclNS=([],), 
    131         cfg=(None,)) 
     141        cfg=(CFG_PARSER_CLASS(),)) 
     142     
     143    LIST_STRING_PAT = re.compile(',\s*') 
     144    _parseListString = lambda opt, section: LIST_STRING_PAT.split( 
     145                                            CFG_PARSER_CLASS.get(opt, section)) 
     146    parseListString = classmethod(_parseListString) 
     147     
     148    CFG_PARSER_GET_FUNC_MAP = { 
     149        basestring: CFG_PARSER_CLASS.get, 
     150        bool: CFG_PARSER_CLASS.getboolean, 
     151        float: CFG_PARSER_CLASS.getfloat, 
     152        int: CFG_PARSER_CLASS.getint, 
     153        list: parseListString 
     154    } 
    132155     
    133156    TYPE_MAP = dict([(k, tuple([type(i) for i in v])) 
     
    135158    __slots__ = TYPE_MAP 
    136159     
    137     def __init__(self, cfg=None): 
     160    def __init__(self): 
    138161        ''' 
    139162        @param cfg: object from which to read config items - a file path, 
     
    144167        for name, val in BaseSignatureHandler.PROPERTY_DEFAULTS.items(): 
    145168            setattr(self, name, val[0]) 
    146  
     169             
     170        self.__reqBinarySecurityTokValType = None 
     171        self.__refC14nKw = None 
     172        self._signedInfoC14nKw = None 
     173         
    147174    def __setattr__(self, name, val): 
    148175        expectedTypes = BaseSignatureHandler.TYPE_MAP.get(name) 
     
    150177            if not isinstance(val, expectedTypes): 
    151178                raise TypeError('Expected type(s) for % attribute are %r; ' 
    152                                 'got %r' % (name, expectedTypes, type(val)) 
     179                                'got %r' % (name, expectedTypes, type(val))) 
    153180                                 
    154181        super(BaseSignatureHandler, self).__setattr__(name, val) 
     
    166193        # file 
    167194        defaultItems = dict(here=os.path.dirname(expandedFilePath)) 
    168         self._cfg = CaseSensitiveConfigParser(defaults=defaultItems) 
    169          
    170         readFilePaths = self._cfg.read(expandedFilePath) 
     195        self.cfg.defaults().update(defaults=defaultItems) 
     196         
     197        readFilePaths = self.cfg.read(expandedFilePath) 
    171198         
    172199        # Check file was read in OK 
     
    174201            raise IOError('Missing config file: "%s"' % expandedFilePath) 
    175202 
    176     def parse(self, **kw): 
    177         '''Extract items from config file and place in dict 
     203    def parse(self, sectionName='DEFAULT', prefix=None): 
     204        '''Extract items from config file and assign to instance attributes 
     205         
     206        @type prefix: None type or basestring 
     207        @param prefix: Prefix for option names - optNames = name as they appear  
     208        in the config file 
     209        ''' 
     210        if prefix: 
     211            optNames = ["%s.%s" % (prefix, optName)  
     212                        for optName in BaseSignatureHandler.PROPERTY_DEFAULTS]  
     213        else: 
     214            optNames = BaseSignatureHandler.PROPERTY_DEFAULTS.keys() 
     215             
     216        paramSettings = zip(optNames,  
     217                            BaseSignatureHandler.PROPERTY_DEFAULTS.keys(), 
     218                            BaseSignatureHandler.TYPE_MAP)  
     219            
     220        for optName, attrName, types in paramSettings: 
     221             
     222            # Parameters may be omitted and set later 
     223            if self.cfg.has_option(sectionName, optName): 
     224                getFunc = BaseSignatureHandler.CFG_PARSER_GET_FUNC_MAP.get( 
     225                                                                    types[0]) 
     226                if getFunc is None: 
     227                    raise WSSecurityConfigError("No Config parser get method " 
     228                        "configured for attribute %r with type %r" % 
     229                        (attrName, type[0])) 
     230                      
     231                val = getFunc(self.cfg, sectionName, optName) 
     232                setattr(self, attrName, val) 
     233                  
     234    def update(self, prefix=None, **kw): 
     235        '''Extract items from a dictionary and assign to instance attributes 
     236         
     237        @type prefix: None type or basestring 
     238        @param prefix: Prefix for option names - optNames = name as they appear  
     239        in the config file 
    178240        @type **kw: dict 
    179241        @param **kw: this enables WS-Security params to be set in a config file 
    180242        with other sections e.g. params could be under the section 'wssecurity' 
    181         ''' 
    182         section = kw.pop('section', 'DEFAULT') 
    183          
    184         # Prefix for option names - optNames = name as they appear in the  
    185         # config file, self._param are the names used in the code. 
    186         prefix = kw.pop('prefix', None) 
    187  
    188         if prefix: 
    189             optNames = ["%s.%s" % (prefix, optName) for optName in self._param]  
    190         else: 
    191             optNames = self._param 
    192              
    193         for optName, paramName in zip(optNames, self._param): 
    194              
     243        '''            
     244        for optName, val in kw.items(): 
    195245            # Parameters may be omitted and set later 
    196             if self._cfg.has_option(section, optName): 
    197                   
     246            if prefix: 
     247                optName = optName.replace(prefix, '', 1) 
     248                setattr(self, optName, val) 
     249                                   
    198250    def _setReqBinarySecurityTokValType(self, value): 
    199251        """Set ValueType attribute for BinarySecurityToken used in a request 
     
    201253        @type value: string 
    202254        @param value: name space for BinarySecurityToken ValueType check 
    203         'BINARY_SECURITY_TOK_VAL_TYPE' class variable for supported types.  Input can be  
    204         shortened to BINARY_SECURITY_TOK_VAL_TYPE keyword if desired. 
     255        'BINARY_SECURITY_TOK_VAL_TYPE' class variable for supported types.   
     256        Input can be shortened to BINARY_SECURITY_TOK_VAL_TYPE keyword if  
     257        desired. 
    205258        """ 
    206         log.debug("Setting reqBINARY_SECURITY_TOK_VAL_TYPE - to %s" %value) 
    207259        if value in self.__class__.BINARY_SECURITY_TOK_VAL_TYPE: 
    208             self.__reqBinarySecurityTokValType = self.__class__.BINARY_SECURITY_TOK_VAL_TYPE[value] 
     260            self.__reqBinarySecurityTokValType = \ 
     261                self.__class__.BINARY_SECURITY_TOK_VAL_TYPE[value] 
    209262  
    210263        elif value in self.__class__.BINARY_SECURITY_TOK_VAL_TYPE.values(): 
    211264            self.__reqBinarySecurityTokValType = value 
    212265        else: 
    213             raise WSSecurityError('Request BinarySecurityToken ValueType ' 
    214                                   '"%s" not recognised' % value) 
     266            raise TypeError('Request BinarySecurityToken ValueType %r not ' 
     267                            'recognised' % value) 
    215268             
    216269    def _getReqBinarySecurityTokValType(self): 
     
    218271        Get ValueType attribute for BinarySecurityToken used in a request 
    219272        """ 
    220         log.debug("Getting reqBINARY_SECURITY_TOK_VAL_TYPE value") 
    221         if hasattr(self, '__reqBinarySecurityTokValType'): 
    222             return self.__reqBinarySecurityTokValType 
    223         else: 
    224             return "" 
    225          
    226     reqBINARY_SECURITY_TOK_VAL_TYPE = property(fset=_setReqBinarySecurityTokValType, 
    227                                    fget=_getReqBinarySecurityTokValType, 
    228          doc="ValueType attribute for BinarySecurityToken used in request") 
    229          
    230  
    231     def __checkC14nKw(self, kw): 
     273        return self.__reqBinarySecurityTokValType 
     274         
     275    reqBinarySecurityTokValType = property(fset=_setReqBinarySecurityTokValType, 
     276                                           fget=_getReqBinarySecurityTokValType, 
     277                                           doc="ValueType attribute for " 
     278                                               "BinarySecurityToken used in " 
     279                                               "request") 
     280     
     281    @classmethod 
     282    def __checkC14nKw(cls, kw): 
    232283        """Check keywords for canonicalization in signing process - generic 
    233284        method for setting keywords for reference element and SignedInfo 
     
    239290        # Check for dict/None - Set to None in order to use inclusive  
    240291        # canonicalization 
    241         if kw is not None and not isinstance(kw, dict): 
     292        if not isinstance(kw, (dict, type(None))): 
    242293            # Otherwise keywords must be a dictionary 
    243             raise AttributeError("Expecting dictionary type for reference " 
    244                                  "C14N keywords") 
     294            raise TypeError("Expecting dictionary type for reference C14N " 
     295                            "keywords") 
    245296                 
    246         elif kw.get('inclusive_namespaces') and \ 
    247              not isinstance(kw['inclusive_namespaces'], (list, tuple)): 
    248             raise AttributeError('Expecting list or tuple of prefix names for ' 
    249                                  '"%s" keyword' % 'inclusive_namespaces') 
     297        elif not isinstance(kw.get(cls.ZSI_C14N_KEYWORD_NAME), (list, tuple)): 
     298            raise TypeError('Expecting list or tuple of prefix names for ' 
     299                            '"%s" keyword' % cls.ZSI_C14N_KEYWORD_NAME) 
    250300         
    251301                 
     
    254304        signing process""" 
    255305        self.__checkC14nKw(kw)                     
    256         self._refC14nKw = kw 
     306        self.__refC14nKw = kw 
    257307         
    258308    def _getRefC14nKw(self): 
    259         if hasattr(self, '_refC14nKw'): 
    260             return self._refC14nKw 
    261         else: 
    262             return {} 
     309        return self.__refC14nKw 
    263310         
    264311    refC14nKw = property(fset=_setRefC14nKw, 
     
    266313                         doc="Keywords for C14N of reference elements") 
    267314         
    268                  
    269315    def _setSignedInfoC14nKw(self, kw): 
    270316        """Set keywords for canonicalization of SignedInfo element in the  
    271317        signing process""" 
    272318        self.__checkC14nKw(kw)                     
    273         self._signedInfoC14nKw = kw 
     319        self.__signedInfoC14nKw = kw 
    274320         
    275321    def _getSignedInfoC14nKw(self): 
    276322        if hasattr(self, '_signedInfoC14nKw'): 
    277             return self._signedInfoC14nKw 
     323            return self.__signedInfoC14nKw 
    278324        else: 
    279325            return {} 
  • TI12-security/trunk/WSSecurity/ndg/wssecurity/common/utils/__init__.py

    r6388 r6391  
     1"""WS-Security utilities package 
     2 
     3NERC DataGrid Project 
     4""" 
     5__author__ = "Philip Kershaw" 
     6__date__ = "25/01/2010" 
     7__copyright__ = "(C) 2010 Science and Technology Facilities Council" 
     8__license__ = "BSD - see LICENSE file in top-level directory" 
     9__contact__ = "Philip.Kershaw@stfc.ac.uk" 
     10__revision__ = '$Id: $' 
Note: See TracChangeset for help on using the changeset viewer.