diff options
author | Rob Crittenden <rcritten@redhat.com> | 2011-04-26 16:45:19 -0400 |
---|---|---|
committer | Rob Crittenden <rcritten@redhat.com> | 2011-06-16 19:27:17 -0400 |
commit | a2a3782efb386f18689faf35a069c4da1085e87d (patch) | |
tree | b8c4b2bf7c13307eccf3be5f962a680ae97e122b /ipalib | |
parent | ed7a3e005a052845b7302744c0f6c16f7cdfd511 (diff) | |
download | freeipa-a2a3782efb386f18689faf35a069c4da1085e87d.tar.gz freeipa-a2a3782efb386f18689faf35a069c4da1085e87d.tar.xz freeipa-a2a3782efb386f18689faf35a069c4da1085e87d.zip |
Require an imported certificate's issuer to match our issuer.
The goal is to not import foreign certificates.
This caused a bunch of tests to fail because we had a hardcoded server
certificate. Instead a developer will need to run make-testcert to
create a server certificate generated by the local CA to test against.
ticket 1134
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/plugins/host.py | 7 | ||||
-rw-r--r-- | ipalib/plugins/service.py | 27 |
2 files changed, 32 insertions, 2 deletions
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py index 29f659f9c..5d6a23f42 100644 --- a/ipalib/plugins/host.py +++ b/ipalib/plugins/host.py @@ -85,6 +85,7 @@ from ipalib.plugins.service import normalize_certificate from ipalib.plugins.service import set_certificate_attrs from ipalib.plugins.service import make_pem, check_writable_file from ipalib.plugins.service import write_certificate +from ipalib.plugins.service import verify_cert_subject from ipalib.plugins.dns import dns_container_exists, _record_types from ipalib.plugins.dns import add_forward_record from ipalib import _, ngettext @@ -400,6 +401,11 @@ class host_add(LDAPCreate): # save the password so it can be displayed in post_callback setattr(context, 'randompassword', entry_attrs['userpassword']) del entry_attrs['random'] + cert = options.get('usercertificate') + if cert: + cert = normalize_certificate(cert) + verify_cert_subject(ldap, keys[-1], cert) + entry_attrs['usercertificate'] = cert entry_attrs['managedby'] = dn return dn @@ -600,6 +606,7 @@ class host_mod(LDAPUpdate): entry_attrs['objectclass'] = obj_classes cert = normalize_certificate(entry_attrs.get('usercertificate')) if cert: + verify_cert_subject(ldap, keys[-1], cert) (dn, entry_attrs_old) = ldap.get_entry(dn, ['usercertificate']) if 'usercertificate' in entry_attrs_old: oldcert = normalize_certificate(entry_attrs_old.get('usercertificate')[0]) diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py index 2f47e065d..85956272b 100644 --- a/ipalib/plugins/service.py +++ b/ipalib/plugins/service.py @@ -206,6 +206,25 @@ def normalize_certificate(cert): return cert +def verify_cert_subject(ldap, hostname, cert): + """ + Verify that the certificate issuer we're adding matches the issuer + base of our installation. + + This assumes the certificate has already been normalized. + + This raises an exception on errors and returns nothing otherwise. + """ + cert = x509.load_certificate(cert, datatype=x509.DER) + subject = str(cert.subject) + issuer = str(cert.issuer) + + # Handle both supported forms of issuer, from selfsign and dogtag. + if ((issuer != 'CN=%s Certificate Authority' % api.env.realm) and + (issuer != 'CN=Certificate Authority,O=%s' % api.env.realm)): + raise errors.CertificateOperationError(error=_('Issuer "%(issuer)s" does not match the expected issuer') % \ + {'issuer' : issuer}) + def set_certificate_attrs(entry_attrs): """ Set individual attributes from some values from a certificate. @@ -342,7 +361,9 @@ class service_add(LDAPCreate): cert = options.get('usercertificate') if cert: - entry_attrs['usercertificate'] = normalize_certificate(cert) + cert = normalize_certificate(cert) + verify_cert_subject(ldap, hostname, cert) + entry_attrs['usercertificate'] = cert if not options.get('force', False): # We know the host exists if we've gotten this far but we @@ -406,9 +427,11 @@ class service_mod(LDAPUpdate): def pre_callback(self, ldap, dn, entry_attrs, *keys, **options): if 'usercertificate' in options: + (service, hostname, realm) = split_principal(keys[-1]) cert = options.get('usercertificate') - cert = normalize_certificate(cert) if cert: + cert = normalize_certificate(cert) + verify_cert_subject(ldap, hostname, cert) (dn, entry_attrs_old) = ldap.get_entry(dn, ['usercertificate']) if 'usercertificate' in entry_attrs_old: # FIXME: what to do here? do we revoke the old cert? |