Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
 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)
Esempio n. 4
0
    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
Esempio n. 5
0
    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]
Esempio n. 6
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
Esempio n. 7
0
def test_authentication_error():
    with pytest.raises(AuthenticationError) as exc:
        raise AuthenticationError("auth error")
    assert str(exc.value) == "auth error"
Esempio n. 8
0
    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