Пример #1
0
    def generate_name_id(value, sp_nq, sp_format, cert=None, debug=False):
        """
        Generates a nameID.

        :param value: fingerprint
        :type: string

        :param sp_nq: SP Name Qualifier
        :type: string

        :param sp_format: SP Format
        :type: string

        :param cert: IdP Public Cert to encrypt the nameID
        :type: string

        :param debug: Activate the xmlsec debug
        :type: bool

        :returns: DOMElement | XMLSec nameID
        :rtype: string
        """
        doc = Document()
        name_id_container = doc.createElementNS(OneLogin_Saml2_Constants.NS_SAML, 'container')
        name_id_container.setAttribute("xmlns:saml", OneLogin_Saml2_Constants.NS_SAML)

        name_id = doc.createElement('saml:NameID')
        name_id.setAttribute('SPNameQualifier', sp_nq)
        name_id.setAttribute('Format', sp_format)
        name_id.appendChild(doc.createTextNode(value))
        name_id_container.appendChild(name_id)

        if cert is not None:
            xml = name_id_container.toxml()
            elem = fromstring(xml)

            xmlsec.initialize()

            if debug:
                xmlsec.set_error_callback(print_xmlsec_errors)

            # Load the public cert
            mngr = xmlsec.KeysMngr()
            file_cert = OneLogin_Saml2_Utils.write_temp_file(cert)
            key_data = xmlsec.Key.load(file_cert.name, xmlsec.KeyDataFormatCertPem, None)
            key_data.name = basename(file_cert.name)
            mngr.addKey(key_data)
            file_cert.close()

            # Prepare for encryption
            enc_data = EncData(xmlsec.TransformAes128Cbc, type=xmlsec.TypeEncElement)
            enc_data.ensureCipherValue()
            key_info = enc_data.ensureKeyInfo()
            # enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaPkcs1)
            enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaOaep)
            enc_key.ensureCipherValue()

            # Encrypt!
            enc_ctx = xmlsec.EncCtx(mngr)
            enc_ctx.encKey = xmlsec.Key.generate(xmlsec.KeyDataAes, 128, xmlsec.KeyDataTypeSession)

            edata = enc_ctx.encryptXml(enc_data, elem[0])

            newdoc = parseString(etree.tostring(edata))

            if newdoc.hasChildNodes():
                child = newdoc.firstChild
                child.removeAttribute('xmlns')
                child.removeAttribute('xmlns:saml')
                child.setAttribute('xmlns:xenc', OneLogin_Saml2_Constants.NS_XENC)
                child.setAttribute('xmlns:dsig', OneLogin_Saml2_Constants.NS_DS)

            nodes = newdoc.getElementsByTagName("*")
            for node in nodes:
                if node.tagName == 'ns0:KeyInfo':
                    node.tagName = 'dsig:KeyInfo'
                    node.removeAttribute('xmlns:ns0')
                    node.setAttribute('xmlns:dsig', OneLogin_Saml2_Constants.NS_DS)
                else:
                    node.tagName = 'xenc:' + node.tagName

            encrypted_id = newdoc.createElement('saml:EncryptedID')
            encrypted_data = newdoc.replaceChild(encrypted_id, newdoc.firstChild)
            encrypted_id.appendChild(encrypted_data)
            return newdoc.saveXML(encrypted_id)
        else:
            return doc.saveXML(name_id)
Пример #2
0
    def generate_name_id(value,
                         sp_nq,
                         sp_format=None,
                         cert=None,
                         debug=False,
                         nq=None):
        """
        Generates a nameID.

        :param value: fingerprint
        :type: string

        :param sp_nq: SP Name Qualifier
        :type: string

        :param sp_format: SP Format
        :type: string

        :param cert: IdP Public Cert to encrypt the nameID
        :type: string

        :param debug: Activate the xmlsec debug
        :type: bool

        :param nq: IDP Name Qualifier
        :type: string

        :returns: DOMElement | XMLSec nameID
        :rtype: string
        """
        doc = Document()
        name_id_container = doc.createElementNS(
            OneLogin_Saml2_Constants.NS_SAML, 'container')
        name_id_container.setAttribute("xmlns:saml",
                                       OneLogin_Saml2_Constants.NS_SAML)

        name_id = doc.createElement('saml:NameID')
        if sp_nq is not None:
            name_id.setAttribute('SPNameQualifier', sp_nq)
        if nq is not None:
            name_id.setAttribute('NameQualifier', nq)
        if sp_format is not None:
            name_id.setAttribute('Format', sp_format)
        name_id.appendChild(doc.createTextNode(value))
        name_id_container.appendChild(name_id)

        if cert is not None:
            xml = name_id_container.toxml()
            elem = fromstring(xml)

            error_callback_method = None
            if debug:
                error_callback_method = print_xmlsec_errors
            xmlsec.set_error_callback(error_callback_method)

            # Load the public cert
            mngr = xmlsec.KeysMngr()
            file_cert = OneLogin_Saml2_Utils.write_temp_file(cert)
            key_data = xmlsec.Key.load(file_cert.name,
                                       xmlsec.KeyDataFormatCertPem, None)
            key_data.name = basename(file_cert.name)
            mngr.addKey(key_data)
            file_cert.close()

            # Prepare for encryption
            enc_data = EncData(xmlsec.TransformAes128Cbc,
                               type=xmlsec.TypeEncElement)
            enc_data.ensureCipherValue()
            key_info = enc_data.ensureKeyInfo()
            # enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaPkcs1)
            enc_key = key_info.addEncryptedKey(xmlsec.TransformRsaOaep)
            enc_key.ensureCipherValue()

            # Encrypt!
            enc_ctx = xmlsec.EncCtx(mngr)
            enc_ctx.encKey = xmlsec.Key.generate(xmlsec.KeyDataAes, 128,
                                                 xmlsec.KeyDataTypeSession)

            edata = enc_ctx.encryptXml(enc_data, elem[0])

            newdoc = parseString(
                tostring(edata, encoding='unicode').encode('utf-8'))

            if newdoc.hasChildNodes():
                child = newdoc.firstChild
                child.removeAttribute('xmlns')
                child.removeAttribute('xmlns:saml')
                child.setAttribute('xmlns:xenc',
                                   OneLogin_Saml2_Constants.NS_XENC)
                child.setAttribute('xmlns:dsig',
                                   OneLogin_Saml2_Constants.NS_DS)

            nodes = newdoc.getElementsByTagName("*")
            for node in nodes:
                if node.tagName == 'ns0:KeyInfo':
                    node.tagName = 'dsig:KeyInfo'
                    node.removeAttribute('xmlns:ns0')
                    node.setAttribute('xmlns:dsig',
                                      OneLogin_Saml2_Constants.NS_DS)
                else:
                    node.tagName = 'xenc:' + node.tagName

            encrypted_id = newdoc.createElement('saml:EncryptedID')
            encrypted_data = newdoc.replaceChild(encrypted_id,
                                                 newdoc.firstChild)
            encrypted_id.appendChild(encrypted_data)
            return newdoc.saveXML(encrypted_id)
        else:
            return doc.saveXML(name_id)
Пример #3
0
class XpathXml:
    def __init__(self, xmlFile=None, xmlRoot=None):
        from xml.dom.minidom import parse, Document, parseString
        self._xmlDoc = Document() if (xmlFile == None or xmlFile == "") else\
            (parse(xmlFile) if os.path.exists(xmlFile) else parseString(xmlFile))
        if xmlRoot != None:
            self._xmlDoc.appendChild(self.CreateNode(xmlRoot))

    def getNode(self, xpath, isGlobal=False, refNode=None):
        jpath = XmlOperation.XpathToJson(xpath, "{'Index':1}")
        if refNode == None:
            refNode = self._xmlDoc
        if isGlobal:
            attrs = [
                attr for attr in jpath.keys()
                if (attr != "Index" and attr != 'ClassName')
            ]
            expIndex = jpath['Index']
            actIndex = 0
            for curDoml in refNode.getElementsByTagName(jpath['ClassName']):
                isFound = True
                for attName in attrs:
                    if curDoml.getAttribute(attName) != jpath[attName]:
                        isFound = False
                        break
                if isFound:
                    actIndex += 1
                    if actIndex == expIndex:
                        return curDoml
            return None

        curDoml = refNode
        while curDoml != None:
            expNode = jpath['ClassName']
            expIndex = jpath['Index']

            actIndex = 0
            for tempDom in curDoml.childNodes:
                if tempDom.nodeName == expNode:
                    actIndex += 1
                    if actIndex == expIndex:
                        break
            if actIndex == expIndex:
                curDoml = tempDom
            else:
                curDoml = None

            try:
                jpath = jpath['Child']
            except:
                break
        return curDoml

    def getNodeContent(self, node, attName=None, refNode=None):
        from xml.dom.minidom import Element
        if refNode != None and type(node) != Element:
            node = self.GetNode(node, False, refNode)
        if node == None:
            return
        if attName == None or attName.length() == 0:
            return node.childNodes[0].nodeValue
        else:
            attNode = node.getAttribute(attName)
            if attNode != None:
                return attNode.nodeValue

    def getChildNodes(self, pXpath, refNode=None):
        from xml.dom.minidom import Element
        fNode = pXpath if type(pXpath) == Element else self.GetNode(
            pXpath, False, refNode)
        return [
            tempNode for tempNode in fNode.childNodes
            if type(tempNode) == Element
        ]

    def getChildren(self, pXpath, attName, seperator, *childXpaths):
        children = []
        if seperator == None:
            seperator = ""

        for tempNode in self.GetChildNodes(pXpath):

            childContent = None
            for childXpath in childXpaths:
                cNode = self.GetNode(childXpath, False, tempNode)
                if cNode != None:
                    if childContent == None:
                        childContent = ""
                    else:
                        childContent += seperator

                    nodeValue = self.GetNodeContent(cNode, attName)
                    if nodeValue != None:
                        childContent += nodeValue

            if childContent != None:
                children.append(childContent)

        return children

    def createNode(self, nodeName, nodeContent=None, **eleAttrs):
        ele = self._xmlDoc.createElement(nodeName)
        if nodeContent != None:
            ele.appendChild(self._xmlDoc.createTextNode(nodeContent))
        for attName in eleAttrs.keys():
            attVal = eleAttrs[attName]
            if attVal != None:
                ele.setAttribute(attName, attVal)
        return ele

    def setNode(self,
                xpath,
                isGlobal=False,
                nodeContent=None,
                nodeName=None,
                **eleAttrs):
        tNode = self.GetNode(xpath, isGlobal)
        if tNode != None:
            if nodeName != None:
                tNode.appendChild(
                    self.CreateNode(nodeName, nodeContent, **eleAttrs))
            else:
                if nodeContent != None:
                    tempContent = self._xmlDoc.createTextNode(str(nodeContent))
                    if len(tNode.childNodes) > 0:
                        tNode.childNodes[0] = tempContent
                    else:
                        tNode.appendChild(tempContent)
                for attName in eleAttrs:
                    tNode.setAttribute(attName, eleAttrs[attName])
            return True
        return False

    def removeNode(self, xpath, isGlobal=False, delNext=None):
        tNode = self.GetNode(xpath, isGlobal)
        if tNode != None:
            pNode = tNode.parentNode.childNodes
            if delNext != None:
                nIndex = pNode.index(tNode)
                for delIndex in range(nIndex, len(pNode)):
                    if pNode[delIndex].nodeName == delNext:
                        pNode.__delitem__(delIndex)
                        break
            pNode.remove(tNode)
            return True
        return False

    def saveTo(self, filePath):
        with codecs.open(filePath, mode='w', encoding="utf-8") as fileHandle:
            fileHandle.write(str(self))

    def __str__(self):
        return self._xmlDoc.saveXML(None)