def convertElementTree(self, root): """ Convert the given tree of etree.Element entries to a list of tree nodes for the current XML toolkit. """ nroot = self.newNode(root.tag) # Copy attributes for key, val in root.attrib: self.setAttribute(nroot, key, val) elements = [] # Add text if root.text: t = libxml2.newText(root.text) self.appendNode(nroot, t) # Add children for c in root: for n in self.expandChildElements(c): self.appendNode(nroot, n) elements.append(nroot) # Add tail if root.tail: tail = libxml2.newText(root.tail) elements.append(tail) return elements
def __parseToXML(self, node, data): # All supported variable types needs to be set up # here. TypeError exception will be raised on # unknown types. t = type(data) if t is unicode or t is str or t is int or t is float: n = libxml2.newText(self.__encode(data)) node.addChild(n) elif t is bool: v = data and "1" or "0" n = libxml2.newText(self.__encode(v)) node.addChild(n) elif t is dict: for (key, val) in data.iteritems(): node2 = libxml2.newNode(self.__encode(self.parsedata_prefix + key, True)) self.__parseToXML(node2, val) node.addChild(node2) elif t is tuple: for v in data: if type(v) is dict: self.__parseToXML(node, v) else: n = libxml2.newNode(self.tuple_tagname) self.__parseToXML(n, v) node.addChild(n) else: raise TypeError, "unhandled type (%s) for value '%s'" % (type(data), unicode(data))
def _build_node(self): ciphers = ",".join([ "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", ]) # Setup our node configuration connector = libxml2.newNode("Connector") self._add_attributes(connector, [ ("port", self.port), ("protocol", "HTTP/1.1"), ("SSLEnabled", "true"), ("maxThreads", "150"), ("scheme", "https"), ("secure", "true"), ]) sslconfig = libxml2.newNode("SSLHostConfig") self._add_attributes( sslconfig, [ ("certificateVerification", "optional"), # Note SSLv3 is not included, to avoid poodle # For the time being, TLSv1 needs to stay enabled in Satellite deployments to support # existing python-rhsm based clients (RHEL5). ("protocols", "+TLSv1,+TLSv1.1,+TLSv1.2"), ("sslProtocol", "TLS"), ("truststoreFile", "conf/keystore"), ("truststorePassword", "password"), ("truststoreType", "JKS"), ("ciphers", ciphers), ]) certificate = libxml2.newNode("Certificate") self._add_attributes(certificate, [ ("certificateKeystoreFile", "conf/keystore"), ("certificateKeystorePassword", "password"), ("certificateKeystoreType", "JKS"), ]) # Put it all together # The libxml2 bindings don't provide an obvious way to output indented XML, so we fake # it here to make it mostly human-readable. connector.addChild(libxml2.newText("\n ")) connector.addChild(sslconfig) connector.addChild(libxml2.newText("\n")) sslconfig.addChild(libxml2.newText("\n ")) sslconfig.addChild(certificate) sslconfig.addChild(libxml2.newText("\n ")) # Return our top-level node return connector
def _add_pretty_child(parentnode, newnode): """ Add 'newnode' as a child of 'parentnode', but try to preserve whitespace and nicely format the result. """ def node_is_text(n): return bool(n and n.type == "text" and not n.content.count("<")) def prevSibling(node): parent = node.get_parent() if not parent: return None prev = None for child in parent.children: if child == node: return prev prev = child return None sib = parentnode.get_last() if not node_is_text(sib): # This case is when we add a child element to a node for the # first time, like: # # <features/> # to # <features> # <acpi/> # </features> prevsib = prevSibling(parentnode) if node_is_text(prevsib): sib = libxml2.newText(prevsib.content) else: sib = libxml2.newText("\n") parentnode.addChild(sib) # This case is adding a child element to an already properly # spaced element. Example: # <features> # <acpi/> # </features> # to # <features> # <acpi/> # <apic/> # </features> sib = parentnode.get_last() content = sib.content sib = sib.addNextSibling(libxml2.newText(" ")) txt = libxml2.newText(content) sib.addNextSibling(newnode) newnode.addNextSibling(txt) return newnode
def _build_node(self): ciphers = ",".join([ "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", ]) # Setup our node configuration connector = libxml2.newNode("Connector") self._add_attributes(connector, [ ("port", self.port), ("protocol", "HTTP/1.1"), ("SSLEnabled", "true"), ("maxThreads", "150"), ("scheme", "https"), ("secure", "true"), ]) sslconfig = libxml2.newNode("SSLHostConfig") self._add_attributes(sslconfig, [ ("certificateVerification", "optional"), # Note SSLv3 is not included, to avoid poodle # For the time being, TLSv1 needs to stay enabled in Satellite deployments to support # existing python-rhsm based clients (RHEL5). ("protocols", "+TLSv1,+TLSv1.1,+TLSv1.2"), ("sslProtocol", "TLS"), ("truststoreFile", "conf/keystore"), ("truststorePassword", "password"), ("truststoreType", "JKS"), ("ciphers", ciphers), ]) certificate = libxml2.newNode("Certificate") self._add_attributes(certificate, [ ("certificateKeystoreFile", "conf/keystore"), ("certificateKeystorePassword", "password"), ("certificateKeystoreType", "JKS"), ]) # Put it all together # The libxml2 bindings don't provide an obvious way to output indented XML, so we fake # it here to make it mostly human-readable. connector.addChild(libxml2.newText("\n ")) connector.addChild(sslconfig) connector.addChild(libxml2.newText("\n")) sslconfig.addChild(libxml2.newText("\n ")) sslconfig.addChild(certificate) sslconfig.addChild(libxml2.newText("\n ")) # Return our top-level node return connector
def node_add_child(parentnode, newnode): """ Add 'newnode' as a child of 'parentnode', but try to preserve whitespace and nicely format the result. """ def node_is_text(n): return bool(n and n.type == "text" and "<" not in n.content) def prevSibling(node): parent = node.get_parent() if not parent: return None prev = None for child in parent.children: if child == node: return prev prev = child return None sib = parentnode.get_last() if not node_is_text(sib): # This case is when we add a child element to a node for the # first time, like: # # <features/> # to # <features> # <acpi/> # </features> prevsib = prevSibling(parentnode) if node_is_text(prevsib): sib = libxml2.newText(prevsib.content) else: sib = libxml2.newText("\n") parentnode.addChild(sib) # This case is adding a child element to an already properly # spaced element. Example: # <features> # <acpi/> # </features> # to # <features> # <acpi/> # <apic/> # </features> sib = parentnode.get_last() content = sib.content sib = sib.addNextSibling(libxml2.newText(" ")) txt = libxml2.newText(content) sib.addNextSibling(newnode) newnode.addNextSibling(txt) return newnode
def _create(self, parent): logger.info("Creating %s under %s on line %s" % (self.new_node, parent.name, parent.lineNo())) self._add_attributes(self.new_node, self.attributes) first_child = parent.firstElementChild() if first_child: # Insert the new node at the top so the output doesn't look like rubbish first_child.addPrevSibling(self.new_node) # Add a new line at the end of the new element first_child.addPrevSibling(libxml2.newText("\n\n")) else: parent.addChild(self.new_node) parent.addChild(libxml2.newText("\n\n"))
def _build_node(self): # <Connector port="8443" protocol="HTTP/1.1" # scheme="https" # secure="true" # SSLEnabled="true" # maxThreads="150"> # # <SSLHostConfig certificateVerification="optional" # protocols="+TLSv1,+TLSv1.1,+TLSv1.2" # sslProtocol="TLS" # ciphers="SSL_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"> # # <Certificate # certificateFile="/etc/candlepin/certs/candlepin-ca.crt" # certificateKeyFile="/etc/candlepin/certs/candlepin-ca.key" # type="RSA" # /> # </SSLHostConfig> # </Connector> connector = libxml2.newNode("Connector") self._add_attributes(connector, self.attributes) ssl_host_config = libxml2.newNode("SSLHostConfig") self._add_attributes(ssl_host_config, [ ("certificateVerification", "optional"), # Note SSLv3 is not included, to avoid poodle # For the time being, TLSv1 needs to stay enabled in Satellite deployments to support # existing python-rhsm based clients (RHEL5). ("protocols", "+TLSv1,+TLSv1.1,+TLSv1.2"), ("sslProtocol", "TLS"), ("ciphers", ",".join(SSL_CIPHERS)) ]) certificate = libxml2.newNode("Certificate") self._add_attributes(certificate, [ ('certificateFile', '/etc/candlepin/certs/candlepin-ca.crt'), ('certificateKeyFile', '/etc/candlepin/certs/candlepin-ca.key'), ('type', 'RSA') ]) # Put it all together # The libxml2 bindings don't provide an obvious way to output indented XML, so we fake # it here to make it mostly human-readable. connector.addChild(libxml2.newText("\n ")) connector.addChild(ssl_host_config) connector.addChild(libxml2.newText("\n")) ssl_host_config.addChild(libxml2.newText("\n ")) ssl_host_config.addChild(certificate) ssl_host_config.addChild(libxml2.newText("\n ")) # return return connector
def _create(self, parent): logger.info("Creating node \"%s\" under \"%s\" on line %s" % (self.new_node.name, parent.name, parent.lineNo())) logger.debug("New node: %s" % (self.new_node)) first_child = parent.firstElementChild() if first_child: # Insert the new node at the top so the output doesn't look like rubbish first_child.addPrevSibling(self.new_node) # Add a new line at the end of the new element first_child.addPrevSibling(libxml2.newText("\n\n")) else: parent.addChild(self.new_node) parent.addChild(libxml2.newText("\n\n"))
def _create(self, parent): logger.info("Creating %s under %s on line %s" % (self.element, parent.name, parent.lineNo())) new_element = libxml2.newNode(self.element) self._add_attributes(new_element, self.attributes) first_child = parent.firstElementChild() if first_child: # Insert the new node at the top so the output doesn't look like rubbish first_child.addPrevSibling(new_element) # Add a new line at the end of the new element first_child.addPrevSibling(libxml2.newText("\n\n")) else: parent.addChild(new_element) parent.addChild(libxml2.newText("\n\n"))
def __generate_internal_xml(self): "Private method: Generates the internal XML needed for XSLT template" # Generate new XML document and set <submit/> to be the root tag xml = libxml2.newDoc('1.0') submit_node = libxml2.newNode('submit') xml.setRootElement(submit_node) # Add white board text if set wb_node = libxml2.newNode('whiteboard') if self.whiteboard is not None: wb_node.addChild(libxml2.newText(self.whiteboard)) submit_node.addChild(wb_node) # Add the recipe node ... recipe_node = libxml2.newNode('recipe') submit_node.addChild(recipe_node) # ... and add all the defined arguments for key in self.jobargs.GetArgumentKeys(): if self.jobargs.IsProcessed(key): continue (tagname, tagnode) = self.jobargs.CreateTag(key) arg = self.jobargs.GetNextArgumentOnTag(tagname) while arg is not None: if arg['value']: recipe_node.addChild(tagnode) if arg['tagvaluetype'] == 'value': tagnode.addChild( libxml2.newText( self.__format_xml_value( arg['argtype'], arg['value']))) elif arg['tagvaluetype'] == 'attribute': tagnode.newProp( arg['tagvaluename'], self.__format_xml_value(arg['argtype'], arg['value'])) elif arg['tagvaluetype'] == "list": for listval in arg["value"].split(","): tagchild_n = self.jobargs.CreateChildTag(key) tagchild_n.addChild(libxml2.newText(listval)) else: raise Exception( "Unknown <tag/> type '%s' found in '%s'" % (arg['tagvaluetype'], key)) self.jobargs.SetProcessed() arg = self.jobargs.GetNextArgumentOnTag(tagname) return xml
def _node_add_child(self, parentxpath, parentnode, newnode): ignore = parentxpath if not node_is_text(parentnode.get_last()): prevsib = parentnode.get_prev() if node_is_text(prevsib): newlast = libxml2.newText(prevsib.content) else: newlast = libxml2.newText("\n") parentnode.addChild(newlast) endtext = parentnode.get_last().content parentnode.addChild(libxml2.newText(" ")) parentnode.addChild(newnode) parentnode.addChild(libxml2.newText(endtext))
def _serialize_to_xml(obj, xmlnode): """Create XML representation of a Python object (list, tuple, dist, or basic number and string types).""" if type(obj) in (list, tuple): listnode = libxml2.newNode('list') for li in obj: itemnode = libxml2.newNode('li') _serialize_to_xml(li, itemnode) listnode.addChild(itemnode) xmlnode.addChild(listnode) elif type(obj) == dict: dictnode = libxml2.newNode('dict') for key, val in obj.iteritems(): itemnode = libxml2.newNode(key.encode('utf-8')) _serialize_to_xml(val, itemnode) dictnode.addChild(itemnode) xmlnode.addChild(dictnode) elif type(obj) in (str, unicode, int, long, float, complex, bool): content = libxml2.newText(unicode(obj).encode('utf-8')) xmlnode.addChild(content) elif type(obj) == type(None): pass else: raise TypeError('Unsupported type %s while serializing to xml' % type(obj))
def _encode(self, doc, tag, children, attributes, value, cdata, ns, nsMap={}): node = libxml2.newNode(tag) if ns: # create a prefix for the ns if not ns in nsMap: nsMap[ns] = 'ns%d' % (len(nsMap) + 1) prefix = nsMap[ns] node.setNs(node.newNs(ns, prefix)) for k, v in attributes.items(): node.setProp(k, v) if children: for (tag, attr) in children: node.addChild( self._encode(doc, tag, attr.get('children'), attr.get('attributes', {}), attr.get('value'), attr.get('cdata'), attr.get('ns'), nsMap)) else: if cdata: node.addChild(doc.newCDataBlock(value, len(value))) else: node.addChild(libxml2.newText(value)) return node
def get_html(self, root = True): assert (self.edit_mode == "html") html_node = libxml2.newNode(DOCBOOK_TO_HTML_NODES[self._xml_root.name]) html_node.newProp("data-docbook-type", self._xml_root.name) self._docbook_to_html_process_properties(self._xml_root, html_node) if root: last_child = None for i in self._children: if i.get_xml_node().name != "text": last_child = i if (i.element_type in ["chapter"] or i.element_type.startswith("sect")): child_node = i.get_html(False) else: child_node = self._docbook_to_html_node(i.get_xml_node()) if type(child_node) != list: child_node = [child_node] for j in child_node: html_node.addChild(j) if last_child and (last_child.get_xml_node().name == "chapter" or last_child.get_xml_node().name.startswith("sect")): html_node.addChild(libxml2.newNode("br")) else: html_node.newProp("class", "subsection %s mceNonEditable" % self._xml_root.name) html_node.addChild(libxml2.newText("Subsection (%s) \"%s\"" % (self._xml_root.name, self.title))) return html_node
def setContent(self, text): #Note: this is a work around for a bug when adding 'one & two' type text t = libxml2.newText(text) text = t.serialize() t.freeNode() self.__node.setContent(text) return self
def _restxsl(xmlDoc, stylesheet, xslParams=None, encoding='ASCII'): # Resolve pyxslt XPATH references. for xmlNode in xmlDoc.xpathEval('//pyxslt-xpath-reference'): # Get the XPATH expression. xpath = origXpath = xmlNode.getContent() # Prepend the ``//pyxslt/`` root to relative XPATH expressions. if xpath[0] != '/': xpath = '//pyxslt/' + xpath # Look up this reference. targetNode = xmlDoc.xpathEval(xpath) if not targetNode: raise InvalidXpathExpression, origXpath # Replace the XPATH reference with the contents of the found # node. newTextNode = libxml2.newText(targetNode[0].getContent()) xmlNode.replaceNode(newTextNode) # Apply the stylesheet to the reStructuredText XML document. out = stylesheet.apply(xmlDoc, xslParams) # Get the contents of the XML file. xml = out.serialize(encoding=encoding) # Free the transformed document. out.freeDoc() # Return the XML text. return xml
def processInsert(parentNode, insertNode): """ Check for pythoncode """ if getAttr(insertNode, "section") == "python": code = getAttr(insertNode, "code") node = libxml2.newNode("pythoncode") node.addChild(libxml2.newText(code)) parentNode.addChild(node)
def __generate_internal_xml(self): "Private method: Generates the internal XML needed for XSLT template" # Generate new XML document and set <submit/> to be the root tag xml = libxml2.newDoc('1.0') submit_node = libxml2.newNode('submit') xml.setRootElement(submit_node) # Add white board text if set wb_node = libxml2.newNode('whiteboard') if self.whiteboard is not None: wb_node.addChild(libxml2.newText(self.whiteboard)) submit_node.addChild(wb_node) # Add the recipe node ... recipe_node = libxml2.newNode('recipe') submit_node.addChild(recipe_node) # ... and add all the defined arguments for key in self.jobargs.GetArgumentKeys(): if self.jobargs.IsProcessed(key): continue (tagname, tagnode) = self.jobargs.CreateTag(key) arg = self.jobargs.GetNextArgumentOnTag(tagname) while arg is not None: if arg['value']: recipe_node.addChild(tagnode) if arg['tagvaluetype'] == 'value': tagnode.addChild(libxml2.newText(self.__format_xml_value(arg['argtype'], arg['value']))) elif arg['tagvaluetype'] == 'attribute': tagnode.newProp(arg['tagvaluename'], self.__format_xml_value(arg['argtype'], arg['value'])) elif arg['tagvaluetype'] == "list": for listval in arg["value"].split(","): tagchild_n = self.jobargs.CreateChildTag(key) tagchild_n.addChild(libxml2.newText(listval)) else: raise Exception("Unknown <tag/> type '%s' found in '%s'" % (arg['tagvaluetype'], key)) self.jobargs.SetProcessed() arg = self.jobargs.GetNextArgumentOnTag(tagname) return xml
def setAttribute(self, name, content): att = self.__node.hasProp(name) if att==None: att = self.__node.newProp(name, content) else: #Note: this is a work around for a bug when adding 'one & two' type text t = libxml2.newText(content) content = t.serialize() t.freeNode() att.setContent(content)
def setAttribute(self, name, content): att = self.__node.hasProp(name) if att == None: att = self.__node.newProp(name, content) else: #Note: this is a work around for a bug when adding 'one & two' type text t = libxml2.newText(content) content = t.serialize() t.freeNode() att.setContent(content)
def create_text_node(self, sNode_name, sNode_value): """ Create and return a text node of name sNode_name with value sNode_value. Note: """ nodeText = libxml2.newText(sNode_value) nodeTmp = libxml2.newNode(sNode_name) nodeTmp.addChild(nodeText) return nodeTmp
def make_node(parentnode, newnode): # Add the needed parent node, try to preserve whitespace by # looking for a starting TEXT node, and copying it def node_is_text(n): return bool(n and n.type == "text" and not n.content.count("<")) sib = parentnode.get_last() if not node_is_text(sib): # This case is when we add a child element to a node for the # first time, like: # # <features/> # to # <features> # <acpi/> # </features> prevsib = prevSibling(parentnode) if node_is_text(prevsib): sib = libxml2.newText(prevsib.content) else: sib = libxml2.newText("") parentnode.addChild(sib) # This is case is adding a child element to an already properly # spaced element. Example: # <features> # <acpi/> # </features> # to # <features> # <acpi/> # <apic/> # </features> sib = parentnode.get_last() content = sib.content sib = sib.addNextSibling(libxml2.newText(" ")) txt = libxml2.newText(content) sib.addNextSibling(newnode) newnode.addNextSibling(txt) return newnode
def _docbook_to_html_node(self, xml_node): if xml_node.name == "text": return xml_node.copyNode(False) elif xml_node.type == "entity_ref": return libxml2.newText(str(xml_node)) elif xml_node.name == "footnote": res = libxml2.newNode("sup") res.newProp("data-docbook-type", "footnote") footnote_content = "" child = xml_node.children while child: footnote_content += str(self._docbook_to_html(child)) child = child.next res.newProp("data-footnote", footnote_content) res.newProp("class", "footnote mceNonEditable") res.addChild(libxml2.newText(_("footnote"))) return res elif xml_node.name in DOCBOOK_TO_HTML_NODES or xml_node.name in ["emphasis"]: res = self._docbook_to_html(xml_node) self._docbook_to_html_process_properties(xml_node, res) return res elif xml_node.name in DOCBOOK_JUMP_NODES: res = [] subchild = xml_node.children while subchild: html_child = self._docbook_to_html_node(subchild) if type(html_child) == list: res += html_child elif html_child != None: res.append(html_child) subchild = subchild.next return res else: self._warn_unconverted_docbook_node_type(xml_node.name) res = self._docbook_to_html(xml_node) self._docbook_to_html_process_properties(xml_node, res) return res
def expandChildElements(self, child): """ Helper function for convertElementTree, converts a single child recursively. """ nchild = self.newNode(child.tag) # Copy attributes for key, val in child.attrib: self.setAttribute(nchild, key, val) elements = [] # Add text if child.text: t = libxml2.newText(child.text) self.appendNode(nchild, t) # Add children for c in child: for n in self.expandChildElements(c): self.appendNode(nchild, n) elements.append(nchild) # Add tail if child.tail: tail = libxml2.newText(child.tail) elements.append(tail) return elements
def _encode(self, doc, tag, children, attributes, value, cdata, ns, nsMap = {}): node = libxml2.newNode(tag) if ns: # create a prefix for the ns if not ns in nsMap: nsMap[ns] = 'ns%d' % (len(nsMap) + 1) prefix = nsMap[ns] node.setNs(node.newNs(ns, prefix)) for k, v in attributes.items(): node.setProp(k, v) if children: for (tag, attr) in children: node.addChild(self._encode(doc, tag, attr.get('children'), attr.get('attributes', {}), attr.get('value'), attr.get('cdata'), attr.get('ns'), nsMap)) else: if cdata: node.addChild(doc.newCDataBlock(value, len(value))) else: node.addChild(libxml2.newText(value)) return node
def string_to_xmlnode(doc, value): return libxml2.newText(str(value))
for t in textnodes: i = int(t.prop('font')) s,c = specs[i] t.unsetProp('font') t.setProp('size',s) t.setProp('color',c) print 'remove the fontspec nodes' for f in fontnodes: f.unlinkNode() f.freeNode() print 'replace all <i> by textit' for n in doc.xpathEval('//i'): content = '\\textit{%s}' %(n.content) new = libxml2.newText(content) n.replaceNode(new) n.freeNode() print 'replace all <b> by textbf' for n in doc.xpathEval('//b'): content = '\\textbf{%s}' %(n.content) new = libxml2.newText(content) n.replaceNode(new) n.freeNode() ### parsing pages def gettext(page): """get a page node, return a list of text nodes from this page""" req ='./text[ (@size="22" and (@color="#231f20" or @color="#007c97" or @color="#b01016")) or (@color="#231f20" and (@size="16" or @size="12" or @size="7"))]'
def send_mainmenu(self): """Build the XML main menu from the module description files in the hard drive. """ if not os.path.isdir(template_path): self.request_done(404, "Can't access service directory %s" % template_path) return debug('Reading XSLT templates from ' + template_path) # Find menu items in the service.xml files in the subdirectories menuitems = {} for f in os.listdir(template_path): if f == 'bin': continue filename = os.path.join(template_path, f, 'service.xml') if not os.path.isfile(filename): continue try: doc = libxml2.parseFile(filename) except libxml2.parserError: debug("Failed to parse " + filename) continue title = '' url = '' root = doc.getRootElement() if (root is None) or (root.name != 'service'): debug("Root node is not 'service' in " + filename) doc.freeDoc() continue node = root.children while node is not None: if node.name == 'title': title = utils.get_content_unicode(node) elif node.name == 'ref': url = utils.get_content_unicode(node) node = node.next doc.freeDoc() if (title == '') or (url == ''): debug("Empty <title> or <ref> in " + filename) continue menuitems[title.lower()] = ('<link>\n' '<label>%s</label>\n' '<ref>%s</ref>\n' '</link>\n' % (libxml2.newText(title), libxml2.newText(url))) # Sort the menu items titles = menuitems.keys() titles.sort() # Build the menu mainmenu = ('<?xml version="1.0"?>\n' '<wvmenu>\n' '<title>Select video source</title>\n') for t in titles: mainmenu += menuitems[t] mainmenu += '</wvmenu>' self.dl = download.DummyDownloader(mainmenu, writefunc=self.writewrapper, donefunc=self.request_done) self.dl.start()
def signMessage( doc, cert, privkey, tbsElements=[], c14nAlgorithm=TRANSFORM_C14N_EXC, transformAlgorithm=TRANSFORM_C14N_EXC, digestAlgorithm=DIGEST_SHA1, signatureAlgorithm=SIGNATURE_RSA_SHA1, ): """ Signs a message using Ws-Security X.509 Certificate Profile 1.0/1.1, using the certificate's Subject Key Identifier as the token reference. The initial document shall not include any Ws-Security-related info. WARNING: this method does not check that the privkey and the certificate are associated. @type doc: libxml2 Document @param doc: the document corresponding to the whole SOAP envelope @type cert: M2Crypto.X509 @param cert: the signing certificate. Must contain a Subject Key Identifier. @type privkey: M2Crypto.PKey @type privkey: the private key associated to the certificate. @type tbsElements: list of libxml2 Element nodes @param tbsElements: the list of elements to be signed (typically the body). @rtype: libxml2 document @returns: the updated XML document, with an added Signature header. """ try: ski = cert.get_ext("subjectKeyIdentifier").get_value() except: raise Exception( "Cannot sign with this certificate (%s), no Subject Key Identifier found" % cert.get_subject().as_text() ) ski = binascii.unhexlify(ski.replace(":", "")) ns_ds = getOrCreateNs(doc.getRootElement(), NS_XMLDSIG, "ds") ns_wsse = getOrCreateNs(doc.getRootElement(), NS_WSSE, "wsse") ns_wsu = getOrCreateNs(doc.getRootElement(), NS_WSU, "wsu") ns_soap = getOrCreateNs(doc.getRootElement(), NS_SOAP, "soap") xpc = doc.xpathNewContext() xpc.xpathRegisterNs("wsse", NS_WSSE) xpc.xpathRegisterNs("soap", NS_SOAP) env = xpc.xpathEval("/soap:Envelope") if not env: raise Exception("Cannot sign this message: not a SOAP envelope") env = env[0] header = xpc.xpathEval("/soap:Envelope/soap:Header") if not header: header = libxml2.newNode("Header") header.setNs(ns_soap) firstElementChild = getFirstElementChild(env) if firstElementChild: firstElementChild.addPrevSibling(header) else: env.addChild(header) else: header = header[0] security = xpc.xpathEval("/soap:Envelope/soap:Header/wsse:Security") if not security: security = libxml2.newNode("Security") security.setNs(ns_wsse) header.addChild(security) else: security = security[0] signature = libxml2.newNode("Signature") signature.setNs(ns_ds) security.addChild(signature) # Signed Info signedInfo = libxml2.newNode("SignedInfo") signedInfo.setNs(ns_ds) # c14n method c14nMethod = libxml2.newNode("CanonicalizationMethod") c14nMethod.setProp("Algorithm", c14nAlgorithm) c14nMethod.setNs(ns_ds) signedInfo.addChild(c14nMethod) # Signature method signatureMethod = libxml2.newNode("SignatureMethod") signatureMethod.setProp("Algorithm", signatureAlgorithm) signatureMethod.setNs(ns_ds) signedInfo.addChild(signatureMethod) # Compute digests for each elements for tbs in tbsElements: reference = libxml2.newNode("Reference") reference.setNs(ns_ds) # Generate a local ID uri = "id-%s" % time.time() reference.setProp("URI", "#" + uri) # Transforms - only a single Transform is used transforms = libxml2.newNode("Transforms") transforms.setNs(ns_ds) transform = libxml2.newNode("Transform") transform.setNs(ns_ds) transform.setProp("Algorithm", transformAlgorithm) transforms.addChild(transform) reference.addChild(transforms) # Digest method digestMethod = libxml2.newNode("DigestMethod") digestMethod.setNs(ns_ds) digestMethod.setProp("Algorithm", digestAlgorithm) reference.addChild(digestMethod) # Digest value # first, add a wsu:Id=uri tbs.setNsProp(ns_wsu, "Id", uri) digest = computeDigest(applyTransform(tbs, transformAlgorithm), digestAlgorithm) digestValue = libxml2.newNode("DigestValue") digestValue.setNs(ns_ds) digestValue.addChild(libxml2.newText(base64.encodestring(digest))) reference.addChild(digestValue) # OK, we're done with this reference/tbs element signedInfo.addChild(reference) signature.addChild(signedInfo) # Signature Value signatureValue = libxml2.newNode("SignatureValue") signatureValue.setNs(ns_ds) # Signature computation # transform the signedInfo tbs = applyTransform(signedInfo, c14nAlgorithm) sign = computeSignature(privkey=privkey, algorithm=signatureAlgorithm, text=tbs) signatureValue.addChild(libxml2.newText(base64.encodestring(sign))) # A single key info (cert SKI) keyInfo = libxml2.newNode("KeyInfo") keyInfo.setNs(ns_ds) securityTokenReference = libxml2.newNode("SecurityTokenReference") securityTokenReference.setNs(ns_wsse) keyIdentifier = libxml2.newNode("KeyIdentifier") keyIdentifier.setNs(ns_wsse) keyIdentifier.setProp("EncodingType", ENCODING_BASE64) keyIdentifier.setProp("ValueType", TOKEN_REFERENCE_VALUE_TYPE_SKI) keyIdentifier.addChild(libxml2.newText(base64.encodestring(ski))) securityTokenReference.addChild(keyIdentifier) keyInfo.addChild(securityTokenReference) signature.addChild(signatureValue) signature.addChild(keyInfo) # OK, return the updated doc return doc
def signMessage(doc, cert, privkey, tbsElements=[], c14nAlgorithm=TRANSFORM_C14N_EXC, transformAlgorithm=TRANSFORM_C14N_EXC, digestAlgorithm=DIGEST_SHA1, signatureAlgorithm=SIGNATURE_RSA_SHA1): """ Signs a message using Ws-Security X.509 Certificate Profile 1.0/1.1, using the certificate's Subject Key Identifier as the token reference. The initial document shall not include any Ws-Security-related info. WARNING: this method does not check that the privkey and the certificate are associated. @type doc: libxml2 Document @param doc: the document corresponding to the whole SOAP envelope @type cert: M2Crypto.X509 @param cert: the signing certificate. Must contain a Subject Key Identifier. @type privkey: M2Crypto.PKey @type privkey: the private key associated to the certificate. @type tbsElements: list of libxml2 Element nodes @param tbsElements: the list of elements to be signed (typically the body). @rtype: libxml2 document @returns: the updated XML document, with an added Signature header. """ try: ski = cert.get_ext('subjectKeyIdentifier').get_value() except: raise Exception( "Cannot sign with this certificate (%s), no Subject Key Identifier found" % cert.get_subject().as_text()) ski = binascii.unhexlify(ski.replace(':', '')) ns_ds = getOrCreateNs(doc.getRootElement(), NS_XMLDSIG, "ds") ns_wsse = getOrCreateNs(doc.getRootElement(), NS_WSSE, "wsse") ns_wsu = getOrCreateNs(doc.getRootElement(), NS_WSU, "wsu") ns_soap = getOrCreateNs(doc.getRootElement(), NS_SOAP, "soap") xpc = doc.xpathNewContext() xpc.xpathRegisterNs("wsse", NS_WSSE) xpc.xpathRegisterNs("soap", NS_SOAP) env = xpc.xpathEval("/soap:Envelope") if not env: raise Exception("Cannot sign this message: not a SOAP envelope") env = env[0] header = xpc.xpathEval("/soap:Envelope/soap:Header") if not header: header = libxml2.newNode("Header") header.setNs(ns_soap) firstElementChild = getFirstElementChild(env) if firstElementChild: firstElementChild.addPrevSibling(header) else: env.addChild(header) else: header = header[0] security = xpc.xpathEval("/soap:Envelope/soap:Header/wsse:Security") if not security: security = libxml2.newNode("Security") security.setNs(ns_wsse) header.addChild(security) else: security = security[0] signature = libxml2.newNode("Signature") signature.setNs(ns_ds) security.addChild(signature) # Signed Info signedInfo = libxml2.newNode("SignedInfo") signedInfo.setNs(ns_ds) # c14n method c14nMethod = libxml2.newNode("CanonicalizationMethod") c14nMethod.setProp("Algorithm", c14nAlgorithm) c14nMethod.setNs(ns_ds) signedInfo.addChild(c14nMethod) # Signature method signatureMethod = libxml2.newNode("SignatureMethod") signatureMethod.setProp("Algorithm", signatureAlgorithm) signatureMethod.setNs(ns_ds) signedInfo.addChild(signatureMethod) # Compute digests for each elements for tbs in tbsElements: reference = libxml2.newNode("Reference") reference.setNs(ns_ds) # Generate a local ID uri = "id-%s" % time.time() reference.setProp("URI", '#' + uri) # Transforms - only a single Transform is used transforms = libxml2.newNode("Transforms") transforms.setNs(ns_ds) transform = libxml2.newNode("Transform") transform.setNs(ns_ds) transform.setProp("Algorithm", transformAlgorithm) transforms.addChild(transform) reference.addChild(transforms) # Digest method digestMethod = libxml2.newNode("DigestMethod") digestMethod.setNs(ns_ds) digestMethod.setProp("Algorithm", digestAlgorithm) reference.addChild(digestMethod) # Digest value # first, add a wsu:Id=uri tbs.setNsProp(ns_wsu, "Id", uri) digest = computeDigest(applyTransform(tbs, transformAlgorithm), digestAlgorithm) digestValue = libxml2.newNode("DigestValue") digestValue.setNs(ns_ds) digestValue.addChild(libxml2.newText(base64.encodestring(digest))) reference.addChild(digestValue) # OK, we're done with this reference/tbs element signedInfo.addChild(reference) signature.addChild(signedInfo) # Signature Value signatureValue = libxml2.newNode("SignatureValue") signatureValue.setNs(ns_ds) # Signature computation # transform the signedInfo tbs = applyTransform(signedInfo, c14nAlgorithm) sign = computeSignature(privkey=privkey, algorithm=signatureAlgorithm, text=tbs) signatureValue.addChild(libxml2.newText(base64.encodestring(sign))) # A single key info (cert SKI) keyInfo = libxml2.newNode("KeyInfo") keyInfo.setNs(ns_ds) securityTokenReference = libxml2.newNode("SecurityTokenReference") securityTokenReference.setNs(ns_wsse) keyIdentifier = libxml2.newNode("KeyIdentifier") keyIdentifier.setNs(ns_wsse) keyIdentifier.setProp("EncodingType", ENCODING_BASE64) keyIdentifier.setProp("ValueType", TOKEN_REFERENCE_VALUE_TYPE_SKI) keyIdentifier.addChild(libxml2.newText(base64.encodestring(ski))) securityTokenReference.addChild(keyIdentifier) keyInfo.addChild(securityTokenReference) signature.addChild(signatureValue) signature.addChild(keyInfo) # OK, return the updated doc return doc
def makeDocElement(name, content): node = libxml2.newNode(name) node.addChild(libxml2.newText(content)) return node