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