diff options
author | Fraser Tweedale <ftweedal@redhat.com> | 2015-07-03 10:15:19 -0400 |
---|---|---|
committer | Tomas Babej <tbabej@redhat.com> | 2015-07-08 17:13:25 +0200 |
commit | ec7e5e0cac4d93f4a0bb62c1de28be46f362740b (patch) | |
tree | 364c3cb94a20a36575cde5a92cb000c2fcb81382 | |
parent | e3c225317be2e4849f0f5f8b35f9872d28379330 (diff) | |
download | freeipa-ec7e5e0cac4d93f4a0bb62c1de28be46f362740b.tar.gz freeipa-ec7e5e0cac4d93f4a0bb62c1de28be46f362740b.tar.xz freeipa-ec7e5e0cac4d93f4a0bb62c1de28be46f362740b.zip |
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
Reviewed-By: David Kupka <dkupka@redhat.com>
-rw-r--r-- | ipalib/plugins/cert.py | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py index 1878e5ad5..743fb4d39 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: |