From 8fb05bd848d5d81c3a1a2a9d22dd427948393ae0 Mon Sep 17 00:00:00 2001 From: Peter Hamilton Date: Mon, 17 Jun 2019 17:17:24 -0400 Subject: [PATCH] Fully enable KMIP 2.0 support for the server This changes adds all of the final core updates necessary to allow KMIP 2.0 message encoding/decoding support for the PyKMIP server. Request and responses now dynamically adjust the KMIP version they encode/decode under based on the KMIP version included in their header segments. Extra server logging has also been added to show the KMIP version specified by the client request. Message tests have been updated to reflect these changes. --- kmip/core/messages/contents.py | 5 +++++ kmip/core/messages/messages.py | 16 ++++++++++++++++ kmip/services/kmip_client.py | 4 +++- kmip/services/server/engine.py | 5 +++++ kmip/tests/unit/core/messages/test_messages.py | 8 ++++---- 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/kmip/core/messages/contents.py b/kmip/core/messages/contents.py index adb5afe..2912dbe 100644 --- a/kmip/core/messages/contents.py +++ b/kmip/core/messages/contents.py @@ -277,6 +277,11 @@ def protocol_version_to_kmip_version(value): return enums.KMIPVersion.KMIP_1_4 else: return None + elif value.major == 2: + if value.minor == 0: + return enums.KMIPVersion.KMIP_2_0 + else: + return None else: return None diff --git a/kmip/core/messages/messages.py b/kmip/core/messages/messages.py index 359f38b..e2e37cf 100644 --- a/kmip/core/messages/messages.py +++ b/kmip/core/messages/messages.py @@ -62,6 +62,10 @@ class RequestHeader(Struct): 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() @@ -185,6 +189,10 @@ class ResponseHeader(Struct): 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) @@ -467,6 +475,10 @@ class RequestMessage(Struct): 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() @@ -507,6 +519,10 @@ class ResponseMessage(Struct): self.response_header = ResponseHeader() self.response_header.read(istream, kmip_version=kmip_version) + kmip_version = contents.protocol_version_to_kmip_version( + self.response_header.protocol_version + ) + self.batch_items = [] for _ in range(self.response_header.batch_count.value): batch_item = ResponseBatchItem() diff --git a/kmip/services/kmip_client.py b/kmip/services/kmip_client.py index 36309ae..f87e65a 100644 --- a/kmip/services/kmip_client.py +++ b/kmip/services/kmip_client.py @@ -1576,8 +1576,10 @@ class KMIPProxy(object): return ProtocolVersion(1, 2) elif self.kmip_version == enums.KMIPVersion.KMIP_1_3: return ProtocolVersion(1, 3) - else: + elif self.kmip_version == enums.KMIPVersion.KMIP_1_4: return ProtocolVersion(1, 4) + else: + return ProtocolVersion(2, 0) def _build_request_message(self, credential, batch_items): protocol_version = self._build_protocol_version() diff --git a/kmip/services/server/engine.py b/kmip/services/server/engine.py index d12489d..839b90e 100644 --- a/kmip/services/server/engine.py +++ b/kmip/services/server/engine.py @@ -213,6 +213,11 @@ class KmipEngine(object): # Process the protocol version self._set_protocol_version(header.protocol_version) + self._logger.debug( + "Request specified KMIP version: {0}".format( + header.protocol_version + ) + ) # Process the maximum response size max_response_size = None diff --git a/kmip/tests/unit/core/messages/test_messages.py b/kmip/tests/unit/core/messages/test_messages.py index ff776a4..9c905b9 100644 --- a/kmip/tests/unit/core/messages/test_messages.py +++ b/kmip/tests/unit/core/messages/test_messages.py @@ -174,8 +174,8 @@ class TestResponseHeader(testtools.TestCase): self.encoding_kmip_2_0 = utils.BytearrayStream( b'\x42\x00\x7A\x01\x00\x00\x00\x70' b'\x42\x00\x69\x01\x00\x00\x00\x20' - b'\x42\x00\x6A\x02\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' - b'\x42\x00\x6B\x02\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' + b'\x42\x00\x6A\x02\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' + b'\x42\x00\x6B\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' b'\x42\x00\x92\x09\x00\x00\x00\x08\x00\x00\x00\x00\x4F\x9A\x54\xE5' b'\x42\x01\x55\x08\x00\x00\x00\x20' b'\xD3\xC3\xBF\x31\xB8\xBF\xBB\xEF\x53\x12\x0F\xD0\x95\x1B\xE5\x38' @@ -229,7 +229,7 @@ class TestResponseHeader(testtools.TestCase): ) self.assertEqual( - contents.ProtocolVersion(major=1, minor=1), + contents.ProtocolVersion(major=2, minor=0), response_header.protocol_version ) self.assertEqual(0x4F9A54E5, response_header.time_stamp.value) @@ -250,7 +250,7 @@ class TestResponseHeader(testtools.TestCase): stream when including KMIP 2.0 fields. """ response_header = messages.ResponseHeader( - protocol_version=contents.ProtocolVersion(major=1, minor=1), + protocol_version=contents.ProtocolVersion(major=2, minor=0), time_stamp=contents.TimeStamp(value=0x4F9A54E5), server_hashed_password=( b'\xD3\xC3\xBF\x31\xB8\xBF\xBB\xEF'