import ipa-4.9.8-7.el9_0

This commit is contained in:
CentOS Sources 2022-05-17 04:44:04 -04:00 committed by Stepan Oksanichenko
commit 4503d8c06c
40 changed files with 6453 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/freeipa-4.9.8.tar.gz

1
.ipa.metadata Normal file
View File

@ -0,0 +1 @@
38641a7f95779ba35089fcc10e25ec82a9b0248e SOURCES/freeipa-4.9.8.tar.gz

View File

@ -0,0 +1,36 @@
From 669f3d71161741c676ddd6a08bd08d4a4ccd495b Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Fri, 26 Nov 2021 17:40:54 +0200
Subject: [PATCH] ipa-kdb: issue PAC_REQUESTER_SID only for TGTs
MS-KILE 3.3.5.6.4.8 in revision after Windows Server November 2021
security fixes added the following requirement:
- PAC_REQUESTER_SID is only added in TGT case (including referrals and
tickets to RODCs)
Fixes: https://pagure.io/freeipa/issue/9031
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
daemons/ipa-kdb/ipa_kdb_mspac.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 6f7d1ac15daf17dfca36ebd3265c866725d24717..538cfbba958068bd2ee0aaae7a2743ae82237898 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -1148,7 +1148,8 @@ static krb5_error_code ipadb_get_pac(krb5_context kcontext,
#endif
#ifdef HAVE_PAC_REQUESTER_SID
- {
+ /* MS-KILE 3.3.5.6.4.8: add PAC_REQUESTER_SID only in TGT case */
+ if ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0) {
union PAC_INFO pac_requester_sid;
/* == Package PAC_REQUESTER_SID == */
memset(&pac_requester_sid, 0, sizeof(pac_requester_sid));
--
2.31.1

View File

@ -0,0 +1,122 @@
From 7d93bda31ce0b4e0e22c6e464c9138800dcf8b1c Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Fri, 26 Nov 2021 11:13:51 +0200
Subject: [PATCH] ipa-kdb: fix requester SID check according to MS-KILE and
MS-SFU updates
New versions of MS-KILE and MS-SFU after Windows Server November 2021
security updates add PAC_REQUESTER_SID buffer check behavior:
- PAC_REQUESTER_SID should only be added for TGT requests
- if PAC_REQUESTER_SID is present, KDC must verify that the cname on
the ticket resolves to the account with the same SID as the
PAC_REQUESTER_SID. If it doesn't KDC must respond with
KDC_ERR_TKT_REVOKED
Change requester SID check to skip exact check for non-local
PAC_REQUESTER_SID but harden to ensure it comes from the trusted domains
we know about.
If requester SID is the same as in PAC, we already do cname vs PAC SID
verification.
With these changes FreeIPA works against Windows Server 2019 with
November 2021 security fixes in cross-realm S4U2Self operations.
Fixes: https://pagure.io/freeipa/issue/9031
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
daemons/ipa-kdb/ipa_kdb_mspac.c | 47 ++++++++++++++++++++++++---------
1 file changed, 34 insertions(+), 13 deletions(-)
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 538cfbba958068bd2ee0aaae7a2743ae82237898..1b972c167dd50619c7a6bd78eb5c81b0e05a4832 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -1697,7 +1697,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
"local [%s], PAC [%s]",
dom ? dom : "<failed to display>",
sid ? sid : "<failed to display>");
- return KRB5KDC_ERR_POLICY;
+ return KRB5KDC_ERR_TGT_REVOKED;
}
}
@@ -1709,7 +1709,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
kerr = ipadb_get_principal(context, client_princ, flags, &client_actual);
if (kerr != 0) {
krb5_klog_syslog(LOG_ERR, "PAC issue: ipadb_get_principal failed.");
- return KRB5KDC_ERR_POLICY;
+ return KRB5KDC_ERR_TGT_REVOKED;
}
ied = (struct ipadb_e_data *)client_actual->e_data;
@@ -1743,7 +1743,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
"local [%s] vs PAC [%s]",
local_sid ? local_sid : "<failed to display>",
pac_sid ? pac_sid : "<failed to display>");
- kerr = KRB5KDC_ERR_POLICY;
+ kerr = KRB5KDC_ERR_TGT_REVOKED;
goto done;
}
@@ -2005,22 +2005,43 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
/* Check that requester SID is the same as in the PAC entry */
if (requester_sid != NULL) {
struct dom_sid client_sid;
+ bool is_from_trusted_domain = false;
kerr = ipadb_get_sid_from_pac(tmpctx, info.info, &client_sid);
if (kerr) {
goto done;
}
result = dom_sid_check(&client_sid, requester_sid, true);
if (!result) {
- /* memctx is freed by the caller */
- char *pac_sid = dom_sid_string(tmpctx, &client_sid);
- char *req_sid = dom_sid_string(tmpctx, requester_sid);
- krb5_klog_syslog(LOG_ERR, "PAC issue: PAC has a SID "
- "different from what PAC requester claims. "
- "PAC [%s] vs PAC requester [%s]",
- pac_sid ? pac_sid : "<failed to display>",
- req_sid ? req_sid : "<failed to display>");
- kerr = KRB5KDC_ERR_POLICY;
- goto done;
+ struct ipadb_context *ipactx = ipadb_get_context(context);
+ if (!ipactx || !ipactx->mspac) {
+ return KRB5_KDB_DBNOTINITED;
+ }
+ /* In S4U case we might be dealing with the PAC issued by the trusted domain */
+ if (is_s4u && (ipactx->mspac->trusts != NULL)) {
+ /* Iterate through list of trusts and check if this SID belongs to
+ * one of the domains we trust */
+ for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
+ result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
+ requester_sid, false);
+ if (result) {
+ is_from_trusted_domain = true;
+ break;
+ }
+ }
+ }
+
+ if (!is_from_trusted_domain) {
+ /* memctx is freed by the caller */
+ char *pac_sid = dom_sid_string(tmpctx, &client_sid);
+ char *req_sid = dom_sid_string(tmpctx, requester_sid);
+ krb5_klog_syslog(LOG_ERR, "PAC issue: PAC has a SID "
+ "different from what PAC requester claims. "
+ "PAC [%s] vs PAC requester [%s]",
+ pac_sid ? pac_sid : "<failed to display>",
+ req_sid ? req_sid : "<failed to display>");
+ kerr = KRB5KDC_ERR_TGT_REVOKED;
+ goto done;
+ }
}
}
--
2.31.1

View File

@ -0,0 +1,48 @@
From ba7ec71ba96280da3841ebe47df2a6dc1cd6341e Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Fri, 26 Nov 2021 12:11:21 +0530
Subject: [PATCH] ipatests: Fix test_ipa_cert_fix.py::TestCertFixReplica
teardown
Fixture `expire_certs` moves date back after renewing the certs.
This is causing the ipa-replica to fail. This fix first uninstalls
the server then moves back the date.
Fixes: https://pagure.io/freeipa/issue/9052
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_ipa_cert_fix.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py
index 39904d5de64c59416f01646f437aabf797d57dd9..5b56054b4f16d5654ebeb61971a8775bfaf341b8 100644
--- a/ipatests/test_integration/test_ipa_cert_fix.py
+++ b/ipatests/test_integration/test_ipa_cert_fix.py
@@ -389,6 +389,12 @@ class TestCertFixReplica(IntegrationTest):
setup_dns=False, extra_args=['--no-ntp']
)
+ @classmethod
+ def uninstall(cls, mh):
+ # Uninstall method is empty as the uninstallation is done in
+ # the fixture
+ pass
+
@pytest.fixture
def expire_certs(self):
# move system date to expire certs
@@ -398,7 +404,8 @@ class TestCertFixReplica(IntegrationTest):
yield
# move date back on replica and master
- for host in self.master, self.replicas[0]:
+ for host in self.replicas[0], self.master:
+ tasks.uninstall_master(host)
tasks.move_date(host, 'start', '-3years-1days')
def test_renew_expired_cert_replica(self, expire_certs):
--
2.34.1

View File

@ -0,0 +1,29 @@
From 8b22ee018c3bb7f58a1b6694a7fd611688f8e74f Mon Sep 17 00:00:00 2001
From: Sumedh Sidhaye <ssidhaye@redhat.com>
Date: Thu, 25 Nov 2021 17:48:20 +0530
Subject: [PATCH] Extend test to see if replica is not shown when running
`ipa-replica-manage list -v <FQDN>`
Related: https://pagure.io/freeipa/issue/8605
Signed-off-by: Sumedh Sidhaye <ssidhaye@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_simple_replication.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_simple_replication.py b/ipatests/test_integration/test_simple_replication.py
index 8de3851447abdfd36171134cbb683115b34df749..17092a49966e61d5a4a9b04c15abcb1de8be9683 100644
--- a/ipatests/test_integration/test_simple_replication.py
+++ b/ipatests/test_integration/test_simple_replication.py
@@ -111,5 +111,6 @@ class TestSimpleReplication(IntegrationTest):
# has to be run with --force, there is no --unattended
self.master.run_command(['ipa-replica-manage', 'del',
self.replicas[0].hostname, '--force'])
- result = self.master.run_command(['ipa-replica-manage', 'list'])
+ result = self.master.run_command(
+ ['ipa-replica-manage', 'list', '-v', self.master.hostname])
assert self.replicas[0].hostname not in result.stdout_text
--
2.34.1

View File

@ -0,0 +1,40 @@
From 465f1669a6c5abc72da1ecaf9aefa8488f80806c Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Mon, 13 Dec 2021 17:37:05 +0530
Subject: [PATCH] ipatests: Test default value of nsslapd-sizelimit.
related : https://pagure.io/freeipa/issue/8962
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_installation.py | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
index 95cfaad54c33a581c6af352097ea95ed435ea2b1..0947241ae2738419c4855e2517670c9033e634f0 100644
--- a/ipatests/test_integration/test_installation.py
+++ b/ipatests/test_integration/test_installation.py
@@ -1067,6 +1067,19 @@ class TestInstallMaster(IntegrationTest):
)
assert "nsslapd-db-locks" not in result.stdout_text
+ def test_nsslapd_sizelimit(self):
+ """ Test for default value of nsslapd-sizelimit.
+
+ Related : https://pagure.io/freeipa/issue/8962
+ """
+ result = tasks.ldapsearch_dm(
+ self.master,
+ "cn=config",
+ ["nsslapd-sizelimit"],
+ scope="base"
+ )
+ assert "nsslapd-sizelimit: 100000" in result.stdout_text
+
def test_admin_root_alias_CVE_2020_10747(self):
# Test for CVE-2020-10747 fix
# https://bugzilla.redhat.com/show_bug.cgi?id=1810160
--
2.34.1

View File

@ -0,0 +1,123 @@
From cbd9ac6ab07dfb60f67da762fdd70856ad35c230 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Thu, 25 Nov 2021 13:10:05 +0530
Subject: [PATCH] ipatests: Test empty cert request doesn't force certmonger to
segfault
When empty cert request is submitted to certmonger, it goes to
segfault. This fix test that if something like this happens,
certmonger should gracefuly handle it
and some PEP8 fixes
related: https://pagure.io/certmonger/issue/191
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
---
ipatests/test_integration/test_cert.py | 79 +++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_cert.py b/ipatests/test_integration/test_cert.py
index 5ffb8c6086328d563084f1d4b73daa1d01d956e7..0518d79545f7592d17571068e2681474bd9e5b14 100644
--- a/ipatests/test_integration/test_cert.py
+++ b/ipatests/test_integration/test_cert.py
@@ -14,6 +14,7 @@ import random
import re
import string
import time
+import textwrap
from ipaplatform.paths import paths
from ipapython.dn import DN
@@ -193,7 +194,7 @@ class TestInstallMasterClient(IntegrationTest):
tasks.kinit_admin(self.master)
tasks.user_add(self.master, user)
- for id in (0,1):
+ for id in (0, 1):
csr_file = f'{id}.csr'
key_file = f'{id}.key'
cert_file = f'{id}.crt'
@@ -584,3 +585,79 @@ class TestCAShowErrorHandling(IntegrationTest):
error_msg = 'ipa: ERROR: The certificate for ' \
'{} is not available on this server.'.format(lwca)
assert error_msg in result.stderr_text
+
+ def test_certmonger_empty_cert_not_segfault(self):
+ """Test empty cert request doesn't force certmonger to segfault
+
+ Test scenario:
+ create a cert request file in /var/lib/certmonger/requests which is
+ missing most of the required information, and ask request a new
+ certificate to certmonger. The wrong request file should not make
+ certmonger crash.
+
+ related: https://pagure.io/certmonger/issue/191
+ """
+ empty_cert_req_content = textwrap.dedent("""
+ id=dogtag-ipa-renew-agent
+ key_type=UNSPECIFIED
+ key_gen_type=UNSPECIFIED
+ key_size=0
+ key_gen_size=0
+ key_next_type=UNSPECIFIED
+ key_next_gen_type=UNSPECIFIED
+ key_next_size=0
+ key_next_gen_size=0
+ key_preserve=0
+ key_storage_type=NONE
+ key_perms=0
+ key_requested_count=0
+ key_issued_count=0
+ cert_storage_type=FILE
+ cert_perms=0
+ cert_is_ca=0
+ cert_ca_path_length=0
+ cert_no_ocsp_check=0
+ last_need_notify_check=19700101000000
+ last_need_enroll_check=19700101000000
+ template_is_ca=0
+ template_ca_path_length=-1
+ template_no_ocsp_check=0
+ state=NEED_KEY_PAIR
+ autorenew=0
+ monitor=0
+ submitted=19700101000000
+ """)
+ # stop certmonger service
+ self.master.run_command(['systemctl', 'stop', 'certmonger'])
+
+ # place an empty cert request file to certmonger request dir
+ self.master.put_file_contents(
+ os.path.join(paths.CERTMONGER_REQUESTS_DIR, '20211125062617'),
+ empty_cert_req_content
+ )
+
+ # start certmonger, it should not fail
+ self.master.run_command(['systemctl', 'start', 'certmonger'])
+
+ # request a new cert, should succeed and certmonger doesn't goes
+ # to segfault
+ result = self.master.run_command([
+ "ipa-getcert", "request",
+ "-f", os.path.join(paths.OPENSSL_CERTS_DIR, "test.pem"),
+ "-k", os.path.join(paths.OPENSSL_PRIVATE_DIR, "test.key"),
+ ])
+ request_id = re.findall(r'\d+', result.stdout_text)
+
+ # check if certificate is in MONITORING state
+ status = tasks.wait_for_request(self.master, request_id[0], 50)
+ assert status == "MONITORING"
+
+ self.master.run_command(
+ ['ipa-getcert', 'stop-tracking', '-i', request_id[0]]
+ )
+ self.master.run_command([
+ 'rm', '-rf',
+ os.path.join(paths.CERTMONGER_REQUESTS_DIR, '20211125062617'),
+ os.path.join(paths.OPENSSL_CERTS_DIR, 'test.pem'),
+ os.path.join(paths.OPENSSL_PRIVATE_DIR, 'test.key')
+ ])
--
2.34.1

View File

@ -0,0 +1,104 @@
From 1d19b860d4cd3bd65a4b143b588425d9a64237fd Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Thu, 18 Nov 2021 18:36:58 +0530
Subject: [PATCH] Test cases for ipa-replica-conncheck command
Following test cases would be checked:
- when called with --principal (it should then prompt for a password)
- when called with --principal / --password
- when called without principal and password but with a kerberos TGT,
kinit admin done before calling ipa-replica-conncheck
- when called without principal and password, and without any kerberos
TGT (it should default to principal=admin and prompt for a password)
related: https://pagure.io/freeipa/issue/9047
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
---
.../test_replica_promotion.py | 70 +++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
index b9c56f775d08885cb6b1226eeb7bcf105f87cdc1..1a4e9bc121abf41a3919aedda3d334de9404d1a0 100644
--- a/ipatests/test_integration/test_replica_promotion.py
+++ b/ipatests/test_integration/test_replica_promotion.py
@@ -437,6 +437,76 @@ class TestRenewalMaster(IntegrationTest):
self.assertCARenewalMaster(master, replica.hostname)
self.assertCARenewalMaster(replica, replica.hostname)
+ def test_replica_concheck(self):
+ """Test cases for ipa-replica-conncheck command
+
+ Following test cases would be checked:
+ - when called with --principal (it should then prompt for a password)
+ - when called with --principal / --password
+ - when called without principal and password but with a kerberos TGT,
+ kinit admin done before calling ipa-replica-conncheck
+ - when called without principal and password, and without any kerberos
+ TGT (it should default to principal=admin and prompt for a password)
+
+ related: https://pagure.io/freeipa/issue/9047
+ """
+ exp_str1 = "Connection from replica to master is OK."
+ exp_str2 = "Connection from master to replica is OK"
+ tasks.kdestroy_all(self.replicas[0])
+ # when called with --principal (it should then prompt for a password)
+ result = self.replicas[0].run_command(
+ ['ipa-replica-conncheck', '--auto-master-check',
+ '--master', self.master.hostname,
+ '-r', self.replicas[0].domain.realm,
+ '-p', self.replicas[0].config.admin_name],
+ stdin_text=self.master.config.admin_password
+ )
+ assert result.returncode == 0
+ assert (
+ exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
+ )
+
+ # when called with --principal / --password
+ result = self.replicas[0].run_command([
+ 'ipa-replica-conncheck', '--auto-master-check',
+ '--master', self.master.hostname,
+ '-r', self.replicas[0].domain.realm,
+ '-p', self.replicas[0].config.admin_name,
+ '-w', self.master.config.admin_password
+ ])
+ assert result.returncode == 0
+ assert (
+ exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
+ )
+
+ # when called without principal and password, and without
+ # any kerberos TGT, it should default to principal=admin
+ # and prompt for a password
+ result = self.replicas[0].run_command(
+ ['ipa-replica-conncheck', '--auto-master-check',
+ '--master', self.master.hostname,
+ '-r', self.replicas[0].domain.realm],
+ stdin_text=self.master.config.admin_password
+ )
+ assert result.returncode == 0
+ assert (
+ exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
+ )
+
+ # when called without principal and password but with a kerberos TGT,
+ # kinit admin done before calling ipa-replica-conncheck
+ tasks.kinit_admin(self.replicas[0])
+ result = self.replicas[0].run_command(
+ ['ipa-replica-conncheck', '--auto-master-check',
+ '--master', self.master.hostname,
+ '-r', self.replicas[0].domain.realm]
+ )
+ assert result.returncode == 0
+ assert (
+ exp_str1 in result.stderr_text and exp_str2 in result.stderr_text
+ )
+ tasks.kdestroy_all(self.replicas[0])
+
def test_automatic_renewal_master_transfer_ondelete(self):
# Test that after replica uninstallation, master overtakes the cert
# renewal master role from replica (which was previously set there)
--
2.34.1

View File

@ -0,0 +1,59 @@
From 5444da016edc416c0c9481c660c013053dbb93b5 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Thu, 18 Nov 2021 18:43:22 +0530
Subject: [PATCH] PEP8 Fixes
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
---
.../test_integration/test_replica_promotion.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
index 1a4e9bc121abf41a3919aedda3d334de9404d1a0..c328b1a08ffc8ac5efb0986d2b18c5074f573432 100644
--- a/ipatests/test_integration/test_replica_promotion.py
+++ b/ipatests/test_integration/test_replica_promotion.py
@@ -138,7 +138,6 @@ class TestReplicaPromotionLevel1(ReplicaPromotionBase):
assert res.returncode == 1
assert expected_err in res.stderr_text
-
@replicas_cleanup
def test_one_command_installation(self):
"""
@@ -150,11 +149,11 @@ class TestReplicaPromotionLevel1(ReplicaPromotionBase):
Firewall(self.replicas[0]).enable_services(["freeipa-ldap",
"freeipa-ldaps"])
self.replicas[0].run_command(['ipa-replica-install', '-w',
- self.master.config.admin_password,
- '-n', self.master.domain.name,
- '-r', self.master.domain.realm,
- '--server', self.master.hostname,
- '-U'])
+ self.master.config.admin_password,
+ '-n', self.master.domain.name,
+ '-r', self.master.domain.realm,
+ '--server', self.master.hostname,
+ '-U'])
# Ensure that pkinit is properly configured, test for 7566
result = self.replicas[0].run_command(['ipa-pkinit-manage', 'status'])
assert "PKINIT is enabled" in result.stdout_text
@@ -321,7 +320,7 @@ class TestWrongClientDomain(IntegrationTest):
result1 = client.run_command(['ipa-replica-install', '-U', '-w',
self.master.config.dirman_password],
raiseonerr=False)
- assert(result1.returncode == 0), (
+ assert (result1.returncode == 0), (
'Failed to promote the client installed with the upcase domain name')
def test_client_rollback(self):
@@ -355,6 +354,7 @@ class TestWrongClientDomain(IntegrationTest):
assert("An error occurred while removing SSSD" not in
result.stdout_text)
+
class TestRenewalMaster(IntegrationTest):
topology = 'star'
--
2.34.1

View File

@ -0,0 +1,209 @@
From edbd8f692a28fc999b92e9032614d366511db323 Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Mon, 6 Dec 2021 20:50:01 +0530
Subject: [PATCH] ipatests: webui: Tests for subordinate ids.
Added web-ui tests to verify where operations
using subordinate ids are working as expected.
Related : https://pagure.io/freeipa/issue/8361
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_webui/test_subid.py | 141 ++++++++++++++++++++++++++++++
ipatests/test_webui/ui_driver.py | 28 ++++++
2 files changed, 169 insertions(+)
create mode 100644 ipatests/test_webui/test_subid.py
diff --git a/ipatests/test_webui/test_subid.py b/ipatests/test_webui/test_subid.py
new file mode 100644
index 0000000000000000000000000000000000000000..26decdba03955f28ab21a41ccffae2a9af7b09fe
--- /dev/null
+++ b/ipatests/test_webui/test_subid.py
@@ -0,0 +1,141 @@
+
+"""
+Tests for subordinateid.
+"""
+
+from ipatests.test_webui.ui_driver import UI_driver
+import ipatests.test_webui.data_config as config_data
+import ipatests.test_webui.data_user as user_data
+from ipatests.test_webui.ui_driver import screenshot
+import re
+
+
+class test_subid(UI_driver):
+
+ def add_user(self, pkey, name, surname):
+ self.add_record('user', {
+ 'pkey': pkey,
+ 'add': [
+ ('textbox', 'uid', pkey),
+ ('textbox', 'givenname', name),
+ ('textbox', 'sn', surname),
+ ]
+ })
+
+ def set_default_subid(self):
+ self.navigate_to_entity(config_data.ENTITY)
+ self.check_option('ipauserdefaultsubordinateid', 'checked')
+ self.facet_button_click('save')
+
+ def get_user_count(self, user_pkey):
+ self.navigate_to_entity('subid', facet='search')
+ self.apply_search_filter(user_pkey)
+ self.wait_for_request()
+ return self.get_rows()
+
+ @screenshot
+ def test_set_defaultsubid(self):
+ """
+ Test to verify that enable/disable is working for
+ adding subids to new users.
+ """
+ self.init_app()
+ self.add_record(user_data.ENTITY, user_data.DATA2)
+ self.navigate_to_entity(config_data.ENTITY)
+ # test subid can be enabled/disabled.
+ self.set_default_subid()
+ assert self.get_field_checked('ipauserdefaultsubordinateid')
+ self.set_default_subid()
+ assert not self.get_field_checked('ipauserdefaultsubordinateid')
+
+ @screenshot
+ def test_user_defaultsubid(self):
+ """
+ Test to verify that subid is generated for new user.
+ """
+ self.init_app()
+ user_pkey = "some-user"
+
+ self.set_default_subid()
+ assert self.get_field_checked('ipauserdefaultsubordinateid')
+
+ before_count = self.get_user_count(user_pkey)
+ assert len(before_count) == 0
+
+ self.add_user(user_pkey, 'Some', 'User')
+ after_count = self.get_user_count(user_pkey)
+ assert len(after_count) == 1
+
+ @screenshot
+ def test_user_subid_mod_desc(self):
+ """
+ Test to verify that auto-assigned subid description is modified.
+ """
+ self.init_app()
+ self.navigate_to_record("some-user")
+ self.switch_to_facet('memberof_subid')
+ rows = self.get_rows()
+ self.navigate_to_row_record(rows[-1])
+ self.fill_textbox("description", "some-user-subid-desc")
+ self.facet_button_click('save')
+
+ @screenshot
+ def test_admin_subid(self):
+ """
+ Test to verify that subid range is created with owner admin.
+ """
+ self.init_app()
+ self.navigate_to_entity('subid', facet='search')
+ self.facet_button_click('add')
+ self.select_combobox('ipaowner', 'admin')
+ self.dialog_button_click('add')
+ self.wait(0.3)
+ self.assert_no_error_dialog()
+
+ @screenshot
+ def test_admin_subid_negative(self):
+ """
+ Test to verify that readding the subid fails with error.
+ """
+ self.init_app()
+ self.navigate_to_entity('subid', facet='search')
+ self.facet_button_click('add')
+ self.select_combobox('ipaowner', 'admin')
+ self.dialog_button_click('add')
+ self.wait(0.3)
+ err_dialog = self.get_last_error_dialog(dialog_name='error_dialog')
+ text = self.get_text('.modal-body div p', err_dialog)
+ text = text.strip()
+ pattern = r'Subordinate id with with name .* already exists.'
+ assert re.search(pattern, text) is not None
+ self.close_all_dialogs()
+
+ @screenshot
+ def test_user_subid_add(self):
+ """
+ Test to verify that subid range is created for given user.
+ """
+ self.init_app()
+ self.navigate_to_entity('subid', facet='search')
+ before_count = self.get_rows()
+ self.facet_button_click('add')
+ self.select_combobox('ipaowner', user_data.PKEY2)
+ self.dialog_button_click('add')
+ self.wait(0.3)
+ self.assert_no_error_dialog()
+ after_count = self.get_rows()
+ assert len(before_count) < len(after_count)
+
+ @screenshot
+ def test_subid_del(self):
+ """
+ Test to remove subordinate id for given user.
+ """
+ self.init_app()
+ self.navigate_to_entity('subid', facet='search')
+ user_uid = self.get_record_pkey("some-user", "ipaowner",
+ table_name="ipauniqueid")
+ before_count = self.get_rows()
+ self.delete_record(user_uid, table_name="ipauniqueid")
+ after_count = self.get_rows()
+ assert len(before_count) > len(after_count)
diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py
index 46fd512ae67bee65be55ae0d4dedec53cc29de97..77fd74e49593183a37fe735bedf2e0d6b9257ac7 100644
--- a/ipatests/test_webui/ui_driver.py
+++ b/ipatests/test_webui/ui_driver.py
@@ -1151,6 +1151,34 @@ class UI_driver:
return row
return None
+ def get_row_by_column_value(self, key, column_name, parent=None,
+ table_name=None):
+ """
+ Get the first matched row element of a search table with given key
+ matched against selected column. None if not found
+ """
+ rows = self.get_rows(parent, table_name)
+ s = "td div[name='%s']" % column_name
+ for row in rows:
+ has = self.find(s, By.CSS_SELECTOR, row)
+ if has.text == key:
+ return row
+ return None
+
+ def get_record_pkey(self, key, column, parent=None, table_name=None):
+ """
+ Get record pkey if value of column is known
+ """
+ row = self.get_row_by_column_value(key,
+ column_name=column,
+ parent=parent,
+ table_name=table_name)
+ val = None
+ if row:
+ el = self.find("td input", By.CSS_SELECTOR, row)
+ val = el.get_attribute("value")
+ return val
+
def navigate_to_row_record(self, row, pkey_column=None):
"""
Navigate to record by clicking on a link.
--
2.34.1

View File

@ -0,0 +1,39 @@
From b9c42fed9b6f60801f908c368d0d97a2a69f7bb2 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 15 Dec 2021 10:47:02 +0100
Subject: [PATCH] Config plugin: return EmptyModlist when no change is applied
When ipa config-mod is called with the option --enable-sid,
the code needs to trap EmptyModlist exception (it is expected
that no LDAP attribute is modified by this operation).
The code had a flaw and was checking:
'enable_sid' in options
instead of
options['enable_sid']
"'enable_sid' in options" always returns true as this option
is a Flag with a default value, hence always present even if
not specified on the command line.
Fixes: https://pagure.io/freeipa/issue/9063
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/plugins/config.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/plugins/config.py b/ipaserver/plugins/config.py
index eae401fc3f7a1b7628eb211db206ba4bc2b36754..24446beb0b03a1510a96316eae915780817db102 100644
--- a/ipaserver/plugins/config.py
+++ b/ipaserver/plugins/config.py
@@ -707,7 +707,7 @@ class config_mod(LDAPUpdate):
if (isinstance(exc, errors.EmptyModlist) and
call_func.__name__ == 'update_entry' and
('ca_renewal_master_server' in options or
- 'enable_sid' in options)):
+ options['enable_sid'])):
return
super(config_mod, self).exc_callback(
--
2.34.1

View File

@ -0,0 +1,36 @@
From cd735099e86304294217147ed578ac902fcf3dd3 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 15 Dec 2021 10:51:05 +0100
Subject: [PATCH] config plugin: add a test ensuring EmptyModlist is returned
Add a test to test_config_plugin, that calls ipa config-mod
with the same value as already present in LDAP.
The call must return EmptyModlist.
Related: https://pagure.io/freeipa/issue/9063
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipatests/test_xmlrpc/test_config_plugin.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ipatests/test_xmlrpc/test_config_plugin.py b/ipatests/test_xmlrpc/test_config_plugin.py
index e981bb4a03d39de450fc459d4b1ce4b636c19029..a8ec9f0e558d7efa091b50deca9fa7ca59fd7b11 100644
--- a/ipatests/test_xmlrpc/test_config_plugin.py
+++ b/ipatests/test_xmlrpc/test_config_plugin.py
@@ -312,4 +312,13 @@ class test_config(Declarative):
'value': None,
},
),
+ dict(
+ desc='Set the value to the already set value, no modifications',
+ command=(
+ 'config_mod', [], {
+ 'ipasearchrecordslimit': u'100',
+ },
+ ),
+ expected=errors.EmptyModlist(),
+ ),
]
--
2.34.1

View File

@ -0,0 +1,36 @@
From 419d7fd6e5a9ed2d356ad05eef1043309f5646ef Mon Sep 17 00:00:00 2001
From: Michal Polovka <mpolovka@redhat.com>
Date: Fri, 7 Jan 2022 12:12:26 +0100
Subject: [PATCH] ipatests: webui: Use safe-loader for loading YAML
configuration file
FullLoader class for YAML loader was introduced in version 5.1 which
also deprecated default loader. SafeLoader, however, stays consistent
across the versions and brings added security.
This fix is necessary as PyYAML > 5.1 is not available in downstream.
Related: https://pagure.io/freeipa/issue/9009
Signed-off-by: Michal Polovka <mpolovka@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipatests/test_webui/ui_driver.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipatests/test_webui/ui_driver.py b/ipatests/test_webui/ui_driver.py
index 77fd74e49593183a37fe735bedf2e0d6b9257ac7..519efee9bba3de2114d22865a08df87f9b5f348a 100644
--- a/ipatests/test_webui/ui_driver.py
+++ b/ipatests/test_webui/ui_driver.py
@@ -192,7 +192,7 @@ class UI_driver:
if not NO_YAML and os.path.isfile(path):
try:
with open(path, 'r') as conf:
- cls.config = yaml.load(stream=conf, Loader=yaml.FullLoader)
+ cls.config = yaml.safe_load(stream=conf)
except yaml.YAMLError as e:
pytest.skip("Invalid Web UI config.\n%s" % e)
except IOError as e:
--
2.34.1

View File

@ -0,0 +1,107 @@
From 0edf915efbb39fac45c784171dd715ec6b28861a Mon Sep 17 00:00:00 2001
From: Sumedh Sidhaye <ssidhaye@redhat.com>
Date: Fri, 14 Jan 2022 19:55:13 +0530
Subject: [PATCH] Added test automation for SHA384withRSA CSR support
Scenario 1:
Setup master with --ca-signing-algorithm=SHA384withRSA
Run certutil and check Signing Algorithm
Scenario 2:
Setup a master
Stop services
Modify default.params.signingAlg in CS.cfg
Restart services
Resubmit cert (Resubmitted cert should have new Algorithm)
Pagure Link: https://pagure.io/freeipa/issue/8906
Signed-off-by: Sumedh Sidhaye <ssidhaye@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Antonio Torres <antorres@redhat.com>
---
.../test_integration/test_installation.py | 63 +++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
index 0947241ae2738419c4855e2517670c9033e634f0..f2d372c0c0356f244971a2af808db45dd6c8cb5b 100644
--- a/ipatests/test_integration/test_installation.py
+++ b/ipatests/test_integration/test_installation.py
@@ -34,6 +34,7 @@ from ipatests.pytest_ipa.integration import tasks
from ipatests.pytest_ipa.integration.env_config import get_global_config
from ipatests.test_integration.base import IntegrationTest
from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup
+from ipatests.test_integration.test_cert import get_certmonger_fs_id
from ipaplatform import services
@@ -1916,3 +1917,65 @@ class TestInstallWithoutNamed(IntegrationTest):
tasks.install_replica(
self.master, self.replicas[0], setup_ca=False, setup_dns=False
)
+
+
+class TestInstallwithSHA384withRSA(IntegrationTest):
+ num_replicas = 0
+
+ def test_install_master_withalgo_sha384withrsa(self, server_cleanup):
+ tasks.install_master(
+ self.master,
+ extra_args=['--ca-signing-algorithm=SHA384withRSA'],
+ )
+
+ # check Signing Algorithm post installation
+ dashed_domain = self.master.domain.realm.replace(".", '-')
+ cmd_args = ['certutil', '-L', '-d',
+ '/etc/dirsrv/slapd-{}/'.format(dashed_domain),
+ '-n', 'Server-Cert']
+ result = self.master.run_command(cmd_args)
+ assert 'SHA-384 With RSA Encryption' in result.stdout_text
+
+ def test_install_master_modify_existing(self, server_cleanup):
+ """
+ Setup a master
+ Stop services
+ Modify default.params.signingAlg in CS.cfg
+ Restart services
+ Resubmit cert (Resubmitted cert should have new Algorithm)
+ """
+ tasks.install_master(self.master)
+ self.master.run_command(['ipactl', 'stop'])
+ cs_cfg_content = self.master.get_file_contents(paths.CA_CS_CFG_PATH,
+ encoding='utf-8')
+ new_lines = []
+ replace_str = "ca.signing.defaultSigningAlgorithm=SHA384withRSA"
+ ocsp_rep_str = "ca.ocsp_signing.defaultSigningAlgorithm=SHA384withRSA"
+ for line in cs_cfg_content.split('\n'):
+ if line.startswith('ca.signing.defaultSigningAlgorithm'):
+ new_lines.append(replace_str)
+ elif line.startswith('ca.ocsp_signing.defaultSigningAlgorithm'):
+ new_lines.append(ocsp_rep_str)
+ else:
+ new_lines.append(line)
+ self.master.put_file_contents(paths.CA_CS_CFG_PATH,
+ '\n'.join(new_lines))
+ self.master.run_command(['ipactl', 'start'])
+
+ cmd = ['getcert', 'list', '-f', paths.RA_AGENT_PEM]
+ result = self.master.run_command(cmd)
+ request_id = get_certmonger_fs_id(result.stdout_text)
+
+ # resubmit RA Agent cert
+ cmd = ['getcert', 'resubmit', '-f', paths.RA_AGENT_PEM]
+ self.master.run_command(cmd)
+
+ tasks.wait_for_certmonger_status(self.master,
+ ('CA_WORKING', 'MONITORING'),
+ request_id)
+
+ cmd_args = ['openssl', 'x509', '-in',
+ paths.RA_AGENT_PEM, '-noout', '-text']
+ result = self.master.run_command(cmd_args)
+ assert_str = 'Signature Algorithm: sha384WithRSAEncryption'
+ assert assert_str in result.stdout_text
--
2.34.1

View File

@ -0,0 +1,44 @@
From 9bae5492270d8b695999cd82831cbee62b04626b Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Fri, 28 Jan 2022 16:58:42 +0100
Subject: [PATCH] ipa-pki-proxy.conf: provide access to
/kra/admin/kra/getStatus
The access to /kra/admin/kra/getStatus will be needed
in order to fix pki-healthcheck.
Note that this commit is a pre-requisite for the fix
to be done on PKI side. No test added since the full
integration test already exists in test_replica_promotion.py,
in TestHiddenReplicaPromotion::test_ipahealthcheck_hidden_replica
Fixes: https://pagure.io/freeipa/issue/9099
Related: https://pagure.io/freeipa/issue/8582
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
install/share/ipa-pki-proxy.conf.template | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/install/share/ipa-pki-proxy.conf.template b/install/share/ipa-pki-proxy.conf.template
index 96708482cdac128930efaca33a806daaeba68042..7a46f20b9058bab63238f56295a92533c232d47a 100644
--- a/install/share/ipa-pki-proxy.conf.template
+++ b/install/share/ipa-pki-proxy.conf.template
@@ -1,4 +1,4 @@
-# VERSION 16 - DO NOT REMOVE THIS LINE
+# VERSION 17 - DO NOT REMOVE THIS LINE
ProxyRequests Off
@@ -11,7 +11,7 @@ ProxyRequests Off
</LocationMatch>
# matches for admin port and installer
-<LocationMatch "^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/admin/ca/updateConnector|^/ca/admin/ca/getSubsystemCert|^/kra/admin/kra/updateNumberRange|^/kra/admin/kra/getConfigEntries">
+<LocationMatch "^/ca/admin/ca/getCertChain|^/ca/admin/ca/getConfigEntries|^/ca/admin/ca/getCookie|^/ca/admin/ca/getStatus|^/ca/admin/ca/securityDomainLogin|^/ca/admin/ca/getDomainXML|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/tokenAuthenticate|^/ca/admin/ca/updateNumberRange|^/ca/admin/ca/updateDomainXML|^/ca/admin/ca/updateConnector|^/ca/admin/ca/getSubsystemCert|^/kra/admin/kra/updateNumberRange|^/kra/admin/kra/getConfigEntries|^/kra/admin/kra/getStatus">
SSLOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
SSLVerifyClient none
ProxyPassMatch ajp://localhost:$DOGTAG_PORT $DOGTAG_AJP_SECRET
--
2.34.1

View File

@ -0,0 +1,59 @@
From 6d70421f57d0eca066a922e09416ef7195ee96d4 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Tue, 1 Feb 2022 16:43:09 +0100
Subject: [PATCH] ipa-kdb: do not remove keys for hardened auth-enabled users
Since 5d51ae5, principal keys were dropped in case user auth indicator
was not including password. Thereafter, the key removal behavior was
removed by 15ff9c8 in the context of the kdcpolicy plugin introduction.
Support for hardened pre-auth methods (FAST and SPAKE) was added in
d057040, and the removal of principal keys was restored afterwards by
f0d12b7, but not taking the new hardened auth indicator into account.
Fixes: https://pagure.io/freeipa/issue/9065
Related to: https://pagure.io/freeipa/issue/8001
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
daemons/ipa-kdb/ipa_kdb_principals.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
index 15f3df4fee8bdfadf60a4b1d9a5115407d1bb294..0d0d3748ce63a8252e84220d036140818ffdfb6e 100644
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -788,17 +788,18 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
&res_key_data, &result, &mkvno);
switch (ret) {
case 0:
- /* Only set a principal's key if password auth can be used. Otherwise
- * the KDC would add pre-authentication methods to the NEEDED_PREAUTH
- * reply for AS-REQs which indicate the password authentication is
- * available. This might confuse applications like e.g. SSSD which try
- * to determine suitable authentication methods and corresponding
- * prompts with the help of MIT Kerberos' responder interface which
- * acts on the returned pre-authentication methods. A typical example
- * is enforced OTP authentication where of course keys are available
- * for the first factor but password authentication should not be
- * advertised by the KDC. */
- if (!(ua & IPADB_USER_AUTH_PASSWORD) && (ua != IPADB_USER_AUTH_NONE)) {
+ /* Only set a principal's key if password or hardened auth can be used.
+ * Otherwise the KDC would add pre-authentication methods to the
+ * NEEDED_PREAUTH reply for AS-REQs which indicate the password
+ * authentication is available. This might confuse applications like
+ * e.g. SSSD which try to determine suitable authentication methods and
+ * corresponding prompts with the help of MIT Kerberos' responder
+ * interface which acts on the returned pre-authentication methods. A
+ * typical example is enforced OTP authentication where of course keys
+ * are available for the first factor but password authentication
+ * should not be advertised by the KDC. */
+ if (!(ua & (IPADB_USER_AUTH_PASSWORD | IPADB_USER_AUTH_HARDENED)) &&
+ (ua != IPADB_USER_AUTH_NONE)) {
/* This is the same behavior as ENOENT below. */
ipa_krb5_free_key_data(res_key_data, result);
break;
--
2.34.1

View File

@ -0,0 +1,63 @@
From 294ae35a61e6ca8816b261c57508e4be21221864 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Tue, 1 Feb 2022 19:38:29 +0100
Subject: [PATCH] ipatests: add case for hardened-only ticket policy
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipatests/test_integration/test_krbtpolicy.py | 30 ++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/ipatests/test_integration/test_krbtpolicy.py b/ipatests/test_integration/test_krbtpolicy.py
index 63e75ae67f493352b1d3a611e7b079d914a7b253..9489fbc97b7836aecf491b57627f254d4849eb56 100644
--- a/ipatests/test_integration/test_krbtpolicy.py
+++ b/ipatests/test_integration/test_krbtpolicy.py
@@ -103,8 +103,8 @@ class TestPWPolicy(IntegrationTest):
result = master.run_command('klist | grep krbtgt')
assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
- def test_krbtpolicy_hardended(self):
- """Test a hardened kerberos ticket policy with 10 min tickets"""
+ def test_krbtpolicy_password_and_hardended(self):
+ """Test a pwd and hardened kerberos ticket policy with 10min tickets"""
master = self.master
master.run_command(['ipa', 'user-mod', USER1,
'--user-auth-type', 'password',
@@ -131,6 +131,32 @@ class TestPWPolicy(IntegrationTest):
result = master.run_command('klist | grep krbtgt')
assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
+ def test_krbtpolicy_hardended(self):
+ """Test a hardened kerberos ticket policy with 30min tickets"""
+ master = self.master
+ master.run_command(['ipa', 'user-mod', USER1,
+ '--user-auth-type', 'hardened'])
+ master.run_command(['ipa', 'config-mod',
+ '--user-auth-type', 'hardened'])
+ master.run_command(['ipa', 'krbtpolicy-mod', USER1,
+ '--hardened-maxlife', '1800'])
+
+ tasks.kdestroy_all(master)
+
+ master.run_command(['kinit', USER1],
+ stdin_text=PASSWORD + '\n')
+ result = master.run_command('klist | grep krbtgt')
+ assert maxlife_within_policy(result.stdout_text, 1800,
+ slush=1800) is True
+
+ tasks.kdestroy_all(master)
+
+ # Verify that the short policy only applies to USER1
+ master.run_command(['kinit', USER2],
+ stdin_text=PASSWORD + '\n')
+ result = master.run_command('klist | grep krbtgt')
+ assert maxlife_within_policy(result.stdout_text, MAXLIFE) is True
+
def test_krbtpolicy_password(self):
"""Test the kerberos ticket policy which issues 20 min tickets"""
master = self.master
--
2.34.1

View File

@ -0,0 +1,104 @@
From edb216849e4f47d6cae95981edf0c3fe2653fd7a Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 28 Jan 2022 16:46:35 -0500
Subject: [PATCH] Don't always override the port in import_included_profiles
I can only guess to the original purpose of this override. I
believe it was because this is called in the installer prior
to Apache being set up. The expectation was that this would
only be called locally. It predates the RestClient class.
RestClient will attempt to find an available service. In this
case, during a CA installation, the local server is not
considered available because it lacks an entry in
cn=masters. So it will never be returned as an option.
So by overriding the port to 8443 the remote connection will
likely fail because we don't require that the port be open.
So instead, instantiate a RestClient and see what happens.
There are several use-cases:
1. Installing an initial server. The RestClient connection
should fail, so we will fall back to the override port and
use the local server. If Apache happens to be running with
a globally-issued certificate then the RestClient will
succeed. In this case if the connected host and the local
hostname are the same, override in that case as well.
2. Installing as a replica. In this case the local server should
be ignored in all cases and a remote CA will be picked with
no override done.
3. Switching from CA-less to CA-ful. The web server will be
trusted but the RestClient login will fail with a 404. Fall
back to the override port in this case.
The motivation for this is trying to install an EL 8.x replica
against an EL 7.9 server. 8.5+ includes the ACME service and
a new profile is needed which doesn't exist in 7. This was
failing because the RestClient determined that the local server
wasn't running a CA so tried the remote one (7.9) on the override
port 8443. Since this port isn't open: failure.
Chances are that adding the profile is still going to fail
because again, 7.9 lacks ACME capabilities, but it will fail in
a way that allows the installation to continue.
I suspect that all of the overrides can similarly handled, or
handled directly within the RestClient class, but for the sake
of "do no harm" I'm only changing this instance for now.
https://pagure.io/freeipa/issue/9100
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/install/cainstance.py | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 8c8bf1b3a7bcf8a9c50183579b874a5710a32ac3..ad206aad411b42336e86e0b651a948fccd3a75ac 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1953,7 +1953,35 @@ def import_included_profiles():
cn=['certprofiles'],
)
- api.Backend.ra_certprofile.override_port = 8443
+ # At this point Apache may or may not be running with a valid
+ # certificate. The local server is not yet recognized as a full
+ # CA yet so it isn't discoverable. So try to do some detection
+ # on what port to use, 443 (remote) or 8443 (local) for importing
+ # the profiles.
+ #
+ # api.Backend.ra_certprofile invokes the RestClient class
+ # which will discover and login to the CA REST API. We can
+ # use this information to detect where to import the profiles.
+ #
+ # If the login is successful (e.g. doesn't raise an exception)
+ # and it returns our hostname (it prefers the local host) then
+ # we override and talk locally.
+ #
+ # Otherwise a NetworkError means we can't connect on 443 (perhaps
+ # a firewall) or we get an HTTP error (valid TLS certificate on
+ # Apache but no CA, login fails with 404) so we override to the
+ # local server.
+ #
+ # When override port was always set to 8443 the RestClient could
+ # pick a remote server and since 8443 isn't in our firewall profile
+ # setting up a new server would fail.
+ try:
+ with api.Backend.ra_certprofile as profile_api:
+ if profile_api.ca_host == api.env.host:
+ api.Backend.ra_certprofile.override_port = 8443
+ except (errors.NetworkError, errors.RemoteRetrieveError) as e:
+ logger.debug('Overriding CA port: %s', e)
+ api.Backend.ra_certprofile.override_port = 8443
for (profile_id, desc, store_issued) in dogtag.INCLUDED_PROFILES:
dn = DN(('cn', profile_id),
--
2.34.1

View File

@ -0,0 +1,115 @@
From 7c5540bb47799b4db95673d22f61995ad5c56440 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 31 Jan 2022 17:31:50 -0500
Subject: [PATCH] Remove ipa-join errors from behind the debug option
This brings it inline with the previous XML-RPC output which
only hid the request and response from the output and not
any errors returned.
https://pagure.io/freeipa/issue/9103
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Peter Keresztes Schmidt <carbenium@outlook.com>
---
client/ipa-join.c | 27 +++++++++------------------
1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/client/ipa-join.c b/client/ipa-join.c
index d98739a9abfb01ecf619187483bfc6677957d498..5888a33bf221eb5d455b2adcfa0f33b38f0969ca 100644
--- a/client/ipa-join.c
+++ b/client/ipa-join.c
@@ -743,8 +743,7 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
json_str = json_dumps(json, 0);
if (!json_str) {
- if (debug)
- fprintf(stderr, _("json_dumps() failed\n"));
+ fprintf(stderr, _("json_dumps() failed\n"));
rval = 17;
goto cleanup;
@@ -758,8 +757,7 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
- if (debug)
- fprintf(stderr, _("JSON-RPC call failed: %s\n"), curl_easy_strerror(res));
+ fprintf(stderr, _("JSON-RPC call failed: %s\n"), curl_easy_strerror(res));
rval = 17;
goto cleanup;
@@ -769,8 +767,7 @@ jsonrpc_request(const char *ipaserver, const json_t *json, curl_buffer *response
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &resp_code);
if (resp_code != 200) {
- if (debug)
- fprintf(stderr, _("JSON-RPC call failed with status code: %li\n"), resp_code);
+ fprintf(stderr, _("JSON-RPC call failed with status code: %li\n"), resp_code);
if (!quiet && resp_code == 401)
fprintf(stderr, _("JSON-RPC call was unauthorized. Check your credentials.\n"));
@@ -848,8 +845,7 @@ jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
j_root = json_loads(payload, 0, &j_error);
if (!j_root) {
- if (debug)
- fprintf(stderr, _("Parsing JSON-RPC response failed: %s\n"), j_error.text);
+ fprintf(stderr, _("Parsing JSON-RPC response failed: %s\n"), j_error.text);
rval = 17;
goto cleanup;
@@ -864,8 +860,7 @@ jsonrpc_parse_response(const char *payload, json_t** j_result_obj, bool quiet) {
*j_result_obj = json_object_get(j_root, "result");
if (!*j_result_obj) {
- if (debug)
- fprintf(stderr, _("Parsing JSON-RPC response failed: no 'result' value found.\n"));
+ fprintf(stderr, _("Parsing JSON-RPC response failed: no 'result' value found.\n"));
rval = 17;
goto cleanup;
@@ -897,8 +892,7 @@ jsonrpc_parse_join_response(const char *payload, join_info *join_i, bool quiet)
&tmp_hostdn,
"krbprincipalname", &tmp_princ,
"krblastpwdchange", &tmp_pwdch) != 0) {
- if (debug)
- fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
+ fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
rval = 17;
goto cleanup;
@@ -941,8 +935,7 @@ join_krb5_jsonrpc(const char *ipaserver, const char *hostname, char **hostdn, co
"nshardwareplatform", uinfo.machine);
if (!json_req) {
- if (debug)
- fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
+ fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
rval = 17;
goto cleanup;
@@ -990,8 +983,7 @@ jsonrpc_parse_unenroll_response(const char *payload, bool* result, bool quiet) {
if (json_unpack_ex(j_result_obj, &j_error, 0, "{s:b}",
"result", result) != 0) {
- if (debug)
- fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
+ fprintf(stderr, _("Extracting the data from the JSON-RPC response failed: %s\n"), j_error.text);
rval = 20;
goto cleanup;
@@ -1021,8 +1013,7 @@ jsonrpc_unenroll_host(const char *ipaserver, const char *host, bool quiet) {
host);
if (!json_req) {
- if (debug)
- fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
+ fprintf(stderr, _("json_pack_ex() failed: %s\n"), j_error.text);
rval = 17;
goto cleanup;
--
2.34.1

View File

@ -0,0 +1,47 @@
From 9b6d0bb1245c4891ccc270f360d0f72a4b1444c1 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 7 Feb 2022 10:39:55 -0500
Subject: [PATCH] Enable the ccache sweep timer during installation
The timer was only being enabled during package installation
if IPA was configured. So effectively only on upgrade.
Add as a separate installation step after the ccache directory
is configured.
Fixes: https://pagure.io/freeipa/issue/9107
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
ipaserver/install/httpinstance.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 732bb58d49addcb2a9f7698d577527257a17fe66..50ccf5e5031c37171cebe6f20232f3bd645cedeb 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -140,6 +140,8 @@ class HTTPInstance(service.Service):
self.step("publish CA cert", self.__publish_ca_cert)
self.step("clean up any existing httpd ccaches",
self.remove_httpd_ccaches)
+ self.step("enable ccache sweep",
+ self.enable_ccache_sweep)
self.step("configuring SELinux for httpd", self.configure_selinux_for_httpd)
if not self.is_kdcproxy_configured():
self.step("create KDC proxy config", self.create_kdcproxy_conf)
@@ -177,6 +179,11 @@ class HTTPInstance(service.Service):
[paths.SYSTEMD_TMPFILES, '--create', '--prefix', paths.IPA_CCACHES]
)
+ def enable_ccache_sweep(self):
+ ipautil.run(
+ [paths.SYSTEMCTL, 'enable', 'ipa-ccache-sweep.timer']
+ )
+
def __configure_http(self):
self.update_httpd_service_ipa_conf()
self.update_httpd_wsgi_conf()
--
2.34.1

View File

@ -0,0 +1,71 @@
From 0d9eb3d515385412abefe9c33e0099ea14f33cbc Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Wed, 9 Feb 2022 18:56:21 +0530
Subject: [PATCH] Test ipa-ccache-sweep.timer enabled by default during
installation
This test checks that ipa-ccache-sweep.timer is enabled by default
during the ipa installation.
related: https://pagure.io/freeipa/issue/9107
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
.../test_integration/test_installation.py | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py
index f2d372c0c0356f244971a2af808db45dd6c8cb5b..63edbaa2bb4dbae174c6ab8c8f193cc24cc45b14 100644
--- a/ipatests/test_integration/test_installation.py
+++ b/ipatests/test_integration/test_installation.py
@@ -475,7 +475,7 @@ class TestInstallCA(IntegrationTest):
# Tweak sysrestore.state to drop installation section
self.master.run_command(
- ['sed','-i', r's/\[installation\]/\[badinstallation\]/',
+ ['sed', '-i', r's/\[installation\]/\[badinstallation\]/',
os.path.join(paths.SYSRESTORE, SYSRESTORE_STATEFILE)])
# Re-run installation check and it should fall back to old method
@@ -485,7 +485,7 @@ class TestInstallCA(IntegrationTest):
# Restore installation section.
self.master.run_command(
- ['sed','-i', r's/\[badinstallation\]/\[installation\]/',
+ ['sed', '-i', r's/\[badinstallation\]/\[installation\]/',
os.path.join(paths.SYSRESTORE, SYSRESTORE_STATEFILE)])
# Uninstall and confirm that the old method reports correctly
@@ -690,6 +690,7 @@ def get_pki_tomcatd_pid(host):
break
return(pid)
+
def get_ipa_services_pids(host):
ipa_services_name = [
"krb5kdc", "kadmin", "named", "httpd", "ipa-custodia",
@@ -1309,6 +1310,20 @@ class TestInstallMasterKRA(IntegrationTest):
def test_install_master(self):
tasks.install_master(self.master, setup_dns=False, setup_kra=True)
+ def test_ipa_ccache_sweep_timer_enabled(self):
+ """Test ipa-ccache-sweep.timer enabled by default during installation
+
+ This test checks that ipa-ccache-sweep.timer is enabled by default
+ during the ipa installation.
+
+ related: https://pagure.io/freeipa/issue/9107
+ """
+ result = self.master.run_command(
+ ['systemctl', 'is-enabled', 'ipa-ccache-sweep.timer'],
+ raiseonerr=False
+ )
+ assert 'enabled' in result.stdout_text
+
def test_install_dns(self):
tasks.install_dns(self.master)
--
2.34.1

View File

@ -0,0 +1,38 @@
From 186ebe311bc9545d7a9860cd5e8c748131bbe41e Mon Sep 17 00:00:00 2001
From: Francisco Trivino <ftrivino@redhat.com>
Date: Thu, 10 Feb 2022 14:23:12 +0100
Subject: [PATCH] ipa_cldap: fix memory leak
ipa_cldap_encode_netlogon() allocates memory to store binary data as part of
berval (bv_val) when processing a CLDAP packet request from a worker. The
data is used by ipa_cldap_respond() but bv_val is not freed later on.
This commit is adding the corresponding free() after ipa_cldap_respond()
is completed.
Discovered by LeakSanitizer
Fixes: https://pagure.io/freeipa/issue/9110
Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
---
daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c
index db4a3d061..252bcf647 100644
--- a/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c
+++ b/daemons/ipa-slapi-plugins/ipa-cldap/ipa_cldap_worker.c
@@ -287,6 +287,7 @@ done:
ipa_cldap_respond(ctx, req, &reply);
ipa_cldap_free_kvps(&req->kvps);
+ free(reply.bv_val);
free(req);
return;
}
--
2.34.1

View File

@ -0,0 +1,31 @@
From b36bcf4ea5ed93baa4dc63f8e2be542d678211fb Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Thu, 10 Feb 2022 18:49:06 +0530
Subject: [PATCH] ipatests: remove additional check for failed units.
On RHEL tests are randomly failing because of this check
and the test doesn't need to check this.
Related : https://pagure.io/freeipa/issue/9108
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_otp.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
index d8ce527ca..6e70ddcb3 100644
--- a/ipatests/test_integration/test_otp.py
+++ b/ipatests/test_integration/test_otp.py
@@ -316,7 +316,6 @@ class TestOTPToken(IntegrationTest):
check_services = self.master.run_command(
['systemctl', 'list-units', '--state=failed']
)
- assert "0 loaded units listed" in check_services.stdout_text
assert "ipa-otpd" not in check_services.stdout_text
# Be sure no services are running and failed units
self.master.run_command(['killall', 'ipa-otpd'], raiseonerr=False)
--
2.34.1

View File

@ -0,0 +1,40 @@
From 4c54e9d6ddb72eab6f654bf3dc2d29f27498ac96 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Sun, 5 Dec 2021 17:38:58 +0100
Subject: [PATCH] ipatests: fix
TestOTPToken::test_check_otpd_after_idle_timeout
The test sets 389-ds nsslapd-idletimeout to 60s, then does a
kinit with an otp token (which makes ipa-otpd create a LDAP
connection), then sleeps for 60s. The expectation is that
ns-slapd will detect that the LDAP conn from ipa-otpd is idle
and close the connection.
According to 389ds doc, the idle timeout is enforced when the
connection table is walked. By doing a ldapsearch, the test
"wakes up" ns-slapd and forces the detection of ipa-otpd
idle connection.
Fixes: https://pagure.io/freeipa/issue/9044
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Anuja More <amore@redhat.com>
---
ipatests/test_integration/test_otp.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
index 353470897..d8ce527ca 100644
--- a/ipatests/test_integration/test_otp.py
+++ b/ipatests/test_integration/test_otp.py
@@ -354,6 +354,9 @@ class TestOTPToken(IntegrationTest):
otpvalue = totp.generate(int(time.time())).decode("ascii")
kinit_otp(self.master, USER, password=PASSWORD, otp=otpvalue)
time.sleep(60)
+ # ldapsearch will wake up slapd and force walking through
+ # the connection list, in order to spot the idle connections
+ tasks.ldapsearch_dm(self.master, "", ldap_args=[], scope="base")
def test_cb(cmd_jornalctl):
# check if LDAP connection is timed out
--
2.34.1

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

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmGf1XcACgkQaYdvcqbi
00/kMQ//Vano94V0/L3YsLaqKiFcGo/py5pTq1Os3wB9zzCYSuU0P/eajuHLBYNe
MfxecZihFFlmUdNooNWbewT4CE0ey1qFLwPfGXuLrse6fXVLLaYnAv2mkPUmDSpM
XfXO0PFU0BtdkMAUsdUATngPCpQzYjVUKsAMwPovi3UcLzFZ8tWJKMA55urhwC4q
E042wPLqzcX6Ee5JBSBkfNe35vG2LY7o3Ynh8SVCee2lBJvdWiuFT5XRhybXUsOp
q3eTsVPz68p7CvOrjlLSsWPP0nbGF1O1UQsN+oaDZAav1Nx8lTOlxUCUQXWbs2X6
BTUAOmZ6VjYu61sNgNSj+BSHlHIT3uRJ55JO5nLH/hLm0Oxn6SGRTVMueqV376QA
CsIk7UrdcX9QUtu70eRxuu1aAWJ5eaF4GDWnFP+62wzd/d6LjWEE+9kXgvrcTF0C
UzjWrmbI8x23bB4kqcROHz8lryMsBpZ94QKPHVppMiPgapDKRkculYkSeRLboADi
q4mh2prkDSq9diWV4HvZTGwPU77oiLrQsvbGuvwD62PAlyQ4rZpfW3FllTL2Lcxy
urA8a9UnQWQtDOsZIyxmMJ7R04gjI5fZfDhq6S09L9MfjFEKjsqO4FzXamj+SbAo
w25sIp1qT0sV1vOt+/R/HYSIyggQyTZpQJu5UB34QLqpfDdUwFg=
=t9up
-----END PGP SIGNATURE-----

3173
SPECS/freeipa.spec Normal file

File diff suppressed because it is too large Load Diff