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