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)
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)
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
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')
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
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)
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)
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)
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
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')
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()