def parseString(s, plotter): ctxt = libxml2.createMemoryParserCtxt(s, len(s)) #ctxt.replaceEntities(1) #ctxt.loadSubset(1) #ctxt.validate(1) # should be set to 0 for greater speed ctxt.parseDocument() if not ctxt.wellFormed(): print "Document not well formed!" if not ctxt.isValid(): print "Document not valid!" doc = ctxt.doc() root = doc.children assert root.name == 'math' return parseTree(root, plotter)
def signRequest(file, request): keysmngr = xmlsec.KeysMngr() if keysmngr is None: raise RuntimeError, "Error: failed to create keys manager." if xmlsec.cryptoAppDefaultKeysMngrInit(keysmngr) < 0: keysmngr.destroy() raise RuntimeError, "Error: failed to initialize keys manager." key = xmlsec.cryptoAppKeyLoad(filename = file, pwd = None, format = xmlsec.KeyDataFormatPem, pwdCallback = None, pwdCallbackCtx = None) if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(keysmngr, key) < 0: keysmngr.destroy() raise RuntimeError, "Error: failed to load key into keys manager" dsig_ctx = xmlsec.DSigCtx(keysmngr) # Match the dtd and replace it. pat = re.compile("(^.*<!DOCTYPE.*distributionRequest[^>]*SYSTEM[ \t]*\")([^\"]*)(\"[^>]*>.*$)", re.DOTALL) m = pat.match(request) request = m.group(1)+"http://dmswww.stsci.edu/dtd/sso/distribution.dtd"+m.group(3) ctxt = libxml2.createMemoryParserCtxt(request, len(request)) ctxt.validate(1) ctxt.parseDocument() doc = ctxt.doc() if doc is None or doc.getRootElement() is None: keysmngr.destroy() raise RuntimeError, "Error: unable to parse XML data" # find the XML-DSig start node node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature, xmlsec.DSigNs) if node is None: fragment = libxml2.parseDoc("""<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI="#distributionRequest"> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" /> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue></DigestValue> </Reference> </SignedInfo> <SignatureValue></SignatureValue> <KeyInfo> <KeyValue><RSAKeyValue> <Modulus></Modulus> <Exponent></Exponent> </RSAKeyValue></KeyValue> </KeyInfo> </Signature> """) # remove the xml header on the front of the document fragment fragment = fragment.getRootElement() # getElementsByTagName doesn't exist here for some reason, have to use xpath ctxt = doc.xpathNewContext() nodeList = ctxt.xpathEval("/distributionRequest") for child in nodeList: child.addChild(fragment) if child.prop('Id') == None: child.setProp('Id', 'distributionRequest') node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature, xmlsec.DSigNs) # Remove passwords ctxt = doc.xpathNewContext() nodeList = ctxt.xpathEval('//requester') for child in nodeList: child.unsetProp('archivePassword') nodeList = ctxt.xpathEval('//ftp') for child in nodeList: if child.hasProp('loginPassword'): child.unsetProp('loginPassword') warnings.warn('ftp password is not allowed in user requests.') # Sign the template, or resign existing block status = dsig_ctx.sign(node) output = str(doc) doc.freeDoc() keysmngr.destroy() if status < 0: raise RuntimeError, "Error: signature failed" return output
def signRequest(file, request, dtd="http://dmswww.stsci.edu/dtd/sso/distribution.dtd", cgi="https://archive.stsci.edu/cgi-bin/dads.cgi", mission='HST'): global usexml if usexml: try: keysmngr = xmlsec.KeysMngr() if keysmngr is None: raise RuntimeError("Error: failed to create keys manager.") if xmlsec.cryptoAppDefaultKeysMngrInit(keysmngr) < 0: keysmngr.destroy() raise RuntimeError("Error: failed to initialize keys manager.") key = xmlsec.cryptoAppKeyLoad(filename = file, pwd = None, format = xmlsec.KeyDataFormatPem, pwdCallback = None, pwdCallbackCtx = None) if xmlsec.cryptoAppDefaultKeysMngrAdoptKey(keysmngr, key) < 0: keysmngr.destroy() raise RuntimeError("Error: failed to load key into keys manager") dsig_ctx = xmlsec.DSigCtx(keysmngr) # Match the dtd and replace it. pat = re.compile("(^.*<!DOCTYPE.*distributionRequest[^>]*SYSTEM[ \t]*\")([^\"]*)(\"[^>]*>.*$)", re.DOTALL) m = pat.match(request) request = m.group(1)+dtd+m.group(3) ctxt = libxml2.createMemoryParserCtxt(request, len(request)) ctxt.validate(1) ctxt.parseDocument() doc = ctxt.doc() if doc is None or doc.getRootElement() is None: keysmngr.destroy() raise RuntimeError("Error: unable to parse XML data") # find the XML-DSig start node node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature, xmlsec.DSigNs) if node is None: fragment = libxml2.parseDoc("""<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> <SignedInfo> <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/> <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <Reference URI="#distributionRequest"> <Transforms> <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" /> </Transforms> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <DigestValue></DigestValue> </Reference> </SignedInfo> <SignatureValue></SignatureValue> <KeyInfo> <KeyValue><RSAKeyValue> <Modulus></Modulus> <Exponent></Exponent> </RSAKeyValue></KeyValue> </KeyInfo> </Signature> """) # remove the xml header on the front of the document fragment fragment = fragment.getRootElement() # getElementsByTagName doesn't exist here for some reason, have to use xpath ctxt = doc.xpathNewContext() nodeList = ctxt.xpathEval("/distributionRequest") for child in nodeList: child.addChild(fragment) if child.prop('Id') == None: child.setProp('Id', 'distributionRequest') node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature, xmlsec.DSigNs) # Remove passwords ctxt = doc.xpathNewContext() nodeList = ctxt.xpathEval('//requester') for child in nodeList: child.unsetProp('archivePassword') nodeList = ctxt.xpathEval('//ftp') for child in nodeList: if child.hasProp('loginPassword'): child.unsetProp('loginPassword') warnings.warn('ftp password is not allowed in user requests.') # Sign the template, or resign existing block status = dsig_ctx.sign(node) output = str(doc) doc.freeDoc() keysmngr.destroy() if status < 0: raise RuntimeError("Error: signature failed") return output except: usexml=False return signRequest(file, request, dtd, cgi) else: values = {'request' : request, 'privatekey' : open(file).read(), 'mission' : mission } data = urlencode(values).encode("utf-8") req = Request(url=cgi, data=data) f = urlopen(req) return f.read()