Import OL ipa-4.12.2-1.0.1.el9_5.3

This commit is contained in:
eabdullin 2025-01-17 09:45:37 +03:00
parent dd295410e9
commit 97c1695387
10 changed files with 3457 additions and 2 deletions

View File

@ -0,0 +1,265 @@
From 18303b94bea4e08a0c889fc357df6ba2f308fa0d Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Wed, 2 Oct 2024 21:26:34 -0400
Subject: [PATCH] Do not let user with an expired OTP token to log in if only
OTP is allowed
If only OTP authentication is allowed, and a user tries to login with an
expired token, do not let them log in with their password. Forcing the
admin to intervene. If the user does not have an OTP token then allow
them to log in with a password until an OTP token is configured
Fixes: https://pagure.io/freeipa/issue/9387
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Julien Rische <jrische@redhat.com>
---
daemons/ipa-kdb/ipa_kdb_principals.c | 63 +++++++++++--
.../ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 3 +-
ipatests/test_integration/test_otp.py | 94 ++++++++++++++++++-
3 files changed, 151 insertions(+), 9 deletions(-)
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
index 14603e528b43acb29234c425e97ad297ac6724a7..114957b884786dd3ca3b01c47f6bb82e8a040beb 100644
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -107,7 +107,6 @@ static char *std_principal_obj_classes[] = {
"krbprincipal",
"krbprincipalaux",
"krbTicketPolicyAux",
-
NULL
};
@@ -338,14 +337,16 @@ static void ipadb_validate_otp(struct ipadb_context *ipactx,
if (dn == NULL)
return;
count = asprintf(&filter, ftmpl, dn, datetime, datetime);
- ldap_memfree(dn);
- if (count < 0)
+ if (count < 0) {
+ ldap_memfree(dn);
return;
+ }
/* Fetch the active token list. */
kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
filter, (char**) attrs, &res);
free(filter);
+ filter = NULL;
if (kerr != 0 || res == NULL)
return;
@@ -353,10 +354,60 @@ static void ipadb_validate_otp(struct ipadb_context *ipactx,
count = ldap_count_entries(ipactx->lcontext, res);
ldap_msgfree(res);
- /* If the user is configured for OTP, but has no active tokens, remove
- * OTP from the list since the user obviously can't log in this way. */
- if (count == 0)
+ /*
+ * If there are no valid tokens then we need to remove the OTP flag,
+ * unless OTP is the only auth type allowed...
+ */
+ if (count == 0) {
+ /* Remove the OTP flag for now */
*ua &= ~IPADB_USER_AUTH_OTP;
+
+ if (*ua == 0) {
+ /*
+ * Ok, we "only" allow OTP, so if there is an expired/disabled
+ * token then add back the OTP flag as the server will double
+ * check the validity and reject the entire bind. Otherwise, this
+ * is the first time the user is authenticating and the user
+ * should be allowed to bind using its password
+ */
+ static const char *expired_ftmpl = "(&"
+ "(objectClass=ipaToken)(ipatokenOwner=%s)"
+ "(|(ipatokenNotAfter<=%s)(!(ipatokenNotAfter=*))"
+ "(ipatokenDisabled=True))"
+ ")";
+ if (asprintf(&filter, expired_ftmpl, dn, datetime) < 0) {
+ ldap_memfree(dn);
+ return;
+ }
+
+ krb5_klog_syslog(LOG_INFO,
+ "Entry (%s) does not have a valid token and only OTP "
+ "authentication is supported, checking for expired tokens...",
+ dn);
+
+ kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
+ filter, (char**) attrs, &res);
+ free(filter);
+ if (kerr != 0 || res == NULL) {
+ ldap_memfree(dn);
+ return;
+ }
+
+ if (ldap_count_entries(ipactx->lcontext, res) > 0) {
+ /*
+ * Ok we only allow OTP, and there are expired/disabled tokens
+ * so add the OTP flag back, and the server will reject the
+ * bind
+ */
+ krb5_klog_syslog(LOG_INFO,
+ "Entry (%s) does have an expired/disabled token so this "
+ "user can not fall through to password auth", dn);
+ *ua |= IPADB_USER_AUTH_OTP;
+ }
+ ldap_msgfree(res);
+ }
+ }
+ ldap_memfree(dn);
}
static void ipadb_validate_radius(struct ipadb_context *ipactx,
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
index c967e2cfffbd920280639f3188783ec150523b47..1c1340e31ac30cb01412a7065ea339cb5461e839 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
@@ -1528,7 +1528,8 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
if (!syncreq && (otpreq == OTP_IS_NOT_REQUIRED)) {
ret = ipapwd_gen_checks(pb, &errMesg, &krbcfg, IPAPWD_CHECK_ONLY_CONFIG);
if (ret != 0) {
- LOG_FATAL("ipapwd_gen_checks failed!?\n");
+ LOG_FATAL("ipapwd_gen_checks failed for '%s': %s\n",
+ slapi_sdn_get_dn(sdn), errMesg);
slapi_entry_free(entry);
slapi_sdn_free(&sdn);
return 0;
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
index 350371bfe1e4c1cc6dcc89f6584f813fcb0d32a0..878b4fb560ba8d7768ead54b065656462545babd 100644
--- a/ipatests/test_integration/test_otp.py
+++ b/ipatests/test_integration/test_otp.py
@@ -10,6 +10,7 @@ import re
import time
import textwrap
from urllib.parse import urlparse, parse_qs
+from paramiko import AuthenticationException
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
@@ -83,7 +84,7 @@ def kinit_otp(host, user, *, password, otp, success=True):
)
-def ssh_2f(hostname, username, answers_dict, port=22):
+def ssh_2f(hostname, username, answers_dict, port=22, unwanted_prompt=""):
"""
:param hostname: hostname
:param username: username
@@ -103,6 +104,10 @@ def ssh_2f(hostname, username, answers_dict, port=22):
logger.info("Prompt is: '%s'", prmpt_str)
logger.info(
"Answer to ssh prompt is: '%s'", answers_dict[prmpt_str])
+ if unwanted_prompt and prmpt_str == unwanted_prompt:
+ # We should not see this prompt
+ raise ValueError("We got an unwanted prompt: "
+ + answers_dict[prmpt_str])
return resp
import paramiko
@@ -193,7 +198,8 @@ class TestOTPToken(IntegrationTest):
# skipping too many OTP fails
otp1 = hotp.generate(10).decode("ascii")
- kinit_otp(self.master, USER, password=PASSWORD, otp=otp1, success=False)
+ kinit_otp(self.master, USER, password=PASSWORD, otp=otp1,
+ success=False)
# Now the token is desynchronized
yield (otpuid, hotp)
@@ -536,3 +542,87 @@ class TestOTPToken(IntegrationTest):
finally:
master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '1'])
master.run_command(['ipa', 'user-del', USER1])
+
+ def test_totp_expired_ldap(self):
+ master = self.master
+ basedn = master.domain.basedn
+ USER1 = 'user-expired-otp'
+ TMP_PASSWORD = 'Secret1234509'
+ binddn = DN(f"uid={USER1},cn=users,cn=accounts,{basedn}")
+ controls = [
+ BooleanControl(
+ controlType="2.16.840.1.113730.3.8.10.7",
+ booleanValue=True)
+ ]
+
+ tasks.kinit_admin(master)
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '0'])
+ tasks.user_add(master, USER1, password=TMP_PASSWORD)
+ # Enforce use of OTP token for this user
+ master.run_command(['ipa', 'user-mod', USER1,
+ '--user-auth-type=otp'])
+ try:
+ # Change initial password through the IPA endpoint
+ url = f'https://{master.hostname}/ipa/session/change_password'
+ master.run_command(['curl', '-d', f'user={USER1}',
+ '-d', f'old_password={TMP_PASSWORD}',
+ '-d', f'new_password={PASSWORD}',
+ '--referer', f'https://{master.hostname}/ipa',
+ url])
+ conn = master.ldap_connect()
+ # First, attempt authenticating with a password but without LDAP
+ # control to enforce OTP presence and without server-side
+ # enforcement of the OTP presence check.
+ conn.simple_bind(binddn, f"{PASSWORD}")
+
+ # Add an OTP token and then modify it to be expired
+ otpuid, totp = add_otptoken(master, USER1, otptype="totp")
+
+ # Make sure OTP auth is working
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
+ conn = master.ldap_connect()
+ conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}",
+ client_controls=controls)
+ conn.unbind()
+
+ # Modfy token so that is now expired
+ args = [
+ "ipa",
+ "otptoken-mod",
+ otpuid,
+ "--not-after",
+ "20241001010000Z",
+ ]
+ master.run_command(args)
+
+ # Next, authenticate with Password+OTP again and with the LDAP
+ # control this operation should now fail
+ time.sleep(45)
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
+
+ conn = master.ldap_connect()
+ with pytest.raises(errors.ACIError):
+ conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}",
+ client_controls=controls)
+
+ # Sleep to make sure we are going to use a different token value
+ time.sleep(45)
+
+ # Use OTP token again but authenticate over ssh and make sure it
+ # doesn't fallthrough to asking for a password
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
+ answers = {
+ 'Enter first factor:': PASSWORD,
+ 'Enter second factor:': otpvalue
+ }
+ with pytest.raises(AuthenticationException):
+ # ssh should fail and NOT ask for a password
+ ssh_2f(master.hostname, USER1, answers,
+ unwanted_prompt="Password:")
+
+ # Remove token
+ del_otptoken(self.master, otpuid)
+
+ finally:
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '1'])
+ master.run_command(['ipa', 'user-del', USER1])
--
2.47.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
From 4fef80aeaaf017b286bd12ebfc30529f6a65a80e Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 2 Sep 2024 18:28:27 +0200
Subject: [PATCH] ipatests: Add missing comma in
test_idrange_no_rid_bases_reversed
The test is calling ipa idrange-add but is missing a comma in
the arguments list.
The resulting call is using "--rid-base 100300000--secondary-rid-base".
Add the missing comma to build the command with
"--rid-base 100300000 --secondary-rid-base"
Fixes: https://pagure.io/freeipa/issue/9656
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
ipatests/test_integration/test_ipa_idrange_fix.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_ipa_idrange_fix.py b/ipatests/test_integration/test_ipa_idrange_fix.py
index de3da9bfd221ce74f1d1bbb0dbe12e4db08b8daa..ff8fbdac9d028d26fc55f5e357f89af879a61723 100644
--- a/ipatests/test_integration/test_ipa_idrange_fix.py
+++ b/ipatests/test_integration/test_ipa_idrange_fix.py
@@ -72,7 +72,7 @@ class TestIpaIdrangeFix(IntegrationTest):
"idrange_reversed",
"--base-id", '50000',
"--range-size", '20000',
- "--rid-base", '100300000'
+ "--rid-base", '100300000',
"--secondary-rid-base", '301000'
])
--
2.47.0

View File

@ -0,0 +1,35 @@
From ae4c2ad6cd966d48c063814f494dcc16cf0ccd4c Mon Sep 17 00:00:00 2001
From: Sudhir Menon <sumenon@redhat.com>
Date: Tue, 24 Sep 2024 13:46:48 +0530
Subject: [PATCH] ipatests: Fixes for ipa-idrange-fix testsuite
This patch adds the line tasks.install_master(cls.master).
The kinit admin command fails with the below error as the
IPA is not configured on the test system
'ipa: ERROR: stderr: kinit: Configuration file does not specify default
realm when parsing name admin'
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipatests/test_integration/test_ipa_idrange_fix.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ipatests/test_integration/test_ipa_idrange_fix.py b/ipatests/test_integration/test_ipa_idrange_fix.py
index ff8fbdac9d028d26fc55f5e357f89af879a61723..0c915bd0931ed11a3aa86c533ee8748aa8a7ec07 100644
--- a/ipatests/test_integration/test_ipa_idrange_fix.py
+++ b/ipatests/test_integration/test_ipa_idrange_fix.py
@@ -17,6 +17,9 @@ logger = logging.getLogger(__name__)
class TestIpaIdrangeFix(IntegrationTest):
+
+ topology = 'line'
+
@classmethod
def install(cls, mh):
super(TestIpaIdrangeFix, cls).install(mh)
--
2.47.0

View File

@ -0,0 +1,166 @@
From d4d56a6705c870901bc73882e4804367f7c9c91a Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Sun, 1 Dec 2024 20:16:54 +0200
Subject: [PATCH] ipalib/x509: support PyCA 44.0
PyCA made x509.Certificate class concrete, it cannot be extended anymore
by Python code. The intent is to use helper functions to instantiate
certificate objects and never create them directly.
FreeIPA wraps PyCA's x509.Certificate class and provides own shim
on top of it. In most cases we load the certificate content via the
helper functions and don't really need to derive from the certificate
class.
Move IPACertificate to be a normal Python object class that stores
x509.Certificate internally. The only place where this breaks is when
IPACertificate object needs to be passed to a code that expects
x509.Certificate (Dogtag PKI). In such cases, expose the underlying
certificate instance via IPACertificate.cert property.
Fixes: https://pagure.io/freeipa/issue/9708
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipalib/ipajson.py | 4 ++--
ipalib/x509.py | 10 +++++++++-
ipapython/ipaldap.py | 15 +++++++--------
ipaserver/plugins/dogtag.py | 3 ++-
4 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/ipalib/ipajson.py b/ipalib/ipajson.py
index 5551d12e5fec7e458fa6fe85560664b2fd897337..fd99c8219c722c52321336f28ff27e1573e906c7 100644
--- a/ipalib/ipajson.py
+++ b/ipalib/ipajson.py
@@ -9,7 +9,7 @@ from decimal import Decimal
import json
import six
from ipalib.constants import LDAP_GENERALIZED_TIME_FORMAT
-from ipalib import capabilities
+from ipalib import capabilities, x509
from ipalib.x509 import Encoding as x509_Encoding
from ipapython.dn import DN
from ipapython.dnsutil import DNSName
@@ -72,7 +72,7 @@ class _JSONPrimer(dict):
list: self._enc_list,
tuple: self._enc_list,
dict: self._enc_dict,
- crypto_x509.Certificate: self._enc_certificate,
+ x509.IPACertificate: self._enc_certificate,
crypto_x509.CertificateSigningRequest: self._enc_certificate,
})
diff --git a/ipalib/x509.py b/ipalib/x509.py
index fd08238962b2b5e9cd056fb13c0a81ee8f31b092..6780bead00b50efdf03c62ce717572eeb9df2e5f 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -88,7 +88,7 @@ SAN_UPN = '1.3.6.1.4.1.311.20.2.3'
SAN_KRB5PRINCIPALNAME = '1.3.6.1.5.2.2'
-class IPACertificate(crypto_x509.Certificate):
+class IPACertificate:
"""
A proxy class wrapping a python-cryptography certificate representation for
IPA purposes
@@ -205,6 +205,10 @@ class IPACertificate(crypto_x509.Certificate):
"""
return self._cert.fingerprint(algorithm)
+ @property
+ def cert(self):
+ return self._cert
+
@property
def serial_number(self):
return self._cert.serial_number
@@ -457,6 +461,8 @@ def load_pem_x509_certificate(data):
:returns: a ``IPACertificate`` object.
:raises: ``ValueError`` if unable to load the certificate.
"""
+ if isinstance(data, IPACertificate):
+ return data
return IPACertificate(
crypto_x509.load_pem_x509_certificate(data, backend=default_backend())
)
@@ -469,6 +475,8 @@ def load_der_x509_certificate(data):
:returns: a ``IPACertificate`` object.
:raises: ``ValueError`` if unable to load the certificate.
"""
+ if isinstance(data, IPACertificate):
+ return data
return IPACertificate(
crypto_x509.load_der_x509_certificate(data, backend=default_backend())
)
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index 1888e40916aa6e641542f08fb30ff2b0d4b850b1..5bb81c1bc844fce9b14251d3702e09099d85cdb5 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -33,7 +33,6 @@ import warnings
from collections import OrderedDict
-from cryptography import x509 as crypto_x509
from cryptography.hazmat.primitives import serialization
import ldap
@@ -748,10 +747,10 @@ class LDAPClient:
'dnszoneidnsname': DNSName,
'krbcanonicalname': Principal,
'krbprincipalname': Principal,
- 'usercertificate': crypto_x509.Certificate,
- 'usercertificate;binary': crypto_x509.Certificate,
- 'cACertificate': crypto_x509.Certificate,
- 'cACertificate;binary': crypto_x509.Certificate,
+ 'usercertificate': x509.IPACertificate,
+ 'usercertificate;binary': x509.IPACertificate,
+ 'cACertificate': x509.IPACertificate,
+ 'cACertificate;binary': x509.IPACertificate,
'nsds5replicalastupdatestart': unicode,
'nsds5replicalastupdateend': unicode,
'nsds5replicalastinitstart': unicode,
@@ -1000,7 +999,7 @@ class LDAPClient:
return dct
elif isinstance(val, datetime):
return val.strftime(LDAP_GENERALIZED_TIME_FORMAT).encode('utf-8')
- elif isinstance(val, crypto_x509.Certificate):
+ elif isinstance(val, x509.IPACertificate):
return val.public_bytes(x509.Encoding.DER)
elif val is None:
return None
@@ -1027,7 +1026,7 @@ class LDAPClient:
return DNSName.from_text(val.decode('utf-8'))
elif target_type in (DN, Principal):
return target_type(val.decode('utf-8'))
- elif target_type is crypto_x509.Certificate:
+ elif target_type is x509.IPACertificate:
return x509.load_der_x509_certificate(val)
else:
return target_type(val)
@@ -1381,7 +1380,7 @@ class LDAPClient:
]
return cls.combine_filters(flts, rules)
elif value is not None:
- if isinstance(value, crypto_x509.Certificate):
+ if isinstance(value, x509.IPACertificate):
value = value.public_bytes(serialization.Encoding.DER)
if isinstance(value, bytes):
value = binascii.hexlify(value).decode('ascii')
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
index 78afb279795ecf74f296cbbb8724505075a6e4a9..ee6d0e347d640a2664e38ba64785c3d8af54bbad 100644
--- a/ipaserver/plugins/dogtag.py
+++ b/ipaserver/plugins/dogtag.py
@@ -1581,7 +1581,8 @@ class kra(Backend):
crypto = cryptoutil.CryptographyCryptoProvider(
transport_cert_nick="ra_agent",
- transport_cert=x509.load_certificate_from_file(paths.RA_AGENT_PEM)
+ transport_cert=x509.load_certificate_from_file(
+ paths.RA_AGENT_PEM).cert
)
# TODO: obtain KRA host & port from IPA service list or point to KRA load balancer
--
2.47.1

View File

@ -0,0 +1,120 @@
From 8dfec28647f7c17e47fbfc96a1720dcde1592386 Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Mon, 2 Dec 2024 15:04:30 +0300
Subject: [PATCH] pyca: adapt import paths for TripleDES cipher
https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.algorithms.TripleDES
> This algorithm has been deprecated and moved to the Decrepit
cryptography module. If you need to continue using it then update your
code to use the new module path. It will be removed from this namespace
in 48.0.0.
Fixes: https://pagure.io/freeipa/issue/9708
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipaclient/plugins/vault.py | 8 +++++++-
ipalib/constants.py | 24 +++++++++++-------------
ipaserver/install/ipa_otptoken_import.py | 8 +++++++-
3 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/ipaclient/plugins/vault.py b/ipaclient/plugins/vault.py
index 75415c03a57242ae674636fa31a72db2fa56d6ea..6af7297936924dfb80e7f79924b570421da65c97 100644
--- a/ipaclient/plugins/vault.py
+++ b/ipaclient/plugins/vault.py
@@ -34,6 +34,12 @@ 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
+try:
+ # cryptography>=43.0.0
+ from cryptography.hazmat.decrepit.ciphers.algorithms import TripleDES
+except ImportError:
+ # will be removed from this module in cryptography 48.0.0
+ from cryptography.hazmat.primitives.ciphers.algorithms import TripleDES
from cryptography.hazmat.primitives.padding import PKCS7
from cryptography.hazmat.primitives.serialization import (
load_pem_public_key, load_pem_private_key)
@@ -661,7 +667,7 @@ class ModVaultData(Local):
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))
+ return TripleDES(os.urandom(196 // 8))
else:
# unreachable
raise ValueError(name)
diff --git a/ipalib/constants.py b/ipalib/constants.py
index b657e5a9065d115d0eff2dbfffff49e992006536..c90caa22149ec3d93d45fcb5480f7401e4555799 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -25,20 +25,19 @@ All constants centralised in one file.
import os
import string
import uuid
-import warnings
-
-warnings.filterwarnings(
- "ignore",
- "TripleDES has been moved to "
- "cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and "
- "will be removed from this module in 48.0.0",
- category=UserWarning)
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.primitives.ciphers import modes
+try:
+ # cryptography>=43.0.0
+ from cryptography.hazmat.decrepit.ciphers.algorithms import TripleDES
+except ImportError:
+ # will be removed from this module in cryptography 48.0.0
+ from cryptography.hazmat.primitives.ciphers.algorithms import TripleDES
+
from cryptography.hazmat.backends.openssl.backend import backend
@@ -389,7 +388,6 @@ VAULT_WRAPPING_SUPPORTED_ALGOS = (
VAULT_WRAPPING_DEFAULT_ALGO = VAULT_WRAPPING_AES128_CBC
# Add 3DES for backwards compatibility if supported
-if getattr(algorithms, 'TripleDES', None):
- if backend.cipher_supported(algorithms.TripleDES(
- b"\x00" * 8), modes.CBC(b"\x00" * 8)):
- VAULT_WRAPPING_SUPPORTED_ALGOS += (VAULT_WRAPPING_3DES,)
+if backend.cipher_supported(TripleDES(
+ b"\x00" * 8), modes.CBC(b"\x00" * 8)):
+ VAULT_WRAPPING_SUPPORTED_ALGOS += (VAULT_WRAPPING_3DES,)
diff --git a/ipaserver/install/ipa_otptoken_import.py b/ipaserver/install/ipa_otptoken_import.py
index 279a7502d2f305309252b3b291e32b772a51a1d3..17457f6c5b81ab70a0ecee13bf744e242ec88ff0 100644
--- a/ipaserver/install/ipa_otptoken_import.py
+++ b/ipaserver/install/ipa_otptoken_import.py
@@ -37,6 +37,12 @@ from cryptography.hazmat.primitives import hashes, hmac
from cryptography.hazmat.primitives.padding import PKCS7
from cryptography.hazmat.primitives.kdf import pbkdf2
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+try:
+ # cryptography>=43.0.0
+ from cryptography.hazmat.decrepit.ciphers.algorithms import TripleDES
+except ImportError:
+ # will be removed from this module in cryptography 48.0.0
+ from cryptography.hazmat.primitives.ciphers.algorithms import TripleDES
from cryptography.hazmat.backends import default_backend
from ipaplatform.paths import paths
@@ -169,7 +175,7 @@ def convertAlgorithm(value):
# in the list of the vault wrapping algorithms, we cannot use 3DES anywhere
if VAULT_WRAPPING_3DES in VAULT_WRAPPING_SUPPORTED_ALGOS:
supported_algs["http://www.w3.org/2001/04/xmlenc#tripledes-cbc"] = (
- algorithms.TripleDES, modes.CBC, 64)
+ TripleDES, modes.CBC, 64)
return supported_algs.get(value.lower(), (None, None, None))
--
2.47.1

View File

@ -0,0 +1,134 @@
From 3e7ec3dc49d0f559bdbe330e52019e59f0b57c18 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Tue, 3 Dec 2024 18:06:45 +0200
Subject: [PATCH] ipa-pwd-extop: clarify OTP use over LDAP binds
OTP use during LDAP bind can be enforced either explicitly via client
specifying a control with OID 2.16.840.1.113730.3.8.10.7 and no payload
or implicitly through the global IPA configuration with EnforceLDAPOTP.
OTP token enforcement overrides IPA user authentication types
requirements:
If OTP enforcement is required:
- if user authentication types still allow password authentication,
authentication with just a password is denied, regardless whether OTP
tokens are associated with the user or not.
If OTP enforcement is not required:
- if user has no OTP tokens but user authentication types require OTP
use, authentication with just a password is allowed until a token is
added.
- if user has OTP tokens and user authentication types require OTP use
but not password, authentication with just a password is denied.
Additionally, enforcement of OTP only applies to LDAP objects which
don't use 'simpleSecurityObject' objectclass. This allows system service
accounts to continue authenticate with a password regardless of the
OTP enforcement.
Fixes: https://pagure.io/freeipa/issue/9699
Fixes: https://pagure.io/freeipa/issue/9711
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
.../ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 38 +++++++++++++++----
1 file changed, 30 insertions(+), 8 deletions(-)
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
index 1c1340e31ac30cb01412a7065ea339cb5461e839..42e880fd0a5c8b4708b145b340209eb218f60c4e 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
@@ -1219,12 +1219,10 @@ typedef enum {
} otp_req_enum;
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
struct berval *creds, otp_req_enum otpreq,
- bool *notokens)
+ bool *notokens, uint32_t *auth_types)
{
- uint32_t auth_types;
-
/* Get the configured authentication types. */
- auth_types = otp_config_auth_types(otp_config, entry);
+ *auth_types = otp_config_auth_types(otp_config, entry);
*notokens = false;
/*
@@ -1237,7 +1235,8 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
* 2. If PWD is enabled or OTP succeeded, fall through to PWD validation.
*/
- if (auth_types & OTP_CONFIG_AUTH_TYPE_OTP) {
+ if ((*auth_types & OTP_CONFIG_AUTH_TYPE_OTP) ||
+ (otpreq != OTP_IS_NOT_REQUIRED)) {
struct otp_token **tokens = NULL;
LOG_PLUGIN_NAME(IPAPWD_PLUGIN_NAME,
@@ -1270,7 +1269,7 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
otp_token_free_array(tokens);
}
- return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) &&
+ return (*auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) &&
(otpreq == OTP_IS_NOT_REQUIRED);
}
@@ -1451,6 +1450,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
struct ipapwd_krbcfg *krbcfg = NULL;
struct berval *credentials = NULL;
Slapi_Entry *entry = NULL;
+ Slapi_Value *objectclass = NULL;
Slapi_DN *target_sdn = NULL;
Slapi_DN *sdn = NULL;
const char *dn = NULL;
@@ -1465,6 +1465,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
int rc = LDAP_INVALID_CREDENTIALS;
char *errMesg = NULL;
bool notokens = false;
+ uint32_t auth_types = 0;
/* get BIND parameters */
ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &target_sdn);
@@ -1538,12 +1539,33 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
otpreq = OTP_IS_REQUIRED_IMPLICITLY;
}
}
+ /* we only apply OTP policy to Kerberos principals */
+ objectclass = slapi_value_new_string("krbprincipalaux");
+ if (objectclass == NULL) {
+ goto invalid_creds;
+ }
+ if (!slapi_entry_attr_has_syntax_value(entry, SLAPI_ATTR_OBJECTCLASS,
+ objectclass)) {
+ otpreq = OTP_IS_NOT_REQUIRED;
+ }
+ slapi_value_free(&objectclass);
+
if (!syncreq && !ipapwd_pre_bind_otp(dn, entry,
- credentials, otpreq, &notokens)) {
+ credentials, otpreq,
+ &notokens, &auth_types)) {
/* We got here because ipapwd_pre_bind_otp() returned false,
* it means that either token verification failed or
* a rule for empty tokens failed current policy. */
- if (!(notokens || (otpreq == OTP_IS_NOT_REQUIRED)))
+
+ /* Check if there were any tokens associated, thus
+ * OTP token verification has really failed */
+ if (notokens == false)
+ goto invalid_creds;
+
+ /* No tokens, check if auth type does not include OTP but OTP is
+ * enforced by the current policy */
+ if (!(auth_types & OTP_CONFIG_AUTH_TYPE_OTP) &&
+ (otpreq != OTP_IS_NOT_REQUIRED))
goto invalid_creds;
}
--
2.47.1

View File

@ -0,0 +1,45 @@
From 477dbba18bf987bf4461fdfdfba0d497159db7ce Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Wed, 4 Dec 2024 19:56:51 +0300
Subject: [PATCH] adtrust: add missing ipaAllowedOperations objectclass
Per @abbra explanation:
> When expected Kerberos principal names for this object were flipped to
follow requirements for cross-realm krbtgt objects expected by Active
Directory, trusted object changed its canonical Kerberos principal name.
The keytab for this Kerberos principal name is fetched by SSSD and it
needs to be permitted to read the key. We added the virtual permission
to allow the keytab retrieval but didn't add the objectclass that
actually allows adding an LDAP attribute to express the permission. When
an attribute is added to an LDAP object, objectclasses of the object
must allow presence of that attribute.
This is the followup to #9471 and fixes the upgrade.
Thanks @abbra!
Related: https://pagure.io/freeipa/issue/9471
Fixes: https://pagure.io/freeipa/issue/9712
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
ipaserver/install/plugins/adtrust.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
index e6d49cb2512bff7dcce57f019ecb6c497d11ed52..ab3d427ef561aeb26eb098270446640ba451c8ad 100644
--- a/ipaserver/install/plugins/adtrust.py
+++ b/ipaserver/install/plugins/adtrust.py
@@ -705,7 +705,8 @@ class update_tdo_to_new_layout(Updater):
self.set_krb_principal([tgt_principal, nbt_principal],
passwd_incoming,
t_dn,
- flags=self.KRB_PRINC_CREATE_DEFAULT)
+ flags=self.KRB_PRINC_CREATE_DEFAULT
+ | self.KRB_PRINC_CREATE_AGENT_PERMISSION)
# 3. INBOUND: krbtgt/<OUR REALM>@<REMOTE REALM> must exist
trust_principal = self.tgt_principal_template.format(
--
2.47.1

File diff suppressed because it is too large Load Diff

View File

@ -224,7 +224,7 @@
Name: %{package_name}
Version: %{IPA_VERSION}
Release: 1%{?rc_version:.%rc_version}%{?dist}
Release: 1%{?rc_version:.%rc_version}.0.1%{?dist}.3
Summary: The Identity, Policy and Audit system
License: GPL-3.0-or-later
@ -250,6 +250,15 @@ Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
%if 0%{?rhel} == 9
Patch0001: 0001-Revert-Replace-netifaces-with-ifaddr.patch
Patch0002: 0002-Revert-custodia-do-not-use-deprecated-jwcrypto-wrapp.patch
Patch0003: 0003-Do-not-let-user-with-an-expired-OTP-token-to-log-in-.patch
Patch0004: 0004-Add-ipa-idrange-fix.patch
Patch0005: 0005-ipatests-Add-missing-comma-in-test_idrange_no_rid_ba.patch
Patch0006: 0006-ipatests-Fixes-for-ipa-idrange-fix-testsuite.patch
Patch0007: 0007-ipalib-x509-support-PyCA-44.0.patch
Patch0008: 0008-pyca-adapt-import-paths-for-TripleDES-cipher.patch
Patch0009: 0009-ipa-pwd-extop-clarify-OTP-use-over-LDAP-binds.patch
Patch0010: 0010-adtrust-add-missing-ipaAllowedOperations-objectclass.patch
Patch0011: 0011-CVE-2024-11029.patch
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
%endif
%endif
@ -578,6 +587,7 @@ BuildArch: noarch
Requires: %{name}-client-common = %{version}-%{release}
Requires: httpd >= %{httpd_version}
Requires: systemd-units >= %{systemd_version}
Requires: bind >= %{bind_version}
%if 0%{?rhel} >= 8 && ! 0%{?eln}
Requires: system-logos-ipa >= 80.4
%endif
@ -1029,7 +1039,8 @@ autoreconf -ivf
%{enable_server_option} \
%{with_ipatests_option} \
%{with_ipa_join_xml_option} \
%{linter_options}
%{linter_options} \
--with-ipaplatform=rhel
# run build in default dir
# -Onone is workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1398405
@ -1496,6 +1507,7 @@ fi
%{_sbindir}/ipa-pkinit-manage
%{_sbindir}/ipa-crlgen-manage
%{_sbindir}/ipa-cert-fix
%{_sbindir}/ipa-idrange-fix
%{_sbindir}/ipa-acme-manage
%{_sbindir}/ipa-migrate
%if 0%{?fedora} >= 38
@ -1575,6 +1587,7 @@ fi
%{_mandir}/man1/ipa-pkinit-manage.1*
%{_mandir}/man1/ipa-crlgen-manage.1*
%{_mandir}/man1/ipa-cert-fix.1*
%{_mandir}/man1/ipa-idrange-fix.1*
%{_mandir}/man1/ipa-acme-manage.1*
%{_mandir}/man1/ipa-migrate.1*
@ -1863,6 +1876,22 @@ fi
%endif
%changelog
* Wed Jan 15 2025 Pooja Senthil Kumar <pooja.senthil.kumar@oracle.com> - 4.12.2-1.0.1.3
- Set IPAPLATFORM=rhel when build on Oracle Linux [Orabug: 29516674]
- Add bind to ipa-server-common Requires [Orabug: 36518596]
* Tue Dec 17 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.2-1.3
- Resolves: RHEL-69928 add support for python cryptography 44.0.0
- Resolves: RHEL-70258 Upgrade to ipa-server-4.12.2-1.el9 OTP-based bind to LDAP without enforceldapotp is broken
- Resolves: RHEL-70482 ipa-server-upgrade fails after established trust with ad
- Resolves: RHEL-67192 CVE-2024-11029 ipa: Administrative user data leaked through systemd journal
* Wed Nov 27 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.2-1.2
- Resolves: RHEL-69294 add a tool to quickly detect and fix issues with IPA ID ranges
* Fri Nov 08 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.2-1.1
- Resolves: RHEL-66173 Last expired OTP token would be considered as still assigned to the user
* Wed Aug 21 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.2-1
- Resolves: RHEL-54546 Covscan issues: Resource Leak
- Resolves: RHEL-49602 misleading warning for missing ipa-selinux-nfast package on luna hsm h/w