import ipa-4.9.8-7.el9_0

This commit is contained in:
CentOS Sources 2022-04-05 06:31:02 -04:00 committed by Stepan Oksanichenko
parent 9ea9b7ab0a
commit 3a117a41e7
13 changed files with 1477 additions and 2 deletions

View File

@ -0,0 +1,326 @@
From 6b70e3c49acc55b5553101cf850fc40978861979 Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Mon, 17 Jan 2022 16:57:52 +0530
Subject: [PATCH] ipatests: Tests for Autoprivate group.
Added tests using posix AD trust and non posix AD trust.
For option --auto-private-groups=[hybrid/true/false]
Related : https://pagure.io/freeipa/issue/8807
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Anuja More <amore@redhat.com>
---
.../nightly_ipa-4-9_latest.yaml | 2 +-
.../nightly_ipa-4-9_latest_selinux.yaml | 2 +-
.../nightly_ipa-4-9_previous.yaml | 2 +-
ipatests/test_integration/test_trust.py | 242 +++++++++++++++++-
4 files changed, 240 insertions(+), 8 deletions(-)
diff --git a/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml b/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml
index 6817421b278999c52c32b3e28dd06587e30d874f..8b1f58c4d99e744e319e6c758050a62a8d35c9ee 100644
--- a/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml
+++ b/ipatests/prci_definitions/nightly_ipa-4-9_latest.yaml
@@ -1627,7 +1627,7 @@ jobs:
build_url: '{fedora-latest-ipa-4-9/build_url}'
test_suite: test_integration/test_trust.py
template: *ci-ipa-4-9-latest
- timeout: 9000
+ timeout: 10000
topology: *adroot_adchild_adtree_master_1client
fedora-latest-ipa-4-9/test_backup_and_restore_TestBackupAndRestoreTrust:
diff --git a/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml b/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml
index 817329756dc145fa5e6bc7aa0477e5df2a6ece5b..a11376ab836e7ed2f942c29753707e5b8e88a00f 100644
--- a/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml
+++ b/ipatests/prci_definitions/nightly_ipa-4-9_latest_selinux.yaml
@@ -1743,7 +1743,7 @@ jobs:
selinux_enforcing: True
test_suite: test_integration/test_trust.py
template: *ci-ipa-4-9-latest
- timeout: 9000
+ timeout: 10000
topology: *adroot_adchild_adtree_master_1client
fedora-latest-ipa-4-9/test_backup_and_restore_TestBackupAndRestoreTrust:
diff --git a/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml b/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml
index 4196265c772ec393ebb8f8bbdc4af845cd6d2d24..3f8ce8b7641fdfdc27278651cbf83c2b152e1a16 100644
--- a/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml
+++ b/ipatests/prci_definitions/nightly_ipa-4-9_previous.yaml
@@ -1627,7 +1627,7 @@ jobs:
build_url: '{fedora-previous-ipa-4-9/build_url}'
test_suite: test_integration/test_trust.py
template: *ci-ipa-4-9-previous
- timeout: 9000
+ timeout: 10000
topology: *adroot_adchild_adtree_master_1client
fedora-previous-ipa-4-9/test_backup_and_restore_TestBackupAndRestoreTrust:
diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
index 0634badbb6a9aa148db2e3062e866215e61e89e7..ff2dd9cc819e1c5620ce449384957a633ae6d1f0 100644
--- a/ipatests/test_integration/test_trust.py
+++ b/ipatests/test_integration/test_trust.py
@@ -62,11 +62,12 @@ class BaseTestTrust(IntegrationTest):
cls.check_sid_generation()
tasks.sync_time(cls.master, cls.ad)
- cls.child_ad = cls.ad_subdomains[0]
- cls.ad_subdomain = cls.child_ad.domain.name
- cls.tree_ad = cls.ad_treedomains[0]
- cls.ad_treedomain = cls.tree_ad.domain.name
-
+ if cls.num_ad_subdomains > 0:
+ cls.child_ad = cls.ad_subdomains[0]
+ cls.ad_subdomain = cls.child_ad.domain.name
+ if cls.num_ad_treedomains > 0:
+ cls.tree_ad = cls.ad_treedomains[0]
+ cls.ad_treedomain = cls.tree_ad.domain.name
# values used in workaround for
# https://bugzilla.redhat.com/show_bug.cgi?id=1711958
cls.srv_gc_record_name = \
@@ -106,6 +107,63 @@ class BaseTestTrust(IntegrationTest):
expected_text = 'iparangetype: %s\n' % expected_type
assert expected_text in result.stdout_text
+ def mod_idrange_auto_private_group(
+ self, option='false'
+ ):
+ """
+ Set the auto-private-group option of the default trusted
+ AD domain range.
+ """
+ tasks.kinit_admin(self.master)
+ rangename = self.ad_domain.upper() + '_id_range'
+ error_msg = "ipa: ERROR: no modifications to be performed"
+ cmd = ["ipa", "idrange-mod", rangename,
+ "--auto-private-groups", option]
+ result = self.master.run_command(cmd, raiseonerr=False)
+ if result.returncode != 0:
+ tasks.assert_error(result, error_msg)
+ tasks.clear_sssd_cache(self.master)
+ tasks.clear_sssd_cache(self.clients[0])
+ test = self.master.run_command(["ipa", "idrange-show", rangename])
+ assert "Auto private groups: {0}".format(option) in test.stdout_text
+
+ def get_user_id(self, host, username):
+ """
+ User uid gid is parsed from the output of id user command.
+ """
+ tasks.clear_sssd_cache(self.master)
+ tasks.clear_sssd_cache(self.clients[0])
+ self.master.run_command(["id", username])
+ test_id = host.run_command(["id", username])
+ regex = r"^uid=(?P<uid>\d+).*gid=(?P<gid>\d+).*groups=(?P<groups>\d+)"
+ match = re.match(regex, test_id.stdout_text)
+ uid = match.group('uid')
+ gid = match.group('gid')
+ return uid, gid
+
+ @contextmanager
+ def set_idoverrideuser(self, user, uid, gid):
+ """
+ Fixture to add/remove idoverrideuser for default idview,
+ also creates idm group with the provided gid because
+ gid overrides requires an existing group.
+ """
+ tasks.clear_sssd_cache(self.master)
+ tasks.clear_sssd_cache(self.clients[0])
+ tasks.kinit_admin(self.master)
+ try:
+ args = ["ipa", "idoverrideuser-add", "Default Trust View",
+ "--gid", gid, "--uid", uid, user]
+ self.master.run_command(args)
+ tasks.group_add(self.master, "idgroup",
+ extra_args=["--gid", gid])
+ yield
+ finally:
+ self.master.run_command([
+ "ipa", "idoverrideuser-del", "Default Trust View", user]
+ )
+ self.master.run_command(["ipa", "group-del", "idgroup"])
+
def remove_trust(self, ad):
tasks.remove_trust_with_ad(self.master,
ad.domain.name, ad.hostname)
@@ -993,3 +1051,177 @@ class TestTrust(BaseTestTrust):
self.master.run_command(['rm', '-f', ad_zone_file])
tasks.configure_dns_for_trust(self.master, self.ad)
self.remove_trust(self.ad)
+
+
+class TestNonPosixAutoPrivateGroup(BaseTestTrust):
+ """
+ Tests for auto-private-groups option with non posix AD trust
+ Related : https://pagure.io/freeipa/issue/8807
+ """
+ topology = 'line'
+ num_ad_domains = 1
+ num_clients = 1
+ num_ad_subdomains = 0
+ num_ad_treedomains = 0
+ uid_override = "99999999"
+ gid_override = "78878787"
+
+ def test_add_nonposix_trust(self):
+ tasks.configure_dns_for_trust(self.master, self.ad)
+ tasks.establish_trust_with_ad(
+ self.master, self.ad_domain,
+ extra_args=['--range-type', 'ipa-ad-trust'])
+
+ @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+ def test_auto_private_groups_default_trusted_range(self, type):
+ """
+ Modify existing range for default trusted AD domain range
+ with auto-private-groups set as true/hybrid/false and test
+ user with no posix attributes.
+ """
+ self.mod_idrange_auto_private_group(type)
+ nonposixuser = "nonposixuser@%s" % self.ad_domain
+ (uid, gid) = self.get_user_id(self.clients[0], nonposixuser)
+ if type == "true":
+ assert uid == gid
+ else:
+ test_group = self.clients[0].run_command(["id", nonposixuser])
+ gid_str = "gid={0}(domain users@{1})".format(gid, self.ad_domain)
+ grp_str = "groups={0}(domain users@{1})".format(gid,
+ self.ad_domain)
+ assert gid_str in test_group.stdout_text
+ assert grp_str in test_group.stdout_text
+ assert uid != gid
+
+ @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+ def test_idoverride_with_auto_private_group(self, type):
+ """
+ Override ad trusted user in default trust view
+ and set auto-private-groups=[hybrid,true,false]
+ and ensure that overridden values takes effect.
+ """
+ nonposixuser = "nonposixuser@%s" % self.ad_domain
+ with self.set_idoverrideuser(nonposixuser,
+ self.uid_override,
+ self.gid_override
+ ):
+ self.mod_idrange_auto_private_group(type)
+ (uid, gid) = self.get_user_id(self.clients[0], nonposixuser)
+ assert (uid == self.uid_override and gid == self.gid_override)
+ test_group = self.clients[0].run_command(
+ ["id", nonposixuser]).stdout_text
+ assert "domain users@{0}".format(self.ad_domain) in test_group
+
+ @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+ def test_nonposixuser_nondefault_primary_group(self, type):
+ """
+ Test for non default primary group.
+ For hybrid/false gid corresponds to the group testgroup1.
+ """
+ nonposixuser1 = "nonposixuser1@%s" % self.ad_domain
+ self.mod_idrange_auto_private_group(type)
+ (uid, gid) = self.get_user_id(self.clients[0], nonposixuser1)
+ if type == "true":
+ assert uid == gid
+ else:
+ test_group = self.clients[0].run_command(["id", nonposixuser1])
+ gid_str = "gid={0}(testgroup1@{1})".format(gid, self.ad_domain)
+ group = "groups={0}(testgroup1@{1})".format(gid, self.ad_domain)
+ assert (gid_str in test_group.stdout_text
+ and group in test_group.stdout_text)
+
+
+class TestPosixAutoPrivateGroup(BaseTestTrust):
+ """
+ Tests for auto-private-groups option with posix AD trust
+ Related : https://pagure.io/freeipa/issue/8807
+ """
+ topology = 'line'
+ num_ad_domains = 1
+ num_clients = 1
+ num_ad_subdomains = 0
+ num_ad_treedomains = 0
+ uid_override = "99999999"
+ gid_override = "78878787"
+
+ def test_add_posix_trust(self):
+ tasks.configure_dns_for_trust(self.master, self.ad)
+ tasks.establish_trust_with_ad(
+ self.master, self.ad_domain,
+ extra_args=['--range-type', 'ipa-ad-trust-posix'])
+
+ @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+ def test_gidnumber_not_corresponding_existing_group(self, type):
+ """
+ Test checks that sssd can resolve AD users which
+ contain posix attributes (uidNumber and gidNumber)
+ but there is no group with the corresponding gidNumber.
+ """
+ posixuser = "testuser2@%s" % self.ad_domain
+ self.mod_idrange_auto_private_group(type)
+ if type != "true":
+ result = self.clients[0].run_command(['id', posixuser],
+ raiseonerr=False)
+ tasks.assert_error(result, "no such user")
+ else:
+ (uid, gid) = self.get_user_id(self.clients[0], posixuser)
+ assert uid == gid
+ assert uid == '10060'
+
+ @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+ def test_only_uid_number_auto_private_group_default(self, type):
+ """
+ Test checks that posix user with only uidNumber defined
+ and gidNumber not set, auto-private-group
+ is set to false/true/hybrid
+ """
+ posixuser = "testuser1@%s" % self.ad_domain
+ self.mod_idrange_auto_private_group(type)
+ if type == "true":
+ (uid, gid) = self.get_user_id(self.clients[0], posixuser)
+ assert uid == gid
+ else:
+ for host in [self.master, self.clients[0]]:
+ result = host.run_command(['id', posixuser], raiseonerr=False)
+ tasks.assert_error(result, "no such user")
+
+ @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+ def test_auto_private_group_primary_group(self, type):
+ """
+ Test checks that AD users which contain posix attributes
+ (uidNumber and gidNumber) and there is primary group
+ with gid number defined.
+ """
+ posixuser = "testuser@%s" % self.ad_domain
+ self.mod_idrange_auto_private_group(type)
+ (uid, gid) = self.get_user_id(self.clients[0], posixuser)
+ test_grp = self.clients[0].run_command(["id", posixuser])
+ assert uid == '10042'
+ if type == "true":
+ assert uid == gid
+ groups = "groups=10042(testuser@{0}),10047(testgroup@{1})".format(
+ self.ad_domain, self.ad_domain)
+ assert groups in test_grp.stdout_text
+ else:
+ assert gid == '10047'
+ groups = "10047(testgroup@{0})".format(self.ad_domain)
+ assert groups in test_grp.stdout_text
+
+ @pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
+ def test_idoverride_with_auto_private_group(self, type):
+ """
+ Override ad trusted user in default trust view
+ and set auto-private-groups=[hybrid,true,false]
+ and ensure that overridden values takes effect.
+ """
+ posixuser = "testuser@%s" % self.ad_domain
+ with self.set_idoverrideuser(posixuser,
+ self.uid_override,
+ self.gid_override):
+ self.mod_idrange_auto_private_group(type)
+ (uid, gid) = self.get_user_id(self.clients[0], posixuser)
+ assert(uid == self.uid_override
+ and gid == self.gid_override)
+ result = self.clients[0].run_command(['id', posixuser])
+ assert "10047(testgroup@{0})".format(
+ self.ad_domain) in result.stdout_text
--
2.34.1

View File

@ -0,0 +1,43 @@
From 84381001d2e114b1f29fe89e16155c040b56b80f Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Thu, 10 Feb 2022 17:07:45 +0530
Subject: [PATCH] mark xfail for
test_idoverride_with_auto_private_group[hybrid]
Related : https://github.com/SSSD/sssd/issues/5989
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Anuja More <amore@redhat.com>
---
ipatests/test_integration/test_trust.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
index ff2dd9cc819e1c5620ce449384957a633ae6d1f0..54bd154628cb8fb063d9839d7928acd37647e2a4 100644
--- a/ipatests/test_integration/test_trust.py
+++ b/ipatests/test_integration/test_trust.py
@@ -15,6 +15,7 @@ from ipaplatform.paths import paths
from ipatests.test_integration.base import IntegrationTest
from ipatests.pytest_ipa.integration import tasks
from ipatests.pytest_ipa.integration import fips
+from ipatests.util import xfail_context
from ipapython.dn import DN
from collections import namedtuple
from contextlib import contextmanager
@@ -1110,7 +1111,11 @@ class TestNonPosixAutoPrivateGroup(BaseTestTrust):
assert (uid == self.uid_override and gid == self.gid_override)
test_group = self.clients[0].run_command(
["id", nonposixuser]).stdout_text
- assert "domain users@{0}".format(self.ad_domain) in test_group
+ version = tasks.get_sssd_version(self.clients[0])
+ with xfail_context(version <= tasks.parse_version('2.6.3')
+ and type == "hybrid",
+ 'https://github.com/SSSD/sssd/issues/5989'):
+ assert "domain users@{0}".format(self.ad_domain) in test_group
@pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
def test_nonposixuser_nondefault_primary_group(self, type):
--
2.34.1

View File

@ -0,0 +1,38 @@
From 7ad500e5d3f7d9af81e8a3137158672c6fafb0b4 Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Thu, 10 Feb 2022 17:29:45 +0530
Subject: [PATCH] Mark xfail
test_gidnumber_not_corresponding_existing_group[true,hybrid]
Related : https://github.com/SSSD/sssd/issues/5988
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Anuja More <amore@redhat.com>
---
ipatests/test_integration/test_trust.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
index 54bd154628cb8fb063d9839d7928acd37647e2a4..c128378151ec4c0fb295823d75f2a04df2f7ffa0 100644
--- a/ipatests/test_integration/test_trust.py
+++ b/ipatests/test_integration/test_trust.py
@@ -1169,9 +1169,12 @@ class TestPosixAutoPrivateGroup(BaseTestTrust):
raiseonerr=False)
tasks.assert_error(result, "no such user")
else:
- (uid, gid) = self.get_user_id(self.clients[0], posixuser)
- assert uid == gid
- assert uid == '10060'
+ sssd_version = tasks.get_sssd_version(self.clients[0])
+ with xfail_context(sssd_version <= tasks.parse_version('2.6.3'),
+ 'https://github.com/SSSD/sssd/issues/5988'):
+ (uid, gid) = self.get_user_id(self.clients[0], posixuser)
+ assert uid == gid
+ assert uid == '10060'
@pytest.mark.parametrize('type', ['hybrid', 'true', "false"])
def test_only_uid_number_auto_private_group_default(self, type):
--
2.34.1

View File

@ -0,0 +1,108 @@
From a51900819bd5332bc05ec9d513f062844b3a7763 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Fri, 25 Feb 2022 08:58:24 +0200
Subject: [PATCH] KRB instance: make provision to work with crypto policy
without SHA-1 HMAC types
RHEL 9 system-wide crypto policies aim at eventual removal of SHA-1 use.
Due to bootstrapping process, force explicitly supported encryption
types in kdc.conf or we may end up with AES128-SHA1 and AES256-SHA2 only
in FIPS mode at bootstrap time which then fails to initialize kadmin
principals requiring use of AES256-SHA2 and AES128-SHA2.
Camellia ciphers must be filtered out in FIPS mode, we do that already
in the kerberos.ldif.
At this point we are not changing the master key encryption type to
AES256-SHA2 because upgrading existing deployments is complicated and
at the time when a replica configuration is deployed, we don't know what
is the encryption type of the master key of the original server as well.
Fixes: https://pagure.io/freeipa/issue/9119
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Julien Rische <jrische@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
install/share/kdc.conf.template | 3 ++-
install/share/kerberos.ldif | 2 ++
ipaserver/install/krbinstance.py | 21 ++++++++++++++++++++-
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/install/share/kdc.conf.template b/install/share/kdc.conf.template
index 232fedc445f660c30a88d8844d9f1b6042db41a7..685d42f3b7fb263e86b7a6db98be8bcc53e7bbe6 100644
--- a/install/share/kdc.conf.template
+++ b/install/share/kdc.conf.template
@@ -6,7 +6,8 @@
[realms]
$REALM = {
- master_key_type = aes256-cts
+ master_key_type = $MASTER_KEY_TYPE
+ supported_enctypes = $SUPPORTED_ENCTYPES
max_life = 7d
max_renewable_life = 14d
acl_file = $KRB5KDC_KADM5_ACL
diff --git a/install/share/kerberos.ldif b/install/share/kerberos.ldif
index 3b75b445641fd86e2029ceb51e479c6ccb17856c..51e5cf9bca4b0b2cf2e1fe3ec85777deb61b76b0 100644
--- a/install/share/kerberos.ldif
+++ b/install/share/kerberos.ldif
@@ -28,6 +28,8 @@ ${FIPS}krbSupportedEncSaltTypes: camellia256-cts-cmac:normal
${FIPS}krbSupportedEncSaltTypes: camellia256-cts-cmac:special
krbMaxTicketLife: 86400
krbMaxRenewableAge: 604800
+krbDefaultEncSaltTypes: aes256-sha2:special
+krbDefaultEncSaltTypes: aes128-sha2:special
krbDefaultEncSaltTypes: aes256-cts:special
krbDefaultEncSaltTypes: aes128-cts:special
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index 216c1032d8abd9fc119d98d8f9976ce17d246ea4..852edcd9978f4a47d355e206fbb4a513ea699865 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -51,6 +51,14 @@ logger = logging.getLogger(__name__)
PKINIT_ENABLED = 'pkinitEnabled'
+MASTER_KEY_TYPE = 'aes256-sha1'
+SUPPORTED_ENCTYPES = ('aes256-sha2:special', 'aes128-sha2:special',
+ 'aes256-sha2:normal', 'aes128-sha2:normal',
+ 'aes256-cts:special', 'aes128-cts:special',
+ 'aes256-cts:normal', 'aes128-cts:normal',
+ 'camellia256-cts:special', 'camellia128-cts:special',
+ 'camellia256-cts:normal', 'camellia128-cts:normal')
+
def get_pkinit_request_ca():
"""
@@ -252,6 +260,7 @@ class KrbInstance(service.Service):
else:
includes = ''
+ fips_enabled = tasks.is_fips_enabled()
self.sub_dict = dict(FQDN=self.fqdn,
IP=self.ip,
PASSWORD=self.kdc_password,
@@ -269,7 +278,17 @@ class KrbInstance(service.Service):
KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM,
INCLUDES=includes,
- FIPS='#' if tasks.is_fips_enabled() else '')
+ FIPS='#' if fips_enabled else '')
+
+ if fips_enabled:
+ supported_enctypes = list(
+ filter(lambda e: not e.startswith('camelia'),
+ SUPPORTED_ENCTYPES))
+ else:
+ supported_enctypes = SUPPORTED_ENCTYPES
+ self.sub_dict['SUPPORTED_ENCTYPES'] = ' '.join(supported_enctypes)
+
+ self.sub_dict['MASTER_KEY_TYPE'] = MASTER_KEY_TYPE
# IPA server/KDC is not a subdomain of default domain
# Proper domain-realm mapping needs to be specified
--
2.34.1

View File

@ -0,0 +1,58 @@
From b016683552a58f9cc2a05cf628cc467234eaf599 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 28 Feb 2022 11:10:49 +0200
Subject: [PATCH] tests: ensure AD-SUPPORT subpolicy is active
Use AD-SUPPORT subpolicy when testing trust to Active Directory in FIPS
mode. This is required in FIPS mode due to AD not supporting Kerberos
AES-bases encryption types using FIPS-compliant PBKDF2 and KDF, as
defined in RFC 8009.
Fixes: https://pagure.io/freeipa/issue/9119
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Julien Rische <jrische@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipatests/pytest_ipa/integration/fips.py | 6 ++++++
ipatests/pytest_ipa/integration/tasks.py | 3 +++
2 files changed, 9 insertions(+)
diff --git a/ipatests/pytest_ipa/integration/fips.py b/ipatests/pytest_ipa/integration/fips.py
index 694ec8a9927da917fe99482094f68540a1032c14..b33aa91b14552d6f47191c913db4f974a5a5948c 100644
--- a/ipatests/pytest_ipa/integration/fips.py
+++ b/ipatests/pytest_ipa/integration/fips.py
@@ -68,3 +68,9 @@ def disable_userspace_fips(host):
# sanity check
assert not is_fips_enabled(host)
host.run_command(["openssl", "md5", "/dev/null"])
+
+
+def enable_crypto_subpolicy(host, subpolicy):
+ result = host.run_command(["update-crypto-policies", "--show"])
+ policy = result.stdin_text.strip() + ":" + subpolicy
+ host.run_command(["update-crypto-policies", "--set", policy])
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
index 7e1b7c24dab00986ff6e75430bf55e55dd1a6b8e..13d84e23fa7dc8a5e562e8498c9142e2bcad696a 100755
--- a/ipatests/pytest_ipa/integration/tasks.py
+++ b/ipatests/pytest_ipa/integration/tasks.py
@@ -66,6 +66,7 @@ from .env_config import env_to_script
from .host import Host
from .firewall import Firewall
from .resolver import ResolvedResolver
+from .fips import is_fips_enabled, enable_crypto_subpolicy
logger = logging.getLogger(__name__)
@@ -362,6 +363,8 @@ def install_master(host, setup_dns=True, setup_kra=False, setup_adtrust=False,
if setup_adtrust:
args.append('--setup-adtrust')
fw_services.append("freeipa-trust")
+ if is_fips_enabled(host):
+ enable_crypto_subpolicy(host, "AD-SUPPORT")
if external_ca:
args.append('--external-ca')
--
2.34.1

View File

@ -0,0 +1,46 @@
From 49d9147e38c5b50c52a1ebc7283753c779c2f81f Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Thu, 3 Mar 2022 14:38:57 +0200
Subject: [PATCH] ipatests: extend AES keyset to SHA2-based ones
Fixes: https://pagure.io/freeipa/issue/9119
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Julien Rische <jrische@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipaserver/install/plugins/adtrust.py | 3 ++-
ipatests/pytest_ipa/integration/tasks.py | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
index 5b87ac47c6919de287b07c9ceef7ae22e1e79398..67e372bdb40a0b1f6815f107fc567f0ae056dad8 100644
--- a/ipaserver/install/plugins/adtrust.py
+++ b/ipaserver/install/plugins/adtrust.py
@@ -754,7 +754,8 @@ class update_host_cifs_keytabs(Updater):
"""
host_princ_template = "host/{master}@{realm}"
- valid_etypes = ['aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
+ valid_etypes = ['aes256-cts-hmac-sha384-192', 'aes128-cts-hmac-sha256-128',
+ 'aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
def extract_key_refs(self, keytab):
host_princ = self.host_princ_template.format(
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
index 13d84e23fa7dc8a5e562e8498c9142e2bcad696a..d06f8eb2cf6c36956ec200a1abb7c488d1dad9aa 100755
--- a/ipatests/pytest_ipa/integration/tasks.py
+++ b/ipatests/pytest_ipa/integration/tasks.py
@@ -2261,7 +2261,8 @@ class KerberosKeyCopier:
copier.copy_keys('/etc/krb5.keytab', tmpname, replacement=replacement)
"""
host_princ_template = "host/{master}@{realm}"
- valid_etypes = ['aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
+ valid_etypes = ['aes256-cts-hmac-sha384-192', 'aes128-cts-hmac-sha256-128',
+ 'aes256-cts-hmac-sha1-96', 'aes128-cts-hmac-sha1-96']
def __init__(self, host):
self.host = host
--
2.34.1

View File

@ -0,0 +1,35 @@
From ee39de46a1c1ea96bbe524f159ae435319b2d072 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Thu, 3 Mar 2022 14:43:11 +0200
Subject: [PATCH] freeipa.spec: bump crypto-policies dependency for CentOS 9
Stream
Fixes: https://pagure.io/freeipa/issue/9119
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Julien Rische <jrische@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
freeipa.spec.in | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 0b24febc0baff6f60fd2b4cb254971bd3e3aa3b8..c1d81605068c6fc3e6c765ad01c4967fa9f03c95 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -695,6 +695,12 @@ Provides: %{name}-admintools = %{version}-%{release}
Conflicts: crypto-policies < 20200629-1
%endif
+%if 0%{?rhel} == 9
+# Conflict with crypto-policies < 20220223-1 to get upgraded AD-SUPPORT and
+# AD-SUPPORT-LEGACY policy modules
+Conflicts: crypto-policies < 20220223-1
+%endif
+
%description client
IPA is an integrated solution to provide centrally managed Identity (users,
hosts, services), Authentication (SSO, 2FA), and Authorization
--
2.34.1

View File

@ -0,0 +1,56 @@
From 3e54c4362490b4da1b6cb3e141bb6e08fecc58c0 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 14 Mar 2022 13:23:04 +0200
Subject: [PATCH] Kerberos instance: default to AES256-SHA2 for master key
encryption
KDC configuration in /var/kerberos/krb5kdc/kdc.conf is generated from
the template in install/share/kdc.conf.template. Master key encryption
type specified there is used to bootstrap the master key in LDAP
database. Once it is done, actual deployment does not rely on the
master_key_type value anymore. The actual master key(s) get loaded from
LDAP database where they stored in a BER-encoded format, preserving all
parameters, including encryption type.
This means we can safely migrate to AES256-SHA2 as the default master
key encryption type for new installations. Replicas will get their
master key encryption type details from the server they were provisioned
from.
MIT Kerberos supports AES256-SHA2 since 1.15 (2015), meaning RHEL 7.4 is
the earliest supported version as it provides krb5 1.15.1. Current
supported RHEL 7 version is RHEL 7.9. Since RHEL 6 already cannot be
used as a replica to IPA 4.5+ due to a domain level 1 upgrade, this
change does not affect old releases.
Migration from the previously deployed master key encryption type is
described by MIT Kerberos upstream in
http://web.mit.edu/kerberos/krb5-latest/doc/admin/advanced/retiring-des.html#the-database-master-key
One would need to use '-x ipa-setup-override-restrictions' to allow
the `kdb5_util` utility to modify the data over IPA KDB driver.
Fixes: https://pagure.io/freeipa/issue/9119
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipaserver/install/krbinstance.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index 01b3309d50c0e8025e3381eac577225b1ef0be9d..a5eaa7b17133498f08e84d01c90764236e8ebe84 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -51,7 +51,7 @@ logger = logging.getLogger(__name__)
PKINIT_ENABLED = 'pkinitEnabled'
-MASTER_KEY_TYPE = 'aes256-sha1'
+MASTER_KEY_TYPE = 'aes256-sha2'
SUPPORTED_ENCTYPES = ('aes256-sha2:special', 'aes128-sha2:special',
'aes256-sha2:normal', 'aes128-sha2:normal',
'aes256-cts:special', 'aes128-cts:special',
--
2.34.1

View File

@ -0,0 +1,44 @@
From 3baae8d1bd0a0c4c707314524289e86e6ecbc0df Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 14 Mar 2022 21:09:36 +0200
Subject: [PATCH] test_otp: do not use paramiko unless it is really needed
paramiko cannot be used in FIPS mode. We have few tests that import
generic methods from test_otp (add_token/del_token) and those tests fail
in FIPS mode due to unconditional 'import paramiko'.
Instead, move 'import paramiko' to the ssh_2f() helper which is not used
in FIPS mode (the whole SSH 2FA test is skipped then).
Related: https://pagure.io/freeipa/issue/9119
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipatests/test_integration/test_otp.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
index bec76d205bf37699483b65ebbc5613cbbb466bb4..04bef4626077e727654898b07a76acab4f1d5971 100644
--- a/ipatests/test_integration/test_otp.py
+++ b/ipatests/test_integration/test_otp.py
@@ -5,7 +5,6 @@
"""
import base64
import logging
-import paramiko
import pytest
import re
import time
@@ -102,6 +101,8 @@ def ssh_2f(hostname, username, answers_dict, port=22):
logger.info(
"Answer to ssh prompt is: '%s'", answers_dict[prmpt_str])
return resp
+
+ import paramiko
trans = paramiko.Transport((hostname, port))
trans.connect()
trans.auth_interactive(username, answer_handler)
--
2.34.1

View File

@ -0,0 +1,44 @@
From 2e70535f74e7d9dd76e728eca1119ce522fd138a Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Tue, 15 Mar 2022 11:39:46 +0200
Subject: [PATCH] test_krbtpolicy: skip SPAKE-related tests in FIPS mode
SPAKE is based on the crypto primitives which are not FIPS compliant
yet. This means that in FIPS mode use of 'hardened' authentication
indicator is not possible. Skip corresponding tests in FIPS mode.
Related: https://pagure.io/freeipa/issue/9119
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipatests/test_integration/test_krbtpolicy.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ipatests/test_integration/test_krbtpolicy.py b/ipatests/test_integration/test_krbtpolicy.py
index 9489fbc97b7836aecf491b57627f254d4849eb56..eae16247bdfb195c1d91209cf2d11eac4c25018f 100644
--- a/ipatests/test_integration/test_krbtpolicy.py
+++ b/ipatests/test_integration/test_krbtpolicy.py
@@ -105,6 +105,9 @@ class TestPWPolicy(IntegrationTest):
def test_krbtpolicy_password_and_hardended(self):
"""Test a pwd and hardened kerberos ticket policy with 10min tickets"""
+ if self.master.is_fips_mode:
+ pytest.skip("SPAKE pre-auth is not compatible with FIPS mode")
+
master = self.master
master.run_command(['ipa', 'user-mod', USER1,
'--user-auth-type', 'password',
@@ -133,6 +136,9 @@ class TestPWPolicy(IntegrationTest):
def test_krbtpolicy_hardended(self):
"""Test a hardened kerberos ticket policy with 30min tickets"""
+ if self.master.is_fips_mode:
+ pytest.skip("SPAKE pre-auth is not compatible with FIPS mode")
+
master = self.master
master.run_command(['ipa', 'user-mod', USER1,
'--user-auth-type', 'hardened'])
--
2.34.1

View File

@ -0,0 +1,555 @@
From 895e99b6843c2fa2274acab824607c33c1a560a4 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Mon, 7 Oct 2019 14:13:03 +0200
Subject: [PATCH] Support AES for KRA archival wrapping
The vault plugin has used TripleDES (des-ede3-cbc) as default wrapping
algorithm since the plugin was introduced. Allow use of AES-128-CBC as
alternative wrapping algorithm for transport of secrets.
Fixes: https://pagure.io/freeipa/issue/6524
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
API.txt | 7 +-
VERSION.m4 | 5 +-
ipaclient/plugins/vault.py | 155 +++++++++++++++++++++++++------------
ipalib/capabilities.py | 4 +
ipalib/constants.py | 12 +++
ipaserver/plugins/vault.py | 61 ++++++++++++---
6 files changed, 180 insertions(+), 64 deletions(-)
diff --git a/API.txt b/API.txt
index 576fa7c51e31886b257ccf176aaf232c0f2ea5ee..f95f2c8457e39f2268386a8a2336952d3285e008 100644
--- a/API.txt
+++ b/API.txt
@@ -6548,7 +6548,7 @@ output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>])
output: Entry('result')
command: vault_archive_internal/1
-args: 1,9,3
+args: 1,10,3
arg: Str('cn', cli_name='name')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Bytes('nonce')
@@ -6559,6 +6559,7 @@ option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Bytes('vault_data')
option: Str('version?')
+option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
@@ -6649,7 +6650,7 @@ output: Output('completed', type=[<type 'int'>])
output: Output('failed', type=[<type 'dict'>])
output: Entry('result')
command: vault_retrieve_internal/1
-args: 1,7,3
+args: 1,8,3
arg: Str('cn', cli_name='name')
option: Flag('all', autofill=True, cli_name='all', default=False)
option: Flag('raw', autofill=True, cli_name='raw', default=False)
@@ -6658,6 +6659,7 @@ option: Bytes('session_key')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Str('version?')
+option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
@@ -7327,6 +7329,7 @@ default: vaultcontainer_del/1
default: vaultcontainer_remove_owner/1
default: vaultcontainer_show/1
default: whoami/1
+capability: vault_aes_keywrap 2.246
capability: messages 2.52
capability: optional_uid_params 2.54
capability: permissions2 2.69
diff --git a/VERSION.m4 b/VERSION.m4
index 70aaff4c9b9514a5937eae60074376e1a592464e..997ac35e74fa6f2a96da027ed3ce93cf809b62a7 100644
--- a/VERSION.m4
+++ b/VERSION.m4
@@ -86,9 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
# #
########################################################
define(IPA_API_VERSION_MAJOR, 2)
-# Last change: add enable_sid to config
-define(IPA_API_VERSION_MINOR, 245)
-
+# Last change: Add wrapping algorithm to vault archive/retrieve
+define(IPA_API_VERSION_MINOR, 246)
########################################################
# Following values are auto-generated from values above
diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
index d3a1d370efaccc7e5b0088bd3df341d76884d509..115171c7768d44251c17d0bcdac9c37b3a25db99 100644
--- a/ipaclient/plugins/vault.py
+++ b/ipaclient/plugins/vault.py
@@ -25,11 +25,12 @@ import io
import json
import logging
import os
+import ssl
import tempfile
from cryptography.fernet import Fernet, InvalidToken
from cryptography.hazmat.backends import default_backend
-from cryptography.hazmat.primitives import hashes, serialization
+from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
@@ -39,7 +40,7 @@ from cryptography.hazmat.primitives.serialization import (
from ipaclient.frontend import MethodOverride
from ipalib import x509
-from ipalib.constants import USER_CACHE_PATH
+from ipalib import constants
from ipalib.frontend import Local, Method, Object
from ipalib.util import classproperty
from ipalib import api, errors
@@ -546,42 +547,49 @@ class vault_mod(Local):
return response
-class _TransportCertCache:
+class _KraConfigCache:
+ """The KRA config cache stores vaultconfig-show result.
+ """
def __init__(self):
self._dirname = os.path.join(
- USER_CACHE_PATH, 'ipa', 'kra-transport-certs'
+ constants.USER_CACHE_PATH, 'ipa', 'kra-config'
)
def _get_filename(self, domain):
- basename = DNSName(domain).ToASCII() + '.pem'
+ basename = DNSName(domain).ToASCII() + '.json'
return os.path.join(self._dirname, basename)
- def load_cert(self, domain):
- """Load cert from cache
+ def load(self, domain):
+ """Load config from cache
:param domain: IPA domain
- :return: cryptography.x509.Certificate or None
+ :return: dict or None
"""
filename = self._get_filename(domain)
try:
try:
- return x509.load_certificate_from_file(filename)
- except EnvironmentError as e:
+ with open(filename) as f:
+ return json.load(f)
+ except OSError as e:
if e.errno != errno.ENOENT:
raise
except Exception:
logger.warning("Failed to load %s", filename, exc_info=True)
return None
- def store_cert(self, domain, transport_cert):
- """Store a new cert or override existing cert
+ def store(self, domain, response):
+ """Store config in cache
:param domain: IPA domain
- :param transport_cert: cryptography.x509.Certificate
- :return: True if cert was stored successfully
+ :param config: ipa vaultconfig-show response
+ :return: True if config was stored successfully
"""
+ config = response['result'].copy()
+ # store certificate as PEM-encoded ASCII
+ config['transport_cert'] = ssl.DER_cert_to_PEM_cert(
+ config['transport_cert']
+ )
filename = self._get_filename(domain)
- pem = transport_cert.public_bytes(serialization.Encoding.PEM)
try:
try:
os.makedirs(self._dirname)
@@ -589,9 +597,9 @@ class _TransportCertCache:
if e.errno != errno.EEXIST:
raise
with tempfile.NamedTemporaryFile(dir=self._dirname, delete=False,
- mode='wb') as f:
+ mode='w') as f:
try:
- f.write(pem)
+ json.dump(config, f)
ipautil.flush_sync(f)
f.close()
os.rename(f.name, filename)
@@ -604,8 +612,8 @@ class _TransportCertCache:
else:
return True
- def remove_cert(self, domain):
- """Remove a cert from cache, ignores errors
+ def remove(self, domain):
+ """Remove a config from cache, ignores errors
:param domain: IPA domain
:return: True if cert was found and removed
@@ -621,7 +629,7 @@ class _TransportCertCache:
return True
-_transport_cert_cache = _TransportCertCache()
+_kra_config_cache = _KraConfigCache()
@register(override=True, no_fail=True)
@@ -636,13 +644,8 @@ class vaultconfig_show(MethodOverride):
response = super(vaultconfig_show, self).forward(*args, **options)
- # cache transport certificate
- transport_cert = x509.load_der_x509_certificate(
- response['result']['transport_cert'])
-
- _transport_cert_cache.store_cert(
- self.api.env.domain, transport_cert
- )
+ # cache config
+ _kra_config_cache.store(self.api.env.domain, response)
if file:
with open(file, 'wb') as f:
@@ -652,10 +655,54 @@ class vaultconfig_show(MethodOverride):
class ModVaultData(Local):
- def _generate_session_key(self):
- key_length = max(algorithms.TripleDES.key_sizes)
- algo = algorithms.TripleDES(os.urandom(key_length // 8))
- return algo
+ def _generate_session_key(self, name):
+ if name not in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
+ msg = _("{algo} is not a supported vault wrapping algorithm")
+ raise errors.ValidationError(msg.format(algo=repr(name)))
+ if name == constants.VAULT_WRAPPING_AES128_CBC:
+ return algorithms.AES(os.urandom(128 // 8))
+ elif name == constants.VAULT_WRAPPING_3DES:
+ return algorithms.TripleDES(os.urandom(196 // 8))
+ else:
+ # unreachable
+ raise ValueError(name)
+
+ def _get_vaultconfig(self, force_refresh=False):
+ config = None
+ if not force_refresh:
+ config = _kra_config_cache.load(self.api.env.domain)
+ if config is None:
+ # vaultconfig_show also caches data
+ response = self.api.Command.vaultconfig_show()
+ config = response['result']
+ transport_cert = x509.load_der_x509_certificate(
+ config['transport_cert']
+ )
+ else:
+ # cached JSON uses PEM-encoded ASCII string
+ transport_cert = x509.load_pem_x509_certificate(
+ config['transport_cert'].encode('ascii')
+ )
+
+ default_algo = config.get('wrapping_default_algorithm')
+ if default_algo is None:
+ # old server
+ wrapping_algo = constants.VAULT_WRAPPING_AES128_CBC
+ elif default_algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
+ # try to use server default
+ wrapping_algo = default_algo
+ else:
+ # prefer server's sorting order
+ for algo in config['wrapping_supported_algorithms']:
+ if algo in constants.VAULT_WRAPPING_SUPPORTED_ALGOS:
+ wrapping_algo = algo
+ break
+ else:
+ raise errors.ValidationError(
+ "No overlapping wrapping algorithm between server and "
+ "client."
+ )
+ return transport_cert, wrapping_algo
def _do_internal(self, algo, transport_cert, raise_unexpected,
*args, **options):
@@ -675,29 +722,23 @@ class ModVaultData(Local):
except (errors.InternalError,
errors.ExecutionError,
errors.GenericError):
- _transport_cert_cache.remove_cert(self.api.env.domain)
+ _kra_config_cache.remove(self.api.env.domain)
if raise_unexpected:
raise
return None
- def internal(self, algo, *args, **options):
+ def internal(self, algo, transport_cert, *args, **options):
"""
Calls the internal counterpart of the command.
"""
- domain = self.api.env.domain
-
# try call with cached transport certificate
- transport_cert = _transport_cert_cache.load_cert(domain)
- if transport_cert is not None:
- result = self._do_internal(algo, transport_cert, False,
+ result = self._do_internal(algo, transport_cert, False,
*args, **options)
- if result is not None:
- return result
+ if result is not None:
+ return result
# retrieve transport certificate (cached by vaultconfig_show)
- response = self.api.Command.vaultconfig_show()
- transport_cert = x509.load_der_x509_certificate(
- response['result']['transport_cert'])
+ transport_cert = self._get_vaultconfig(force_refresh=True)[0]
# call with the retrieved transport certificate
return self._do_internal(algo, transport_cert, True,
*args, **options)
@@ -777,7 +818,7 @@ class vault_archive(ModVaultData):
def _wrap_data(self, algo, json_vault_data):
"""Encrypt data with wrapped session key and transport cert
- :param bytes algo: wrapping algorithm instance
+ :param algo: wrapping algorithm instance
:param bytes json_vault_data: dumped vault data
:return:
"""
@@ -929,15 +970,24 @@ class vault_archive(ModVaultData):
json_vault_data = json.dumps(vault_data).encode('utf-8')
+ # get config
+ transport_cert, wrapping_algo = self._get_vaultconfig()
+ # let options override wrapping algo
+ # For backwards compatibility do not send old legacy wrapping algo
+ # to server. Only send the option when non-3DES is used.
+ wrapping_algo = options.pop('wrapping_algo', wrapping_algo)
+ if wrapping_algo != constants.VAULT_WRAPPING_3DES:
+ options['wrapping_algo'] = wrapping_algo
+
# generate session key
- algo = self._generate_session_key()
+ algo = self._generate_session_key(wrapping_algo)
# wrap vault data
nonce, wrapped_vault_data = self._wrap_data(algo, json_vault_data)
options.update(
nonce=nonce,
vault_data=wrapped_vault_data
)
- return self.internal(algo, *args, **options)
+ return self.internal(algo, transport_cert, *args, **options)
@register(no_fail=True)
@@ -1061,10 +1111,19 @@ class vault_retrieve(ModVaultData):
vault = self.api.Command.vault_show(*args, **options)['result']
vault_type = vault['ipavaulttype'][0]
+ # get config
+ transport_cert, wrapping_algo = self._get_vaultconfig()
+ # let options override wrapping algo
+ # For backwards compatibility do not send old legacy wrapping algo
+ # to server. Only send the option when non-3DES is used.
+ wrapping_algo = options.pop('wrapping_algo', wrapping_algo)
+ if wrapping_algo != constants.VAULT_WRAPPING_3DES:
+ options['wrapping_algo'] = wrapping_algo
+
# generate session key
- algo = self._generate_session_key()
+ algo = self._generate_session_key(wrapping_algo)
# send retrieval request to server
- response = self.internal(algo, *args, **options)
+ response = self.internal(algo, transport_cert, *args, **options)
# unwrap data with session key
vault_data = self._unwrap_response(
algo,
diff --git a/ipalib/capabilities.py b/ipalib/capabilities.py
index 55b84aa6bc73d583e7bd5d03d2f4f1cc5c8e7c0b..4d8ae408bf67c280d27ce494baa9db9aaff0cd69 100644
--- a/ipalib/capabilities.py
+++ b/ipalib/capabilities.py
@@ -54,6 +54,10 @@ capabilities = dict(
# dns_name_values: dnsnames as objects
dns_name_values=u'2.88',
+
+ # vault supports aes key wrapping
+ vault_aes_keywrap='2.246'
+
)
diff --git a/ipalib/constants.py b/ipalib/constants.py
index 9f19b0f9941ba5068f1e6c218092e3b76fdc7599..11171b2e8aeb6f7306299b2bd7db3a3f39d29d4a 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -374,3 +374,15 @@ KRA_TRACKING_REQS = {
}
ALLOWED_NETBIOS_CHARS = string.ascii_uppercase + string.digits + '-'
+
+# vault data wrapping algorithms
+VAULT_WRAPPING_3DES = 'des-ede3-cbc'
+VAULT_WRAPPING_AES128_CBC = 'aes-128-cbc'
+VAULT_WRAPPING_SUPPORTED_ALGOS = (
+ # old default was 3DES
+ VAULT_WRAPPING_3DES,
+ # supported since pki-kra >= 10.4
+ VAULT_WRAPPING_AES128_CBC,
+)
+# 3DES for backwards compatibility
+VAULT_WRAPPING_DEFAULT_ALGO = VAULT_WRAPPING_3DES
diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
index aebac7dff7bb9d183c6012cc685577d476e18c4e..4d40f66c6a793a831e91c5fe25c8b5277cbd1972 100644
--- a/ipaserver/plugins/vault.py
+++ b/ipaserver/plugins/vault.py
@@ -23,6 +23,10 @@ from ipalib.frontend import Command, Object
from ipalib import api, errors
from ipalib import Bytes, Flag, Str, StrEnum
from ipalib import output
+from ipalib.constants import (
+ VAULT_WRAPPING_SUPPORTED_ALGOS, VAULT_WRAPPING_DEFAULT_ALGO,
+ VAULT_WRAPPING_3DES, VAULT_WRAPPING_AES128_CBC,
+)
from ipalib.crud import PKQuery, Retrieve
from ipalib.parameters import Principal
from ipalib.plugable import Registry
@@ -39,14 +43,8 @@ from ipaserver.masters import is_service_enabled
if api.env.in_server:
import pki.account
import pki.key
- # pylint: disable=no-member
- try:
- # pki >= 10.4.0
- from pki.crypto import DES_EDE3_CBC_OID
- except ImportError:
- DES_EDE3_CBC_OID = pki.key.KeyClient.DES_EDE3_CBC_OID
- # pylint: enable=no-member
-
+ from pki.crypto import DES_EDE3_CBC_OID
+ from pki.crypto import AES_128_CBC_OID
if six.PY3:
unicode = str
@@ -652,6 +652,20 @@ class vault(LDAPObject):
),
)
+ def _translate_algorithm(self, name):
+ if name is None:
+ name = VAULT_WRAPPING_DEFAULT_ALGO
+ if name not in VAULT_WRAPPING_SUPPORTED_ALGOS:
+ msg = _("{algo} is not a supported vault wrapping algorithm")
+ raise errors.ValidationError(msg.format(algo=name))
+ if name == VAULT_WRAPPING_3DES:
+ return DES_EDE3_CBC_OID
+ elif name == VAULT_WRAPPING_AES128_CBC:
+ return AES_128_CBC_OID
+ else:
+ # unreachable
+ raise ValueError(name)
+
def get_dn(self, *keys, **options):
"""
Generates vault DN from parameters.
@@ -992,14 +1006,18 @@ class vaultconfig_show(Retrieve):
)
def execute(self, *args, **options):
-
if not self.api.Command.kra_is_enabled()['result']:
raise errors.InvocationError(
format=_('KRA service is not enabled'))
+ config = dict(
+ wrapping_supported_algorithms=VAULT_WRAPPING_SUPPORTED_ALGOS,
+ wrapping_default_algorithm=VAULT_WRAPPING_DEFAULT_ALGO,
+ )
+
with self.api.Backend.kra.get_client() as kra_client:
transport_cert = kra_client.system_certs.get_transport_cert()
- config = {'transport_cert': transport_cert.binary}
+ config['transport_cert'] = transport_cert.binary
self.api.Object.config.show_servroles_attributes(
config, "KRA server", **options)
@@ -1029,6 +1047,13 @@ class vault_archive_internal(PKQuery):
'nonce',
doc=_('Nonce'),
),
+ StrEnum(
+ 'wrapping_algo?',
+ doc=_('Key wrapping algorithm'),
+ values=VAULT_WRAPPING_SUPPORTED_ALGOS,
+ default=VAULT_WRAPPING_DEFAULT_ALGO,
+ autofill=True,
+ ),
)
has_output = output.standard_entry
@@ -1045,6 +1070,9 @@ class vault_archive_internal(PKQuery):
nonce = options.pop('nonce')
wrapped_session_key = options.pop('session_key')
+ wrapping_algo = options.pop('wrapping_algo', None)
+ algorithm_oid = self.obj._translate_algorithm(wrapping_algo)
+
# retrieve vault info
vault = self.api.Command.vault_show(*args, **options)['result']
@@ -1071,7 +1099,7 @@ class vault_archive_internal(PKQuery):
pki.key.KeyClient.PASS_PHRASE_TYPE,
wrapped_vault_data,
wrapped_session_key,
- algorithm_oid=DES_EDE3_CBC_OID,
+ algorithm_oid=algorithm_oid,
nonce_iv=nonce,
)
@@ -1098,6 +1126,13 @@ class vault_retrieve_internal(PKQuery):
'session_key',
doc=_('Session key wrapped with transport certificate'),
),
+ StrEnum(
+ 'wrapping_algo?',
+ doc=_('Key wrapping algorithm'),
+ values=VAULT_WRAPPING_SUPPORTED_ALGOS,
+ default=VAULT_WRAPPING_DEFAULT_ALGO,
+ autofill=True,
+ ),
)
has_output = output.standard_entry
@@ -1112,6 +1147,9 @@ class vault_retrieve_internal(PKQuery):
wrapped_session_key = options.pop('session_key')
+ wrapping_algo = options.pop('wrapping_algo', None)
+ algorithm_oid = self.obj._translate_algorithm(wrapping_algo)
+
# retrieve vault info
vault = self.api.Command.vault_show(*args, **options)['result']
@@ -1132,6 +1170,9 @@ class vault_retrieve_internal(PKQuery):
key_info = response.key_infos[0]
+ # XXX hack
+ kra_client.keys.encrypt_alg_oid = algorithm_oid
+
# retrieve encrypted data from KRA
key = kra_client.keys.retrieve_key(
key_info.get_key_id(),
--
2.34.1

View File

@ -0,0 +1,86 @@
From 984190eea01ac42cd1f97567a67dd9446e5b0bf9 Mon Sep 17 00:00:00 2001
From: Francisco Trivino <ftrivino@redhat.com>
Date: Fri, 11 Mar 2022 17:47:38 +0100
Subject: [PATCH] Set AES as default for KRA archival wrapping
This commit sets AES-128-CBC as default wrapping algorithm as
TripleDES (des-ede3-cbc) is not supported anymore in C9S.
Fixes: https://pagure.io/freeipa/issue/6524
Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
API.txt | 6 +++---
ipalib/constants.py | 14 +++++++++-----
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/API.txt b/API.txt
index f95f2c8457e39f2268386a8a2336952d3285e008..1f27dcc616a6395c56ef91f3453e7620625c7645 100644
--- a/API.txt
+++ b/API.txt
@@ -6559,7 +6559,7 @@ option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Bytes('vault_data')
option: Str('version?')
-option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
+option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
@@ -6659,7 +6659,7 @@ option: Bytes('session_key')
option: Flag('shared?', autofill=True, default=False)
option: Str('username?', cli_name='user')
option: Str('version?')
-option: StrEnum('wrapping_algo?', autofill=True, default=u'des-ede3-cbc', values=[u'des-ede3-cbc', u'aes-128-cbc'])
+option: StrEnum('wrapping_algo?', autofill=True, default=u'aes-128-cbc', values=[u'aes-128-cbc', u'des-ede3-cbc'])
output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
@@ -7329,10 +7329,10 @@ default: vaultcontainer_del/1
default: vaultcontainer_remove_owner/1
default: vaultcontainer_show/1
default: whoami/1
-capability: vault_aes_keywrap 2.246
capability: messages 2.52
capability: optional_uid_params 2.54
capability: permissions2 2.69
capability: primary_key_types 2.83
capability: datetime_values 2.84
capability: dns_name_values 2.88
+capability: vault_aes_keywrap 2.246
diff --git a/ipalib/constants.py b/ipalib/constants.py
index 11171b2e8aeb6f7306299b2bd7db3a3f39d29d4a..68178004181bebcc8c093dac55e18d5afe0251e5 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -29,6 +29,8 @@ from ipaplatform.constants import constants as _constants
from ipapython.dn import DN
from ipapython.fqdn import gethostfqdn
from ipapython.version import VERSION, API_VERSION
+from cryptography.hazmat.primitives.ciphers import algorithms, modes
+from cryptography.hazmat.backends.openssl.backend import backend
FQDN = gethostfqdn()
@@ -379,10 +381,12 @@ ALLOWED_NETBIOS_CHARS = string.ascii_uppercase + string.digits + '-'
VAULT_WRAPPING_3DES = 'des-ede3-cbc'
VAULT_WRAPPING_AES128_CBC = 'aes-128-cbc'
VAULT_WRAPPING_SUPPORTED_ALGOS = (
- # old default was 3DES
- VAULT_WRAPPING_3DES,
- # supported since pki-kra >= 10.4
+ # new default and supported since pki-kra >= 10.4
VAULT_WRAPPING_AES128_CBC,
)
-# 3DES for backwards compatibility
-VAULT_WRAPPING_DEFAULT_ALGO = VAULT_WRAPPING_3DES
+VAULT_WRAPPING_DEFAULT_ALGO = VAULT_WRAPPING_AES128_CBC
+
+# Add 3DES for backwards compatibility if supported
+if backend.cipher_supported(algorithms.TripleDES(b"\x00" * 8),
+ modes.CBC(b"\x00" * 8)):
+ VAULT_WRAPPING_SUPPORTED_ALGOS += (VAULT_WRAPPING_3DES,)
--
2.34.1

View File

@ -66,7 +66,7 @@
%if 0%{?rhel} %if 0%{?rhel}
%global package_name ipa %global package_name ipa
%global alt_name freeipa %global alt_name freeipa
%global krb5_version 1.18.2-2 %global krb5_version 1.19.1-15
%global krb5_kdb_version 8.0 %global krb5_kdb_version 8.0
# 0.7.16: https://github.com/drkjam/netaddr/issues/71 # 0.7.16: https://github.com/drkjam/netaddr/issues/71
%global python_netaddr_version 0.7.19 %global python_netaddr_version 0.7.19
@ -198,7 +198,7 @@
Name: %{package_name} Name: %{package_name}
Version: %{IPA_VERSION} Version: %{IPA_VERSION}
Release: 5%{?rc_version:.%rc_version}%{?dist} Release: 7%{?rc_version:.%rc_version}%{?dist}
Summary: The Identity, Policy and Audit system Summary: The Identity, Policy and Audit system
License: GPLv3+ License: GPLv3+
@ -241,6 +241,18 @@ Patch0020: 0020-Test-ipa-ccache-sweep.timer-enabled-by-default-durin.patch
Patch0021: 0021-ipa_cldap-fix-memory-leak.patch Patch0021: 0021-ipa_cldap-fix-memory-leak.patch
Patch0022: 0022-ipatests-remove-additional-check-for-failed-units_rhbz#2053025.patch Patch0022: 0022-ipatests-remove-additional-check-for-failed-units_rhbz#2053025.patch
Patch0023: 0023-ipatests-fix-TestOTPToken-rhbz#2053025.patch Patch0023: 0023-ipatests-fix-TestOTPToken-rhbz#2053025.patch
Patch0024: 0024-ipatests-Tests-for-Autoprivate-group.patch
Patch0025: 0025-mark-xfail-for-test_idoverride_with_auto_private_gro.patch
Patch0026: 0026-Mark-xfail-test_gidnumber_not_corresponding_existing.patch
Patch0027: 0027-KRB-instance-make-provision-to-work-with-crypto-poli.patch
Patch0028: 0028-tests-ensure-AD-SUPPORT-subpolicy-is-active.patch
Patch0029: 0029-ipatests-extend-AES-keyset-to-SHA2-based-ones.patch
Patch0030: 0030-freeipa.spec-bump-crypto-policies-dependency-for-Cen.patch
Patch0031: 0031-Kerberos-instance-default-to-AES256-SHA2-for-master-.patch
Patch0032: 0032-test_otp-do-not-use-paramiko-unless-it-is-really-nee.patch
Patch0033: 0033-test_krbtpolicy-skip-SPAKE-related-tests-in-FIPS-mod.patch
Patch0034: 0034-Support-AES-for-KRA-archival-wrapping.patch
Patch0035: 0035-Set-AES-as-default-for-KRA-archival-wrapping.patch
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
%endif %endif
%endif %endif
@ -713,6 +725,12 @@ Provides: %{name}-admintools = %{version}-%{release}
Conflicts: crypto-policies < 20200629-1 Conflicts: crypto-policies < 20200629-1
%endif %endif
%if 0%{?rhel} == 9
# Conflict with crypto-policies < 20220223-1 to get upgraded AD-SUPPORT and
# AD-SUPPORT-LEGACY policy modules
Conflicts: crypto-policies < 20220223-1
%endif
%description client %description client
IPA is an integrated solution to provide centrally managed Identity (users, IPA is an integrated solution to provide centrally managed Identity (users,
hosts, services), Authentication (SSO, 2FA), and Authorization hosts, services), Authentication (SSO, 2FA), and Authorization
@ -1732,6 +1750,24 @@ fi
%endif %endif
%changelog %changelog
* Mon Mar 21 2022 Florence Blanc-Renaud <frenaud@redhat.com> - 4.9.8-7
- Resolves: rhbz#2057471 Consequences of FIPS crypto policy tightening in RHEL 9
- KRB instance: make provision to work with crypto policy without SHA-1 HMAC types
- tests: ensure AD-SUPPORT subpolicy is active
- ipatests: extend AES keyset to SHA2-based ones
- freeipa.spec: bump crypto-policies dependency for CentOS 9 Stream
- Kerberos instance: default to AES256-SHA2 for master key encryption
- test_otp: do not use paramiko unless it is really needed
- test_krbtpolicy: skip SPAKE-related tests in FIPS mode
- Support AES for KRA archival wrapping
- Set AES as default for KRA archival wrapping
* Thu Feb 24 2022 Florence Blanc-Renaud <frenaud@redhat.com> - 4.9.8-6
- Resolves: rhbz#2057467 Backport latest test fixes in python3-ipatests
- ipatests: Tests for Autoprivate group.
- mark xfail for test_idoverride_with_auto_private_group[hybrid]
- Mark xfail test_gidnumber_not_corresponding_existing_group[true,hybrid]
* Mon Feb 14 2022 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.8-5 * Mon Feb 14 2022 Alexander Bokovoy <abokovoy@redhat.com> - 4.9.8-5
- Resolves: rhbz#2053025 - Resolves: rhbz#2053025
- add IPA test suite fixes - add IPA test suite fixes