Ejemplo n.º 1
0
    def test_authenticate_against_unrecognized_plugin(self):
        """
        Test that the session correctly handles an unrecognized plugin
        configuration.
        """
        kmip_session = session.KmipSession(
            None,
            None,
            None,
            name='TestSession',
            auth_settings=[("auth:unrecognized", {})]
        )
        kmip_session._logger = mock.MagicMock()
        fake_request = messages.RequestMessage(
            request_header=messages.RequestHeader()
        )

        args = ("fake_certificate", fake_request)
        self.assertRaisesRegexp(
            exceptions.PermissionDenied,
            "Authentication failed.",
            kmip_session.authenticate,
            *args
        )

        kmip_session._logger.warning.assert_any_call(
            "Authentication plugin 'auth:unrecognized' is not supported."
        )
Ejemplo n.º 2
0
    def _handle_message_loop(self):
        request_data = self._receive_request()
        request = messages.RequestMessage()

        max_size = self._max_response_size

        try:
            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()))
            client_identity = self._get_client_identity()
            request.read(request_data)
        except Exception as e:
            self._logger.warning("Failure parsing request message.")
            self._logger.exception(e)
            response = self._engine.build_error_response(
                contents.ProtocolVersion.create(1, 0),
                enums.ResultReason.INVALID_MESSAGE,
                "Error parsing request message. See server logs for more "
                "information.")
        else:
            try:
                response, max_response_size = self._engine.process_request(
                    request, client_identity)
                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)

        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)

        self._send_response(response_data.buffer)
Ejemplo n.º 3
0
    def test_authenticate(self, mock_get):
        """
        Test that the session correctly uses the authentication plugin
        framework to authenticate new connections.
        """
        mock_get.return_value = "John Doe"
        kmip_session = session.KmipSession(
            None,
            None,
            None,
            name='TestSession'
        )
        kmip_session._logger = mock.MagicMock()
        fake_request = messages.RequestMessage(
            request_header=messages.RequestHeader()
        )

        session_identity = kmip_session.authenticate(
            "fake_certificate",
            fake_request
        )

        kmip_session._logger.debug.assert_any_call(
            "No authentication plugins are enabled. The client identity will "
            "be extracted from the client certificate."
        )
        mock_get.assert_any_call("fake_certificate")
        kmip_session._logger.debug.assert_any_call(
            "Extraction succeeded for client identity: John Doe"
        )
        self.assertEqual(("John Doe", None), session_identity)
Ejemplo n.º 4
0
    def test_handle_message_loop_with_authentication_failure(
            self, request_mock, cert_mock):
        """
        Test that the correct logging and error handling occurs when an
        authentication error is generated while processing a request.
        """
        data = utils.BytearrayStream(())

        cert_mock.return_value = 'test_certificate'
        kmip_engine = engine.KmipEngine()
        kmip_engine._logger = mock.MagicMock()
        kmip_session = session.KmipSession(kmip_engine,
                                           None,
                                           None,
                                           name='name',
                                           enable_tls_client_auth=False)
        kmip_session.authenticate = mock.MagicMock()
        kmip_session.authenticate.side_effect = exceptions.PermissionDenied(
            "Authentication failed.")
        kmip_session._engine = mock.MagicMock()
        kmip_session._engine.default_protocol_version = \
            kmip_engine.default_protocol_version
        kmip_session._logger = mock.MagicMock()
        kmip_session._connection = mock.MagicMock()
        kmip_session._receive_request = mock.MagicMock(return_value=data)
        kmip_session._send_response = mock.MagicMock()
        fake_version = contents.ProtocolVersion(1, 2)
        fake_credential = objects.Credential(
            credential_type=enums.CredentialType.USERNAME_AND_PASSWORD,
            credential_value=objects.UsernamePasswordCredential(
                username="******", password="******"))
        fake_header = messages.RequestHeader(
            protocol_version=fake_version,
            authentication=contents.Authentication(
                credentials=[fake_credential]))
        fake_request = messages.RequestMessage()
        fake_request.request_header = fake_header
        fake_request.read = mock.MagicMock()
        request_mock.return_value = fake_request

        kmip_session._handle_message_loop()

        kmip_session._receive_request.assert_called_once_with()
        fake_request.read.assert_called_once_with(
            data, kmip_version=enums.KMIPVersion.KMIP_1_2)
        kmip_session.authenticate.assert_called_once_with(
            "test_certificate", fake_request)
        kmip_session._logger.warning.assert_called_once_with(
            "Authentication failed.")
        kmip_session._engine.build_error_response.assert_called_once_with(
            fake_version, enums.ResultReason.AUTHENTICATION_NOT_SUCCESSFUL,
            "An error occurred during client authentication. "
            "See server logs for more information.")
        kmip_session._logger.exception.assert_not_called()
        self.assertTrue(kmip_session._send_response.called)
Ejemplo n.º 5
0
    def test_authenticate_against_slugs(self, mock_connector):
        """
        Test that the session correctly handles authentication with SLUGS.
        """
        mock_instance = mock.MagicMock()
        mock_instance.authenticate.return_value = ("John Doe", ["Group A"])
        mock_connector.return_value = mock_instance
        kmip_session = session.KmipSession(
            None,
            None,
            ("127.0.0.1", 48026),
            name='TestSession',
            auth_settings=[(
                "auth:slugs",
                {"enabled": "True", "url": "test_url"}
            )]
        )
        kmip_session._logger = mock.MagicMock()
        fake_credential = objects.Credential(
            credential_type=enums.CredentialType.USERNAME_AND_PASSWORD,
            credential_value=objects.UsernamePasswordCredential(
                username="******",
                password="******"
            )
        )
        fake_request = messages.RequestMessage(
            request_header=messages.RequestHeader(
                authentication=contents.Authentication(
                    credentials=[fake_credential]
                )
            )
        )

        result = kmip_session.authenticate(
            "fake_certificate",
            fake_request
        )

        mock_connector.assert_any_call("test_url")
        kmip_session._logger.debug.assert_any_call(
            "Authenticating with plugin: auth:slugs"
        )
        mock_instance.authenticate.assert_any_call(
            "fake_certificate",
            (("127.0.0.1", 48026), kmip_session._session_time),
            fake_request.request_header.authentication.credentials
        )
        kmip_session._logger.debug(
            "Authentication succeeded for client identity: John Doe"
        )
        self.assertEqual(2, len(result))
        self.assertEqual("John Doe", result[0])
        self.assertEqual(["Group A"], result[1])
Ejemplo n.º 6
0
    def test_authenticate_against_slugs_with_failure(self, mock_connector):
        """
        Test that the session correctly handles a SLUGS authentication error.
        """
        mock_instance = mock.MagicMock()
        test_exception = exceptions.PermissionDenied(
            "Unrecognized user ID: John Doe"
        )
        mock_instance.authenticate.side_effect = test_exception
        mock_connector.return_value = mock_instance
        kmip_session = session.KmipSession(
            None,
            None,
            ("127.0.0.1", 48026),
            name='TestSession',
            auth_settings=[(
                "auth:slugs",
                {"enabled": "True", "url": "test_url"}
            )]
        )
        kmip_session._logger = mock.MagicMock()
        fake_credential = objects.Credential(
            credential_type=enums.CredentialType.USERNAME_AND_PASSWORD,
            credential_value=objects.UsernamePasswordCredential(
                username="******",
                password="******"
            )
        )
        fake_request = messages.RequestMessage(
            request_header=messages.RequestHeader(
                authentication=contents.Authentication(
                    credentials=[fake_credential]
                )
            )
        )

        args = ("fake_certificate", fake_request)
        self.assertRaisesRegexp(
            exceptions.PermissionDenied,
            "Authentication failed.",
            kmip_session.authenticate,
            *args
        )

        mock_connector.assert_any_call("test_url")
        kmip_session._logger.debug.assert_any_call(
            "Authenticating with plugin: auth:slugs"
        )
        kmip_session._logger.warning.assert_any_call("Authentication failed.")
        kmip_session._logger.exception.assert_any_call(test_exception)
Ejemplo n.º 7
0
    def _build_request_message(self, credential, batch_items):
        protocol_version = ProtocolVersion.create(1, 2)

        if credential is None:
            credential = self._build_credential()

        authentication = None
        if credential is not None:
            authentication = Authentication(credential)

        batch_count = BatchCount(len(batch_items))
        req_header = messages.RequestHeader(protocol_version=protocol_version,
                                            authentication=authentication,
                                            batch_count=batch_count)

        return messages.RequestMessage(request_header=req_header,
                                       batch_items=batch_items)
Ejemplo n.º 8
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)