ac7d03
From 2409b5204101cceafb28289db0d99c1474ee2430 Mon Sep 17 00:00:00 2001
ac7d03
From: Jan Cholasta <jcholast@redhat.com>
ac7d03
Date: Fri, 7 Apr 2017 07:43:09 +0200
ac7d03
Subject: [PATCH] dsinstance, httpinstance: consolidate certificate request
ac7d03
 code
ac7d03
ac7d03
A different code path is used for DS and httpd certificate requests in
ac7d03
replica promotion. This is rather unnecessary and makes the certificate
ac7d03
request code not easy to follow.
ac7d03
ac7d03
Consolidate the non-promotion and promotion code paths into one.
ac7d03
ac7d03
https://pagure.io/freeipa/issue/6757
ac7d03
ac7d03
Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
ac7d03
---
ac7d03
 ipaserver/install/dsinstance.py            | 76 +++++++++---------------------
ac7d03
 ipaserver/install/httpinstance.py          | 40 ++++++++--------
ac7d03
 ipaserver/install/server/install.py        |  4 --
ac7d03
 ipaserver/install/server/replicainstall.py | 22 +--------
ac7d03
 4 files changed, 43 insertions(+), 99 deletions(-)
ac7d03
ac7d03
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
ac7d03
index fb5f925de8e658dca9370714413012527f00c39d..31dbd4ec8bcaf4a7545b4f9f316fe609b845cb75 100644
ac7d03
--- a/ipaserver/install/dsinstance.py
ac7d03
+++ b/ipaserver/install/dsinstance.py
ac7d03
@@ -396,10 +396,7 @@ class DsInstance(service.Service):
ac7d03
 
ac7d03
         self.step("creating DS keytab", self.request_service_keytab)
ac7d03
         if self.promote:
ac7d03
-            if self.pkcs12_info:
ac7d03
-                self.step("configuring TLS for DS instance", self.__enable_ssl)
ac7d03
-            else:
ac7d03
-                self.step("retrieving DS Certificate", self.__get_ds_cert)
ac7d03
+            self.step("configuring TLS for DS instance", self.__enable_ssl)
ac7d03
             self.step("restarting directory server", self.__restart_instance)
ac7d03
 
ac7d03
         self.step("setting up initial replication", self.__setup_replica)
ac7d03
@@ -810,18 +807,23 @@ class DsInstance(service.Service):
ac7d03
                 dsdb.track_server_cert(
ac7d03
                     self.nickname, self.principal, dsdb.passwd_fname,
ac7d03
                     'restart_dirsrv %s' % self.serverid)
ac7d03
+
ac7d03
+            self.add_cert_to_service()
ac7d03
         else:
ac7d03
             dsdb.create_from_cacert()
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
+            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
+                prev_helper = None
ac7d03
             try:
ac7d03
                 cmd = 'restart_dirsrv %s' % self.serverid
ac7d03
                 certmonger.request_and_wait_for_cert(
ac7d03
@@ -835,7 +837,8 @@ class DsInstance(service.Service):
ac7d03
                     dns=[self.fqdn],
ac7d03
                     post_command=cmd)
ac7d03
             finally:
ac7d03
-                certmonger.modify_ca_helper('IPA', prev_helper)
ac7d03
+                if prev_helper is not None:
ac7d03
+                    certmonger.modify_ca_helper('IPA', prev_helper)
ac7d03
 
ac7d03
             # restart_dirsrv in the request above restarts DS, reconnect ldap2
ac7d03
             api.Backend.ldap2.disconnect()
ac7d03
@@ -843,6 +846,9 @@ class DsInstance(service.Service):
ac7d03
 
ac7d03
             self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
ac7d03
 
ac7d03
+            if prev_helper is not None:
ac7d03
+                self.add_cert_to_service()
ac7d03
+
ac7d03
         dsdb.create_pin_file()
ac7d03
 
ac7d03
         self.cacert_name = dsdb.cacert_name
ac7d03
@@ -1236,46 +1242,6 @@ class DsInstance(service.Service):
ac7d03
         ipautil.config_replace_variables(paths.SYSCONFIG_DIRSRV,
ac7d03
                                          replacevars=vardict)
ac7d03
 
ac7d03
-    def __get_ds_cert(self):
ac7d03
-        nssdb_dir = config_dirname(self.serverid)
ac7d03
-        db = certs.CertDB(
ac7d03
-            self.realm,
ac7d03
-            nssdir=nssdb_dir,
ac7d03
-            subject_base=self.subject_base,
ac7d03
-            ca_subject=self.ca_subject,
ac7d03
-        )
ac7d03
-        db.create_from_cacert()
ac7d03
-        db.request_service_cert(self.nickname, self.principal, self.fqdn)
ac7d03
-        db.create_pin_file()
ac7d03
-
ac7d03
-        # Connect to self over ldapi as Directory Manager and configure SSL
ac7d03
-        ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=self.realm)
ac7d03
-        conn = ipaldap.LDAPClient(ldap_uri)
ac7d03
-        conn.external_bind()
ac7d03
-
ac7d03
-        mod = [(ldap.MOD_REPLACE, "nsSSLClientAuth", "allowed"),
ac7d03
-               (ldap.MOD_REPLACE, "nsSSL3Ciphers", "default"),
ac7d03
-               (ldap.MOD_REPLACE, "allowWeakCipher", "off")]
ac7d03
-        conn.modify_s(DN(('cn', 'encryption'), ('cn', 'config')), mod)
ac7d03
-
ac7d03
-        mod = [(ldap.MOD_ADD, "nsslapd-security", "on")]
ac7d03
-        conn.modify_s(DN(('cn', 'config')), mod)
ac7d03
-
ac7d03
-        entry = conn.make_entry(
ac7d03
-            DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')),
ac7d03
-            objectclass=["top", "nsEncryptionModule"],
ac7d03
-            cn=["RSA"],
ac7d03
-            nsSSLPersonalitySSL=[self.nickname],
ac7d03
-            nsSSLToken=["internal (software)"],
ac7d03
-            nsSSLActivation=["on"],
ac7d03
-        )
ac7d03
-        conn.add_entry(entry)
ac7d03
-
ac7d03
-        conn.unbind()
ac7d03
-
ac7d03
-        # check for open secure port 636 from now on
ac7d03
-        self.open_ports.append(636)
ac7d03
-
ac7d03
 
ac7d03
 def write_certmap_conf(realm, ca_subject):
ac7d03
     """(Re)write certmap.conf with given CA subject DN."""
ac7d03
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
ac7d03
index d7cd776ab9831b5408797ae41b7c7fbb10707b18..45bf479d1088c3b3396d955bf2592c4bce1e886f 100644
ac7d03
--- a/ipaserver/install/httpinstance.py
ac7d03
+++ b/ipaserver/install/httpinstance.py
ac7d03
@@ -376,12 +376,12 @@ class HTTPInstance(service.Service):
ac7d03
         return False
ac7d03
 
ac7d03
     def __setup_ssl(self):
ac7d03
-        truncate = not self.promote or not self.ca_is_configured
ac7d03
         db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
ac7d03
                           subject_base=self.subject_base, user="root",
ac7d03
                           group=constants.HTTPD_GROUP,
ac7d03
-                          truncate=truncate)
ac7d03
+                          truncate=True)
ac7d03
         self.disable_system_trust()
ac7d03
+        self.create_password_conf()
ac7d03
         if self.pkcs12_info:
ac7d03
             if self.ca_is_configured:
ac7d03
                 trust_flags = 'CT,C,C'
ac7d03
@@ -394,8 +394,6 @@ class HTTPInstance(service.Service):
ac7d03
             if len(server_certs) == 0:
ac7d03
                 raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0])
ac7d03
 
ac7d03
-            self.create_password_conf()
ac7d03
-
ac7d03
             # We only handle one server cert
ac7d03
             nickname = server_certs[0][0]
ac7d03
             if nickname == 'ipaCert':
ac7d03
@@ -410,7 +408,6 @@ class HTTPInstance(service.Service):
ac7d03
 
ac7d03
         else:
ac7d03
             if not self.promote:
ac7d03
-                self.create_password_conf()
ac7d03
                 ca_args = [
ac7d03
                     paths.CERTMONGER_DOGTAG_SUBMIT,
ac7d03
                     '--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
ac7d03
@@ -421,23 +418,26 @@ class HTTPInstance(service.Service):
ac7d03
                 ]
ac7d03
                 helper = " ".join(ca_args)
ac7d03
                 prev_helper = certmonger.modify_ca_helper('IPA', helper)
ac7d03
-
ac7d03
-                try:
ac7d03
-                    certmonger.request_and_wait_for_cert(
ac7d03
-                        certpath=db.secdir,
ac7d03
-                        nickname=self.cert_nickname,
ac7d03
-                        principal=self.principal,
ac7d03
-                        passwd_fname=db.passwd_fname,
ac7d03
-                        subject=str(DN(('CN', self.fqdn), self.subject_base)),
ac7d03
-                        ca='IPA',
ac7d03
-                        profile=dogtag.DEFAULT_PROFILE,
ac7d03
-                        dns=[self.fqdn],
ac7d03
-                        post_command='restart_httpd')
ac7d03
-                    self.dercert = db.get_cert_from_db(
ac7d03
-                        self.cert_nickname, pem=False)
ac7d03
-                finally:
ac7d03
+            else:
ac7d03
+                prev_helper = None
ac7d03
+            try:
ac7d03
+                certmonger.request_and_wait_for_cert(
ac7d03
+                    certpath=db.secdir,
ac7d03
+                    nickname=self.cert_nickname,
ac7d03
+                    principal=self.principal,
ac7d03
+                    passwd_fname=db.passwd_fname,
ac7d03
+                    subject=str(DN(('CN', self.fqdn), self.subject_base)),
ac7d03
+                    ca='IPA',
ac7d03
+                    profile=dogtag.DEFAULT_PROFILE,
ac7d03
+                    dns=[self.fqdn],
ac7d03
+                    post_command='restart_httpd')
ac7d03
+            finally:
ac7d03
+                if prev_helper is not None:
ac7d03
                     certmonger.modify_ca_helper('IPA', prev_helper)
ac7d03
 
ac7d03
+            self.dercert = db.get_cert_from_db(self.cert_nickname, pem=False)
ac7d03
+
ac7d03
+            if prev_helper is not None:
ac7d03
                 self.add_cert_to_service()
ac7d03
 
ac7d03
             # Verify we have a valid server cert
ac7d03
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
ac7d03
index d7eb0bfacd0815026c82f59d76962f527e2b7dad..f8e64ec26e85bbc6218018eec8f403a0567b45a2 100644
ac7d03
--- a/ipaserver/install/server/install.py
ac7d03
+++ b/ipaserver/install/server/install.py
ac7d03
@@ -807,10 +807,6 @@ def install(installer):
ac7d03
     if setup_ca:
ac7d03
         ca.install_step_1(False, None, options)
ac7d03
 
ac7d03
-    # The DS instance is created before the keytab, add the SSL cert we
ac7d03
-    # generated
ac7d03
-    ds.add_cert_to_service()
ac7d03
-
ac7d03
     otpd = otpdinstance.OtpdInstance()
ac7d03
     otpd.create_instance('OTPD', host_name,
ac7d03
                          ipautil.realm_to_suffix(realm_name))
ac7d03
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
ac7d03
index f489e691999fd9d6e82879341922510e56eac47d..cd6a62f9540f4a46da70e0cc5686eff5f54e7dfe 100644
ac7d03
--- a/ipaserver/install/server/replicainstall.py
ac7d03
+++ b/ipaserver/install/server/replicainstall.py
ac7d03
@@ -27,7 +27,6 @@ from ipapython.dn import DN
ac7d03
 from ipapython.ipa_log_manager import root_logger
ac7d03
 from ipapython.admintool import ScriptError
ac7d03
 from ipaplatform import services
ac7d03
-from ipaplatform.constants import constants as pconstants
ac7d03
 from ipaplatform.tasks import tasks
ac7d03
 from ipaplatform.paths import paths
ac7d03
 from ipalib import api, constants, create_api, errors, rpc, x509
ac7d03
@@ -77,18 +76,6 @@ def make_pkcs12_info(directory, cert_name, password_name):
ac7d03
         return None
ac7d03
 
ac7d03
 
ac7d03
-def install_http_certs(host_name, realm_name, subject_base):
ac7d03
-    principal = 'HTTP/%s@%s' % (host_name, realm_name)
ac7d03
-    subject = subject_base or DN(('O', realm_name))
ac7d03
-    db = certs.CertDB(realm_name, nssdir=paths.HTTPD_ALIAS_DIR,
ac7d03
-                      subject_base=subject, user="root",
ac7d03
-                      group=pconstants.HTTPD_GROUP, truncate=True)
ac7d03
-    db.request_service_cert('Server-Cert', principal, host_name)
ac7d03
-    # Obtain certificate for the HTTP service
ac7d03
-    http = httpinstance.HTTPInstance()
ac7d03
-    http.create_password_conf()
ac7d03
-
ac7d03
-
ac7d03
 def install_replica_ds(config, options, ca_is_configured, remote_api,
ac7d03
                        ca_file, promote=False, pkcs12_info=None):
ac7d03
     dsinstance.check_ports()
ac7d03
@@ -175,7 +162,8 @@ def install_http(config, auto_redirect, ca_is_configured, ca_file,
ac7d03
     http.create_instance(
ac7d03
         config.realm_name, config.host_name, config.domain_name,
ac7d03
         pkcs12_info, auto_redirect=auto_redirect, ca_file=ca_file,
ac7d03
-        ca_is_configured=ca_is_configured, promote=promote)
ac7d03
+        ca_is_configured=ca_is_configured, promote=promote,
ac7d03
+        subject_base=config.subject_base)
ac7d03
 
ac7d03
     return http
ac7d03
 
ac7d03
@@ -1414,12 +1402,6 @@ def install(installer):
ac7d03
         # Always try to install DNS records
ac7d03
         install_dns_records(config, options, remote_api)
ac7d03
 
ac7d03
-        if promote and ca_enabled:
ac7d03
-            # we need to install http certs to setup ssl for httpd
ac7d03
-            install_http_certs(config.host_name,
ac7d03
-                               config.realm_name,
ac7d03
-                               config.subject_base)
ac7d03
-
ac7d03
         ntpinstance.ntp_ldap_enable(config.host_name, ds.suffix,
ac7d03
                                     remote_api.env.realm)
ac7d03
     finally:
ac7d03
-- 
ac7d03
2.9.3
ac7d03