Example #1
0
    def _kerberos_client_request(self, host, handler, errcode, errmsg,
                                 headers):
        """Kerberos auth - create a client request string"""

        # check if "Negotiate" challenge is present in headers
        negotiate = [
            i.lower() for i in headers.get("WWW-Authenticate", "").split(", ")
        ]
        if "negotiate" not in negotiate:
            # negotiate not supported, raise 401 error
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg,
                                          headers)

        # initialize GSSAPI
        service = "HTTP@%s" % host
        rc, vc = kerberos.authGSSClientInit(service)
        if rc != 1:
            errmsg = "KERBEROS: Could not initialize GSSAPI"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg,
                                          headers)

        # do a client step
        rc = kerberos.authGSSClientStep(vc, "")
        if rc != 0:
            errmsg = "KERBEROS: Client step failed"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg,
                                          headers)

        return vc, kerberos.authGSSClientResponse(vc)
Example #2
0
    def _kerberos_verify_response(self, vc, host, handler, errcode, errmsg, headers):
        """Kerberos auth - verify client identity"""
        # verify that headers contain WWW-Authenticate header
        auth_header = headers.get("WWW-Authenticate", None)
        if auth_header is None:
            errcode = 401
            errmsg = "KERBEROS: No WWW-Authenticate header in second HTTP response"
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # verify that WWW-Authenticate contains Negotiate
        splits = auth_header.split(" ", 1)
        if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
            errcode = 401
            errmsg = "KERBEROS: Incorrect WWW-Authenticate header in second HTTP response: %s" % auth_header
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # do another client step to verify response from server
        errmsg = "KERBEROS: Could not verify server WWW-Authenticate header in second HTTP response"
        try:
            rc = kerberos.authGSSClientStep(vc, splits[1])
            if rc == -1:
                errcode = 401
                raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
        except kerberos.GSSError as ex:
            errcode = 401
            errmsg += ": %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)

        # cleanup
        rc = kerberos.authGSSClientClean(vc)
        if rc != 1:
            errcode = 401
            errmsg = "KERBEROS: Could not clean-up GSSAPI: %s/%s" % (ex[0][0], ex[1][0])
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg, headers)
Example #3
0
    def single_request_with_cookies(self,
                                    host,
                                    handler,
                                    request_body,
                                    verbose=0):
        # ADDED: construct the URL and Request object for proper cookie handling
        request_url = "%s://%s%s" % (self.scheme, host, handler)
        #log.debug("request_url is %s" % request_url)
        cookie_request = urllib2.Request(request_url)

        try:
            if six.PY2:
                h = self.make_connection(host)
                if verbose:
                    h.set_debuglevel(1)
                self.send_request(h, handler, request_body)
                self.send_host(h, host)
                self.send_cookies(
                    h, cookie_request)  # ADDED. creates cookiejar if None.
                self.send_user_agent(h)
                self.send_content(h, request_body)
            else:
                # Python 3 xmlrpc.client.Transport makes its own connection
                h = self.send_request(host, handler, request_body, verbose)

            response = h.getresponse()

            # ADDED: parse headers and get cookies here
            cookie_response = CookieResponse(response.msg)
            # Okay, extract the cookies from the headers
            self.cookiejar.extract_cookies(cookie_response, cookie_request)
            #log.debug("cookiejar now contains: %s" % self.cookiejar._cookies)
            # And write back any changes
            if hasattr(self.cookiejar, 'save'):
                try:
                    self.cookiejar.save(self.cookiejar.filename)
                except Exception as e:
                    raise
                    #log.error("Couldn't write cookiefile %s: %s" % \
                    #        (self.cookiejar.filename,str(e)))

            if response.status == 200:
                self.verbose = verbose
                return self.parse_response(response)

            if (response.getheader("content-length", 0)):
                response.read()
            raise xmlrpclib.ProtocolError(
                host + handler,
                response.status,
                response.reason,
                response.msg,
            )
        except xmlrpclib.Fault:
            raise
        finally:
            try:
                h.close()
            except NameError:  # h not initialized yet
                pass
Example #4
0
    def _single_request(self, host, handler, request_body, verbose=0):
        # issue XML-RPC request

        request_url = "%s://%s/" % (self.scheme, host)
        cookie_request = urllib2.Request(request_url)

        h = self.make_connection(host)
        self.verbose = verbose
        if verbose:
            h.set_debuglevel(1)

        try:
            self.send_request(h, handler, request_body)
            self.send_host(h, host)
            self.send_cookies(h, cookie_request)
            self.send_user_agent(h)
            self.send_content(h, request_body)

            response = h.getresponse(buffering=True)

            if response.status == 401 and USE_KERBEROS:
                vc, challenge = self._kerberos_client_request(
                    host, handler, response.status, response.reason,
                    response.msg)

                # discard any response data
                if (response.getheader("content-length", 0)):
                    response.read()

                # retry the original request & add the Authorization header:
                self.send_request(h, handler, request_body)
                self._extra_headers = [("Authorization",
                                        "Negotiate %s" % challenge)]
                self.send_host(h, host)
                self.send_user_agent(h)
                self.send_content(h, request_body)
                self._extra_headers = []
                response = h.getresponse(buffering=True)
                self._kerberos_verify_response(vc, host, handler,
                                               response.status,
                                               response.reason, response.msg)

            if response.status == 200:
                self.verbose = verbose
                self._save_cookies(response.msg, cookie_request)
                return self.parse_response(response)
        except xmlrpclib.Fault:
            raise
        except Exception:
            # All unexpected errors leave connection in
            # a strange state, so we clear it.
            self.close()
            raise

        # discard any response data and raise exception
        if (response.getheader("content-length", 0)):
            response.read()
        raise xmlrpclib.ProtocolError(host + handler, response.status,
                                      response.reason, response.msg)
 def _validate_request(self, proc=None):
     '''Validates request and simulates errors when not valid'''
     if 'invalid_host' in self.url:
         # Simulate connecting to an invalid host/port in order to
         # raise `socket.error: [Errno 111] Connection refused`
         socket().connect(('localhost', 38837))
     elif 'invalid_pass' in self.url:
         # Simulate xmlrpc exception for invalid credentials
         raise xmlrpclib.ProtocolError(self.url[7:], 401, 'Unauthorized',
                                       None)
     elif proc is not None and 'invalid' in proc:
         # Simulate xmlrpc exception for process not found
         raise xmlrpclib.Fault(10, 'BAD_NAME')
Example #6
0
    def single_request(self, host, handler, request_body, verbose=0):
        start_time = time.time()
        try:
            result = None
            h = self.make_connection(host)
            if verbose:
                h.set_debuglevel(1)

            try:
                self.send_request(h, handler, request_body)
                self.send_host(h, host)
                self.send_user_agent(h)
                self.send_content(h, request_body)

                response = h.getresponse(buffering=True)
                if response.status == 200:
                    self.verbose = verbose
                    result = self.parse_response(response)
            except xmlrpc_client.Fault:
                raise
            except Exception:
                # All unexpected errors leave connection in
                # a strange state, so we clear it.
                self.close()
                raise

            if response.status != 200:
                #discard any response data and raise exception
                if (response.getheader("content-length", 0)):
                    response.read()
                raise xmlrpc_client.ProtocolError(
                    host + handler,
                    response.status,
                    response.reason,
                    response.msg,
                )
        except xmlrpc_client.Fault as e:
            total_time = int((time.time() - start_time) * 1000)
            events.request_failure.fire(request_type="xmlrpc",
                                        name=handler,
                                        response_time=total_time,
                                        exception=e)
            return ""
        else:
            total_time = int((time.time() - start_time) * 1000)
            response_length = int(response.getheader("content-length", 0))
            events.request_success.fire(request_type="xmlrpc",
                                        name=handler,
                                        response_time=total_time,
                                        response_length=response_length)
            return result
Example #7
0
    def single_request(self, host, handler, request_body, verbose=0):
        # issue XML-RPC request

        request_url = "%s://%s/" % (self.scheme, host)
        self.cookie_request = request.Request(request_url)
        self.verbose = verbose

        try:

            http_con = self.send_request(host, handler, request_body, False)  # pylint: disable=too-many-function-args
            self._extra_headers = []
            response = http_con.getresponse()

            if response.status == 401 and USE_KERBEROS:
                vc, challenge = self._kerberos_client_request(
                    host, handler, response.status, response.reason,
                    response.msg)

                # discard any response data
                if response.getheader("content-length", 0):
                    response.read()

                # retry the original request & add the Authorization header:
                self._extra_headers = [("Authorization",
                                        "Negotiate %s" % challenge)]
                http_con = self.send_request(host, handler, request_body,
                                             verbose)  # pylint: disable=too-many-function-args
                self._extra_headers = []

                response = http_con.getresponse()
                self._kerberos_verify_response(vc, host, handler, response.msg)

            if response.status == 200:
                self.verbose = verbose
                self._save_cookies(response.msg, self.cookie_request)
                return self.parse_response(response)
        except xmlrpclib.Fault:
            raise
        except Exception:
            # All unexpected errors leave connection in
            # a strange state, so we clear it.
            if hasattr(self, 'close'):
                self.close()
            raise

        # discard any response data and raise exception
        if response.getheader("content-length", 0):
            response.read()
        raise xmlrpclib.ProtocolError(host + handler, response.status,
                                      response.reason, response.msg)
Example #8
0
 def request(self, host, handler, request_body, verbose):
     """
     Make an xmlrpc request.
     """
     headers = {'User-Agent': self.user_agent}
     resp = requests.post(self._url,
                          data=request_body,
                          headers=headers,
                          verify=False)
     try:
         resp.raise_for_status()
     except requests.RequestException as e:
         raise xmlrpc_client.ProtocolError(self._url, resp.status_code,
                                           str(e), resp.headers)
     else:
         return self.parse_response(resp)
Example #9
0
    def _request(self, host, handler, request_body, verbose=0):
        """Send a HTTP request."""
        h = self.make_connection(host)
        self.verbose = verbose
        if verbose:
            h.set_debuglevel(1)

        request_url = "%s://%s/" % (self.scheme, host)
        cookie_request = urllib2.Request(request_url)

        self.send_request(h, handler, request_body)
        self.send_host(h, host)
        self.send_cookies(h, cookie_request)
        self.send_user_agent(h)
        self.send_content(h, request_body)
        errcode, errmsg, headers = h.getreply()

        if errcode == 401 and USE_KERBEROS:
            vc, challenge = self._kerberos_client_request(
                host, handler, errcode, errmsg, headers)
            # retry the original request & add the Authorization header:
            self.send_request(h, handler, request_body)
            self.send_host(h, host)
            h.putheader("Authorization", "Negotiate %s" % challenge)
            self.send_cookies(h, cookie_request)
            self.send_user_agent(h)
            self.send_content(h, request_body)
            errcode, errmsg, headers = h.getreply()
            self._kerberos_verify_response(vc, host, handler, errcode, errmsg,
                                           headers)

        elif errcode != 200:
            raise xmlrpclib.ProtocolError(host + handler, errcode, errmsg,
                                          headers)

        self._save_cookies(headers, cookie_request)

        try:
            sock = h._conn.sock
        except AttributeError:
            sock = None

        return self._parse_response(h.getfile(), sock)
Example #10
0
    def single_request(self, host, handler, request_body, verbose=False):
        # issue XML-RPC request
        start_time = time.time()
        try:
            try:
                http_conn = self.send_request(host, handler, request_body,
                                              verbose)
                resp = http_conn.getresponse()
                if resp.status == 200:
                    self.verbose = verbose
                    result = self.parse_response(resp)

            except xmlrpc_client.Fault:
                raise
            except Exception:
                #All unexpected errors leave connection in
                # a strange state, so we clear it.
                self.close()
                raise

            #We got an error response.
            #Discard any response data and raise exception
            if resp.status != 200:
                if resp.getheader("content-length", ""):
                    resp.read()
                raise xmlrpc_client.ProtocolError(host + handler, resp.status,
                                                  resp.reason,
                                                  dict(resp.getheaders()))
        except xmlrpc_client.Fault as e:
            total_time = int((time.time() - start_time) * 1000)
            events.request_failure.fire(request_type="xmlrpc",
                                        name=handler,
                                        response_time=total_time,
                                        exception=e)
            return ""
        else:
            total_time = int((time.time() - start_time) * 1000)
            response_length = int(resp.getheader("content-length", 0))
            events.request_success.fire(request_type="xmlrpc",
                                        name=handler,
                                        response_time=total_time,
                                        response_length=response_length)
            return result
Example #11
0
    def _validate_request(self, proc=None):
        '''Validates request and simulates errors when not valid'''

        # Password not part of URL if connecting via socket
        transport_password = self.transport.password if self.transport else ""

        # `host` is optional connecting via socket
        transport_socket = self.transport.serverurl if self.transport else ""

        # if 'socket_file' in self.url:
        if 'invalid_host' in self.url or 'invalid_socket' in transport_socket:
            # Simulate connecting to an invalid host/port in order to
            # raise `socket.error: [Errno 111] Connection refused`
            socket().connect(('localhost', 38837))
        elif 'invalid_pass' in self.url or 'invalid_pass' in transport_password:
            # Simulate xmlrpc exception for invalid credentials
            raise xmlrpclib.ProtocolError(self.url[7:], 401, 'Unauthorized', None)
        elif proc is not None and 'invalid' in proc:
            # Simulate xmlrpc exception for process not found
            raise xmlrpclib.Fault(10, 'BAD_NAME')
Example #12
0
    def request(self, host, handler, request_body, verbose=0):
        if not self.connection:
            self.connection = self._get_connection()
            self.headers = {
                "User-Agent": self.user_agent,
                "Content-Type": "text/xml",
                "Accept": "text/xml"
            }

            # basic auth
            if self.username is not None and self.password is not None:
                unencoded = "%s:%s" % (self.username, self.password)
                encoded = unencoded.encode('base64')
                encoded = encoded.replace('\012', '')
                self.headers["Authorization"] = "Basic %s" % encoded

        self.headers["Content-Length"] = str(len(request_body))

        self.connection.request('POST', handler, request_body, self.headers)

        r = self.connection.getresponse()

        if r.status != 200:
            self.connection.close()
            self.connection = None
            raise xmlrpc_client.ProtocolError(
                host + handler,
                r.status,
                r.reason,
                '',
            )
        data = r.read()
        p, u = self.getparser()
        p.feed(data)
        p.close()
        return u.close()