Changeset 4624


Ignore:
Timestamp:
12/12/08 16:13:31 (11 years ago)
Author:
pjkersha
Message:

#941: refactored to use ini file instead of XML for config.

Location:
TI12-security/trunk/python/MyProxyClient
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/python/MyProxyClient/myproxy.py

    r4615 r4624  
    11"""MyProxy Client interface 
    22 
    3 NERC Data Grid Project 
     3Developed for the NERC DataGrid Project: http://ndg.nerc.ac.uk/ 
    44 
    55Major re-write of an original class.   This updated version implements methods 
     
    2323certain rights.""" 
    2424__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    25 __revision__ = '$Id: MyProxy.py 3196 2008-01-10 14:45:59Z pjkersha $' 
    26  
     25__revision__ = '$Id$' 
     26import logging 
     27log = logging.getLogger(__name__) 
    2728import sys, os 
    2829import socket 
     
    3839    import cElementTree as ElementTree 
    3940 
    40 from ndg.security.common.openssl import OpenSSLConfig, OpenSSLConfigError 
    41  
    42 class MyProxyClientError(Exception): 
    43     """Catch all exception class""" 
    44      
    45 class GetError(Exception): 
    46     """Exceptions arising from get request to server""" 
    47      
    48 class RetrieveError(Exception): 
    49     """Error recovering a response from MyProxy""" 
     41from openssl import OpenSSLConfig, OpenSSLConfigError 
     42 
     43from ConfigParser import SafeConfigParser 
     44 
     45class CaseSensitiveConfigParser(SafeConfigParser): 
     46    '''Subclass the SafeConfigParser - to preserve the original string case of  
     47    config section names 
     48    '''    
     49    def optionxform(self, optionstr): 
     50        '''Extend SafeConfigParser.optionxform to preserve case of option names 
     51        ''' 
     52        return optionstr 
     53 
    5054 
    5155class _HostCheck(SSL.Checker.Checker): 
     
    96100            # Try match against DN set from MYPROXY_SERVER_DN / config 
    97101            # file setting 
    98             peerCertDN = '/' + \ 
    99                     peerCert.get_subject().as_text().replace(', ', '/') 
     102            peerCertDN = '/'+peerCert.get_subject().as_text().replace(', ','/') 
     103             
     104            # If they match drop the exception and return all OK instead 
    100105            if peerCertDN != self.myProxyServerDN: 
    101                 # They match - drop the exception and return all OK instead 
    102                 raise e 
     106                raise 
    103107             
    104108        return True 
     109     
     110     
     111class MyProxyClientError(Exception): 
     112    """Base exception class for MyProxyClient exceptions""" 
     113 
     114class MyProxyClientConfigError(MyProxyClientError): 
     115    """Error with configuration""" 
     116      
     117class MyProxyClientGetError(MyProxyClientError): 
     118    """Exceptions arising from get request to server""" 
     119     
     120class MyProxyClientRetrieveError(MyProxyClientError): 
     121    """Error recovering a response from MyProxy""" 
    105122             
    106123         
     
    112129    http://grid.ncsa.uiuc.edu/myproxy/protocol/ 
    113130     
    114     @type __getCmd: string 
    115     @cvar __getCmd: get command string 
    116      
    117     @type __infoCmd: string 
    118     @cvar __infoCmd: info command string 
    119      
    120     @type __destroyCmd: string 
    121     @cvar __destroyCmd: destroy command string 
    122      
    123     @type __changePassphrase: string 
    124     @cvar __changePassphrase: command string to change cred pass-phrase 
    125      
    126     @type __storeCmd: string 
    127     @cvar __storeCmd: store command string 
     131    @type getCmd: string 
     132    @cvar getCmd: get command string 
     133     
     134    @type infoCmd: string 
     135    @cvar infoCmd: info command string 
     136     
     137    @type destroyCmd: string 
     138    @cvar destroyCmd: destroy command string 
     139     
     140    @type changePassphraseCmd: string 
     141    @cvar changePassphraseCmd: command string to change cred pass-phrase 
     142     
     143    @type storeCmd: string 
     144    @cvar storeCmd: store command string 
    128145     
    129146    @type _hostCertSubDirPath: string 
     
    133150    @cvar _hostKeySubDirPath: sub-directory path to host key (as tuple) 
    134151     
    135     @type __validKeys: tuple 
    136     @cvar __validKeys: sets permissable element names for MyProxy XML config 
     152    @type propertyDefaults: tuple 
     153    @cvar propertyDefaults: sets permissable element names for MyProxy config  
    137154    file 
    138155    """ 
    139156       
    140     __getCmd="""VERSION=MYPROXYv2 
     157    getCmd="""VERSION=MYPROXYv2 
    141158COMMAND=0 
    142159USERNAME=%s 
     
    144161LIFETIME=%d""" 
    145162  
    146     __infoCmd="""VERSION=MYPROXYv2 
     163    infoCmd="""VERSION=MYPROXYv2 
    147164COMMAND=2 
    148165USERNAME=%s 
     
    150167LIFETIME=0""" 
    151168  
    152     __destroyCmd="""VERSION=MYPROXYv2 
     169    destroyCmd="""VERSION=MYPROXYv2 
    153170COMMAND=3 
    154171USERNAME=%s 
     
    156173LIFETIME=0""" 
    157174 
    158     __changePassphraseCmd="""VERSION=MYPROXYv2 
     175    changePassphraseCmd="""VERSION=MYPROXYv2 
    159176 COMMAND=4 
    160177 USERNAME=%s 
     
    163180 LIFETIME=0""" 
    164181    
    165     __storeCmd="""VERSION=MYPROXYv2 
     182    storeCmd="""VERSION=MYPROXYv2 
    166183COMMAND=5 
    167184USERNAME=%s 
     
    173190     
    174191    # valid configuration property keywords 
    175     __validKeys = ('hostname', 
    176                    'port', 
    177                    'serverDN', 
    178                    'serverCNprefix', 
    179                    'gridSecurityDir', 
    180                    'openSSLConfFilePath', 
    181                    'tmpDir', 
    182                    'proxyCertMaxLifetime', 
    183                    'proxyCertLifetime', 
    184                    'caCertFile') 
     192    propertyDefaults = { 
     193       'hostname':              'localhost', 
     194       'port':                  7512, 
     195       'serverDN':              '', 
     196       'serverCNPrefix':        'host/', 
     197       'openSSLConfFilePath':   '', 
     198       'proxyCertMaxLifetime':  43200, 
     199       'proxyCertLifetime':     43200, 
     200       'caCertFilePathList':    [] 
     201    } 
    185202 
    186203    # Work out default location of proxy file if it exists.  This is set if a 
     
    191208 
    192209    @classmethod 
    193     def writeProxyFile(cls, proxyCert, proxyPriKey, userX509Cert, filePath=None): 
     210    def writeProxyFile(cls,proxyCert,proxyPriKey,userX509Cert,filePath=None): 
    194211        """Write out proxy cert to file in the same way as myproxy-logon -  
    195212        proxy cert, private key, user cert.  Nb. output from logon can be 
     
    209226             
    210227        if filePath is None: 
    211             MyProxyClientError, \ 
    212                 "Error setting proxy file path - invalid platform?" 
     228            MyProxyClientConfigError("Error setting proxy file path - invalid " 
     229                                     "platform?") 
    213230         
    214231        outStr = proxyCert + proxyPriKey + userX509Cert        
    215232        open(MyProxyClient.defProxyFile, 'w').write(outStr) 
    216233        try: 
    217             # Make sure permssions are set correctly 
     234            # Make sure permissions are set correctly 
    218235            os.chmod(MyProxyClient.defProxyFile, 0600) 
    219         except Exception: 
     236        except Exception, e: 
    220237            # Don't leave the file lying around if couldn't change it's 
    221238            # permissions 
    222239            os.unlink(MyProxyClient.defProxyFile) 
    223240             
    224             raise MyProxyClientError, \ 
    225                 'Unable to set 0600 permissions for proxy file "%s": %s' % \ 
    226                 (MyProxyClient.defProxyFile, e) 
     241            log.error('Unable to set 0600 permissions for proxy file "%s": %s'%  
     242                      (MyProxyClient.defProxyFile, e)) 
     243            raise 
    227244 
    228245    @classmethod 
     
    235252        if filePath is None: 
    236253            filePath = MyProxyClient.defProxyFile 
     254             
     255        if filePath is None: 
     256            MyProxyClientConfigError("Error setting proxy file path - invalid " 
     257                                     "platform?") 
    237258                
    238259        proxy = open(MyProxyClient.defProxyFile).read() 
     
    242263         
    243264         
    244     def __init__(self, propFilePath=None, **prop): 
     265    def __init__(self, cfgFilePath=None, **prop): 
    245266        """Make any initial settings for client connections to MyProxy 
    246267         
    247268        Settings are held in a dictionary which can be set from **prop, 
    248269        a call to setProperties() or by passing settings in an XML file 
    249         given by propFilePath 
    250          
    251         @param propFilePath:   set properties via a configuration file 
    252         @param **prop:         set properties via keywords - see __validKeys 
    253         class variable for a list of these 
    254         """ 
    255          
    256         # Check for parameter names set from input 
    257         #self.certReqDNparam = None 
    258  
    259         # settings dictionary 
    260         self.__prop = {} 
    261          
    262         # Server host name - take from environment variable if available 
    263         if 'MYPROXY_SERVER' in os.environ: 
    264             self.__prop['hostname'] = os.environ['MYPROXY_SERVER'] 
    265              
    266         # ... and port number 
    267         if 'MYPROXY_SERVER_PORT' in os.environ: 
    268             self.__prop['port'] = int(os.environ['MYPROXY_SERVER_PORT']) 
    269         else: 
    270             # Usual default is ... 
    271             self.__prop['port'] = 7512 
    272              
    273         self.__prop['proxyCertLifetime'] = 43200 
    274         self.__prop['proxyCertMaxLifetime'] = 43200 
     270        given by cfgFilePath 
     271         
     272        @param cfgFilePath:   set properties via a configuration file 
     273        @param **prop:         set properties via keywords - see  
     274        propertyDefaults class variable for a list of these 
     275        """ 
    275276        
    276277        # Configuration file used to get default subject when generating a 
    277278        # new proxy certificate request 
    278         self.__openSSLConf = OpenSSLConfig() 
    279  
    280         # Properties set via input keywords 
    281         self.setProperties(**prop) 
    282  
     279        self._openSSLConfig = OpenSSLConfig() 
     280         
     281        # Default settings.  Nb. '_' - override property methods in order to  
     282        # set defaults 
     283        for opt, val in MyProxyClient.propertyDefaults.items(): 
     284            setattr(self, '_'+opt, val) 
     285         
     286        # Server host name - take from environment variable if available 
     287        if 'MYPROXY_SERVER' in os.environ: 
     288            self.hostname = os.environ['MYPROXY_SERVER'] 
     289             
     290        # ... and port number 
     291        if 'MYPROXY_SERVER_PORT' in os.environ: 
     292            self.port = int(os.environ['MYPROXY_SERVER_PORT']) 
     293 
     294        # keyword settings 
     295        for opt, val in prop.items(): 
     296            setattr(self, opt, val) 
     297         
    283298        # If properties file is set any parameters settings in file will 
    284299        # override those set by input keyword 
    285         if propFilePath is not None: 
    286             self.readProperties(propFilePath) 
    287  
    288  
    289     #_________________________________________________________________________ 
    290     def setProperties(self, **prop): 
    291         """Update existing properties from an input dictionary 
    292         Check input keys are valid names""" 
    293          
    294         invalidKeys = [key for key in prop if key not in self.__validKeys] 
    295         if invalidKeys: 
    296             raise MyProxyClientError, 'Invalid property name(s) set: "%s"' % \ 
    297                                     '", "'.join(invalidKeys) 
    298                  
    299         self.__prop.update(prop) 
    300  
    301         # Update openssl conf file path 
    302         # 
    303         # Check 'prop' to see if they've been in THIS update 
    304         # Check 'self.__prop' to ensure both are present in 
    305         # order to construct a file path 
    306         if 'openSSLConfFilePath' in prop:             
    307             self.__openSSLConf.filePath = self.__prop['openSSLConfFilePath'] 
    308             self.__openSSLConf.read() 
    309              
    310  
    311     #_________________________________________________________________________ 
    312     def readProperties(self, propFilePath=None, propElem=None): 
    313         """Read XML properties from a file or cElementTree node 
    314          
    315         propFilePath|propertiesElem 
    316  
    317         @type propFilePath: string 
    318         @param propFilePath: set to read from the specified file 
    319          
    320         @type propElem: ElementTree node 
    321         @param propElem: set to read beginning from a cElementTree node 
    322         """ 
    323  
    324         if propFilePath is not None: 
    325             try: 
    326                 tree = ElementTree.parse(propFilePath) 
    327                 propElem = tree.getroot() 
    328                  
    329             except IOError, e: 
    330                 raise MyProxyClientError, \ 
    331                                 "Error parsing properties file \"%s\": %s" % \ 
    332                                 (e.filename, e.strerror)            
    333             except Exception, e: 
    334                 raise MyProxyClientError, \ 
    335                                 "Error parsing properties file: %s" % str(e) 
    336                                  
    337         if propElem is None: 
    338             raise MyProxyClientError, \ 
    339                     "Root element for parsing properties file is not defined" 
    340  
    341  
    342         # Get properties as a data dictionary 
    343         prop = {} 
    344         try: 
    345             for elem in propElem: 
    346                 # Check for string type to avoid exceptions from isdigit and 
    347                 # expandvars 
    348                 if isinstance(elem.text, basestring): 
    349                     if elem.text.isdigit(): 
    350                         prop[elem.tag] = int(elem.text) 
    351                     else: 
    352                         prop[elem.tag] = os.path.expandvars(elem.text) 
    353                 else: 
    354                     prop[elem.tag] = elem.text 
    355                      
    356         except Exception, e: 
    357             raise SessionManagerError, \ 
    358                 "Error parsing tag \"%s\" in properties file" % elem.tag 
    359          
    360         self.setProperties(**prop) 
    361  
    362  
    363     #_________________________________________________________________________ 
    364     def __getOpenSSLConfig(self): 
     300        if cfgFilePath is not None: 
     301            self.parseConfig(cfg=cfgFilePath) 
     302 
     303 
     304    def parseConfig(self, cfg, section='DEFAULT'): 
     305        '''Extract parameters from _cfg config object''' 
     306         
     307        if isinstance(cfg, basestring): 
     308            cfgFilePath = os.path.expandvars(cfg) 
     309            self._cfg = CaseSensitiveConfigParser() 
     310            self._cfg.read(cfgFilePath) 
     311        else: 
     312            cfgFilePath = None 
     313            self._cfg = cfg 
     314         
     315        for key, val in self._cfg.items(section): 
     316            setattr(self, key, val) 
     317         
     318    # Get/Set Property methods 
     319    def _getHostname(self): 
     320        return self._hostname 
     321     
     322    def _setHostname(self, val): 
     323        if not isinstance(val, basestring): 
     324            raise AttributeError("Expecting string type for hostname " 
     325                                 "attribute") 
     326        self._hostname = val 
     327         
     328    hostname = property(fget=_getHostname, 
     329                        fset=_setHostname, 
     330                        doc="hostname of MyProxy server") 
     331     
     332    def _getPort(self): 
     333        return self._port 
     334     
     335    def _setPort(self, val): 
     336        if isinstance(val, basestring): 
     337            self._port = int(val) 
     338        elif isinstance(val, int): 
     339            self._port = val 
     340        else: 
     341            raise AttributeError("Expecting int type for port attribute") 
     342     
     343    port = property(fget=_getPort, 
     344                    fset=_setPort, 
     345                    doc="Port number for MyProxy server") 
     346     
     347    def _getServerDN(self): 
     348        return self._serverDN 
     349     
     350    def _setServerDN(self, val): 
     351        if not isinstance(val, basestring): 
     352            raise AttributeError("Expecting string type for serverDN " 
     353                                 "attribute") 
     354        self._serverDN = val 
     355     
     356    serverDN = property(fget=_getServerDN, 
     357                        fset=_setServerDN, 
     358                        doc="Distinguished Name for MyProxy Server " 
     359                            "Certificate") 
     360     
     361    def _getServerCNPrefix(self): 
     362        return self._serverCNPrefix 
     363     
     364    def _setServerCNPrefix(self, val): 
     365        if not isinstance(val, basestring): 
     366            raise AttributeError("Expecting string type for serverCNPrefix " 
     367                                 "attribute") 
     368        self._serverCNPrefix = val 
     369     
     370    serverCNPrefix = property(fget=_getServerCNPrefix, 
     371                              fset=_setServerCNPrefix, 
     372                              doc="Prefix if any for Server Certificate DN " 
     373                                  "Common Name e.g. 'host/'") 
     374     
     375    def _getOpenSSLConfFilePath(self): 
     376        return self._openSSLConfFilePath 
     377     
     378    def _setOpenSSLConfFilePath(self, val): 
     379        if not isinstance(val, basestring): 
     380            raise AttributeError("Expecting string type for " 
     381                                 "openSSLConfFilePath attribute") 
     382        self._openSSLConfFilePath = os.path.expandvars(val) 
     383        self._openSSLConfig.filePath = self._openSSLConfFilePath 
     384        self._openSSLConfig.read()   
     385     
     386    openSSLConfFilePath = property(fget=_getOpenSSLConfFilePath, 
     387                                   fset=_setOpenSSLConfFilePath, 
     388                                   doc="file path for OpenSSL config file") 
     389     
     390    def _getProxyCertMaxLifetime(self): 
     391        return self._proxyCertMaxLifetime 
     392     
     393    def _setProxyCertMaxLifetime(self, val): 
     394        if isinstance(val, basestring): 
     395            self._proxyCertMaxLifetime = int(val) 
     396             
     397        elif isinstance(val, int): 
     398            self._proxyCertMaxLifetime = val 
     399        else: 
     400            raise AttributeError("Expecting int type for proxyCertMaxLifetime " 
     401                                 "attribute") 
     402     
     403    proxyCertMaxLifetime = property(fget=_getProxyCertMaxLifetime, 
     404                                    fset=_setProxyCertMaxLifetime, 
     405                                    doc="Default max. lifetime allowed for " 
     406                                        "Proxy Certificate retrieved - used " 
     407                                        "by store method") 
     408     
     409    def _getProxyCertLifetime(self): 
     410        return self._proxyCertLifetime 
     411     
     412    def _setProxyCertLifetime(self, val): 
     413        if isinstance(val, basestring): 
     414            self._proxyCertLifetime = int(val) 
     415        elif isinstance(val, int): 
     416            self._proxyCertLifetime = val 
     417        else: 
     418            raise AttributeError("Expecting int type for proxyCertLifetime " 
     419                                 "attribute") 
     420     
     421    proxyCertLifetime = property(fget=_getProxyCertLifetime, 
     422                                 fset=_setProxyCertLifetime, 
     423                                 doc="Default proxy cert. lifetime used in " 
     424                                     "logon request") 
     425     
     426    def _getCACertFilePath(self): 
     427        return self._caCertFilePath 
     428     
     429    def _setCACertFilePath(self, val): 
     430        '''@type val: basestring 
     431        @param val: file path for CA certificate to be used to verify  
     432        MyProxy server certificate''' 
     433         
     434        if not isinstance(val, basestring): 
     435            raise AttributeError("Expecting string type for caCertFilePath " 
     436                                 "attribute") 
     437             
     438        self._caCertFilePath = os.path.expandvars(val) 
     439         
     440    caCertFilePath = property(fget=_getCACertFilePath, 
     441                              fset=_setCACertFilePath, 
     442                              doc="CA certificate file path - MyProxy server " 
     443                                  "certificate must validate against it and/" 
     444                                  "or any present in caCertDir") 
     445 
     446    def _getCACertDir(self): 
     447        return self._caCertDir 
     448 
     449    def _setCACertDir(self, val): 
     450        '''Specify a directory containing PEM encoded CA certs. used for  
     451        validation of MyProxy server certificate. 
     452         
     453        @type val: basestring 
     454        @param val: directory path''' 
     455         
     456        if not isinstance(val, basestring): 
     457            raise AttributeError("Expecting string type for caCertDir " 
     458                                 "attribute") 
     459             
     460        self._caCertDir = os.path.expandvars(val) 
     461         
     462    caCertFileDir = property(fget=_getCACertDir, 
     463                             fset=_setCACertDir, 
     464                             doc="directory containing PEM encoded CA " 
     465                                 "certs. used along with caCertFilePath " 
     466                                 "setting to validate MyProxy server " 
     467                                 "certificate") 
     468 
     469 
     470    def _getOpenSSLConfig(self): 
    365471        "Get OpenSSLConfig object property method" 
    366         return self.__openSSLConfig 
    367      
    368     openSSLConfig = property(fget=__getOpenSSLConfig, 
     472        return self._openSSLConfig 
     473     
     474    openSSLConfig = property(fget=_getOpenSSLConfig, 
    369475                             doc="OpenSSLConfig object") 
    370476 
    371              
    372     #_________________________________________________________________________         
     477           
    373478    def _initConnection(self,  
    374479                        ownerCertFile=None,  
     
    378483        server side identity checks 
    379484         
     485        @type ownerCertFile: basestring 
    380486        @param ownerCertFile: client certificate and owner of credential 
    381487        to be acted on.  Can be a proxy cert + proxy's signing cert.  Cert 
    382488        and private key are not necessary for getDelegation / logon calls 
     489        @type ownerKeyFile: basestring 
    383490        @param ownerKeyFile: client private key file 
     491        @type ownerPassphrase: basestring 
    384492        @param ownerPassphrase: pass-phrase protecting private key if set -  
    385493        not needed in the case of a proxy private key 
     
    389497        context = SSL.Context(protocol='sslv3') 
    390498 
    391         if 'caCertFile' in self.__prop: 
    392             context.load_verify_locations(cafile=self.__prop['caCertFile']) 
     499        if self.caCertFilePath or self.caCertDir: 
     500            context.load_verify_locations(cafile=self.caCertFilePath, 
     501                                          capath=self.caCertDir) 
    393502                             
    394503            # Stop if peer's certificate can't be verified 
     
    400509            try: 
    401510                context.load_cert_chain(ownerCertFile, 
    402                                 keyfile=ownerKeyFile, 
    403                                 callback=lambda *ar, **kw: ownerPassphrase) 
     511                                    keyfile=ownerKeyFile, 
     512                                    callback=lambda *ar, **kw: ownerPassphrase) 
    404513            except Exception, e: 
    405                 raise MyProxyClientError, \ 
    406             "Error loading CA cert., cert. and key for SSL connection: %s" % e  
     514                raise MyProxyClientError("Error loading CA cert., cert. and " 
     515                                         "key for SSL connection: %s" % e)  
    407516             
    408517            # Verify peer's certificate 
     
    421530        # 'serverDN'  
    422531        # host/<hostname> one 
    423         hostCheck = _HostCheck(host=self.__prop['hostname'], 
    424                                myProxyServerDN=self.__prop.get('serverDN'), 
    425                                cnHostPfx=self.__prop.get('serverCNprefix')) 
     532        hostCheck = _HostCheck(host=self.hostname, 
     533                               myProxyServerDN=self.serverDN, 
     534                               cnHostPfx=self.serverCNPrefix) 
    426535        conn.set_post_connection_check_callback(hostCheck) 
    427536         
     
    429538     
    430539             
    431     #_________________________________________________________________________         
    432540    def _createCertReq(self, CN, nBitsForKey=1024, messageDigest="md5"): 
    433541        """ 
    434542        Create a certificate request. 
    435543         
     544        @type CN: basestring 
    436545        @param CN: Common Name for certificate - effectively the same as the 
    437546        username for the MyProxy credential 
     547        @type nBitsForKey: int 
    438548        @param nBitsForKey: number of bits for private key generation -  
    439549        default is 1024 
    440         @param messageDigest: message disgest type - default is MD5 
    441         @return tuple of certificate request PEM text and private key PEM text 
     550        @type messageDigest: basestring 
     551        @param messageDigest: message digest type - default is MD5 
     552        @rtype: tuple 
     553        @return certificate request PEM text and private key PEM text 
    442554        """ 
    443555         
     
    457569        req.set_pubkey(pubKey) 
    458570         
    459         defaultReqDN = self.__openSSLConf.reqDN 
     571        defaultReqDN = self._openSSLConfig.reqDN 
    460572              
    461573        # Set DN 
     
    474586     
    475587     
    476     #_________________________________________________________________________            
    477588    def _deserializeResponse(self, msg, *fieldNames): 
    478589        """ 
     
    522633     
    523634   
    524     #_________________________________________________________________________              
    525635    def _deserializeCerts(self, inputDat): 
    526636        """Unpack certificates returned from a get delegation call to the 
     
    556666 
    557667 
    558     #_________________________________________________________________________    
    559668    def info(self, 
    560669             username,  
     
    565674        given username 
    566675         
    567         Exceptions:  GetError, RetrieveError 
     676        @raise MyProxyClientGetError: 
     677        @raise MyProxyClientRetrieveError: 
    568678         
    569679        @type username: string 
     
    586696            if globusLoc: 
    587697                ownerCertFile = os.path.join(globusLoc,  
    588                                          *MyProxyClient._hostCertSubDirPath) 
     698                                            *MyProxyClient._hostCertSubDirPath) 
    589699                ownerKeyFile = os.path.join(globusLoc,  
    590                                          *MyProxyClient._hostKeySubDirPath) 
     700                                            *MyProxyClient._hostKeySubDirPath) 
    591701            else: 
    592                 raise MyProxyClientError, \ 
    593             "No client authentication cert. and private key file were given" 
     702                raise MyProxyClientError( 
     703            "No client authentication cert. and private key file were given") 
    594704 
    595705        # Set-up SSL connection 
     
    598708                                    ownerPassphrase=ownerPassphrase) 
    599709         
    600         conn.connect((self.__prop['hostname'], self.__prop['port'])) 
     710        conn.connect((self.hostname, self.port)) 
    601711         
    602712        # send globus compatibility stuff 
     
    604714     
    605715        # send info command - ensure conversion from unicode before writing 
    606         cmd = MyProxyClient.__infoCmd % username 
     716        cmd = MyProxyClient.infoCmd % username 
    607717        conn.write(str(cmd)) 
    608718     
     
    612722        # Pass in the names of fields to return in the dictionary 'field'  
    613723        respCode, errorTxt, field = self._deserializeResponse(dat,  
    614                                                          'CRED_START_TIME',  
    615                                                          'CRED_END_TIME',  
    616                                                          'CRED_OWNER') 
     724                                                             'CRED_START_TIME',  
     725                                                             'CRED_END_TIME',  
     726                                                             'CRED_OWNER') 
    617727 
    618728        return not bool(respCode), errorTxt, field 
    619729 
    620730 
    621     #_________________________________________________________________________    
    622731    def changePassphrase(self, 
    623732                         username,  
     
    629738        """change pass-phrase protecting the credentials for a given username 
    630739         
    631         Exceptions:  GetError, RetrieveError 
     740        @raise MyProxyClientGetError: 
     741        @raise MyProxyClientRetrieveError: 
    632742         
    633743        @param username: username of credential 
     
    653763                                         *MyProxyClient._hostKeySubDirPath) 
    654764            else: 
    655                 raise MyProxyClientError, \ 
    656             "No client authentication cert. and private key file were given" 
     765                raise MyProxyClientError( 
     766            "No client authentication cert. and private key file were given") 
    657767         
    658768        # Set-up SSL connection 
     
    661771                                    ownerPassphrase=ownerPassphrase) 
    662772 
    663         conn.connect((self.__prop['hostname'], self.__prop['port'])) 
     773        conn.connect((self.hostname, self.port)) 
    664774         
    665775        # send globus compatibility stuff 
     
    667777     
    668778        # send command - ensure conversion from unicode before writing 
    669         cmd = MyProxyClient.__changePassphraseCmd % (username,  
    670                                                      passphrase, 
    671                                                      newPassphrase) 
     779        cmd = MyProxyClient.changePassphraseCmd % (username,  
     780                                                   passphrase, 
     781                                                   newPassphrase) 
    672782        conn.write(str(cmd)) 
    673783     
     
    677787        respCode, errorTxt = self._deserializeResponse(dat) 
    678788        if respCode: 
    679             raise GetError, errorTxt 
    680  
    681  
    682     #_________________________________________________________________________    
     789            raise MyProxyClientGetError(errorTxt) 
     790 
     791 
    683792    def destroy(self, 
    684793                username,  
     
    688797        """destroy credentials from the server for a given username 
    689798         
    690         Exceptions:  GetError, RetrieveError 
     799        @raise MyProxyClientGetError: 
     800        @raise MyProxyClientRetrieveError: 
    691801         
    692802        @param username: username selected for credential 
     
    710820                                         *MyProxyClient._hostKeySubDirPath) 
    711821            else: 
    712                 raise MyProxyClientError, \ 
    713             "No client authentication cert. and private key file were given" 
     822                raise MyProxyClientError( 
     823            "No client authentication cert. and private key file were given") 
    714824         
    715825        # Set-up SSL connection 
     
    718828                                    ownerPassphrase=ownerPassphrase) 
    719829 
    720         conn.connect((self.__prop['hostname'], self.__prop['port'])) 
     830        conn.connect((self.hostname, self.port)) 
    721831         
    722832        # send globus compatibility stuff 
     
    724834     
    725835        # send destroy command - ensure conversion from unicode before writing 
    726         cmd = MyProxyClient.__destroyCmd % username 
     836        cmd = MyProxyClient.destroyCmd % username 
    727837        conn.write(str(cmd)) 
    728838     
     
    732842        respCode, errorTxt = self._deserializeResponse(dat) 
    733843        if respCode: 
    734             raise GetError, errorTxt 
    735  
    736  
    737     #_________________________________________________________________________    
     844            raise MyProxyClientGetError(errorTxt) 
     845 
     846 
    738847    def store(self, 
    739848              username, 
     
    748857        """Upload credentials to the server 
    749858         
    750         @raise GetError: 
    751         @raise RetrieveError: 
     859        @raise MyProxyClientGetError: 
     860        @raise MyProxyClientRetrieveError: 
    752861         
    753862        @type username: string 
     
    781890        """ 
    782891         
    783         lifetime = lifetime or self.__prop['proxyCertMaxLifetime'] 
     892        lifetime = lifetime or self.proxyCertMaxLifetime 
    784893 
    785894        # Inputs must be string type otherwise server will reject the request 
     
    810919                         ownerKeyFile=ownerKeyFile, 
    811920                         ownerPassphrase=ownerPassphrase)[0]: 
    812                 raise MyProxyClientError, \ 
    813                         "Credentials already exist for user: %s" % username 
     921                raise MyProxyClientError( 
     922                        "Credentials already exist for user: %s" % username) 
    814923 
    815924        # Set up SSL connection 
     
    818927                                    ownerPassphrase=ownerPassphrase) 
    819928         
    820         conn.connect((self.__prop['hostname'], self.__prop['port'])) 
     929        conn.connect((self.hostname, self.port)) 
    821930         
    822931        # send globus compatibility stuff 
     
    824933     
    825934        # send store command - ensure conversion from unicode before writing 
    826         cmd = MyProxyClient.__storeCmd % (username, lifetime) 
     935        cmd = MyProxyClient.storeCmd % (username, lifetime) 
    827936        conn.write(str(cmd)) 
    828937     
     
    832941        respCode, errorTxt = self._deserializeResponse(dat) 
    833942        if respCode: 
    834             raise GetError, errorTxt 
     943            raise MyProxyClientGetError(errorTxt) 
    835944         
    836945        # Send certificate and private key 
     
    845954        respCode, errorTxt = self._deserializeResponse(resp) 
    846955        if respCode: 
    847             raise RetrieveError, errorTxt 
    848          
    849          
    850     #_________________________________________________________________________            
     956            raise MyProxyClientRetrieveError(errorTxt) 
     957         
     958          
    851959    def logon(self, username, passphrase, lifetime=None): 
    852960        """Retrieve a proxy credential from a MyProxy server 
    853961         
    854         Exceptions:  GetError, RetrieveError 
     962        Exceptions:  MyProxyClientGetError, MyProxyClientRetrieveError 
    855963         
    856964        @type username: basestring 
     
    870978        """ 
    871979         
    872         lifetime = lifetime or self.__prop['proxyCertLifetime'] 
     980        lifetime = lifetime or self.proxyCertLifetime 
    873981 
    874982        # Generate certificate request here - any errors will be thrown 
     
    881989        # Set-up SSL connection 
    882990        conn = self._initConnection() 
    883         conn.connect((self.__prop['hostname'], self.__prop['port'])) 
     991        conn.connect((self.hostname, self.port)) 
    884992         
    885993        # send globus compatibility stuff 
     
    887995     
    888996        # send get command - ensure conversion from unicode before writing 
    889         cmd = MyProxyClient.__getCmd % (username, passphrase, lifetime) 
     997        cmd = MyProxyClient.getCmd % (username, passphrase, lifetime) 
    890998        conn.write(str(cmd)) 
    891999     
     
    8941002        respCode, errorTxt = self._deserializeResponse(dat) 
    8951003        if respCode: 
    896             raise GetError, errorTxt 
     1004            raise MyProxyClientGetError(errorTxt) 
    8971005         
    8981006        # Send certificate request 
     
    9111019        respCode, errorTxt = self._deserializeResponse(resp) 
    9121020        if respCode: 
    913             raise RetrieveError, errorTxt 
     1021            raise MyProxyClientRetrieveError(errorTxt) 
    9141022     
    9151023        # deserialize certs from received cert data 
    9161024        pemCerts = self._deserializeCerts(dat) 
    9171025        if len(pemCerts) != nCerts: 
    918             RetrieveError, "%d certs expected, %d received" % \ 
    919                                                     (nCerts, len(pemCerts)) 
     1026            MyProxyClientRetrieveError("%d certs expected, %d received" %  
     1027                                                    (nCerts, len(pemCerts))) 
    9201028     
    9211029        # Return certs and private key 
     
    9321040        """Retrieve proxy cert for user - same as logon""" 
    9331041        return self.logon(*arg, **kw) 
    934  
    935  
    936 #_____________________________________________________________________________    
    937 def main(): 
    938     import traceback 
    939     import pdb;pdb.set_trace() 
    940     try: 
    941         CmdLineClient()             
    942     except Exception, e: 
    943         print "Error: ", e 
    944         print traceback.print_exc() 
    945         sys.exit(1) 
    946  
    947 #  help="check whether a credential exists") 
    948 # 
    949 #  help="destroy credential") 
    950 # 
    951 #  help="change pass-phrase protecting credential") 
    952  
    953 import optparse 
    954 import getpass 
    955  
    956 class CmdLineClientError(Exception): 
    957     """Errors related to CmdLineClient class""" 
    958      
    959 class CmdLineClient(object): 
    960     """Command line interface to MyProxyClient class.  Where possible it  
    961     supports the same options as the Globus myproxy-* client commands""" 
    962      
    963     run = { 
    964         'info': 'runInfo',  
    965         'logon': 'runLogon', 
    966         'get-delegation': 'runGetDelegation', 
    967         'destroy': 'runDestroy',  
    968         'change-pass': 'runChangePassphrase', 
    969         'store': 'runStore' 
    970     } 
    971  
    972     initOpts = { 
    973         'info': '_addInfoOpts',  
    974         'logon': '_addLogonOpts', 
    975         'get-delegation': '_addGetDelegationOpts', 
    976         'destroy': '_addDestroyOpts',  
    977         'change-pass': '_addChangePassphraseOpts', 
    978         'store': '_addStoreOpts' 
    979     } 
    980  
    981     cmdUsage = { 
    982         'info': "usage: %prog info arg1 arg2",  
    983         'logon': "usage: %prog logon arg1 arg2", 
    984         'get-delegation': "usage: %prog get-delegation arg1 arg2", 
    985         'destroy': "usage: %prog destroy arg1 arg2",  
    986         'change-pass': "usage: %prog change-pass arg1 arg2", 
    987         'store': "usage: %prog store arg1 arg2" 
    988     } 
    989      
    990     # Keep '%prog' in a separate string otherwise it confuses the % operator 
    991     usage = "usage: %prog" + " [%s] arg1 arg2" % '|'.join(run.keys())     
    992     version = "%prog 0.8.7" 
    993          
    994     def __init__(self): 
    995         """Parse the command line and run the appropriate command""" 
    996          
    997         self.parser = optparse.OptionParser(usage=self.__class__.usage, 
    998                                             version=self.__class__.version) 
    999  
    1000         # Get command - expected to be 1st arg 
    1001         if len(sys.argv) > 1: 
    1002             cmd = sys.argv[1] 
    1003             if cmd not in self.__class__.run: 
    1004                 self.parser.error('"%s" command option not recognised' % cmd) 
    1005         else: 
    1006             self.parser.error('No command option set') 
    1007  
    1008         # Ammend usage string for specific command 
    1009         self.parser.set_usage(self.__class__.cmdUsage[cmd]) 
    1010          
    1011         # Add options based on the command set 
    1012         self._addGenericOpts() 
    1013         getattr(self, self.initOpts[cmd])() 
    1014          
    1015         # Omit command options as parser won't understand it 
    1016         (self.opts, args) = self.parser.parse_args(args=sys.argv[2:])      
    1017      
    1018         # Process generic options 
    1019          
    1020         # Not all commands require username option - for those that do, check  
    1021         # to see if it was set or omitted 
    1022         if hasattr(self.opts, 'username') and not self.opts.username: 
    1023             if sys.platform == 'win32': 
    1024                 self.opts.username = os.environ["USERNAME"] 
    1025             else: 
    1026                 import pwd 
    1027                 self.opts.username = pwd.getpwuid(os.geteuid())[0] 
    1028      
    1029         self.myProxy = MyProxyClient(hostname=self.opts.host, 
    1030                                      port=self.opts.port)#, 
    1031 #                                     O='NDG', 
    1032 #                                     OU='BADC') 
    1033  
    1034         # Run the command 
    1035         getattr(self, self.run[cmd])() 
    1036  
    1037                  
    1038     def _addGenericOpts(self): 
    1039         """Generic options applying to all commands""" 
    1040         self.parser.add_option("-s",  
    1041                           "--pshost",  
    1042                           dest="host", 
    1043                           default=os.environ.get('MYPROXY_SERVER'), 
    1044                           help="The hostname of the MyProxy server to contact") 
    1045  
    1046         defPort = int(os.environ.get('MYPROXY_SERVER_PORT') or '7512') 
    1047         self.parser.add_option("-p",  
    1048                           "--psport",  
    1049                           dest="port",  
    1050                           default=defPort, 
    1051                           type="int", 
    1052                           help="The port of the MyProxy server to contact") 
    1053  
    1054     def _addInfoOpts(self): 
    1055         """Add command line options for info""" 
    1056         self.parser.add_option("-l",  
    1057                           "--username",  
    1058                           dest="username",  
    1059                           help="Username for the delegated proxy") 
    1060  
    1061         self.parser.add_option("-C",  
    1062                           "--owner-certfile",  
    1063                           dest="ownerCertFile",  
    1064                           help=\ 
    1065 """Certificate for owner of credentials to be queried.  If omitted, it  
    1066 defaults to $GLOBUS_LOCATION/etc/hostcert.pem.""") 
    1067          
    1068         self.parser.add_option("-Y",  
    1069                           "--owner-keyfile",  
    1070                           dest="ownerKeyFile",  
    1071                           default=None, 
    1072                           help=\ 
    1073 """Private key for owner of credentials to be stored.  If omitted, it defaults 
    1074 to $GLOBUS_LOCATION/etc/hostkey.pem.""") 
    1075         
    1076         self.parser.add_option("-w",  
    1077                           "--owner-keyfile-passphrase",  
    1078                           dest="ownerPassphrase",  
    1079                           default=None, 
    1080                           help=\ 
    1081                           "Pass-phrase for Private key used for SSL client") 
    1082          
    1083     def _addLogonOpts(self): 
    1084         """Add command line options for logon""" 
    1085         self.parser.add_option("-l",  
    1086                                "--username",  
    1087                                dest="username",  
    1088                                help="Username for the delegated proxy") 
    1089  
    1090         self.parser.add_option("-t",  
    1091                                "--proxy_lifetime",  
    1092                                dest="lifetime",  
    1093                                default=43200, # = 12 hours in seconds 
    1094                                type="int", 
    1095                                help=\ 
    1096             "Lifetime of proxies delegated by the server (default 12 hours)") 
    1097  
    1098         self.parser.add_option("-o",  
    1099                                "--out",  
    1100                                dest="outfile",  
    1101                                help="Location of delegated proxy") 
    1102  
    1103     def _addGetDelegationOpts(self): 
    1104         """Add command line options for Get Delegation""" 
    1105         self._addLogonOpts() 
    1106  
    1107     def _addDestroyOpts(self): 
    1108         """Add command line options for destroy""" 
    1109         self.parser.add_option("-l",  
    1110                                "--username",  
    1111                                dest="username",  
    1112                                help=\ 
    1113                        "Username corresponding to credentials to be removed") 
    1114  
    1115     def _addChangePassphraseOpts(self): 
    1116         """Add command line options for change pass-phrase""" 
    1117         self.parser.add_option("-l",  
    1118                           "--username",  
    1119                           dest="username",  
    1120                           help="Username for the target proxy") 
    1121          
    1122     def _addStoreOpts(self): 
    1123         """Add command line options for store""" 
    1124         self.parser.add_option("-l",  
    1125                                "--username",  
    1126                                dest="username",  
    1127                                help=\ 
    1128                        "Username corresponding to credentials to be stored") 
    1129          
    1130         self.parser.add_option("-c",  
    1131                           "--certfile",  
    1132                           dest="certFile",  
    1133                           default=None, 
    1134                           help="Certificate to be stored") 
    1135          
    1136         self.parser.add_option("-y",  
    1137                           "--keyfile",  
    1138                           dest="keyFile",  
    1139                           default=None, 
    1140                           help="Private key to be stored") 
    1141  
    1142         self.parser.add_option("-C",  
    1143                           "--owner-certfile",  
    1144                           dest="ownerCertFile",  
    1145                           help=\ 
    1146 """Cert. for owner of credentials to be stored.  If omitted, it defaults to 
    1147 $GLOBUS_LOCATION/etc/hostcert.pem.  If this is not readable, the cert. to be 
    1148 stored is set as the owner.""") 
    1149          
    1150         self.parser.add_option("-Y",  
    1151                           "--owner-keyfile",  
    1152                           dest="ownerKeyFile",  
    1153                           default=None, 
    1154                           help=\ 
    1155 """Private key for owner of credentials to be stored.  If omitted, it defaults 
    1156 to $GLOBUS_LOCATION/etc/hostcert.pem.""") 
    1157         
    1158         self.parser.add_option("-w",  
    1159                           "--owner-keyfile-passphrase",  
    1160                           dest="ownerPassphrase",  
    1161                           default=None, 
    1162                           help=\ 
    1163                           "Pass-phrase for Private key used for SSL client") 
    1164  
    1165         self.parser.add_option("-t",  
    1166                                "--proxy_lifetime",  
    1167                                dest="lifetime",  
    1168                                default=43200, # = 12 hours in seconds 
    1169                                type="int", 
    1170                                help=\ 
    1171             "Lifetime of proxies delegated by the server (default 12 hours)") 
    1172  
    1173     def runGetDelegation(self): 
    1174         """Call MyProxyClient.getDelegation""" 
    1175         self.runLogon() 
    1176          
    1177     def runLogon(self): 
    1178         """Call MyProxyClient.logon""" 
    1179         outfile = self.opts.outfile or MyProxyClient.defProxyFile 
    1180      
    1181         # Get MyProxy password 
    1182         passphrase = getpass.getpass() 
    1183              
    1184         # Retrieve proxy cert 
    1185         creds = self.myProxy.logon(self.opts.username,  
    1186                                    passphrase,  
    1187                                    lifetime=self.opts.lifetime) 
    1188         MyProxyClient.writeProxyFile(*creds) 
    1189              
    1190         print "A proxy has been received for user %s in %s." % \ 
    1191             (self.opts.username, outfile) 
    1192              
    1193     def runChangePassphrase(self): 
    1194         """Call MyProxyClient.changePassphrase""" 
    1195          
    1196         # Get MyProxy password 
    1197         passphrase = getpass.getpass(\ 
    1198                      prompt='Enter (current) MyProxy pass phrase: ') 
    1199          
    1200         newPassphrase = getpass.getpass(\ 
    1201                                  prompt='Enter new MyProxy pass phrase: ') 
    1202          
    1203         if newPassphrase != getpass.getpass(\ 
    1204                      prompt='Verifying - Enter new MyProxy pass phrase: '): 
    1205             raise Exception, "Pass-phrases entered don't match" 
    1206                  
    1207         self.myProxy.changePassphrase(username, 
    1208                              passphrase, 
    1209                              newPassphrase,  
    1210                              self.opts.certFile, 
    1211                              self.opts.keyFile, 
    1212                              ownerPassphrase=open('../tmp2').read().strip())             
    1213                  
    1214     def runInfo(self): 
    1215         """Call MyProxyClient.info""" 
    1216         if not self.opts.ownerCertFile or not self.opts.ownerKeyFile: 
    1217 #            self.opts.ownerCertFile = MyProxyClient.defProxyFile 
    1218             # Look for proxy file stored from previous call to logon/ 
    1219             # get-delegation 
    1220             try: 
    1221                 creds = MyProxyClient.readProxyFile() 
    1222              
    1223                 # Copy proxy and user certificates 
    1224                 self.opts.ownerCertFile = './proxy-cert.pem' 
    1225                 self.opts.ownerKeyFile = './proxy-key.pem' 
    1226                 open(self.opts.ownerCertFile, 'w').write(creds[0] + ''.join(creds[2:])) 
    1227                 open(self.opts.ownerKeyFile, 'w').write(creds[1]) 
    1228             except IOError: 
    1229                 # No such file - try proceeding regardless 
    1230                 pass 
    1231              
    1232         credExists, errorTxt, fields = self.myProxy.info(self.opts.username,  
    1233                              ownerCertFile=self.opts.ownerCertFile, 
    1234                              ownerKeyFile=self.opts.ownerKeyFile, 
    1235                              ownerPassphrase=self.opts.ownerPassphrase) 
    1236         if errorTxt: 
    1237             raise CmdLineClientError, "User %s: %s" % (self.opts.username,  
    1238                                                        errorTxt) 
    1239                  
    1240         elif credExists: 
    1241             print "username: %s" % self.opts.username 
    1242             print "owner: %s" % fields['CRED_OWNER'] 
    1243             print "  time left: %d" % \ 
    1244                     (fields['CRED_END_TIME'] - fields['CRED_START_TIME']) 
    1245         else: 
    1246             ownerCert = ''#X509.load_cert(self.opts.ownerCertFile) 
    1247             ownerCertDN = ''#'/' + \ 
    1248                 #ownerCert.get_subject().as_text().replace(', ', '/') 
    1249             print "no credentials found for user %s, owner \"%s\"" % \ 
    1250                 (self.opts.username, ownerCertDN) 
    1251                  
    1252     def runDestroy(self): 
    1253         """Call MyProxyClient.destroy""" 
    1254         self.myProxy.destroy(self.opts.username,  
    1255                             ownerCertFile=self.opts.certFile, 
    1256                             ownerKeyFile=self.opts.keyFile, 
    1257                             ownerPassphrase=open('../tmp2').read().strip()) 
    1258          
    1259     def runStore(self): 
    1260         self.myProxy.store(self.opts.username,  
    1261                           self.opts.certFile, 
    1262                           self.opts.keyFile, 
    1263                           ownerCertFile=self.opts.certFile, 
    1264                           ownerKeyFile=self.opts.keyFile, 
    1265                           ownerPassphrase=open('./tmp').read().strip(), 
    1266                           lifetime=self.opts.lifetime) 
    1267  
    1268  
    1269 if __name__ == "__main__": 
    1270     main() 
  • TI12-security/trunk/python/MyProxyClient/setup.py

    r4615 r4624  
    3838    maintainer_email =          'Philip.Kershaw@stfc.ac.uk', 
    3939    url =                   'http://proj.badc.rl.ac.uk/ndg/wiki/Security', 
    40     install_requires =      ['ndg_security_client', 'ndg_security_server'], 
    41     dependency_links =      ["http://ndg.nerc.ac.uk/dist"], 
     40    install_requires =      ['M2Crypto'], 
    4241    license =               __license__, 
    4342    zip_safe = True 
  • TI12-security/trunk/python/MyProxyClient/test/README

    r3192 r4624  
    22======================== 
    33To set-up this test, A MyProxy server process must be running to test against. 
    4 MyProxy is installed as part of the NDG Security installation.  See the  
    5 installation guide for details: 
     4See http://grid.ncsa.uiuc.edu/myproxy/ for guidance on obtaining and installing 
     5it. 
    66 
    7 http://proj.badc.rl.ac.uk/ndg/browser/TI12-security/trunk/documentation/InstallationGuide/pdf/NDGSecurityInstallationGuide.pdf?format=raw 
     7To run these tests: 
    88 
    991) Start myproxy-server on it's host machine e.g. as root run, 
     
    17173) Run the tests with the command: 
    1818 
    19 $ python ./MyProxyClientTest.py 
     19$ python ./test_myproxyclient.py 
    2020 
    21214) To run individual tests give the test method name: 
    2222 
    23 $ python ./MyProxyClientTest.py MyProxyClientTestCase.test1Store 
     23$ python ./test_myproxyclient.py MyProxyClientTestCase.test1Store 
    2424 
    2525 * Note that some tests are dependent on the output of previous tests.   
     
    2828   check the existence of the credential after the test run test3Info: 
    2929    
    30    $ python ./MyProxyClientTest.py MyProxyClientTestCase.test3Info 
     30   $ python ./test_myproxyclient.py MyProxyClientTestCase.test3Info 
    3131    
    3232   or use MyProxy client commands on the MyProxy host: myproxy-info, 
     
    3636 * See the installation guide for MyProxy trouble shooting information. 
    3737 
     38P J Kershaw 12/12/08 
  • TI12-security/trunk/python/MyProxyClient/test/myProxyClient.cfg

    r4621 r4624  
     1# 
     2# MyProxyClient configuration file 
     3# 
     4# NERC Data Grid Project 
     5# 
     6# P J Kershaw 12/12/08 
     7# 
     8# Copyright (C) 2008 STFC & NERC 
     9#  
     10# This software may be distributed under the terms of the Q Public License, 
     11# version 1.0 or later. 
     12[DEFAULT] 
    113# Delete this element and take setting from MYPROXY_SERVER environment  
    214# variable if required 
  • TI12-security/trunk/python/MyProxyClient/test/myProxyClientTest.cfg

    r4621 r4624  
     1# 
     2# MyProxyClient Unit Tests configuration file 
     3# 
    14# NERC Data Grid Project 
    25# 
    36# P J Kershaw 13/12/06 
    47# 
    5 # Copyright (C) 2006 STFC & NERC 
     8# Copyright (C) 2008 STFC & NERC 
    69#  
    710# This software may be distributed under the terms of the Q Public License, 
    811# version 1.0 or later. 
    912[setUp] 
    10 propFilePath: $MYPROXYCLIENT_UNITTEST_DIR/myProxyProperties.xml 
     13cfgFilePath: $MYPROXYCLIENT_UNITTEST_DIR/myProxyClient.cfg 
    1114 
    1215# If a pass-phrase entry is commented out it will be prompted for from the 
  • TI12-security/trunk/python/MyProxyClient/test/test_myproxyclient.py

    r4621 r4624  
    1919import traceback 
    2020 
    21 from ConfigParser import SafeConfigParser 
    22 from ndg.security.common.myproxy import MyProxyClient 
     21from myproxy import CaseSensitiveConfigParser, MyProxyClient 
    2322 
    2423xpdVars = os.path.expandvars 
    2524jnPath = os.path.join 
    26 mkPath = lambda file: jnPath(os.environ['NDGSEC_MYPROXY_UNITTEST_DIR'], file) 
     25mkPath = lambda file: jnPath(os.environ['MYPROXYCLIENT_UNITTEST_DIR'], file) 
    2726 
    2827class MyProxyClientTestCase(unittest.TestCase): 
     
    3433            pdb.set_trace() 
    3534         
    36         if 'NDGSEC_MYPROXY_UNITTEST_DIR' not in os.environ: 
    37             os.environ['NDGSEC_MYPROXY_UNITTEST_DIR'] = \ 
     35        if 'MYPROXYCLIENT_UNITTEST_DIR' not in os.environ: 
     36            os.environ['MYPROXYCLIENT_UNITTEST_DIR'] = \ 
    3837                os.path.abspath(os.path.dirname(__file__)) 
    3938                 
    40         configParser = SafeConfigParser() 
    41         configFilePath = jnPath(os.environ['NDGSEC_MYPROXY_UNITTEST_DIR'], 
     39        configParser = CaseSensitiveConfigParser() 
     40        configFilePath = jnPath(os.environ['MYPROXYCLIENT_UNITTEST_DIR'], 
    4241                                "myProxyClientTest.cfg") 
    4342        configParser.read(configFilePath) 
     
    4746            self.cfg[section] = dict(configParser.items(section)) 
    4847             
    49         self.clnt = MyProxyClient(\ 
    50                     propFilePath=xpdVars(self.cfg['setUp']['propfilepath'])) 
     48        self.clnt = MyProxyClient( 
     49                        cfgFilePath=xpdVars(self.cfg['setUp']['cfgFilePath'])) 
    5150         
    5251 
    5352    def test1Store(self): 
    5453        '''test1Store: upload X509 cert and private key to repository''' 
     54        thisSection = self.cfg['test1Store'] 
     55         
     56        passphrase = thisSection.get('passphrase') 
     57        if passphrase is None: 
     58            passphrase = getpass.getpass(prompt="\ntest1Store credential " 
     59                                                "pass-phrase: ") 
    5560             
    56         passphrase = self.cfg['test1Store'].get('passphrase') 
    57         if passphrase is None: 
    58             passphrase = getpass.getpass(\ 
    59                                  prompt="\ntest1Store cred. pass-phrase: ") 
     61        ownerPassphrase = thisSection.get('ownerPassphrase') 
     62        if ownerPassphrase is None: 
     63            ownerPassphrase = getpass.getpass(prompt="\ntest1Store credential " 
     64                                                     " owner pass-phrase: ") 
     65 
     66        certFile = xpdVars(thisSection['signingCertFilePath']) 
     67        keyFile = xpdVars(thisSection['signingPriKeyFilePath']) 
     68        ownerCertFile = xpdVars(thisSection['ownerCertFile']) 
     69        ownerKeyFile = xpdVars(thisSection['ownerKeyFile']) 
    6070             
    61         ownerPassphrase = self.cfg['test1Store'].get('ownerpassphrase') 
    62         if ownerPassphrase is None: 
    63             ownerPassphrase = getpass.getpass(\ 
    64                               prompt="\ntest1Store cred. owner pass-phrase: ") 
    65  
    66         certFile = xpdVars(self.cfg['test1Store']['signingcertfilepath']) 
    67         keyFile = xpdVars(self.cfg['test1Store']['signingprikeyfilepath']) 
    68         ownerCertFile = xpdVars(self.cfg['test1Store']['ownercertfile']) 
    69         ownerKeyFile = xpdVars(self.cfg['test1Store']['ownerkeyfile']) 
    70              
    71         try: 
    72             self.clnt.store(self.cfg['test1Store']['username'], 
    73                             passphrase, 
    74                             certFile, 
    75                             keyFile, 
    76                             ownerCertFile=ownerCertFile, 
    77                             ownerKeyFile=ownerKeyFile, 
    78                             ownerPassphrase=ownerPassphrase, 
    79                             force=False) 
    80             print "Store creds for user %s" % \ 
    81                                             self.cfg['test1Store']['username'] 
    82         except: 
    83             self.fail(traceback.print_exc()) 
     71        self.clnt.store(thisSection['username'], 
     72                        passphrase, 
     73                        certFile, 
     74                        keyFile, 
     75                        ownerCertFile=ownerCertFile, 
     76                        ownerKeyFile=ownerKeyFile, 
     77                        ownerPassphrase=ownerPassphrase, 
     78                        force=False) 
     79        print "Store creds for user %s" % thisSection['username'] 
    8480     
    8581     
    8682    def test2GetDelegation(self): 
    8783        '''test2GetDelegation: retrieve proxy cert./private key''' 
    88         passphrase = self.cfg['test2GetDelegation'].get('passphrase') 
     84        thisSection = self.cfg['test2GetDelegation'] 
     85         
     86        passphrase = thisSection.get('passphrase') 
    8987        if passphrase is None: 
    90             passphrase = getpass.getpass(\ 
    91                                  prompt="\ntest2GetDelegation pass-phrase: ") 
     88            passphrase = getpass.getpass(prompt="\ntest2GetDelegation " 
     89                                                "pass-phrase: ") 
    9290          
    93         try: 
    94             proxyCertFile = \ 
    95                 xpdVars(self.cfg['test2GetDelegation']['proxycertfileout']) 
    96             proxyKeyFile = \ 
    97                 xpdVars(self.cfg['test2GetDelegation']['proxykeyfileout']) 
     91        proxyCertFile = xpdVars(thisSection['proxyCertFileOut']) 
     92        proxyKeyFile = xpdVars(thisSection['proxykeyfileout']) 
    9893 
    99             creds = self.clnt.getDelegation(\ 
    100                                   self.cfg['test2GetDelegation']['username'],  
    101                                   passphrase) 
    102             print "proxy credentials:"  
    103             print ''.join(creds) 
    104             open(proxyCertFile, 'w').write(creds[0]+''.join(creds[2:]))             
    105             open(proxyKeyFile, 'w').write(creds[1]) 
    106         except: 
    107             self.fail(traceback.print_exc()) 
     94        creds = self.clnt.getDelegation(thisSection['username'],  
     95                                        passphrase) 
     96        print "proxy credentials:"  
     97        print ''.join(creds) 
     98        open(proxyCertFile, 'w').write(creds[0]+''.join(creds[2:]))             
     99        open(proxyKeyFile, 'w').write(creds[1]) 
    108100 
    109101 
    110102    def test3Info(self): 
    111103        '''test3Info: Retrieve information about a given credential''' 
     104        thisSection = thisSection 
    112105         
    113         # ownerpassphrase can be omitted from the congif file in which case 
     106        # ownerPassphrase can be omitted from the congif file in which case 
    114107        # the get call below would return None 
    115         ownerPassphrase = self.cfg['test3Info'].get('ownerpassphrase') 
     108        ownerPassphrase = thisSection.get('ownerPassphrase') 
    116109        if ownerPassphrase is None: 
    117             ownerPassphrase = getpass.getpass(\ 
    118                               prompt="\ntest3Info owner creds pass-phrase: ") 
     110            ownerPassphrase = getpass.getpass(prompt="\ntest3Info owner " 
     111                                              "credentials pass-phrase: ") 
    119112 
    120         try: 
    121             credExists, errorTxt, fields = self.clnt.info( 
    122                              self.cfg['test3Info']['username'], 
    123                              xpdVars(self.cfg['test3Info']['ownercertfile']), 
    124                              xpdVars(self.cfg['test3Info']['ownerkeyfile']), 
    125                              ownerPassphrase=ownerPassphrase) 
    126             print "test3Info... " 
    127             print "credExists: %s" % credExists 
    128             print "errorTxt: " + errorTxt 
    129             print "fields: %s" % fields 
    130         except: 
    131             self.fail(traceback.print_exc()) 
     113        credExists, errorTxt, fields = self.clnt.info( 
     114                                     thisSection['username'], 
     115                                     xpdVars(thisSection['ownerCertFile']), 
     116                                     xpdVars(thisSection['ownerKeyFile']), 
     117                                     ownerPassphrase=ownerPassphrase) 
     118        print "test3Info... " 
     119        print "credExists: %s" % credExists 
     120        print "errorTxt: " + errorTxt 
     121        print "fields: %s" % fields 
    132122 
    133123 
     
    135125        """test4ChangePassphrase: change pass-phrase protecting a given 
    136126        credential""" 
    137         try: 
    138             passphrase=self.cfg['test4ChangePassphrase'].get('passphrase') 
    139             if passphrase is None: 
    140                 passphrase = getpass.getpass(\ 
    141                              prompt="test4ChangePassphrase - pass-phrase: ") 
    142              
    143             newPassphrase = \ 
    144                         self.cfg['test4ChangePassphrase'].get('newpassphrase') 
    145             if newPassphrase is None: 
    146                 newPassphrase = getpass.getpass(\ 
    147                         prompt="test4ChangePassphrase - new pass-phrase: ") 
    148      
    149                 confirmNewPassphrase = getpass.getpass(\ 
    150                 prompt="test4ChangePassphrase - confirm new pass-phrase: ") 
    151      
    152                 if newPassphrase != confirmNewPassphrase: 
    153                     self.fail("New and confirmed new password don't match") 
    154                      
    155             ownerPassphrase = \ 
    156                 self.cfg['test4ChangePassphrase'].get('ownerpassphrase') or \ 
    157                 passphrase 
    158      
    159             self.clnt.changePassphrase( 
    160                 self.cfg['test4ChangePassphrase']['username'], 
    161                 passphrase, 
    162                 newPassphrase,  
    163                 xpdVars(self.cfg['test4ChangePassphrase']['ownercertfile']), 
    164                 xpdVars(self.cfg['test4ChangePassphrase']['ownerkeyfile']), 
    165                 ownerPassphrase=ownerPassphrase) 
    166             print "Change pass-phrase" 
    167         except: 
    168             self.fail(traceback.print_exc()) 
     127        thisSection = self.cfg['test4ChangePassphrase'] 
     128         
     129        passphrase = thisSection.get('passphrase') 
     130        if passphrase is None: 
     131            passphrase = getpass.getpass(prompt="test4ChangePassphrase - " 
     132                                                "pass-phrase: ") 
     133         
     134        newPassphrase = thisSection.get('newpassphrase') 
     135        if newPassphrase is None: 
     136            newPassphrase = getpass.getpass(prompt="test4ChangePassphrase " 
     137                                                   "- new pass-phrase: ") 
     138 
     139            confirmNewPassphrase = getpass.getpass(prompt=\ 
     140                                                   "test4ChangePassphrase " 
     141                                                   "- confirm new " 
     142                                                   "pass-phrase: ") 
     143 
     144            if newPassphrase != confirmNewPassphrase: 
     145                self.fail("New and confirmed new password don't match") 
     146                 
     147        ownerPassphrase = thisSection.get('ownerPassphrase') or passphrase 
     148 
     149        self.clnt.changePassphrase(thisSection['username'], 
     150                                   passphrase, 
     151                                   newPassphrase,  
     152                                   xpdVars(thisSection['ownerCertFile']), 
     153                                   xpdVars(thisSection['ownerKeyFile']), 
     154                                   ownerPassphrase=ownerPassphrase) 
     155        print "Change pass-phrase" 
    169156 
    170157 
     
    172159        '''test5Destroy: destroy credentials for a given user''' 
    173160 
    174         ownerPassphrase = self.cfg['test5Destroy'].get('ownerpassphrase') 
     161        ownerPassphrase = self.cfg['test5Destroy'].get('ownerPassphrase') 
    175162        if ownerPassphrase is None: 
    176             ownerPassphrase = getpass.getpass(\ 
    177                           prompt="\ntest5Destroy cred. owner pass-phrase: ") 
     163            ownerPassphrase = getpass.getpass(prompt="\ntest5Destroy " 
     164                                              "credential owner pass-phrase: ") 
    178165 
    179166        try: 
    180167            self.clnt.destroy(self.cfg['test5Destroy']['username'],  
    181             ownerCertFile=xpdVars(self.cfg['test5Destroy']['ownercertfile']), 
    182             ownerKeyFile=xpdVars(self.cfg['test5Destroy']['ownerkeyfile']), 
     168            ownerCertFile=xpdVars(self.cfg['test5Destroy']['ownerCertFile']), 
     169            ownerKeyFile=xpdVars(self.cfg['test5Destroy']['ownerKeyFile']), 
    183170            ownerPassphrase=ownerPassphrase) 
    184171            print "Destroy creds for user %s" % \ 
     
    188175         
    189176  
    190 #_____________________________________________________________________________        
    191177class MyProxyClientTestSuite(unittest.TestSuite): 
    192178    def __init__(self): 
Note: See TracChangeset for help on using the changeset viewer.