[Freeipa-devel] [PATCH] 0026..0027 #5096 enforce caacl for SAN principals
Fraser Tweedale
ftweedal at redhat.com
Fri Jul 3 14:26:39 UTC 2015
The attached patches fix:
- a bug that caused caacl false negatives for hosts principals
- #5096 cert-request: enforce caacl for subjectAltName principals
Thanks,
Fraser
-------------- next part --------------
From f6d7f8e58a7fcb09261ae18a8722f28da778779c Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Fri, 3 Jul 2015 10:05:40 -0400
Subject: [PATCH 26/27] caacl: fix incorrect construction of HbacRequest for
hosts
The _acl_make_request function is using the 'host/' prefix itself
instead of the hostname after it. Use split_any_principal to do the
splitting correctly, also taking realm into account.
---
ipalib/plugins/caacl.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/ipalib/plugins/caacl.py b/ipalib/plugins/caacl.py
index 6bf39d2330c8999726484e1e9fb44fdb7c755767..247d6df143aef1fba9f0ee74a9f7d8386bef5180 100644
--- a/ipalib/plugins/caacl.py
+++ b/ipalib/plugins/caacl.py
@@ -55,13 +55,15 @@ register = Registry()
def _acl_make_request(principal_type, principal, ca_ref, profile_id):
"""Construct HBAC request for the given principal, CA and profile"""
+ service, name, realm = split_any_principal(principal)
+
req = pyhbac.HbacRequest()
req.targethost.name = ca_ref
req.service.name = profile_id
if principal_type == 'user':
req.user.name = principal
elif principal_type == 'host':
- req.user.name = principal[:5] # strip 'host/'
+ req.user.name = name
elif principal_type == 'service':
req.user.name = normalize_principal(principal)
groups = []
@@ -70,8 +72,7 @@ def _acl_make_request(principal_type, principal, ca_ref, profile_id):
groups = user_obj.get('memberof_group', [])
groups += user_obj.get('memberofindirect_group', [])
elif principal_type == 'host':
- service, hostname, realm = split_any_principal(principal)
- host_obj = api.Command.host_show(hostname)['result']
+ host_obj = api.Command.host_show(name)['result']
groups = host_obj.get('memberof_hostgroup', [])
groups += host_obj.get('memberofindirect_hostgroup', [])
req.user.groups = sorted(set(groups))
--
2.1.0
-------------- next part --------------
From c39c0f122310f070997c058aefc5617ca75a7ff2 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Fri, 3 Jul 2015 10:15:19 -0400
Subject: [PATCH 27/27] cert-request: enforce caacl for principals in SAN
cert-request currently does not enforce caacls for principals
included in the subjectAltName requestExtension. Enforce for any
dNSName values recognised as hosts/services known to FreeIPA.
Fixes: https://fedorahosted.org/freeipa/ticket/5096
---
ipalib/plugins/cert.py | 42 +++++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
index 1878e5ad5f80fa93e1a77b0a88711c1da0016681..743fb4d3930f051c4a2098128b09b241a844cb43 100644
--- a/ipalib/plugins/cert.py
+++ b/ipalib/plugins/cert.py
@@ -220,6 +220,22 @@ def ca_enabled_check():
if not api.Command.ca_is_enabled()['result']:
raise errors.NotFound(reason=_('CA is not configured'))
+def caacl_check(principal_type, principal_string, ca, profile_id):
+ principal_type_map = {USER: 'user', HOST: 'host', SERVICE: 'service'}
+ if not ipalib.plugins.caacl.acl_evaluate(
+ principal_type_map[principal_type],
+ principal_string, ca, profile_id):
+ raise errors.ACIError(info=_(
+ "Principal '%(principal)s' "
+ "is not permitted to use CA '%(ca)s' "
+ "with profile '%(profile_id)s' for certificate issuance."
+ ) % dict(
+ principal=principal_string,
+ ca=ca or '.',
+ profile_id=profile_id
+ )
+ )
+
@register()
class cert_request(VirtualCommand):
__doc__ = _('Submit a certificate signing request.')
@@ -305,6 +321,7 @@ class cert_request(VirtualCommand):
add = kw.get('add')
request_type = kw.get('request_type')
profile_id = kw.get('profile_id', self.Backend.ra.DEFAULT_PROFILE)
+ ca = '.' # top-level CA hardcoded until subca plugin implemented
"""
Access control is partially handled by the ACI titled
@@ -327,21 +344,7 @@ class cert_request(VirtualCommand):
else:
principal_type = SERVICE
- principal_type_map = {USER: 'user', HOST: 'host', SERVICE: 'service'}
- ca = '.' # top-level CA hardcoded until subca plugin implemented
- if not ipalib.plugins.caacl.acl_evaluate(
- principal_type_map[principal_type],
- principal_string, ca, profile_id):
- raise errors.ACIError(info=_(
- "Principal '%(principal)s' "
- "is not permitted to use CA '%(ca)s' "
- "with profile '%(profile_id)s' for certificate issuance."
- ) % dict(
- principal=principal_string,
- ca=ca or '.',
- profile_id=profile_id
- )
- )
+ caacl_check(principal_type, principal_string, ca, profile_id)
bind_principal = split_any_principal(getattr(context, 'principal'))
bind_service, bind_name, bind_realm = bind_principal
@@ -439,13 +442,15 @@ class cert_request(VirtualCommand):
if name_type == pkcs10.SAN_DNSNAME:
name = unicode(name)
alt_principal_obj = None
+ alt_principal_string = None
try:
if principal_type == HOST:
+ alt_principal_string = 'host/%s@%s' % (name, realm)
alt_principal_obj = api.Command['host_show'](name, all=True)
elif principal_type == SERVICE:
- altprincipal = '%s/%s@%s' % (servicename, name, realm)
+ alt_principal_string = '%s/%s@%s' % (servicename, name, realm)
alt_principal_obj = api.Command['service_show'](
- altprincipal, all=True)
+ alt_principal_string, all=True)
elif principal_type == USER:
raise errors.ValidationError(
name='csr',
@@ -465,6 +470,9 @@ class cert_request(VirtualCommand):
raise errors.ACIError(info=_(
"Insufficient privilege to create a certificate "
"with subject alt name '%s'.") % name)
+ if alt_principal_string is not None:
+ caacl_check(
+ principal_type, alt_principal_string, ca, profile_id)
elif name_type in (pkcs10.SAN_OTHERNAME_KRB5PRINCIPALNAME,
pkcs10.SAN_OTHERNAME_UPN):
if name != principal_string:
--
2.1.0
More information about the Freeipa-devel
mailing list