def dispatch(self, req):
        path = req.uri[1:]
        if (path[-1] == "/"):
            path = path[:-1]

        if not configs.has_key(path):
            if req.method == "POST":
                self.send_fault(
                    Fault(Fault.Client,
                          "Unknown Database Path %s" % (repr(configs.keys()))),
                    req)
            else:
                # Construct simple table of contents page
                xml = ['<databases>']
                for k in configs:
                    xml.append("<database><path>%s</path></database>" % k)
                xml.append('</databases>')
                txt = ''.join(xml)
                self.send_xml(txt, req)
        else:
            xreq = None
            config = configs[path]
            if (req.method == "POST"):
                try:
                    data = req.read()
                    dstr = StringIO.StringIO(data)
                    ps = ParsedSoap(dstr, readerclass=reader)
                except Exception, e:
                    try:
                        self.send_fault(FaultFromException(e, 0), req)
                    except Exception, e:
                        self.send_fault(FaultFromException(e, 0), req)
                    return
                callname = ps.body_root.localName
                classname = callname[0].upper() + callname[1:]
                try:
                    try:
                        mod = SRW.protocolModules[ps.body_root.namespaceURI]
                    except KeyError:
                        log("%r -> %r" % (ps.body_root.namespaceURI, data))
                        self.send_fault(Fault(Fault.Client, 'Bad Namespace'),
                                        req)
                        return
                    config = config[ps.body_root.namespaceURI]
                    objType = getattr(mod, classname)
                    xreq = ps.Parse(objType)
                    xreq.configure(config)
                    xreq.calledAt = path
                    result = self.call(xreq)
                except AttributeError, err:
                    # result = self.processUnknownOperation(classname, err, config)
                    self.send_fault(
                        Fault(Fault.Client,
                              'Unknown Operation (%s)' % str(err)), req)
                    return
示例#2
0
    def do_POST(self):
        """The POST command."""

        chunked = False

        # If the headers indicate chunked transfer encoding, fake
        # a Content-Length header field that matches the first chunk.
        try:
            te = self.headers['transfer-encoding']
            if te.startswith('chunked'):
                chunked = True
                length = int(self.rfile.readline(), 16)
                if length > 0:
                    self.headers['content-length'] = length
                    pass
                pass
            pass
        except:
            pass

        # Process the request.
        SOAPRequestHandler.do_POST(self)

        # If we're using chunked transfer encoding, check for the last chunk.
        if chunked:
            crlf = self.rfile.readline()
            length = int(self.rfile.readline(), 16)
            if not length == 0:
                self.send_fault(Fault(500, "Cannot handle multiple chunks"))
                pass
            pass
        pass
示例#3
0
def AsQuery():
	'''Handle the Amazon QUERY interface'''
	try:
		form = cgi.FieldStorage()
		args = {}
		signStr = ""
		for var in form:
			args[var] = form[var].value
			if (var != "Signature"):
				signStr += var + args[var]
			log("[QUERY] %s=%s\n" % (var, args[var]))
		secretKey = userDict[args['AWSAccessKeyId']][0]
		calculatedSig = base64.b64encode(hmac.new(secretKey, signStr, hashlib.sha1).digest())
		if (args['Signature'] != calculatedSig):
			_CGISendFault(Fault(Fault.Client, 'Could not authenticate'))
			return
		tashi.aws.util.authorizedUser = userDict[args['AWSAccessKeyId']][1]
		log("[AUTH] authorizedUser = %s\n" % (tashi.aws.util.authorizedUser))
		functionName = args['Action']
		res = eval("%s(args)" % (functionName))
		_CGISendXML(res)
	except Exception, e:
		_CGISendFault(Fault(Fault.Client, str(e)))
示例#4
0
文件: soap.py 项目: atumanov/tashi
 def validate(self, xml):
     '''A simple blob of code that validates the xmldsig in an xml string using xmlsec1'''
     doc = minidom.parseString(xml)
     tokens = doc.getElementsByTagName("wsse:BinarySecurityToken")
     if (len(tokens) != 1):
         return -1
     token = tokens[0]
     if (len(token.childNodes) != 1):
         return -1
     childNode = token.childNodes[0]
     if (not getattr(childNode, 'wholeText', None)):
         return -1
     cert = childNode.wholeText
     CERT_DIGEST = md5.md5(cert).hexdigest()
     log("[AUTH] CERT_DIGEST=%s\n" % (CERT_DIGEST))
     output = xml
     ofile = "/tmp/%5.5d.%s.xml" % (os.getpid(),
                                    md5.md5(output).hexdigest())
     f2 = open(ofile, "w")
     f2.write(output)
     f2.close()
     # XXXpipe: what are we doing here?
     (stdin, stdout) = os.popen4(
         "xmlsec1 --verify --id-attr:Id Timestamp --id-attr:Id Body --pubkey-cert-pem /var/lib/tashi-ec2/%s.crt --print-debug %s"
         % (CERT_DIGEST, ofile))
     stdin.close()
     res = stdout.read()
     stdout.close()
     os.unlink(ofile)
     verified = False
     lines = res.split("\n")
     cmpRe = re.compile('==== Subject Name: (.*)')
     for line in lines:
         if (line.strip() == "OK"):
             verified = True
         res = cmpRe.match(line)
         if (res):
             varStrs = res.groups()[0].split("/")
             for var in varStrs:
                 (key, sep, val) = var.partition("=")
                 if (key != '' and val != ''):
                     vars[key] = val
     if (not verified):
         _CGISendFault(Fault(Fault.Client, 'Could not authenticate'))
         return verified
     tashi.aws.util.authorizedUser = vars.get('CN', 'UNKNOWN')
     log("[AUTH] authorizedUser = %s\n" % (tashi.aws.util.authorizedUser))
     return verified
示例#5
0
def AsCGI(nsdict={}, typesmodule=None, rpc=False, modules=None):
    '''Dispatch within a CGI script.
    '''
    if os.environ.get('REQUEST_METHOD') != 'POST':
        _CGISendFault(Fault(Fault.Client, 'Must use POST'))
        return
    ct = os.environ['CONTENT_TYPE']
    try:
        if ct.startswith('multipart/'):
            cid = resolvers.MIMEResolver(ct, sys.stdin)
            xml = cid.GetSOAPPart()
            ps = ParsedSoap(xml, resolver=cid.Resolve)
        else:
            length = int(os.environ['CONTENT_LENGTH'])
            ps = ParsedSoap(sys.stdin.read(length))
    except ParseException as e:
        _CGISendFault(FaultFromZSIException(e))
        return
    _Dispatch(ps, modules, _CGISendXML, _CGISendFault, nsdict=nsdict,
              typesmodule=typesmodule, rpc=rpc)
示例#6
0
def AsJonPy(request=None, modules=None, **kw):
    '''Dispatch within a jonpy CGI/FastCGI script.
    '''

    kw['request'] = request
    if request.environ.get('REQUEST_METHOD') != 'POST':
        _JonPySendFault(Fault(Fault.Client, 'Must use POST'), **kw)
        return
    ct = request.environ['CONTENT_TYPE']
    try:
        if ct.startswith('multipart/'):
            cid = resolvers.MIMEResolver(ct, request.stdin)
            xml = cid.GetSOAPPart()
            ps = ParsedSoap(xml, resolver=cid.Resolve)
        else:
            length = int(request.environ['CONTENT_LENGTH'])
            ps = ParsedSoap(request.stdin.read(length))
    except ParseException as e:
        _JonPySendFault(FaultFromZSIException(e), **kw)
        return
    _Dispatch(ps, modules, _JonPySendXML, _JonPySendFault, **kw)
示例#7
0
def WSDLFaultFromException(ex, inheader, tb=None, actor=None):
    '''Return a Fault object created from a Python exception.

    <SOAP-ENV:Fault>
      <faultcode>SOAP-ENV:Server</faultcode>
      <faultstring>Processing Failure</faultstring>
      <detail>
        <ZSI:FaultDetail>
          <ZSI:string></ZSI:string>
          <ZSI:trace></ZSI:trace>
        </ZSI:FaultDetail>
      </detail>
    </SOAP-ENV:Fault>
    '''
    tracetext = None
    if tb:
        try:
            lines = '\n'.join(['%s:%d:%s' % (name, line, func)
                        for name, line, func, text in traceback.extract_tb(tb)])
        except:
            pass
        else:
            tracetext = lines

    exceptionName = ""
    try:
        exceptionName = ":".join([ex.__module__, ex.__class__.__name__])
    except: pass

    if isinstance(ex, Fault):
        return ex

    elt = ZSIFaultDetail(string=exceptionName + "\n" + str(ex), trace=tracetext)
    if inheader:
        detail, headerdetail = None, elt
    else:
        detail, headerdetail = elt, None
    return Fault(Fault.Server, 'Processing Failure',
                actor, detail, headerdetail)
class reqHandler:
    def send_xml(self, text, req, code=200):
        req.content_type = 'text/xml'
        req.content_length = len(text)
        req.send_http_header()
        req.write(text)

    def send_fault(self, f, req):
        self.send_xml(f.AsSOAP(), req, 500)

    def processUnknownOperation(self, operation, err, config):
        result = SRW.types.ExplainResponse('explainResponse')
        req = SRW.types.ExplainRequest('explainRequest',
                                       opts={
                                           'recordPacking': 'xml',
                                           'version': "1.1"
                                       },
                                       config=config)
        result.processQuery(session, req)
        if isinstance(err, SRWDiagnostics.SRWDiagnostic):
            result.diagnostics = [err]
        else:
            diag = SRWDiagnostics.Diagnostic4()
            diag.uri = diag.uri
            diag.details = operation + ": " + str(err)
            diag.message = diag.message
            result.diagnostics = [diag]
        return result

    def dispatch(self, req):
        path = req.uri[1:]
        if (path[-1] == "/"):
            path = path[:-1]

        if not configs.has_key(path):
            if req.method == "POST":
                self.send_fault(
                    Fault(Fault.Client,
                          "Unknown Database Path %s" % (repr(configs.keys()))),
                    req)
            else:
                # Construct simple table of contents page
                xml = ['<databases>']
                for k in configs:
                    xml.append("<database><path>%s</path></database>" % k)
                xml.append('</databases>')
                txt = ''.join(xml)
                self.send_xml(txt, req)
        else:
            xreq = None
            config = configs[path]
            if (req.method == "POST"):
                try:
                    data = req.read()
                    dstr = StringIO.StringIO(data)
                    ps = ParsedSoap(dstr, readerclass=reader)
                except Exception, e:
                    try:
                        self.send_fault(FaultFromException(e, 0), req)
                    except Exception, e:
                        self.send_fault(FaultFromException(e, 0), req)
                    return
                callname = ps.body_root.localName
                classname = callname[0].upper() + callname[1:]
                try:
                    try:
                        mod = SRW.protocolModules[ps.body_root.namespaceURI]
                    except KeyError:
                        log("%r -> %r" % (ps.body_root.namespaceURI, data))
                        self.send_fault(Fault(Fault.Client, 'Bad Namespace'),
                                        req)
                        return
                    config = config[ps.body_root.namespaceURI]
                    objType = getattr(mod, classname)
                    xreq = ps.Parse(objType)
                    xreq.configure(config)
                    xreq.calledAt = path
                    result = self.call(xreq)
                except AttributeError, err:
                    # result = self.processUnknownOperation(classname, err, config)
                    self.send_fault(
                        Fault(Fault.Client,
                              'Unknown Operation (%s)' % str(err)), req)
                    return
                except Exception, err:
                    self.send_fault(
                        Fault(Fault.Client,
                              'Broken request %s: (%s)' % (err, data)), req)
                    return
                    except AttributeError, err:
                        result = self.processUnknownOperation(
                            operation, err, config)

            reply = StringIO.StringIO()

            if (req.method == "GET"):
                sw = SoapWriter(reply, envelope=0)
            else:
                sw = SoapWriter(reply, nsdict=SRW.protocolNamespaces)
            try:
                sw.serialize(result, inline=1)
                sw.close()
                text = reply.getvalue()
            except Exception, err:
                self.send_fault(Fault(Fault.Client, 'Busted (%s)' % str(err)),
                                req)
                return

            if (req.method == "GET"):
                if xreq and hasattr(xreq, 'stylesheet') and xreq.stylesheet:
                    headerText = u'<?xml version="1.0"?>\n<?xml-stylesheet type="text/xsl" href="%s"?>\n' % (
                        xreq.stylesheet)
                elif xreq and hasattr(
                        xreq, 'defaultStylesheet') and xreq.defaultStylesheet:
                    headerText = u'<?xml version="1.0"?>\n<?xml-stylesheet type="text/xsl" href="%s"?>\n' % (
                        xreq.defaultStylesheet)
                else:
                    headerText = u""

                text = text.replace(
示例#10
0
            address.parse(ps)
        except Exception, e:
            return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)
        if action and action != address.getAction():
            e = WSActionException('SOAP Action("%s") must match WS-Action("%s") if specified.' \
                %(action,address.getAction()))
            return SendFault(FaultFromException(e, 0, None), **kw)
        action = address.getAction()

    if isinstance(service, ServiceInterface) is False:
        e = NoSuchService('no service at POST(%s) in container: %s' %
                          (post, server))
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

    if not service.authorize(None, post, action):
        return SendFault(Fault(Fault.Server, "Not authorized"), code=401)
        #try:
        #    raise NotAuthorized()
        #except Exception, e:
        #return SendFault(FaultFromException(e, 0, None), code=401, **kw)
        ##return SendFault(FaultFromException(NotAuthorized(), 0, None), code=401, **kw)

    try:
        method = service.getOperation(ps, address)
    except Exception, e:
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

    try:
        if isWSResource is True:
            request, result = method(ps, address)
        else:
示例#11
0
def _Dispatch(ps,
              server,
              SendResponse,
              SendFault,
              post,
              action,
              nsdict={},
              **kw):
    '''Send ParsedSoap instance to ServiceContainer, which dispatches to
    appropriate service via post, and method via action.  Response is a
    self-describing pyobj, which is passed to a SoapWriter.

    Call SendResponse or SendFault to send the reply back, appropriately.
        server -- ServiceContainer instance

    '''
    localURL = 'http://%s:%d%s' % (server.server_name, server.server_port,
                                   post)
    address = action
    service = server.getNode(post)
    isWSResource = False
    if isinstance(service, WSAResource):
        isWSResource = True
        service.setServiceURL(localURL)
        address = Address()
        try:
            address.parse(ps)
        except Exception as e:
            return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)
        if action and action != address.getAction():
            e = WSActionException('SOAP Action("%s") must match WS-Action("%s") if specified.' \
                %(action,address.getAction()))
            return SendFault(FaultFromException(e, 0, None), **kw)
        action = address.getAction()

    if isinstance(service, ServiceInterface) is False:
        e = NoSuchService('no service at POST(%s) in container: %s' %
                          (post, server))
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

    if not service.authorize(None, post, action):
        return SendFault(Fault(Fault.Server, "Not authorized"), code=401)
        #try:
        #    raise NotAuthorized()
        #except Exception, e:
        #return SendFault(FaultFromException(e, 0, None), code=401, **kw)
        ##return SendFault(FaultFromException(NotAuthorized(), 0, None), code=401, **kw)

    try:
        method = service.getOperation(ps, address)
    except Exception as e:
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

    try:
        if isWSResource is True:
            _, result = method(ps, address)
        else:
            _, result = method(ps)
    except Exception as e:
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

    # Verify if Signed
    service.verify(ps)

    # If No response just return.
    if result is None:
        return SendResponse('', **kw)

    sw = SoapWriter(nsdict=nsdict)
    try:
        sw.serialize(result)
    except Exception as e:
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

    if isWSResource is True:
        action = service.getResponseAction(ps, action)
        addressRsp = Address(action=action)
        try:
            addressRsp.setResponseFromWSAddress(address, localURL)
            addressRsp.serialize(sw)
        except Exception as e:
            return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

    # Create Signatures
    service.sign(sw)

    try:
        soapdata = str(sw)
        return SendResponse(soapdata, **kw)
    except Exception as e:
        return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)