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