summaryrefslogtreecommitdiffstats
path: root/ipalib/plugins
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2011-04-26 16:45:19 -0400
committerRob Crittenden <rcritten@redhat.com>2011-06-16 19:27:17 -0400
commita2a3782efb386f18689faf35a069c4da1085e87d (patch)
treeb8c4b2bf7c13307eccf3be5f962a680ae97e122b /ipalib/plugins
parented7a3e005a052845b7302744c0f6c16f7cdfd511 (diff)
downloadfreeipa-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/plugins')
-rw-r--r--ipalib/plugins/host.py7
-rw-r--r--ipalib/plugins/service.py27
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?