- Resolves: RHEL-100450 eDNS: multiple issues during encrypted DNS setup - Resolves: RHEL-89907 Privilege escalation from host to domain admin in FreeIPA - Resolves: RHEL-99315 Include latest fixes in python3-ipatests package - Resolves: RHEL-98565 ipa-idrange-fix: 'Env' object has no attribute 'basedn' - Resolves: RHEL-96920 Nightly test failure (rawhide) in test_trust.py::TestTrust::test_server_option_with_unreachable_ad - Resolves: RHEL-31907 kdb: support storing and retrieving multiple master keys Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
332 lines
13 KiB
Diff
332 lines
13 KiB
Diff
From b69616ed48224b48b5615044314787f69af13c13 Mon Sep 17 00:00:00 2001
|
|
From: Julien Rische <jrische@redhat.com>
|
|
Date: Wed, 12 Mar 2025 13:50:46 +0100
|
|
Subject: [PATCH] Add test for master key upgrade
|
|
|
|
Since commit 4ed7da378940198cf4415f86d4eb013de6ac6455 in MIT krb5,
|
|
kdb5_util sets the required bits on the modification mask of updated
|
|
principal entries to enable ipa-kdb to switch the active master key.
|
|
|
|
This commit creates a "test_fedora_legacy" ipaplatform where the AES
|
|
HMAC-SHA2 encryption types are not enabled. "test_mkey_upgrade" uses
|
|
this platform to initialize a domain with an aes256-cts-hmac-sha1-96
|
|
master key, and test its upgrade to aes256-cts-hmac-sha384-192.
|
|
|
|
Some parts of the test infrastructure had to be made aware of this new
|
|
platform (e.g. firewall integration).
|
|
|
|
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
---
|
|
ipaplatform/setup.py | 1 +
|
|
ipaplatform/test_fedora_legacy/__init__.py | 7 +
|
|
ipaplatform/test_fedora_legacy/constants.py | 16 +++
|
|
ipaplatform/test_fedora_legacy/paths.py | 13 ++
|
|
ipaplatform/test_fedora_legacy/services.py | 27 ++++
|
|
ipaplatform/test_fedora_legacy/tasks.py | 35 +++++
|
|
ipatests/pytest_ipa/integration/firewall.py | 1 +
|
|
.../test_integration/test_mkey_upgrade.py | 135 ++++++++++++++++++
|
|
8 files changed, 235 insertions(+)
|
|
create mode 100644 ipaplatform/test_fedora_legacy/__init__.py
|
|
create mode 100644 ipaplatform/test_fedora_legacy/constants.py
|
|
create mode 100644 ipaplatform/test_fedora_legacy/paths.py
|
|
create mode 100644 ipaplatform/test_fedora_legacy/services.py
|
|
create mode 100644 ipaplatform/test_fedora_legacy/tasks.py
|
|
create mode 100644 ipatests/test_integration/test_mkey_upgrade.py
|
|
|
|
diff --git a/ipaplatform/setup.py b/ipaplatform/setup.py
|
|
index 086a99d1fa602551d2ff3270113608aa0fbc026c..1d6df1eff62b434162a7ce815e8273241d424c78 100644
|
|
--- a/ipaplatform/setup.py
|
|
+++ b/ipaplatform/setup.py
|
|
@@ -42,6 +42,7 @@ if __name__ == '__main__':
|
|
"ipaplatform.rhel",
|
|
"ipaplatform.rhel_container",
|
|
"ipaplatform.suse",
|
|
+ "ipaplatform.test_fedora_legacy",
|
|
"ipaplatform.opencloudos",
|
|
"ipaplatform.tencentos"
|
|
],
|
|
diff --git a/ipaplatform/test_fedora_legacy/__init__.py b/ipaplatform/test_fedora_legacy/__init__.py
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..a4f4cff5a7084d5d1697aefbe2bebcfb89e0a694
|
|
--- /dev/null
|
|
+++ b/ipaplatform/test_fedora_legacy/__init__.py
|
|
@@ -0,0 +1,7 @@
|
|
+#
|
|
+# Copyright (C) 2025 FreeIPA Contributors see COPYING for license
|
|
+#
|
|
+"""
|
|
+This module contains Fedora AES HMAC-SHA1 master key specific platform files.
|
|
+"""
|
|
+NAME = 'test_fedora_legacy'
|
|
diff --git a/ipaplatform/test_fedora_legacy/constants.py b/ipaplatform/test_fedora_legacy/constants.py
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..0cebac86a9eea45803af669d8237dffd34675d74
|
|
--- /dev/null
|
|
+++ b/ipaplatform/test_fedora_legacy/constants.py
|
|
@@ -0,0 +1,16 @@
|
|
+#
|
|
+# Copyright (C) 2025 FreeIPA Contributors see COPYING for license
|
|
+#
|
|
+"""Fedora AES HMAC-SHA1 master key constants
|
|
+"""
|
|
+from ipaplatform.fedora.constants import FedoraConstantsNamespace, User, Group
|
|
+
|
|
+
|
|
+__all__ = ("constants", "User", "Group")
|
|
+
|
|
+
|
|
+class TestFedoraLegacyConstantsNamespace(FedoraConstantsNamespace):
|
|
+ pass
|
|
+
|
|
+
|
|
+constants = TestFedoraLegacyConstantsNamespace()
|
|
diff --git a/ipaplatform/test_fedora_legacy/paths.py b/ipaplatform/test_fedora_legacy/paths.py
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..71fb8acdc9143a4daa14a0b0dc7cf46fe5fdc2ce
|
|
--- /dev/null
|
|
+++ b/ipaplatform/test_fedora_legacy/paths.py
|
|
@@ -0,0 +1,13 @@
|
|
+#
|
|
+# Copyright (C) 2025 FreeIPA Contributors see COPYING for license
|
|
+#
|
|
+"""Fedora AES HMAC-SHA1 master key paths
|
|
+"""
|
|
+from ipaplatform.fedora.paths import FedoraPathNamespace
|
|
+
|
|
+
|
|
+class TestFedoraLegacyPathNamespace(FedoraPathNamespace):
|
|
+ pass
|
|
+
|
|
+
|
|
+paths = TestFedoraLegacyPathNamespace()
|
|
diff --git a/ipaplatform/test_fedora_legacy/services.py b/ipaplatform/test_fedora_legacy/services.py
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..adbe21f82e215349e54b586cdd5201374dd1378e
|
|
--- /dev/null
|
|
+++ b/ipaplatform/test_fedora_legacy/services.py
|
|
@@ -0,0 +1,27 @@
|
|
+#
|
|
+# Copyright (C) 2025 FreeIPA Contributors see COPYING for license
|
|
+#
|
|
+"""Fedora AES HMAC-SHA1 master key services
|
|
+"""
|
|
+from ipaplatform.fedora import services as fedora_services
|
|
+
|
|
+
|
|
+test_fedora_legacy_system_units = fedora_services.fedora_system_units.copy()
|
|
+
|
|
+
|
|
+class TestFedoraLegacyService(fedora_services.FedoraService):
|
|
+ system_units = test_fedora_legacy_system_units
|
|
+
|
|
+
|
|
+def test_fedora_legacy_service_class_factory(name, api=None):
|
|
+ return fedora_services.fedora_service_class_factory(name, api)
|
|
+
|
|
+
|
|
+class TestFedoraLegacyServices(fedora_services.FedoraServices):
|
|
+ def service_class_factory(self, name, api=None):
|
|
+ return test_fedora_legacy_service_class_factory(name, api)
|
|
+
|
|
+
|
|
+timedate_services = fedora_services.timedate_services
|
|
+service = test_fedora_legacy_service_class_factory
|
|
+knownservices = TestFedoraLegacyServices()
|
|
diff --git a/ipaplatform/test_fedora_legacy/tasks.py b/ipaplatform/test_fedora_legacy/tasks.py
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..e6e72d7237cbc7d2a14b92cbb746bf8d66b197f2
|
|
--- /dev/null
|
|
+++ b/ipaplatform/test_fedora_legacy/tasks.py
|
|
@@ -0,0 +1,35 @@
|
|
+#
|
|
+# Copyright (C) 2025 FreeIPA Contributors see COPYING for license
|
|
+#
|
|
+"""Fedora AES HMAC-SHA1 master key tasks
|
|
+"""
|
|
+from ipaplatform.fedora.tasks import FedoraTaskNamespace
|
|
+
|
|
+from re import compile
|
|
+
|
|
+
|
|
+def add_aes_sha1(enctypes):
|
|
+ return tuple({*enctypes,
|
|
+ 'aes256-cts:special', 'aes128-cts:special',
|
|
+ 'aes256-cts:normal', 'aes128-cts:normal'})
|
|
+
|
|
+
|
|
+class TestFedoraLegacyTaskNamespace(FedoraTaskNamespace):
|
|
+
|
|
+ def get_masterkey_enctype(self):
|
|
+ return 'aes256-cts'
|
|
+
|
|
+ def get_supported_enctypes(self):
|
|
+ aes_sha2_pattern = compile('^aes[0-9]+-sha2:')
|
|
+
|
|
+ return tuple(e for e in super().get_supported_enctypes()
|
|
+ if not aes_sha2_pattern.match(e))
|
|
+
|
|
+ def get_removed_supported_enctypes(self):
|
|
+ return add_aes_sha1(super().get_removed_supported_enctypes())
|
|
+
|
|
+ def get_removed_default_enctypes(self):
|
|
+ return add_aes_sha1(super().get_removed_default_enctypes())
|
|
+
|
|
+
|
|
+tasks = TestFedoraLegacyTaskNamespace()
|
|
diff --git a/ipatests/pytest_ipa/integration/firewall.py b/ipatests/pytest_ipa/integration/firewall.py
|
|
index 1a5af5c5e71f71da4c939cddede7cab4817dd3a3..01661b6c6ab84b5ad0f13ebd537b25a2adf0ec1c 100644
|
|
--- a/ipatests/pytest_ipa/integration/firewall.py
|
|
+++ b/ipatests/pytest_ipa/integration/firewall.py
|
|
@@ -239,6 +239,7 @@ class Firewall(FirewallBase):
|
|
firewalls = {
|
|
'rhel': FirewallD,
|
|
'fedora': FirewallD,
|
|
+ 'test_fedora_legacy': FirewallD,
|
|
'debian': FirewallD,
|
|
'ubuntu': FirewallD,
|
|
'altlinux': NoOpFirewall,
|
|
diff --git a/ipatests/test_integration/test_mkey_upgrade.py b/ipatests/test_integration/test_mkey_upgrade.py
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..933623fbfc913ed6efe5409b3a35af1524305c8e
|
|
--- /dev/null
|
|
+++ b/ipatests/test_integration/test_mkey_upgrade.py
|
|
@@ -0,0 +1,135 @@
|
|
+#
|
|
+# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
|
+#
|
|
+
|
|
+import re
|
|
+import textwrap
|
|
+
|
|
+from ipatests.pytest_ipa.integration import tasks
|
|
+from ipatests.test_integration.base import IntegrationTest
|
|
+
|
|
+
|
|
+class TestMkeyUpgrade(IntegrationTest):
|
|
+
|
|
+ num_replicas = 1
|
|
+ topology = 'line'
|
|
+
|
|
+ @classmethod
|
|
+ def install(cls, mh):
|
|
+ cls.master.put_file_contents(
|
|
+ '/etc/profile.d/ipaplatform.sh',
|
|
+ 'export IPAPLATFORM_OVERRIDE=test_fedora_legacy')
|
|
+ cls.master.run_command(['mkdir', '/etc/systemd/system/ipa.service.d'])
|
|
+ cls.master.put_file_contents(
|
|
+ '/etc/systemd/system/ipa.service.d/platform.conf',
|
|
+ '[Service]\n'
|
|
+ 'Environment="IPAPLATFORM_OVERRIDE=test_fedora_legacy"')
|
|
+ cls.master.run_command(['systemctl', 'daemon-reload'])
|
|
+ tasks.install_master(cls.master, setup_dns=False)
|
|
+ tasks.install_replica(cls.master, cls.replicas[0], setup_dns=False)
|
|
+
|
|
+ def test_old_active_mkey(self):
|
|
+ p = re.compile('^KVNO: 1, Enctype: aes256-cts-hmac-sha1-96, .+ \\*$',
|
|
+ flags=re.MULTILINE)
|
|
+
|
|
+ result = self.master.run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert p.search(result.stdout_text)
|
|
+ result = self.replicas[0].run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert p.search(result.stdout_text)
|
|
+
|
|
+ def test_enable_new_entypes(self):
|
|
+ base_dn = "dc=%s" % (",dc=".join(self.master.domain.name.split(".")))
|
|
+ realm = self.master.domain.name.upper()
|
|
+
|
|
+ entry_ldif = textwrap.dedent("""
|
|
+ dn: cn={realm},cn=kerberos,{base_dn}
|
|
+ changetype: modify
|
|
+ replace: krbSupportedEncSaltTypes
|
|
+ krbSupportedEncSaltTypes: aes128-sha2:normal
|
|
+ krbSupportedEncSaltTypes: aes128-sha2:special
|
|
+ krbSupportedEncSaltTypes: aes256-sha2:normal
|
|
+ krbSupportedEncSaltTypes: aes256-sha2:special
|
|
+ krbSupportedEncSaltTypes: aes256-cts:normal
|
|
+ krbSupportedEncSaltTypes: aes256-cts:special
|
|
+ krbSupportedEncSaltTypes: aes128-cts:normal
|
|
+ krbSupportedEncSaltTypes: aes128-cts:special
|
|
+ krbSupportedEncSaltTypes: camellia128-cts-cmac:normal
|
|
+ krbSupportedEncSaltTypes: camellia128-cts-cmac:special
|
|
+ krbSupportedEncSaltTypes: camellia256-cts-cmac:normal
|
|
+ krbSupportedEncSaltTypes: camellia256-cts-cmac:special
|
|
+ -
|
|
+ replace: krbDefaultEncSaltTypes
|
|
+ krbDefaultEncSaltTypes: aes256-sha2:special
|
|
+ krbDefaultEncSaltTypes: aes128-sha2:special
|
|
+ krbDefaultEncSaltTypes: aes256-cts:special
|
|
+ krbDefaultEncSaltTypes: aes128-cts:special""").format(
|
|
+ base_dn=base_dn, realm=realm)
|
|
+ tasks.ldapmodify_dm(self.master, entry_ldif)
|
|
+
|
|
+ def test_add_new_mkey(self):
|
|
+ self.master.run_command('kdb5_util add_mkey -e aes256-sha2 -s',
|
|
+ stdin_text='Secret123\nSecret123')
|
|
+
|
|
+ def test_new_inactive_mkey(self):
|
|
+ p = re.compile('^KVNO: 2, Enctype: aes256-cts-hmac-sha384-192, ',
|
|
+ flags=re.MULTILINE)
|
|
+
|
|
+ result = self.master.run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert p.search(result.stdout_text)
|
|
+ result = self.replicas[0].run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert p.search(result.stdout_text)
|
|
+
|
|
+ def test_switch_mkey(self):
|
|
+ self.master.run_command(['kdb5_util', 'use_mkey', '2'])
|
|
+
|
|
+ def test_new_active_mkey(self):
|
|
+ p = re.compile('^KVNO: 2, Enctype: aes256-cts-hmac-sha384-192, .+ \\*$',
|
|
+ flags=re.MULTILINE)
|
|
+
|
|
+ result = self.master.run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert p.search(result.stdout_text)
|
|
+ result = self.replicas[0].run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert p.search(result.stdout_text)
|
|
+
|
|
+ def test_used_old_mkey(self):
|
|
+ p = re.compile('^MKey: vno 1$', flags=re.MULTILINE)
|
|
+
|
|
+ result = self.master.run_command(['kadmin.local', 'getprinc',
|
|
+ f'ldap/{self.master.hostname}'])
|
|
+ assert p.search(result.stdout_text)
|
|
+ result = self.replicas[0].run_command(['kadmin.local', 'getprinc',
|
|
+ f'ldap/{self.master.hostname}'])
|
|
+ assert p.search(result.stdout_text)
|
|
+
|
|
+ def test_reencrypt_with_new_mkey(self):
|
|
+ self.master.run_command(['kdb5_util', '-x', 'unlockiter',
|
|
+ 'update_princ_encryption', '-vf'])
|
|
+
|
|
+ def test_used_new_mkey(self):
|
|
+ p = re.compile('^MKey: vno 2$', flags=re.MULTILINE)
|
|
+
|
|
+ result = self.master.run_command(['kadmin.local', 'getprinc',
|
|
+ f'ldap/{self.master.hostname}'])
|
|
+ assert p.search(result.stdout_text)
|
|
+ result = self.replicas[0].run_command(['kadmin.local', 'getprinc',
|
|
+ f'ldap/{self.master.hostname}'])
|
|
+ assert p.search(result.stdout_text)
|
|
+
|
|
+ def test_purge_old_mkey(self):
|
|
+ self.master.run_command(['kdb5_util', 'purge_mkeys', '-vf'])
|
|
+
|
|
+ def test_only_new_mkey(self):
|
|
+ p = re.compile('^KVNO: 1,', flags=re.MULTILINE)
|
|
+
|
|
+ result = self.master.run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert not p.search(result.stdout_text)
|
|
+ result = self.replicas[0].run_command(['kdb5_util', 'list_mkeys'])
|
|
+ assert not p.search(result.stdout_text)
|
|
+
|
|
+ @classmethod
|
|
+ def uninstall(cls, mh):
|
|
+ cls.master.run_command([
|
|
+ 'rm', '/etc/profile.d/ipaplatform.sh',
|
|
+ '/etc/systemd/system/ipa.service.d/platform.conf'])
|
|
+ cls.master.run_command(['rmdir', '/etc/systemd/system/ipa.service.d'])
|
|
+ super().uninstall(mh)
|
|
--
|
|
2.50.0
|
|
|