def _send_request(self, request, hostname): response = self.session.send(request, timeout=(self.connection_timeout, self.read_timeout)) content_type = response.headers.get('content-type', "") if content_type.startswith("multipart/encrypted;") or \ content_type.startswith("multipart/x-multi-encrypted;"): response_content = self.encryption.unwrap_message( response.content, hostname) response_text = to_string(response_content) else: response_content = response.content response_text = response.text if response_content else '' log.debug("Received message: %s" % response_text) # for testing, keep commented out # self._test_messages[-1]['response'] = response_text try: response.raise_for_status() except requests.HTTPError as err: response = err.response if response.status_code == 401: raise AuthenticationError("Failed to authenticate the user %s " "with %s" % (self.username, self.auth)) else: code = response.status_code raise WinRMTransportError('http', code, response_text) return response_content
def _send_request(self, request: requests.PreparedRequest) -> bytes: response = self.session.send(request, timeout=(self.connection_timeout, self.read_timeout)) # type: ignore[union-attr] # This should not happen content_type = response.headers.get("content-type", "") if content_type.startswith("multipart/encrypted;") or content_type.startswith("multipart/x-multi-encrypted;"): boundary = re.search("boundary=[" '|\\"](.*)[' '|\\"]', response.headers["content-type"]).group(1) # type: ignore[union-attr] # This should not happen response_content = self.encryption.unwrap_message(response.content, to_unicode(boundary)) # type: ignore[union-attr] # This should not happen response_text = to_string(response_content) else: response_content = response.content response_text = response.text if response_content else "" log.debug("Received message: %s" % response_text) # for testing, keep commented out # self._test_messages[-1]['response'] = response_text try: response.raise_for_status() except requests.HTTPError as err: response = err.response if response.status_code == 401: raise AuthenticationError("Failed to authenticate the user %s with %s" % (self.username, self.auth)) else: code = response.status_code raise WinRMTransportError("http", code, response_text) return response_content
def _check_auth_supported(response, auth_provider): auth_supported = response.headers.get('www-authenticate', '') if auth_provider.upper() not in auth_supported.upper(): error_msg = "The server did not response with the " \ "authentication method of %s - actual: '%s'" \ % (auth_provider, auth_supported) raise AuthenticationError(error_msg)
def send(self, message): current_msg = self._test_meta[self._test_msg_key][self._msg_counter] message = self._normalise_xml(message, generify=False) request = self._normalise_xml(current_msg['request'], overrides=current_msg.get( 'overrides', None)) response = self._normalise_xml(current_msg['response']) assert message == request, "Message %d request for test %s does not " \ "match expectation\nActual: %s\n" \ "Expected: %s" % (self._msg_counter, self._test_name, message, request) self._msg_counter += 1 # check if test metadata indicates we want to raise an exception here # instead of returning the response if 'transport_error' in current_msg.keys(): raise WinRMTransportError( current_msg['transport_error']['protocol'], current_msg['transport_error']['code'], response) elif current_msg.get('auth_error', False): raise AuthenticationError("Failed to authenticate the user %s " "with %s" % (self.username, self.auth)) if 'timeout' in current_msg.keys(): time.sleep(current_msg['timeout']) return response
def _check_auth_supported(response, auth_providers): auth_supported = response.headers.get('www-authenticate', '') matched_providers = [ p for p in auth_providers if p.upper() in auth_supported.upper() ] if not matched_providers: raise AuthenticationError( "The server did not response with one of the following authentication methods " "%s - actual: '%s'" % (", ".join(auth_providers), auth_supported)) return matched_providers[0]
def _step(self, token): success_codes = [ sspicon.SEC_E_OK, sspicon.SEC_I_COMPLETE_AND_CONTINUE, sspicon.SEC_I_COMPLETE_NEEDED, sspicon.SEC_I_CONTINUE_NEEDED ] sec_tokens = [] if token is not None: sec_token = win32security.PySecBufferType( self._context.pkg_info['MaxToken'], sspicon.SECBUFFER_TOKEN ) sec_token.Buffer = token sec_tokens.append(sec_token) if self.cbt_app_data is not None: sec_token = win32security.PySecBufferType( len(self.cbt_app_data), sspicon.SECBUFFER_CHANNEL_BINDINGS ) sec_token.Buffer = self.cbt_app_data sec_tokens.append(sec_token) if len(sec_tokens) > 0: sec_buffer = win32security.PySecBufferDescType() for sec_token in sec_tokens: sec_buffer.append(sec_token) else: sec_buffer = None rc, out_buffer = self._context.authorize(sec_buffer_in=sec_buffer) self._call_counter += 1 if rc not in success_codes: rc_name = "Unknown Error" for name, value in vars(sspicon).items(): if isinstance(value, int) and name.startswith("SEC_") and \ value == rc: rc_name = name break raise AuthenticationError( "InitializeSecurityContext failed on call %d: (%d) %s 0x%s" % (self._call_counter, rc, rc_name, format(rc, 'x')) ) return out_buffer[0].Buffer
def test_authentication_error(): with pytest.raises(AuthenticationError) as exc: raise AuthenticationError("auth error") assert str(exc.value) == "auth error"
def send(self, message): current_msg = self._test_meta[self._test_msg_key][self._msg_counter] actual = self._normalise_xml(message, generify=False, psrp_fragment_type="actual") expected = self._normalise_xml(current_msg["request"], overrides=current_msg.get( "overrides", None), psrp_fragment_type="expected") failure_msg = "Message %d request for test %s does not match expectation\nActual: %s\nExpected: %s" % ( self._msg_counter, self._test_name, actual, expected, ) assert_xml_diff(actual, expected, msg=failure_msg) for obj_id in list(self._psrp_fragments.keys()): details = self._psrp_fragments[obj_id] if not details["end"]: continue fragment_ids = list(details["actual"].keys()) fragment_ids.sort() actual_obj = b"" expected_obj = b"" for i in range(0, fragment_ids[-1] + 1): actual_obj += details["actual"][i] expected_obj += details["expected"][i] actual_destination = struct.unpack("<I", actual_obj[:4])[0] actual_message_type = struct.unpack("<I", actual_obj[4:8])[0] actual_message = self._normalise_xml(actual_obj[40:], generify=False) expected_destination = struct.unpack("<I", expected_obj[:4])[0] expected_message_type = struct.unpack("<I", expected_obj[4:8])[0] expected_message = self._normalise_xml(expected_obj[40:], generify=False) assert actual_destination == expected_destination assert actual_message_type == expected_message_type # Only do the XML compare if the message had data, otherwise just # compare the actual values failure_msg = ( "PSRP Message object %d for test %s does not match " "expectation\nActual: %s\nExpected: %s" % (obj_id, self._test_name, actual_message, expected_message)) assert_xml_diff(actual_message, expected_message, msg=failure_msg) # Remove the fragments for the obj as we've verified them del self._psrp_fragments[obj_id] response = self._normalise_xml(current_msg["response"]) self._msg_counter += 1 # check if test metadata indicates we want to raise an exception here # instead of returning the response if "transport_error" in current_msg.keys(): raise WinRMTransportError( current_msg["transport_error"]["protocol"], current_msg["transport_error"]["code"], response) elif current_msg.get("auth_error", False): raise AuthenticationError( "Failed to authenticate the user %s with %s" % (self.username, self.auth)) if "timeout" in current_msg.keys(): time.sleep(current_msg["timeout"]) return response