Changeset 1945


Ignore:
Timestamp:
03/01/07 16:41:07 (13 years ago)
Author:
pjkersha
Message:

python/ndg.security.server/ndg/security/server/SessionMgr/init.py: started refactoring of connect, addUser
and reqAuthorisation methods to allow for new ZSI code, doc-lit. WSDL, WS-Security and new MyProxy? client.

python/ndg.security.server/ndg/security/server/MyProxy.py,
python/ndg.security.test/ndg/security/test/MyProxy/myProxyClientTest.cfg and
python/ndg.security.test/ndg/security/test/MyProxy/MyProxyClientTest.py: changed store method to include explicit
passphrase argument.

python/ndg.security.test/ndg/security/test/SessionMgr/SessionMgrClientTest.py: moved from test/ into a dedicated
module directory.

python/ndg.security.test/ndg/security/test/XMLSecDoc/*: unit test for new XMLSecDoc class which implements
enveloped signature using M2Crypto, ZSI and DOM rather than pyXMLSec as before.

python/Tests/MyProxyClient/m2CryptoMyPxClnt.py: allow client post connection check - i.e. commented out:
conn.clientPostConnectionCheck = None

python/ndg.security.common/ndg/security/common/XMLMsg.py: no longer needed with new version of ZSI + use of
WS-Security.

Location:
TI12-security/trunk/python
Files:
5 added
1 deleted
7 edited
1 moved

Legend:

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

    r1856 r1945  
    513513        # Fudge to avoid checking client cert - seems to pick globus  
    514514        # host/<hostname> one 
    515         conn.clientPostConnectionCheck = None 
     515        #conn.clientPostConnectionCheck = None 
    516516        conn.connect((self.hostname, self.port)) 
    517517         
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/CredWallet.py

    r1781 r1945  
    120120 
    121121 
     122            
     123#_____________________________________________________________________________ 
     124class _MetaCredWallet(type): 
     125    """Enable CredWallet to have read only class variables e.g. 
     126     
     127    print CredWallet.accessDenied  
     128     
     129    ... is allowed but, 
     130     
     131    CredWallet.accessDenied = None 
     132     
     133    ... raises - AttributeError: can't set attribute""" 
     134     
     135    def __getAccessDenied(cls): 
     136        '''accessDenied get method''' 
     137        return False 
     138     
     139    accessDenied = property(fget=__getAccessDenied) 
     140     
     141    def __getAccessGranted(cls): 
     142        '''accessGranted get method''' 
     143        return True 
     144     
     145    accessGranted = property(fget=__getAccessGranted) 
    122146 
    123147#_____________________________________________________________________________         
  • TI12-security/trunk/python/ndg.security.common/ndg/security/common/XMLSecDoc.py

    r1783 r1945  
    2727from cStringIO import StringIO 
    2828 
    29 # xmlsec requires libxml2 
    30 # Comment out until completed refactoring XML Sig to not use pyXMLSec 
    31 #import libxml2 
    32  
    33 # XML security module 
    34 # Comment out until completed refactoring XML Sig to not use pyXMLSec 
    35 #import xmlsec         
     29# Include for re-parsing doc ready for canonicalization in sign method - see 
     30# associated note 
     31from xml.dom.ext.reader.PyExpat import Reader 
    3632 
    3733 
     
    4642 
    4743 
    48 class XMLSecDoc(object): 
     44class XMLSecDocOld(object): 
    4945    """Implements XML Signature and XML Encryption for a Document.""" 
    5046 
     
    420416 
    421417    #_________________________________________________________________________ 
    422     def __setEncrPubKeyFilePath(self, filePath): 
     418    def __setEncrCertFilePath(self, filePath): 
    423419        """Set file path for certificate publiv key used to decrypt doc.""" 
    424420         
     
    430426 
    431427    # Publish attribute as write only 
    432     encrCertFilePath = property(fset=__setEncrPubKeyFilePath, 
     428    encrCertFilePath = property(fset=__setEncrCertFilePath, 
    433429        doc="file path for certificate publiv key used to decrypt doc") 
    434430 
     
    949945         
    950946        if encrCertFilePath: 
    951             self.__setEncrPubKeyFilePath(encrCertFilePath) 
     947            self.__setEncrCertFilePath(encrCertFilePath) 
    952948             
    953949             
     
    14051401        return key 
    14061402 
     1403############################################################################## 
     1404class XMLSecDoc(object): 
     1405    """Implements XML Signature and XML Encryption for a Document.""" 
     1406 
     1407    def __init__(self, 
     1408                 filePath=None, 
     1409                 signingKeyFilePath=None, 
     1410                 encrCertFilePath=None, 
     1411                 encrPriKeyFilePath=None, 
     1412                 certFilePathList=None): 
     1413 
     1414        """Initialisation - 
     1415             
     1416        @param filePath:            file path for document 
     1417        @param signingKeyFilePath:  file path for private key used in  
     1418        signature 
     1419        @param encrPriKeyFilePath:  file path for private key used to decrypt 
     1420        previously encrypted document 
     1421        @param certFilePathList:    list of certificates used in verification  
     1422        of a signed document""" 
     1423 
     1424        self.__filePath = None 
     1425        self.__signingKeyFilePath = None 
     1426        self.__certFilePathList = None 
     1427        self.__encrCertFilePath = None 
     1428        self.__encrPriKeyFilePath = None 
     1429        self.__docNode = None 
     1430 
     1431 
     1432        if filePath is not None: 
     1433            self.__setFilePath(filePath) 
     1434 
     1435        # Private key file to be used to sign the document 
     1436        if signingKeyFilePath is not None: 
     1437            self.__setSigningKeyFilePath(signingKeyFilePath) 
     1438 
     1439        # Public key file to be used to encrypt document 
     1440        if encrCertFilePath is not None: 
     1441            self.__setEncrCertFilePath(encrCertFilePath) 
     1442 
     1443        # Private key file to be used to decrypt document 
     1444        if encrPriKeyFilePath is not None: 
     1445            self.__setEncrPriKeyFilePath(encrPriKeyFilePath) 
     1446 
     1447        # This may be either of: 
     1448        # 1) Certificate file to be used for signing document 
     1449        # 2) list of certificates used to verify a signed document 
     1450        if certFilePathList is not None: 
     1451            self.__setCertFilePathList(certFilePathList) 
     1452         
     1453         
     1454    def __str__(self): 
     1455        """String representation of doc - only applies if doc had been read 
     1456        or parsed""" 
     1457 
     1458 
     1459    def __getFilePath(self): 
     1460        """Get file path for file to be signed/encrypted.""" 
     1461        return self.__filePath 
     1462 
     1463 
     1464    def __setFilePath(self, filePath): 
     1465        """Set file path for file to be signed/encrypted.""" 
     1466         
     1467        if filePath is None or not isinstance(filePath, basestring):             
     1468            raise XMLSecDocError, "Document file path must be a valid string" 
     1469         
     1470        self.__filePath = filePath 
     1471 
     1472 
     1473    def __delFilePath(self): 
     1474        """Prevent file path being deleted.""" 
     1475        raise AttributeError, "\"filePath\" cannot be deleted" 
     1476  
     1477   
     1478    # Publish attribute as read/write 
     1479    filePath = property(fget=__getFilePath, 
     1480                        fset=__setFilePath, 
     1481                        fdel=__delFilePath, 
     1482                        doc="File Path for XML document to apply security to") 
     1483 
     1484 
     1485    #_________________________________________________________________________ 
     1486    def __setCertFilePathList(self, filePath): 
     1487        """File path for certificate used to sign document /  
     1488        list of certificates used to check the signature of a document""" 
     1489         
     1490        if isinstance(filePath, basestring):         
     1491            self.__certFilePathList = [filePath] 
     1492 
     1493        elif isinstance(filePath, list): 
     1494            self.__certFilePathList = filePath 
     1495                                             
     1496        elif isinstance(filePath, tuple): 
     1497            self.__certFilePathList = list(filePath) 
     1498 
     1499        else: 
     1500            raise XMLSecDocError, \ 
     1501            "Signing Certificate file path must be a valid string or list" 
     1502  
     1503   
     1504    # Publish attribute as write only 
     1505    certFilePathList = property(fset=__setCertFilePathList, 
     1506        doc="File Path of certificate used to sign document / " + \ 
     1507            "list of certificates used to check the signature of a doc") 
     1508 
     1509 
     1510    #_________________________________________________________________________ 
     1511    def __setSigningKeyFilePath(self, filePath): 
     1512        """Set file path for certificate private key used to sign doc.""" 
     1513         
     1514        if filePath is None or not isinstance(filePath, basestring):             
     1515            raise XMLSecDocError, \ 
     1516                "Certificate key file path must be a valid string" 
     1517         
     1518        self.__signingKeyFilePath = filePath 
     1519 
     1520    # Publish attribute as write only 
     1521    signingKeyFilePath = property(fset=__setSigningKeyFilePath, 
     1522                doc="file path for certificate private key used to sign doc") 
     1523 
     1524 
     1525 
     1526    #_________________________________________________________________________ 
     1527    def __setEncrCertFilePath(self, filePath): 
     1528        """Set file path for certificate publiv key used to decrypt doc.""" 
     1529         
     1530        if filePath is None or not isinstance(filePath, basestring):             
     1531            raise XMLSecDocError, \ 
     1532                "Certificate key file path must be a valid string" 
     1533 
     1534        self.__encrCertFilePath = filePath 
     1535 
     1536    # Publish attribute as write only 
     1537    encrCertFilePath = property(fset=__setEncrCertFilePath, 
     1538        doc="file path for certificate publiv key used to decrypt doc") 
     1539 
     1540 
     1541    #_________________________________________________________________________ 
     1542    def __setEncrPriKeyFilePath(self, filePath): 
     1543        """Set file path for certificate private key used to decrypt doc.""" 
     1544         
     1545        if filePath is None or not isinstance(filePath, basestring):             
     1546            raise XMLSecDocError, \ 
     1547                "Certificate key file path must be a valid string" 
     1548         
     1549        self.__encrPriKeyFilePath = filePath 
     1550 
     1551    # Publish attribute as write only 
     1552    encrPriKeyFilePath = property(fset=__setEncrPriKeyFilePath, 
     1553        doc="file path for certificate private key used to decrypt doc") 
     1554 
     1555 
     1556    #_________________________________________________________________________ 
     1557    def asString(self, filePath=None, stripXMLhdr=False): 
     1558        """Return certificate file content as a string""" 
     1559         
     1560        # Check libxml2.xmlDoc object has been instantiated - if not call 
     1561        # read method 
     1562        if self.__libxml2Doc is None: 
     1563            if filePath is None: 
     1564                raise XMLSecDocError, \ 
     1565                    "A file must be parsed first for asString()" 
     1566                     
     1567            self.read(filePath) 
     1568 
     1569        try: 
     1570            # Make a buffer 
     1571            f = StringIO() 
     1572            buf = libxml2.createOutputBuffer(f, 'UTF-8') 
     1573 
     1574            # Write to buffer 
     1575            self.__libxml2Doc.saveFormatFileTo(buf, 'UTF-8', 0) 
     1576 
     1577 
     1578            # Return string content 
     1579            if stripXMLhdr: 
     1580                return re.sub("<\?xml.*>\s", "", f.getvalue()) 
     1581            else: 
     1582                return f.getvalue() 
     1583 
     1584        except Exception, e: 
     1585            raise XMLSecDocError("Error outputting document as a string:" % \ 
     1586                                 e) 
     1587 
     1588 
     1589    #_________________________________________________________________________ 
     1590    def parse(self, xmlTxt): 
     1591        """Parse string containing XML into a DOM to allow signature or  
     1592        signature validation""" 
     1593        self.__docNode = Reader().fromString(xmlTxt) 
     1594 
     1595    #_________________________________________________________________________ 
     1596    def read(self, stream=None): 
     1597 
     1598        """Read XML into a libxml2 document to allow signature validation""" 
     1599        if stream is None: 
     1600            stream = open(self.__filePath) 
     1601                 
     1602        self.__docNode = Reader.fromStream(stream) 
     1603 
     1604 
     1605    #_________________________________________________________________________ 
     1606    def write(self): 
     1607        """Write XML document""" 
     1608 
     1609 
     1610    #_________________________________________________________________________ 
     1611    def createXML(self): 
     1612        """VIRTUAL method - derived class should implement - 
     1613        Create text for output and return as a string""" 
     1614         
     1615        """A new user to Credentials Repository""" 
     1616        raise NotImplementedError, \ 
     1617                                self.createXML.__doc__.replace('\n       ','') 
     1618 
     1619 
     1620    #_________________________________________________________________________ 
     1621    def sign(self, 
     1622             xmlTxt=None, 
     1623             signingKeyFilePath=None, 
     1624             signingKeyPwd=None, 
     1625             certFilePathList=None, 
     1626             inclX509Cert=True, 
     1627             inclX509SubjName=True, 
     1628             inclX509IssSerial=True, 
     1629             rtnAsString=False): 
     1630        """Sign XML document using an X.509 certificate private key 
     1631 
     1632        xmlTxt:                 string buffer containing xml to be signed. If 
     1633                                not provided, calls XMLSecDoc.createXML(). 
     1634                                This is a virtual method so must be defined 
     1635                                in a derived class. 
     1636                             
     1637        signingKeyFilePath:     file path to private key file used to sign 
     1638                                the document 
     1639 
     1640        signingKeyPwd:          password for signing key file. 
     1641         
     1642        certFilePathList:        include certificate of signer  
     1643        inclX509Cert:            include MIME encoded content of X.509  
     1644                                certificate that will sign the document 
     1645        inclX509SubjName:        include subject name of signing X.509  
     1646                                certificate. 
     1647        inclX509IssSerial:        include issuer name and serial inumber in 
     1648                                signature 
     1649                                     
     1650        rtnAsString:            This method returns None by default.  Set to  
     1651                                True to override and return the signed 
     1652                                result instead as a string.""" 
     1653 
     1654        # Create string buffer from virtual function if not passed 
     1655        # as input argument - derived class must implement  
     1656        if xmlTxt: 
     1657            self.parse(xmlTxt) 
     1658 
     1659             
     1660        # Set private key file 
     1661        if signingKeyFilePath is not None: 
     1662            self.__setSigningKeyFilePath(signingKeyFilePath)             
     1663 
     1664 
     1665        # Public certificate file  
     1666        if certFilePathList is not None: 
     1667            self.__setCertFilePathList(certFilePathList) 
     1668             
     1669        # Return as required 
     1670        if rtnAsString: 
     1671            return self.asString() 
     1672         
     1673         
     1674        # Add X.509 cert as binary security token 
     1675        x509Cert = X509.load_cert(self.__certFilePathList[0]) 
     1676         
     1677        x509CertPat = re.compile(\ 
     1678            '-----BEGIN CERTIFICATE-----\n?(.*?)\n?-----END CERTIFICATE-----', 
     1679            re.S) 
     1680        x509CertStr = x509CertPat.findall(x509Cert.as_pem())[0] 
     1681 
     1682        soapWriter._header.setNamespaceAttribute('ds', DSIG.BASE) 
     1683        soapWriter._header.setNamespaceAttribute('ec', DSIG.C14N_EXCL) 
     1684         
     1685         
     1686        # Change value and encoding types to suite WebSphere 
     1687#        binSecTokElem.node.setAttribute('ValueType', "wsse:X509v3") 
     1688        valueType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509" 
     1689        binSecTokElem.node.setAttribute('ValueType', valueType) 
     1690#        binSecTokElem.node.setAttribute('EncodingType', "wsse:Base64Binary") 
     1691        encodingType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" 
     1692        binSecTokElem.node.setAttribute('EncodingType', encodingType) 
     1693         
     1694        # Add ID so that the binary token can be included in the signature 
     1695        binSecTokElem.node.setAttribute('wsu:Id', "binaryToken") 
     1696 
     1697        binSecTokElem.createAppendTextNode(x509CertStr) 
     1698 
     1699         
     1700        # Signature 
     1701        signatureElem = wsseElem.createAppendElement(DSIG.BASE, 'Signature') 
     1702        signatureElem.setNamespaceAttribute('ds', DSIG.BASE) 
     1703         
     1704        # Signature - Signed Info 
     1705        signedInfoElem = signatureElem.createAppendElement(DSIG.BASE,  
     1706                                                           'SignedInfo') 
     1707         
     1708        # Signed Info - Canonicalization method 
     1709        signedInfoC14nKw = {} 
     1710        signedInfoC14nKw['unsuppressedPrefixes'] = ['ds'] 
     1711        c14nMethodElem = signedInfoElem.createAppendElement(DSIG.BASE, 
     1712                                                    'CanonicalizationMethod') 
     1713        c14nMethodElem.node.setAttribute('Algorithm', DSIG.C14N_EXCL) 
     1714        c14nInclNamespacesElem = c14nMethodElem.createAppendElement(\ 
     1715                        DSIG.C14N_EXCL, 
     1716                                                'InclusiveNamespaces') 
     1717        c14nInclNamespacesElem.node.setAttribute('PrefixList',  
     1718            ' '.join(signedInfoC14nKw['unsuppressedPrefixes'])) 
     1719         
     1720        # Signed Info - Signature method 
     1721        sigMethodElem = signedInfoElem.createAppendElement(DSIG.BASE, 
     1722                                                    'SignatureMethod') 
     1723        #sigMethodElem.node.setAttribute('Algorithm', DSIG.DIGEST_SHA1) 
     1724        sigMethodElem.node.setAttribute('Algorithm', DSIG.SIG_RSA_SHA1) 
     1725         
     1726        # Signature - Signature value 
     1727        signatureValueElem = signatureElem.createAppendElement(DSIG.BASE,  
     1728                                                             'SignatureValue') 
     1729         
     1730        # Key Info 
     1731        KeyInfoElem = signatureElem.createAppendElement(DSIG.BASE, 'KeyInfo') 
     1732 
     1733        # Serialize and re-parse prior to reference generation - calculating 
     1734        # canonicalization based on soapWriter.dom.node seems to give an 
     1735        # error: the order of wsu:Id attribute is not correct 
     1736        docNode = Reader().fromString(str(soapWriter)) 
     1737         
     1738        # Namespaces for XPath searches 
     1739        processorNss = \ 
     1740        { 
     1741            'ds':     DSIG.BASE,  
     1742        } 
     1743        ctxt = Context(docNode, processorNss=processorNss) 
     1744        idNodes = xpath.Evaluate('//*[@wsu:Id]',  
     1745                                 contextNode=docNode,  
     1746                                 context=ctxt) 
     1747         
     1748        # 1) Reference Generation 
     1749        # 
     1750        # Find references 
     1751        c14nKw = {} 
     1752        c14nKw['unsuppressedPrefixes'] = ['xmlns', 'xsi', 'xsd', 'SOAP-ENV', 'wsu', 'wsse', 'ns1'] 
     1753        for idNode in idNodes: 
     1754             
     1755            # Set URI attribute to point to reference to be signed 
     1756            #uri = u"#" + idNode.getAttribute('wsu:Id') 
     1757            uri = u"#" + idNode.attributes[(_WSU.UTILITY, 'Id')].value 
     1758             
     1759            # Canonicalize reference 
     1760            c14nRef = Canonicalize(idNode, **c14nKw) 
     1761             
     1762            # Calculate digest for reference and base 64 encode 
     1763            # 
     1764            # Nb. encodestring adds a trailing newline char 
     1765            digestValue = base64.encodestring(sha(c14nRef).digest()).strip() 
     1766 
     1767 
     1768            # Add a new reference element to SignedInfo 
     1769            refElem = signedInfoElem.createAppendElement(DSIG.BASE,  
     1770                                                         'Reference') 
     1771            refElem.node.setAttribute('URI', uri) 
     1772             
     1773            # Use ds:Transforms or wsse:TransformationParameters? 
     1774            transformsElem = refElem.createAppendElement(DSIG.BASE,  
     1775                                                        'Transforms') 
     1776            transformElem = transformsElem.createAppendElement(DSIG.BASE,  
     1777                                                               'Transform') 
     1778            transformElem.node.setAttribute('Algorithm', DSIG.C14N_EXCL) 
     1779 
     1780            inclNamespacesElem = transformElem.createAppendElement(\ 
     1781                            DSIG.C14N_EXCL, 
     1782                                                       'InclusiveNamespaces') 
     1783            inclNamespacesElem.node.setAttribute('PrefixList', 
     1784                ' '.join(c14nKw['unsuppressedPrefixes'])) 
     1785             
     1786            # Digest Method  
     1787            digestMethodElem = refElem.createAppendElement(DSIG.BASE,  
     1788                                                           'DigestMethod') 
     1789            digestMethodElem.node.setAttribute('Algorithm', DSIG.DIGEST_SHA1) 
     1790             
     1791            # Digest Value 
     1792            digestValueElem = refElem.createAppendElement(DSIG.BASE,  
     1793                                                          'DigestValue') 
     1794            digestValueElem.createAppendTextNode(digestValue) 
     1795 
     1796    
     1797        # 2) Signature Generation 
     1798        # 
     1799 
     1800        # Test against signature generated by pyXMLSec version 
     1801        #xmlTxt = open('./wsseSign-xmlsec-res.xml').read() 
     1802        #dom = NonvalidatingReader.parseStream(StringIO(xmlTxt)) 
     1803         
     1804        # Canonicalize the signedInfo node 
     1805        # 
     1806        # Nb. When extracted the code adds the namespace attribute to the 
     1807        # signedInfo!  This has important consequences for validation - 
     1808        # 
     1809        # 1) Do you strip the namespace attribute before taking the digest to  
     1810        # ensure the text is exactly the same as what is displayed in the  
     1811        # message? 
     1812        # 
     1813        # 2) Leave it in and assume the validation algorithm will expect to  
     1814        # add in the namespace attribute?! 
     1815        # 
     1816        # http://www.w3.org/TR/xml-c14n#NoNSPrefixRewriting implies you need  
     1817        # to include namespace declarations for namespaces referenced in a doc 
     1818        # subset - yes to 2) 
     1819        #c14nSignedInfo = signedInfoElem.canonicalize() 
     1820        c14nSignedInfo = Canonicalize(signedInfoElem.node, **signedInfoC14nKw) 
     1821 
     1822        # Calculate digest of SignedInfo 
     1823        signedInfoDigestValue = sha(c14nSignedInfo).digest().strip() 
     1824         
     1825        # Read Private key to sign with     
     1826        priKeyFile = BIO.File(open(self.__priKeyFilePath))                                             
     1827        priKey = RSA.load_key_bio(priKeyFile,  
     1828                                  callback=lambda *ar, **kw: self.__priKeyPwd) 
     1829         
     1830        # Sign using the private key and base 64 encode the result 
     1831        signatureValue = priKey.sign(signedInfoDigestValue) 
     1832        b64EncSignatureValue = base64.encodestring(signatureValue).strip() 
     1833 
     1834        # Add to <SignatureValue> 
     1835        signatureValueElem.createAppendTextNode(b64EncSignatureValue) 
     1836         
     1837        # Extract RSA public key from the cert 
     1838        rsaPubKey = x509Cert.get_pubkey().get_rsa() 
     1839         
     1840        # Check the signature  
     1841#        verify = bool(rsaPubKey.verify(signedInfoDigestValue, signatureValue)) 
     1842#         
     1843#        open('soap.xml', 'w').write(str(soapWriter)) 
     1844#        import pdb;pdb.set_trace()  
     1845        print "Signature Generated" 
     1846        print str(soapWriter) 
     1847 
     1848 
     1849         
     1850 
     1851    #_________________________________________________________________________ 
     1852    def verify(self, filePath=None, certFilePathList=None): 
     1853 
     1854        """ 
     1855        Verify XML signature in file.  Returns True if valid otherwise 
     1856        False. 
     1857 
     1858        xmlTxt:                 string buffer containing the text from the XML 
     1859                                file to be checked.  If omitted, the 
     1860                                filePath argument is used instead. 
     1861 
     1862        filePath:               file path to XML file to be checked.  This 
     1863                                argument is used if no xmlTxt was provided. 
     1864                                If filePath itself is omitted the file set 
     1865                                by self.__filePath is read instead. 
     1866 
     1867        certFilePathList:       Certificate used to sign the document. 
     1868                                """ 
     1869 
     1870        if certFilePathList is not None: 
     1871            self.__setCertFilePathList(certFilePathList) 
     1872 
     1873         
     1874        # Check Certificate files for read access 
     1875        if not self.__certFilePathList:                 
     1876            raise XMLSecDocError, "No certificate files set for check" 
     1877 
     1878 
     1879         
     1880        processorNss = \ 
     1881        { 
     1882            'ds':     DSIG.BASE,  
     1883            'wsu':    _WSU.UTILITY,  
     1884            'wsse':   OASIS.WSSE,  
     1885            'soapenv':"http://schemas.xmlsoap.org/soap/envelope/"  
     1886        } 
     1887        ctxt = Context(parsedSOAP.dom, processorNss=processorNss) 
     1888         
     1889 
     1890        signatureNodes = xpath.Evaluate('//ds:Signature',  
     1891                                        contextNode=parsedSOAP.dom,  
     1892                                        context=ctxt) 
     1893        if len(signatureNodes) > 1: 
     1894            raise VerifyError, 'Multiple ds:Signature elements found' 
     1895         
     1896        try: 
     1897            signatureNodes = signatureNodes[0] 
     1898        except: 
     1899            # Message wasn't signed 
     1900            return 
     1901         
     1902        # Two stage process: reference validation followed by signature  
     1903        # validation  
     1904         
     1905        # 1) Reference Validation 
     1906         
     1907        # Check for canonicalization set via ds:CanonicalizationMethod - 
     1908        # Use this later as a back up in case no Canonicalization was set in  
     1909        # the transforms elements 
     1910        c14nMethodNode = xpath.Evaluate('//ds:CanonicalizationMethod',  
     1911                                        contextNode=parsedSOAP.dom,  
     1912                                        context=ctxt)[0] 
     1913         
     1914        refNodes = xpath.Evaluate('//ds:Reference',  
     1915                                  contextNode=parsedSOAP.dom,  
     1916                                  context=ctxt) 
     1917            
     1918        for refNode in refNodes: 
     1919            # Get the URI for the reference 
     1920            refURI = refNode.getAttributeNodeNS(None, 'URI').value 
     1921                             
     1922            try: 
     1923                transformsNode = getElements(refNode, "Transforms")[0] 
     1924                transforms = getElements(transformsNode, "Transform") 
     1925     
     1926                refAlgorithm = transforms[0].getAttributeNodeNS(None,  
     1927                                                         "Algorithm").value 
     1928            except Exception, e: 
     1929                raise VerifyError, \ 
     1930            'failed to get transform algorithm for <ds:Reference URI="%s">'%\ 
     1931                        (refURI, str(e)) 
     1932                 
     1933            # Add extra keyword for Exclusive canonicalization method 
     1934            c14nKw = {} 
     1935            if refAlgorithm == DSIG.C14N_EXCL: 
     1936                try: 
     1937                    inclusiveNS = getElements(transforms[0],  
     1938                                              "InclusiveNamespaces") 
     1939                     
     1940                    pfxListAttNode = inclusiveNS[0].getAttributeNodeNS(None,  
     1941                                                               'PrefixList') 
     1942                    c14nKw['unsuppressedPrefixes'] = \ 
     1943                                                pfxListAttNode.value.split() 
     1944                except: 
     1945                    raise VerifyError, \ 
     1946                'failed to handle transform (%s) in <ds:Reference URI="%s">'%\ 
     1947                        (transforms[0], refURI) 
     1948         
     1949            # Canonicalize the reference data and calculate the digest 
     1950            if refURI[0] != "#": 
     1951                raise VerifyError, \ 
     1952                    "Expecting # identifier for Reference URI \"%s\"" % refURI 
     1953                     
     1954            # XPath reference 
     1955            uriXPath = '//*[@wsu:Id="%s"]' % refURI[1:] 
     1956            uriNode = xpath.Evaluate(uriXPath,  
     1957                                     contextNode=parsedSOAP.dom,  
     1958                                     context=ctxt)[0] 
     1959 
     1960            c14nRef = Canonicalize(uriNode, **c14nKw) 
     1961            digestValue = base64.encodestring(sha(c14nRef).digest()).strip() 
     1962             
     1963            # Extract the digest value that was stored             
     1964            digestNode = getElements(refNode, "DigestValue")[0] 
     1965            nodeDigestValue = str(digestNode.childNodes[0].nodeValue).strip()    
     1966             
     1967            # Reference validates if the two digest values are the same 
     1968            if digestValue != nodeDigestValue: 
     1969                raise VerifyError, \ 
     1970                        'Digest Values do not match for URI: "%s"' % refURI 
     1971                 
     1972        # 2) Signature Validation 
     1973        signedInfoNode = xpath.Evaluate('//ds:SignedInfo', 
     1974                                        contextNode=parsedSOAP.dom,  
     1975                                        context=ctxt)[0] 
     1976 
     1977        #import pdb;pdb.set_trace() 
     1978        # Get algorithm used for canonicalization of the SignedInfo  
     1979        # element.  Nb. This is NOT necessarily the same as that used to 
     1980        # canonicalize the reference elements checked above! 
     1981        signedInfoC14nAlg = c14nMethodNode.getAttributeNodeNS(None,  
     1982                                                         "Algorithm").value 
     1983        signedInfoC14nKw = {} 
     1984        if signedInfoC14nAlg == DSIG.C14N_EXCL: 
     1985            try: 
     1986                inclusiveNS = getElements(c14nMethodNode, 
     1987                                          "InclusiveNamespaces") 
     1988                 
     1989                pfxListAttNode = inclusiveNS[0].getAttributeNodeNS(None,  
     1990                                                           'PrefixList') 
     1991                signedInfoC14nKw['unsuppressedPrefixes'] = \ 
     1992                                            pfxListAttNode.value.split() 
     1993            except Exception, e: 
     1994                raise VerifyError, \ 
     1995            'failed to handle exclusive canonicalisation for SignedInfo: %s'%\ 
     1996                        str(e) 
     1997 
     1998        # Canonicalize the SignedInfo node and take digest 
     1999        c14nSignedInfo = Canonicalize(signedInfoNode, **signedInfoC14nKw)         
     2000        signedInfoDigestValue = sha(c14nSignedInfo).digest() 
     2001         
     2002        # Get the signature value in order to check against the digest just 
     2003        # calculated 
     2004        signatureValueNode = xpath.Evaluate('//ds:SignatureValue', 
     2005                                            contextNode=parsedSOAP.dom,  
     2006                                            context=ctxt)[0] 
     2007 
     2008        # Remove base 64 encoding 
     2009        b64EncSignatureValue = \ 
     2010                    str(signatureValueNode.childNodes[0].nodeValue).strip() 
     2011                     
     2012        signatureValue = base64.decodestring(b64EncSignatureValue) 
     2013 
     2014 
     2015        # Look for X.509 Cert in wsse:BinarySecurityToken node 
     2016        try: 
     2017            binSecTokNode = xpath.Evaluate('//wsse:BinarySecurityToken', 
     2018                                           contextNode=parsedSOAP.dom, 
     2019                                           context=ctxt)[0] 
     2020            x509str = binSecTokNode.childNodes[0]._get_nodeValue() 
     2021            x509strAlt = '' 
     2022            i = 0 
     2023            while i < len(x509str): 
     2024                x509strAlt += "%s\n" % x509str[i:i+64] 
     2025                i += 64 
     2026     
     2027            raise Exception, "Try reading from file" 
     2028            x509Cert = X509.load_cert_string(x509strAlt) 
     2029        except: 
     2030            # If not, check cert file     
     2031            x509Cert = X509.load_cert(self.__certFilePath) 
     2032         
     2033        # Extract RSA public key from the cert 
     2034        rsaPubKey = x509Cert.get_pubkey().get_rsa() 
     2035         
     2036        # Apply the signature verification 
     2037        try: 
     2038            verify = bool(rsaPubKey.verify(signedInfoDigestValue,  
     2039                                           signatureValue)) 
     2040        except RSA.RSAError: 
     2041            raise VerifyError, "Error in Signature" 
     2042         
     2043        if not verify: 
     2044            raise VerifyError, "Invalid signature" 
     2045         
     2046#        import pdb;pdb.set_trace() 
     2047 
     2048 
     2049    #_________________________________________________________________________ 
     2050    def encrypt(self, 
     2051                xmlTxt=None,  
     2052                filePath=None,  
     2053                encrCertFilePath=None, 
     2054                inclX509SubjName=True, 
     2055                inclX509IssSerial=True, 
     2056                rtnAsString=False): 
     2057        """Encrypt a document using recipient's public key 
     2058 
     2059        Encrypts xml file using a dynamically created template, a session  
     2060        triple DES key and an RSA key from keys manager. 
     2061         
     2062        xmlTxt:                 string buffer containing the text from the XML 
     2063                                file to be encrypted.  If omitted, the 
     2064                                filePath argument is used instead. 
     2065 
     2066        filePath:               file path to XML file to be encrypted.  This 
     2067                                argument is used if no xmlTxt was provided. 
     2068                                If filePath itself is omitted the file set 
     2069                                by self.__filePath is read instead. 
     2070                                 
     2071        encrCertFilePath:     file path to RSA public key file used to 
     2072                                encrypt the document. 
     2073                                 
     2074        inclX509SubjName:       include subject name of signing X.509  
     2075                                certificate. 
     2076        inclX509IssSerial:      include issuer name and serial number in 
     2077                                signature     
     2078         
     2079        rtnAsString:            This method returns None by default.  Set to  
     2080                                True to override and return the encrypted 
     2081                                result instead as a string.""" 
     2082         
     2083 
     2084        # Success 
     2085        if rtnAsString: 
     2086            return self.asString() 
     2087  
     2088  
     2089    #_________________________________________________________________________ 
     2090    def decrypt(self,  
     2091                xmlTxt=None,  
     2092                filePath=None,  
     2093                encrPriKeyFilePath=None, 
     2094                encrPriKeyPwd=None, 
     2095                rtnAsString=False): 
     2096        """Decrypt a document using a private key of public/private key pair 
     2097         
     2098        xmlTxt:                 string buffer containing the text from the XML 
     2099                                file to be decrypted.  If omitted, the 
     2100                                filePath argument is used instead. 
     2101 
     2102        filePath:               file path to XML file to be decrypted.  This 
     2103                                argument is used if no xmlTxt was provided. 
     2104                                If filePath itself is omitted the file set 
     2105                                by self.__filePath is read instead. 
     2106                                 
     2107        encrPriKeyFilePath:     file path to private key file used to decrypt 
     2108 
     2109        encrPriKeyPwd:          password for private key file. 
     2110         
     2111        rtnAsString:            This method returns None by default.  Set to  
     2112                                True to override and return the decrypted 
     2113                                result instead as a string.""" 
     2114         
     2115        if encrPriKeyFilePath: 
     2116            self.__setEncrPriKeyFilePath(encrPriKeyFilePath) 
     2117     
     2118        # Success 
     2119        if rtnAsString: 
     2120            return self.asString() 
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/MyProxy.py

    r1940 r1945  
    661661    #_________________________________________________________________________    
    662662    def store(self, 
    663               username,  
     663              username, 
     664              passphrase,  
    664665              certFile, 
    665666              keyFile, 
     
    673674        Exceptions:  GetError, RetrieveError 
    674675         
    675         @param username: username selected for credential 
     676        @param username: username selected for new credential 
     677        @param passphrase: pass-phrase for new credential.  This is the pass 
     678        phrase which protects keyfile. 
    676679        @param certFile: user's X.509 certificate in PEM format 
    677680        @param keyFile: equivalent private key file in PEM format 
     
    704707                                         *MyProxyClient._hostKeySubDirPath) 
    705708            else: 
     709                # Default so that the owner is the same as the ID of the  
     710                # credentials to be uploaded. 
    706711                ownerCertFile = certFile  
    707712                ownerKeyFile = keyFile 
    708          
     713                ownerPassphrase = passphrase 
     714                 
    709715        if not force: 
    710716            # Check credentials don't already exist 
     
    749755        if respCode: 
    750756            raise RetrieveError, errorTxt 
     757         
    751758         
    752759    #_________________________________________________________________________            
  • TI12-security/trunk/python/ndg.security.server/ndg/security/server/SessionMgr/__init__.py

    r1940 r1945  
    223223         
    224224        sessCookie = SessionCookie(dtExpiry=dtExpiry, 
    225                                  cookieDomain=cookieDomain, 
    226                                  **cookieTagsKw) 
     225                                   cookieDomain=cookieDomain, 
     226                                   **cookieTagsKw) 
    227227        if asString: 
    228228            return str(sessCookie) 
     
    282282        # MyProxy interface 
    283283        try: 
    284             self.__myPx = MyProxy() 
     284            self.__myPx = MyProxyClient() 
    285285             
    286286        except Exception, e: 
     
    383383    def __delitem__(self, key): 
    384384        "Session Manager keys cannot be removed"         
    385         raise KeyError('Keys cannot be deleted from '+self.__class__.__name__) 
     385        raise KeyError, 'Keys cannot be deleted from '+self.__class__.__name__ 
    386386 
    387387 
     
    391391        """ 
    392392        if key not in self.__prop: 
    393             raise KeyError("Invalid key " + key) 
     393            raise KeyError, "Invalid key " + key 
    394394         
    395395        return self.__prop[key] 
     
    403403 
    404404    def clear(self): 
    405         raise KeyError("Data cannot be cleared from "+self.__class__.__name__) 
     405        raise KeyError, "Data cannot be cleared from "+self.__class__.__name__ 
    406406    
    407407    def keys(self): 
     
    533533 
    534534    #_________________________________________________________________________ 
    535     def addUser(self, caConfigFilePath=None, caPassPhrase=None, **reqKeys):         
     535    def addUser(self, username, passphrase=None):         
    536536        """Register a new user with an NDG data centre 
    537537         
     
    552552                                        passphrase is required. 
    553553                                         
    554         **reqKeys:                      use as alternative to  
     554        **kw:                      use as alternative to  
    555555                                        reqXMLtxt keyword - pass in  
    556556                                        username and pass-phrase for new user  
    557557                                        unencrypted as keywords username 
    558                                         and pPhrase respectively.  See 
    559                                         SessionMgrIO.AddUserRequest class for 
    560                                         reference.""" 
     558                                        and pPhrase respectively.""" 
    561559               
    562         try: 
    563             # Add new user certificate to MyProxy Repository 
    564             # 
    565             # Changed so that record is NOT added to UserID table of  
    566             # CredentialRepository.  Instead, a check can be made when a new 
    567             # Attribute Certificate credential is added: if no entry is  
    568             # present for the user, add them into the UserID table at this  
    569             # point. 
    570             # 
    571             # By removing the add record call, MyProxy and Credential 
    572             # Repository can be independent of one another 
    573             user = self.__myPx.addUser(reqKeys['userName'], 
    574                                        reqKeys['pPhrase'], 
    575                                        caConfigFilePath=caConfigFilePath, 
    576                                        caPassPhrase=caPassPhrase, 
    577                                        retDN=True)            
    578         except Exception, e: 
    579             return AddUserResp(errMsg=str(e)) 
    580  
    581         return AddUserResp(errMsg='') 
     560        # Ask CA to sign certificate 
     561         
     562        # Add new user certificate to MyProxy Repository 
     563        self.__myPx.store(username,  
     564          certFile, 
     565          keyFile, 
     566          ownerCertFile=None, 
     567          ownerKeyFile=None, 
     568          ownerPassphrase=None, 
     569          lifetime=None, 
     570          force=True) 
     571 
     572        return userDN            
    582573     
    583574     
    584575    #_________________________________________________________________________         
    585     def connect(self, **reqKeys):         
     576    def connect(self, getCookie=False, createServerSess=True, **kw):         
    586577        """Create a new user session or connect to an existing one: 
    587578 
    588         connect([getCookie=True/False][createServerSess=Tue/False, ] 
    589                 [, userName=u, pPhrase=p]|[, proxyCert=px]|[, sessID=id]) 
    590  
    591         getCookie:              If True, allocate a user session with a  
    592                                 wallet in the session manager and return a  
    593                                 cookie containing the new session ID  
    594                                 allocated.  If set False, return a proxy  
    595                                 certificate only.  The client is then  
    596                                 responsible for Credential Wallet management. 
    597         createServerSess:       If set to True, the SessionMgr will create 
    598                                 and manage a session for the user.  Nb. 
    599                                 this flag is ignored and set to True if 
    600                                 getCookie is set.  For command line case, 
    601                                 where getCookie is False, it's possible 
    602                                 to choose to have a client or server side 
    603                                 session using this keyword. 
    604         reqKeys:                username and pass-phrase OR proxy certificate 
    605                                 OR session ID""" 
    606          
    607  
    608         if 'sessID' in reqKeys: 
    609              
     579        connect([getCookie=True/False][createServerSess=True/False, ] 
     580                [, username=u, passphrase=p]|[, proxyCert=px]|[, sessID=id]) 
     581 
     582        @param getCookie: If True, allocate a user session with a wallet in  
     583        the session manager and return a cookie containing the new session ID  
     584        allocated.  If set False, return a proxy certificate only.  The client 
     585        is then responsible for Credential Wallet management. 
     586         
     587        @param createServerSess: If set to True, the SessionMgr will create 
     588        and manage a session for the user.  Nb. this flag is ignored and set  
     589        to True if getCookie is set.  For command line case, where getCookie 
     590        is False, it's possible to choose to have a client or server side 
     591        session using this keyword. 
     592         
     593        @param **kw: username and pass-phrase OR proxy certificate OR session  
     594        ID keywords 
     595        @return tuple containing proxy certificate and session cookie  
     596        respectively.  Cookie will be None if getCookie is set to False.   
     597        Proxy cert. will be None if 'proxyCert' was set as an input.""" 
     598         
     599        # Initial proxy cert and cookie to be returned 
     600        proxyCert, sessCookie = None, None 
     601         
     602        if 'sessID' in kw:             
    610603            # Connect to an existing session identified by a session ID and  
    611604            # return equivalent proxy cert 
    612             userSess = self.__connect2UserSession(sessID=sessID) 
    613             return ConnectResp(proxyCert=userSess.credWallet.proxyCertTxt) 
    614          
    615         elif 'proxyCert' in reqKeys: 
     605            userSess = self.__connect2UserSession(sessID=kw['sessID']) 
     606            proxyCert = userSess.credWallet.proxyCertTxt 
     607         
     608        elif 'proxyCert' in kw: 
    616609            # Connect to an existing session identified by a proxy  
    617             # certificate and return an equivalent session cookie 
    618             userSess = self.__connect2UserSession(proxyCert=proxyCert) 
    619             sessCookie = userSess.createCookie(self.__prop['sessMgrWSDLuri'], 
    620                                                self.__prop['sessMgrEncrKey']) 
    621             return ConnectResp(sessCookie=sessCookie) 
    622          
     610            # certificate  
     611            userSess = self.__connect2UserSession(proxyCert=kw['proxyCert']) 
     612             
     613            # Make a new session cookie 
     614            sessCookie = userSess.createCookie(\ 
     615                                   self.__prop['sessMgrWSDLuri'], 
     616                                   self.__prop['sessMgrEncrKey'], 
     617                                   cookieDomain=self.__prop['cookieDomain']) 
    623618        else: 
    624619            # Create a fresh session 
     
    626621                # Get a proxy certificate to represent users ID for the new 
    627622                # session 
    628                 proxyCert = self.__myPx.getDelegation(reqKeys['userName'],  
    629                                                       reqKeys['pPhrase'])     
     623                proxyCert = self.__myPx.getDelegation(kw['username'],  
     624                                                      kw['passphrase'])     
    630625            except Exception, e: 
    631626                raise SessionMgrError, "Delegating from MyProxy: %s" % e 
    632627 
    633             bGetCookie = 'getCookie' in reqKeys and reqKeys['getCookie'] 
    634                                                  
    635             bCreateServerSess = 'createServerSess' in reqKeys and \ 
    636                                             reqKeys['createServerSess'] 
    637                                              
    638             if bGetCookie or bCreateServerSess: 
     628            if getCookie or createServerSess: 
    639629                # Session Manager creates and manages user's session 
    640630                userSess = self.__createUserSession(proxyCert) 
    641   
    642                                 
    643             if bGetCookie: 
    644                  
     631                                 
     632            if getCookie:                 
    645633                # Web browser client - Return session cookie 
    646                 userSess.cookieDomain = self.__prop['cookieDomain'] 
    647  
    648634                sessCookie = userSess.createCookie(\ 
    649                                             self.__prop['sessMgrWSDLuri'], 
    650                                             self.__prop['sessMgrEncrKey']) 
    651                  
    652                 try: 
    653                     # Encrypt response if a client public key is available 
    654                     return ConnectResp(sessCookie=sessCookie) 
    655                  
    656                 except Exception, e: 
    657                     raise SessionMgrError, \ 
    658                                 "Error formatting connect response: %s" % e               
    659             else: 
    660                 # NDG Command line client - Return proxy certificate 
    661                 return ConnectResp(proxyCert=proxyCert)         
     635                                    self.__prop['sessMgrWSDLuri'], 
     636                                    self.__prop['sessMgrEncrKey'], 
     637                                    cookieDomain=self.__prop['cookieDomain']) 
     638                 
     639        # Return proxy certificate and cookie 
     640        return proxyCert, sessCookie         
    662641         
    663642        
     
    667646        and return 
    668647         
    669         """ 
    670          
    671         try:    
    672             # Check for an existing session for the same user 
    673             try: 
    674                 userDN = str(X509CertParse(proxyCert).dn) 
    675                  
    676             except Exception, e: 
    677                 raise SessionMgrError, \ 
    678                 "Parsing input proxy certificate DN for session create: %s"%\ 
    679                                                                         str(e) 
    680  
    681             if userDN in self.__dnDict: 
    682                 # Update existing session with proxy cert and add a new  
    683                 # session ID to access it - a single session can be accessed 
    684                 # via multiple session IDs e.g. a user may wish to access the 
    685                 # same session from the their desktop PC and their laptop. 
    686                 # Different session IDs are allocated in each case. 
    687                 userSess = self.__dnDict[userDN] 
    688                 userSess.addNewSessID() 
    689                  
    690             else: 
    691                 # Create a new user session using the new proxy certificate 
    692                 # and session ID 
    693                 # 
    694                 # Nb. Client pub/pri key info to allow message level  
    695                 # encryption for responses from Attribute Authority WS 
     648        @param proxyCert: string containing proxy certificate, private key 
     649        and issuing certificate.""" 
     650         
     651        # Check for an existing session for the same user 
     652        try: 
     653            userDN = str(X509CertParse(proxyCert).dn) 
     654             
     655        except Exception, e: 
     656            raise SessionMgrError, \ 
     657            "Parsing input proxy certificate DN for session create: %s" % \ 
     658                                                                    str(e) 
     659 
     660        if userDN in self.__dnDict: 
     661            # Update existing session with proxy cert and add a new  
     662            # session ID to access it - a single session can be accessed 
     663            # via multiple session IDs e.g. a user may wish to access the 
     664            # same session from the their desktop PC and their laptop. 
     665            # Different session IDs are allocated in each case. 
     666            userSess = self.__dnDict[userDN] 
     667            userSess.addNewSessID() 
     668             
     669        else: 
     670            # Create a new user session using the new proxy certificate 
     671            # and session ID 
     672            # 
     673            # Nb. Client pub/pri key info to allow message level  
     674            # encryption for responses from Attribute Authority WS 
     675            try:    
    696676                userSess = UserSession(proxyCert,  
    697677                                   caCertFilePath=self.__prop['caCertFile'], 
     
    699679                                   clntPriKeyFilePath=self.__prop['keyFile'], 
    700680                                   clntPriKeyPwd=self.__prop['keyPPhrase'], 
    701                                    credRepos=self.__credRepos) 
    702  
    703                 # Also allow access by user DN 
    704                 self.__dnDict[userDN] = userSess 
    705  
    706                                  
    707             newSessID = userSess.latestSessID 
    708              
    709             # Check for unique session ID 
    710             if newSessID in self.__sessDict: 
    711                 raise SessionMgrError, \ 
    712                     "New Session ID is already in use:\n\n %s" % newSessID 
    713  
    714             # Add new session to list                  
    715             self.__sessDict[newSessID] = userSess 
    716                      
    717             # Return new session 
    718             return userSess 
    719          
    720         except Exception, e: 
    721             raise SessionMgrError, "Creating User Session: %s" % str(e) 
     681                                   credRepos=self.__credRepos)        
     682            except Exception, e: 
     683                raise SessionMgrError, "Creating User Session: %s" % str(e) 
     684 
     685            # Also allow access by user DN 
     686            self.__dnDict[userDN] = userSess 
     687 
     688                             
     689        newSessID = userSess.latestSessID 
     690         
     691        # Check for unique session ID 
     692        if newSessID in self.__sessDict: 
     693            raise SessionMgrError, \ 
     694                "New Session ID is already in use:\n\n %s" % newSessID 
     695 
     696        # Add new session to list                  
     697        self.__sessDict[newSessID] = userSess 
     698                 
     699        # Return new session 
     700        return userSess 
    722701 
    723702 
    724703    #_________________________________________________________________________         
    725     def __connect2UserSession(self, **idKeys): 
     704    def __connect2UserSession(self, **idKw): 
    726705        """Connect to an existing session by providing a valid session ID or 
    727706        proxy certificate 
     
    729708        __connect2UserSession([proxyCert]|[sessID]) 
    730709         
    731         proxyCert:    proxy certificate string corresponding to an existing  
    732                       session to connect to. 
    733         sessID:       similiarly, a web browser session ID linking to an 
    734                       an existing session.""" 
     710        @param proxyCert: proxy certificate string corresponding to an  
     711        existing session to connect to. 
     712         
     713        @param sessID: similiarly, a web browser session ID linking to an 
     714        an existing session.""" 
    735715         
    736716             
    737717        # Look for a session corresponding to this ID 
    738         if 'sessID' in idKeys: 
     718        if 'sessID' in idKw: 
    739719            try: 
    740720                # Check matched session has not expired 
    741                 userSess = self.__sessDict[idKeys['sessID']] 
     721                userSess = self.__sessDict[idKw['sessID']] 
    742722                 
    743723            except KeyError: 
     
    755735                 
    756736         
    757         elif 'proxyCert' in idKeys: 
    758             try: 
    759                 userDN = str(X509CertParse(idKeys['proxyCert']).dn) 
     737        elif 'proxyCert' in idKw: 
     738            try: 
     739                userDN = str(X509CertParse(idKw['proxyCert']).dn) 
    760740                 
    761741            except Exception, e: 
     
    791771        __deleteUserSession([proxyCert]|[sessID]) 
    792772         
    793         proxyCert:    proxy certificate corresponding to an existing  
    794                       session to connect to. 
    795         sessID:      similiarly, a web browser session ID linking to an 
    796                       an existing session.""" 
     773        @param proxyCert: proxy certificate corresponding to an existing  
     774        session to connect to. 
     775        @param sessID: similiarly, a web browser session ID linking to an 
     776        an existing session.""" 
    797777         
    798778             
     
    811791        elif proxyCert: 
    812792            try: 
    813                 userDN = str(X509CertParse(idKeys['proxyCert']).dn) 
     793                userDN = str(X509CertParse(idKw['proxyCert']).dn) 
    814794                 
    815795            except Exception, e: 
     
    843823 
    844824    #_________________________________________________________________________ 
    845     def reqAuthorisation(self, **reqKeys): 
    846         """For given sessID, request authorisation from an Attribute Authority 
    847         given by aaWSDL.  If sucessful, an attribute certificate is 
    848         returned. 
    849  
    850         **reqKeys:            pass equivalent to XML as keywords instead. 
    851                               See SessionMgrIO.AuthorisationReq class 
     825    def reqAuthorisation(self, **kw): 
     826        """For a given user, request authorisation from an Attribute Authority 
     827        given by service URI.  If sucessful, an attribute certificate is 
     828        added to the user session credential wallet and also returned from  
     829        this method 
     830 
     831        @param **kw: 
    852832        """ 
    853833         
    854834        # Web browser client input will include the encrypted address of the 
    855835        # Session Manager where the user's session is held. 
    856         if 'encrSessMgrWSDLuri' in reqKeys: 
     836        if 'encrSessMgrWSDLuri' in kw: 
    857837             
    858838            # Decrypt the URI for where the user's session resides 
    859             userSessMgrWSDLuri = UserSession.decrypt(\ 
    860                                                 reqKeys['encrSessMgrWSDLuri'], 
     839            userSessMgrURI = UserSession.decrypt(kw['encrSessMgrWSDLuri'], 
    861840                                                self.__prop['sessMgrEncrKey']) 
    862841                                                
    863842            # Check the address against the address of THIS Session Manager   
    864             if userSessMgrWSDLuri != self.__prop['sessMgrWSDLuri']: 
     843            if userSessMgrURI != self.__prop['sessMgrWSDLuri']: 
    865844                 
    866845                # Session is held on a remote Session  Manager 
    867846                userSessMgrResp = self.__redirectAuthorisationReq(\ 
    868                                                         userSessMgrWSDLuri, 
    869                                                         **reqKeys) 
     847                                                        userSessMgrURI, 
     848                                                        **kw) 
    870849 
    871850                # Reset response by making a new AuthorisationResp object 
     
    882861        # Retrieve session corresponding to user's session ID using relevant 
    883862        # input credential 
    884         idKeys = {} 
    885         if 'sessID' in reqKeys: 
    886             idKeys['sessID'] = reqKeys['sessID'] 
    887              
    888         elif 'proxyCert' in reqKeys: 
    889             idKeys['proxyCert'] = reqKeys['proxyCert']            
     863        idKw = {} 
     864        if 'sessID' in kw: 
     865            idKw['sessID'] = kw['sessID'] 
     866             
     867        elif 'proxyCert' in kw: 
     868            idKw['proxyCert'] = kw['proxyCert']            
    890869        else: 
    891870            raise SessionMgrError,'Expecting "sessID" or "proxyCert" keywords' 
    892871                                 
    893         userSess = self.__connect2UserSession(**idKeys) 
     872        userSess = self.__connect2UserSession(**idKw) 
    894873 
    895874 
     
    900879        delKeys = ('proxyCert', 
    901880                   'sessID', 
    902                    'encrCert', 
    903881                   'encrSessMgrWSDLuri',  
    904882                   'aaCert') 
    905883                    
    906         aaKeys = dict([i for i in reqKeys.items() if i[0] not in delKeys]) 
    907  
    908  
    909         if 'aaCert' not in reqKeys: 
     884        aaKeys = dict([i for i in kw.items() if i[0] not in delKeys]) 
     885 
     886 
     887        if 'aaCert' not in kw: 
    910888            # Get public key using WS 
    911889            try: 
    912                 aaClnt = AttAuthorityClient(aaWSDL=reqKeys['aaWSDL'])                 
    913                 reqKeys['aaCert'] = aaClnt.getCert() 
     890                aaClnt = AttAuthorityClient(aaWSDL=kw['aaWSDL'])                 
     891                kw['aaCert'] = aaClnt.getCert() 
    914892 
    915893            except Exception, e: 
     
    923901        try: 
    924902            aaCertTmpFile = tempfile.NamedTemporaryFile() 
    925             open(aaCertTmpFile.name, "w").write(reqKeys['aaCert']) 
     903            open(aaCertTmpFile.name, "w").write(kw['aaCert']) 
    926904            aaKeys['aaCertFilePath'] = aaCertTmpFile.name 
    927905             
     
    934912                                  "Authority public key: %s" % str(e) 
    935913 
    936                                                
     914        # Initialise return args 
     915        attCert, statCode, msg, extAttCertList = None, \ 
     916                                            CredWallet.accessDenied, None, [] 
     917                                            
    937918        # User's Credential Wallet carries out authorisation request to the 
    938919        # Attribute Authority 
     
    942923            # AuthorisationResp class formats a response message in XML and 
    943924            # allow dictionary-like access to XML tags 
    944             resp = AuthorisationResp(attCert=attCert,  
    945                                      statCode=AuthorisationResp.accessGranted) 
     925            statCode = CredWallet.accessGranted 
    946926             
    947927        except CredWalletAuthorisationDenied, e: 
     
    949929            # which could be used to re-try to get authorisation via a mapped 
    950930            # certificate 
    951             resp = AuthorisationResp(extAttCertList=e.extAttCertList, 
    952                                      statCode=AuthorisationResp.accessDenied, 
    953                                      errMsg=str(e)) 
    954          
    955         except Exception, e: 
    956             # Some other error occured - create an error Authorisation 
    957             # response 
    958             resp = AuthorisationResp(statCode=AuthorisationResp.accessError, 
    959                                      errMsg=str(e)) 
    960      
    961         return resp 
    962  
    963  
    964     #_________________________________________________________________________ 
    965     def __redirectAuthorisationReq(self, userSessMgrWSDLuri, **reqKeys): 
     931            msg = str(e) 
     932     
     933        return attCert, statCode, msg, extAttCertList 
     934 
     935 
     936    #_________________________________________________________________________ 
     937    def __redirectAuthorisationReq(self, userSessMgrURI, **kw): 
    966938        """Handle case where User session resides on another Session Manager - 
    967         forward the request""" 
     939        forward the request 
     940         
     941        @param userSessMgrURI: address of remote session manager where user 
     942        session is held 
     943         
     944        @param **kw: same keywords which apply to reqAuthorisation call""" 
    968945         
    969946        # Instantiate WS proxy for remote session manager 
    970947        try: 
    971             sessClnt = SessionClient(smWSDL=userSessMgrWSDLuri, 
     948            sessClnt = SessionClient(smWSDL=userSessMgrURI, 
    972949                                 clntCertFilePath=self.__prop['certFile'], 
    973950                                 clntPriKeyFilePath=self.__prop['keyFile'])            
    974951        except Exception, e: 
    975             raise SessionMgrError(\ 
     952            raise SessionMgrError, \ 
    976953                        "Re-directing authorisation request to \"%s\": %s" % \ 
    977                         (userSessMgrWSDLuri, str(e))) 
     954                        (userSessMgrURI, str(e)) 
    978955 
    979956             
     
    981958        # and return result to caller 
    982959        try: 
    983             # encrCert key not needed - it gets set above via  
    984             # 'clntCertFilePath' 
    985             if 'encrCert' in reqKeys: 
    986                 del reqKeys['encrCert'] 
    987                  
    988960            # Call remote SessionMgr where users session lies 
    989961            redirectAuthResp = sessClnt.reqAuthorisation(\ 
    990962                                    clntPriKeyPwd=self.__prop['keyPPhrase'], 
    991                                     **reqKeys) 
     963                                    **kw) 
    992964           
    993965            return redirectAuthResp 
    994966         
    995967        except Exception, e: 
    996             raise SessionMgrError(\ 
     968            raise SessionMgrError, \ 
    997969        "Forwarding Authorisation request for Session Manager \"%s\": %s" %\ 
    998                 (userSessMgrWSDLuri, e)) 
     970                (userSessMgrURI, e) 
    999971 
    1000972 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/MyProxy/MyProxyClientTest.py

    r1940 r1945  
    3737    def test1Store(self): 
    3838        '''test1Store: upload X509 cert and private key to repository''' 
    39         ownerPassphrase = self.cfg['test1Store']['ownerpassphrase'] or \ 
     39             
     40        passphrase = self.cfg['test1Store'].get('passphrase') or \ 
     41            getpass.getpass(prompt="\ntest1Store cred. pass-phrase: ") 
     42             
     43        ownerPassphrase = self.cfg['test1Store'].get('ownerpassphrase') or \ 
    4044            getpass.getpass(prompt="\ntest1Store cred. owner pass-phrase: ") 
    4145             
    4246        try: 
    4347            self.clnt.store(self.cfg['test1Store']['username'], 
    44                         self.cfg['test1Store']['ownercertfile'], 
    45                         self.cfg['test1Store']['ownerkeyfile'], 
     48                        passphrase, 
     49                        self.cfg['test1Store']['certfile'], 
     50                        self.cfg['test1Store']['keyfile'], 
    4651                        ownerCertFile=self.cfg['test1Store']['ownercertfile'], 
    4752                        ownerKeyFile=self.cfg['test1Store']['ownerkeyfile'], 
     
    7378    def test3Info(self): 
    7479        '''test3Info: Retrieve information about a given credential''' 
    75         ownerpassphrase = self.cfg['test3Info']['ownerpassphrase'] or \ 
     80         
     81        # ownerpassphrase can be omitted from the congif file in which case 
     82        # the get call below would return None 
     83        ownerpassphrase = self.cfg['test3Info'].get('ownerpassphrase') or \ 
    7684            getpass.getpass(prompt="\ntest3Info owner creds pass-phrase: ") 
    7785 
    78         ownerpassphrase = (ownerpassphrase == 'None') and None 
    79          
    8086        try: 
    8187            credExists, errorTxt, fields = self.clnt.info( 
  • TI12-security/trunk/python/ndg.security.test/ndg/security/test/MyProxy/myProxyClientTest.cfg

    r1881 r1945  
    1212[test1Store] 
    1313username: sstljakTestUser 
     14passphrase: 
    1415certFile: ./userCert.pem 
    1516keyFile: ./userKey.pem 
Note: See TracChangeset for help on using the changeset viewer.