pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone

Blame SOURCES/0100-Allow-for-configuration-of-all-three-PKINIT-variants.patch

483b06
From 152715b8514b1b94e1c353baedff12d24efaacb7 Mon Sep 17 00:00:00 2001
483b06
From: Martin Babinsky <mbabinsk@redhat.com>
483b06
Date: Fri, 31 Mar 2017 15:06:46 +0200
483b06
Subject: [PATCH] Allow for configuration of all three PKINIT variants when
483b06
 deploying KDC
483b06
483b06
The PKINIT setup code now can configure PKINIT using IPA CA signed
483b06
certificate, 3rd party certificate and local PKINIT with self-signed
483b06
keypair. The local PKINIT is also selected as a fallback mechanism if
483b06
the CSR is rejected by CA master or `--no-pkinit` is used.
483b06
483b06
http://www.freeipa.org/page/V4/Kerberos_PKINIT
483b06
https://pagure.io/freeipa/issue/6830
483b06
483b06
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
483b06
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
483b06
Reviewed-By: Martin Basti <mbasti@redhat.com>
483b06
Reviewed-By: Simo Sorce <ssorce@redhat.com>
483b06
---
483b06
 ipaserver/install/krbinstance.py | 145 +++++++++++++++++++++++++--------------
483b06
 1 file changed, 93 insertions(+), 52 deletions(-)
483b06
483b06
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
483b06
index 6c105f74c8da2bfd34ace607b13170bc96a8ff1d..80215788cf4031ef82e9ec7e08bde6cfc4390303 100644
483b06
--- a/ipaserver/install/krbinstance.py
483b06
+++ b/ipaserver/install/krbinstance.py
483b06
@@ -38,6 +38,7 @@ from ipalib.constants import ANON_USER
483b06
 from ipalib.install import certmonger
483b06
 from ipapython.ipa_log_manager import root_logger
483b06
 from ipapython.dn import DN
483b06
+from ipapython.dogtag import KDC_PROFILE
483b06
 
483b06
 from ipaserver.install import replication
483b06
 from ipaserver.install import ldapupdate
483b06
@@ -354,61 +355,84 @@ class KrbInstance(service.Service):
483b06
             remote_ldap.gssapi_bind()
483b06
             replication.wait_for_entry(remote_ldap, kdc_dn, timeout=60)
483b06
 
483b06
-    def setup_pkinit(self):
483b06
-        if self.pkcs12_info:
483b06
-            certs.install_pem_from_p12(self.pkcs12_info[0],
483b06
-                                       self.pkcs12_info[1],
483b06
-                                       paths.KDC_CERT)
483b06
-            certs.install_key_from_p12(self.pkcs12_info[0],
483b06
-                                       self.pkcs12_info[1],
483b06
-                                       paths.KDC_KEY)
483b06
-        else:
483b06
-            subject = str(DN(('cn', self.fqdn), self.subject_base))
483b06
-            krbtgt = "krbtgt/" + self.realm + "@" + self.realm
483b06
-            certpath = (paths.KDC_CERT, paths.KDC_KEY)
483b06
+    def _call_certmonger(self, certmonger_ca='IPA'):
483b06
+        subject = str(DN(('cn', self.fqdn), self.subject_base))
483b06
+        krbtgt = "krbtgt/" + self.realm + "@" + self.realm
483b06
+        certpath = (paths.KDC_CERT, paths.KDC_KEY)
483b06
 
483b06
-            try:
483b06
-                prev_helper = None
483b06
-                if self.master_fqdn is None:
483b06
-                    ca_args = [
483b06
-                        paths.CERTMONGER_DOGTAG_SUBMIT,
483b06
-                        '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
483b06
-                        '--certfile', paths.RA_AGENT_PEM,
483b06
-                        '--keyfile', paths.RA_AGENT_KEY,
483b06
-                        '--cafile', paths.IPA_CA_CRT,
483b06
-                        '--agent-submit'
483b06
-                    ]
483b06
-                    helper = " ".join(ca_args)
483b06
-                    prev_helper = certmonger.modify_ca_helper('IPA', helper)
483b06
-                else:
483b06
-                    self._wait_for_replica_kdc_entry()
483b06
-
483b06
-                certmonger.request_and_wait_for_cert(
483b06
-                    certpath,
483b06
-                    subject,
483b06
-                    krbtgt,
483b06
-                    dns=self.fqdn,
483b06
-                    storage='FILE',
483b06
-                    profile='KDCs_PKINIT_Certs')
483b06
-            except dbus.DBusException as e:
483b06
-                # if the certificate is already tracked, ignore the error
483b06
-                name = e.get_dbus_name()
483b06
-                if name != 'org.fedorahosted.certmonger.duplicate':
483b06
-                    root_logger.error("Failed to initiate the request: %s", e)
483b06
-                return
483b06
-            finally:
483b06
-                if prev_helper is not None:
483b06
-                    certmonger.modify_ca_helper('IPA', prev_helper)
483b06
-
483b06
-        # Finally copy the cacert in the krb directory so we don't
483b06
-        # have any selinux issues with the file context
483b06
+        try:
483b06
+            prev_helper = None
483b06
+            # on the first CA-ful master without '--no-pkinit', we issue the
483b06
+            # certificate by contacting Dogtag directly
483b06
+            use_dogtag_submit = all(
483b06
+                [self.master_fqdn is None,
483b06
+                 self.pkcs12_info is None,
483b06
+                 self.config_pkinit])
483b06
+
483b06
+            if use_dogtag_submit:
483b06
+                ca_args = [
483b06
+                    paths.CERTMONGER_DOGTAG_SUBMIT,
483b06
+                    '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
483b06
+                    '--certfile', paths.RA_AGENT_PEM,
483b06
+                    '--keyfile', paths.RA_AGENT_KEY,
483b06
+                    '--cafile', paths.IPA_CA_CRT,
483b06
+                    '--agent-submit'
483b06
+                ]
483b06
+                helper = " ".join(ca_args)
483b06
+                prev_helper = certmonger.modify_ca_helper(certmonger_ca, helper)
483b06
+
483b06
+            certmonger.request_and_wait_for_cert(
483b06
+                certpath,
483b06
+                subject,
483b06
+                krbtgt,
483b06
+                ca=certmonger_ca,
483b06
+                dns=self.fqdn,
483b06
+                storage='FILE',
483b06
+                profile=KDC_PROFILE)
483b06
+        except dbus.DBusException as e:
483b06
+            # if the certificate is already tracked, ignore the error
483b06
+            name = e.get_dbus_name()
483b06
+            if name != 'org.fedorahosted.certmonger.duplicate':
483b06
+                root_logger.error("Failed to initiate the request: %s", e)
483b06
+            return
483b06
+        finally:
483b06
+            if prev_helper is not None:
483b06
+                certmonger.modify_ca_helper(certmonger_ca, prev_helper)
483b06
+
483b06
+    def issue_selfsigned_pkinit_certs(self):
483b06
+        self._call_certmonger(certmonger_ca="SelfSign")
483b06
+        # for self-signed certificate, the certificate is its own CA, copy it
483b06
+        # as CA cert
483b06
+        shutil.copyfile(paths.KDC_CERT, paths.CACERT_PEM)
483b06
+
483b06
+    def issue_ipa_ca_signed_pkinit_certs(self):
483b06
+        try:
483b06
+            self._call_certmonger()
483b06
+            # copy IPA CA bundle to the KDC's CA cert bundle
483b06
+            shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
483b06
+        except RuntimeError as e:
483b06
+            root_logger.error("PKINIT certificate request failed: %s", e)
483b06
+            root_logger.error("Failed to configure PKINIT")
483b06
+            self.stop_tracking_certs()
483b06
+            self.issue_selfsigned_pkinit_certs()
483b06
+
483b06
+    def install_external_pkinit_certs(self):
483b06
+        certs.install_pem_from_p12(self.pkcs12_info[0],
483b06
+                                   self.pkcs12_info[1],
483b06
+                                   paths.KDC_CERT)
483b06
+        certs.install_key_from_p12(self.pkcs12_info[0],
483b06
+                                   self.pkcs12_info[1],
483b06
+                                   paths.KDC_KEY)
483b06
+        # copy IPA CA bundle to the KDC's CA cert bundle
483b06
+        # NOTE: this may not be the same set of CA certificates trusted by
483b06
+        # externally provided PKINIT cert.
483b06
         shutil.copyfile(paths.IPA_CA_CRT, paths.CACERT_PEM)
483b06
 
483b06
-        try:
483b06
-            self.restart()
483b06
-        except Exception:
483b06
-            root_logger.critical("krb5kdc service failed to restart")
483b06
-            raise
483b06
+    def setup_pkinit(self):
483b06
+        if self.pkcs12_info:
483b06
+            self.install_external_pkinit_certs()
483b06
+        elif self.config_pkinit:
483b06
+            self.issue_ipa_ca_signed_pkinit_certs()
483b06
 
483b06
     def test_anonymous_pkinit(self):
483b06
         with ipautil.private_ccache() as anon_ccache:
483b06
@@ -418,6 +442,15 @@ class KrbInstance(service.Service):
483b06
                 raise RuntimeError("Failed to configure anonymous PKINIT")
483b06
 
483b06
     def enable_ssl(self):
483b06
+        """
483b06
+        generate PKINIT certificate for KDC. If `--no-pkinit` was specified,
483b06
+        only configure local self-signed KDC certificate for use as a FAST
483b06
+        channel generator for WebUI. Do not advertise the installation steps in
483b06
+        this case.
483b06
+        """
483b06
+        if self.master_fqdn is not None:
483b06
+            self._wait_for_replica_kdc_entry()
483b06
+
483b06
         if self.config_pkinit:
483b06
             self.steps = []
483b06
             self.step("installing X509 Certificate for PKINIT",
483b06
@@ -425,6 +458,14 @@ class KrbInstance(service.Service):
483b06
             self.step("testing anonymous PKINIT", self.test_anonymous_pkinit)
483b06
 
483b06
             self.start_creation()
483b06
+        else:
483b06
+            self.issue_selfsigned_pkinit_certs()
483b06
+
483b06
+        try:
483b06
+            self.restart()
483b06
+        except Exception:
483b06
+            root_logger.critical("krb5kdc service failed to restart")
483b06
+            raise
483b06
 
483b06
     def get_anonymous_principal_name(self):
483b06
         return "%s@%s" % (ANON_USER, self.realm)
483b06
-- 
483b06
2.12.2
483b06