예제 #1
0
    def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0):
        super(ResponseHeader, self).read(
            istream,
            kmip_version=kmip_version
        )
        tstream = BytearrayStream(istream.read(self.length))

        self.protocol_version = contents.ProtocolVersion()
        self.protocol_version.read(tstream, kmip_version=kmip_version)

        kmip_version = contents.protocol_version_to_kmip_version(
            self.protocol_version
        )

        self.time_stamp = contents.TimeStamp()
        self.time_stamp.read(tstream, kmip_version=kmip_version)

        if kmip_version >= enums.KMIPVersion.KMIP_2_0:
            if self.is_tag_next(enums.Tags.SERVER_HASHED_PASSWORD, tstream):
                server_hashed_password = primitives.ByteString(
                    tag=enums.Tags.SERVER_HASHED_PASSWORD
                )
                server_hashed_password.read(tstream, kmip_version=kmip_version)
                self._server_hashed_password = server_hashed_password

        self.batch_count = contents.BatchCount()
        self.batch_count.read(tstream, kmip_version=kmip_version)

        self.is_oversized(tstream)
        self.validate()
예제 #2
0
 def test_protocol_version_to_kmip_version_invalid_major(self):
     """
     Test the conversion from invalid ProtocolVersion major value to None.
     """
     result = contents.protocol_version_to_kmip_version(
         contents.ProtocolVersion(9, 5))
     self.assertIsNone(result)
예제 #3
0
 def test_protocol_version_to_kmip_version_kmip_1_4(self):
     """
     Test the conversion from ProtocolVersion(1, 4) to KMIPVersion.KMIP_1_4.
     """
     result = contents.protocol_version_to_kmip_version(
         contents.ProtocolVersion(1, 4))
     self.assertEqual(result, enums.KMIPVersion.KMIP_1_4)
예제 #4
0
    def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0):
        super(RequestHeader, self).read(
            istream,
            kmip_version=kmip_version
        )
        tstream = BytearrayStream(istream.read(self.length))

        self.protocol_version = contents.ProtocolVersion()
        self.protocol_version.read(tstream, kmip_version=kmip_version)

        kmip_version = contents.protocol_version_to_kmip_version(
            self.protocol_version
        )

        # Read the maximum response size if it is present
        if self.is_tag_next(Tags.MAXIMUM_RESPONSE_SIZE, tstream):
            self.maximum_response_size = contents.MaximumResponseSize()
            self.maximum_response_size.read(tstream, kmip_version=kmip_version)

        # Read the asynchronous indicator if it is present
        if self.is_tag_next(Tags.ASYNCHRONOUS_INDICATOR, tstream):
            self.asynchronous_indicator = contents.AsynchronousIndicator()
            self.asynchronous_indicator.read(
                tstream,
                kmip_version=kmip_version
            )

        # Read the authentication if it is present
        if self.is_tag_next(Tags.AUTHENTICATION, tstream):
            self.authentication = contents.Authentication()
            self.authentication.read(tstream, kmip_version=kmip_version)

        # Read the batch error continuation option if it is present
        if self.is_tag_next(Tags.BATCH_ERROR_CONTINUATION_OPTION, tstream):
            self.batch_error_cont_option = BatchErrorContinuationOption()
            self.batch_error_cont_option.read(
                tstream,
                kmip_version=kmip_version
            )

        # Read the batch order option if it is present
        if self.is_tag_next(Tags.BATCH_ORDER_OPTION, tstream):
            self.batch_order_option = contents.BatchOrderOption()
            self.batch_order_option.read(tstream, kmip_version=kmip_version)

        # Read the time stamp if it is present
        if self.is_tag_next(Tags.TIME_STAMP, tstream):
            self.time_stamp = contents.TimeStamp()
            self.time_stamp.read(tstream, kmip_version=kmip_version)

        self.batch_count = contents.BatchCount()
        self.batch_count.read(tstream, kmip_version=kmip_version)

        self.is_oversized(tstream)
예제 #5
0
    def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0):
        super(RequestMessage, self).read(
            istream,
            kmip_version=kmip_version
        )

        self.request_header = RequestHeader()
        self.request_header.read(istream, kmip_version=kmip_version)

        kmip_version = contents.protocol_version_to_kmip_version(
            self.request_header.protocol_version
        )

        self.batch_items = []
        for _ in range(self.request_header.batch_count.value):
            batch_item = RequestBatchItem()
            batch_item.read(istream, kmip_version=kmip_version)
            self.batch_items.append(batch_item)
예제 #6
0
    def _handle_message_loop(self):
        request_data = self._receive_request()
        request = messages.RequestMessage()

        max_size = self._max_response_size
        kmip_version = contents.protocol_version_to_kmip_version(
            self._engine.default_protocol_version)

        try:
            if hasattr(self._connection, 'shared_ciphers'):
                shared_ciphers = self._connection.shared_ciphers()
                self._logger.debug("Possible session ciphers: {0}".format(
                    len(shared_ciphers)))
                for cipher in shared_ciphers:
                    self._logger.debug(cipher)
            self._logger.debug("Session cipher selected: {0}".format(
                self._connection.cipher()))

            certificate = auth.get_certificate_from_connection(
                self._connection)
            if certificate is None:
                raise exceptions.PermissionDenied(
                    "The client certificate could not be loaded from the "
                    "session connection.")

            if self._enable_tls_client_auth:
                extension = auth.get_extended_key_usage_from_certificate(
                    certificate)
                if extension is None:
                    raise exceptions.PermissionDenied(
                        "The extended key usage extension is missing from "
                        "the client certificate.")
                if x509.oid.ExtendedKeyUsageOID.CLIENT_AUTH not in extension:
                    raise exceptions.PermissionDenied(
                        "The extended key usage extension is not marked for "
                        "client authentication in the client certificate.")

            request.read(request_data, kmip_version=kmip_version)
        except exceptions.PermissionDenied as e:
            self._logger.warning("Failure verifying the client certificate.")
            self._logger.exception(e)
            response = self._engine.build_error_response(
                contents.ProtocolVersion(1, 0),
                enums.ResultReason.AUTHENTICATION_NOT_SUCCESSFUL,
                "Error verifying the client certificate. "
                "See server logs for more information.")
        except Exception as e:
            self._logger.warning("Failure parsing request message.")
            self._logger.exception(e)
            response = self._engine.build_error_response(
                contents.ProtocolVersion(1, 0),
                enums.ResultReason.INVALID_MESSAGE,
                "Error parsing request message. See server logs for more "
                "information.")
        else:
            try:
                client_identity = self.authenticate(certificate, request)
                self._logger.info("Session client identity: {}".format(
                    client_identity[0]))
            except Exception:
                self._logger.warning("Authentication failed.")
                response = self._engine.build_error_response(
                    request.request_header.protocol_version,
                    enums.ResultReason.AUTHENTICATION_NOT_SUCCESSFUL,
                    "An error occurred during client authentication. "
                    "See server logs for more information.")
            else:
                try:
                    results = self._engine.process_request(
                        request, client_identity)
                    response, max_response_size, protocol_version = results
                    kmip_version = contents.protocol_version_to_kmip_version(
                        protocol_version)

                    if max_response_size:
                        max_size = max_response_size
                except exceptions.KmipError as e:
                    response = self._engine.build_error_response(
                        request.request_header.protocol_version, e.reason,
                        str(e))
                except Exception as e:
                    self._logger.warning(
                        "An unexpected error occurred while processing "
                        "request.")
                    self._logger.exception(e)
                    response = self._engine.build_error_response(
                        request.request_header.protocol_version,
                        enums.ResultReason.GENERAL_FAILURE,
                        "An unexpected error occurred while processing "
                        "request. See server logs for more information.")

        response_data = utils.BytearrayStream()
        response.write(response_data, kmip_version=kmip_version)

        if len(response_data) > max_size:
            self._logger.warning("Response message length too large: "
                                 "{0} bytes, max {1} bytes".format(
                                     len(response_data),
                                     self._max_response_size))
            response = self._engine.build_error_response(
                request.request_header.protocol_version,
                enums.ResultReason.RESPONSE_TOO_LARGE,
                "Response message length too large. See server logs for "
                "more information.")
            response_data = utils.BytearrayStream()
            response.write(response_data, kmip_version=kmip_version)

        self._send_response(response_data.buffer)