diff options
| author | Jan Cholasta <jcholast@redhat.com> | 2016-10-24 14:33:19 +0200 |
|---|---|---|
| committer | Jan Cholasta <jcholast@redhat.com> | 2016-11-11 12:13:56 +0100 |
| commit | dc38d53de1eff71570ec5ef55db6de2c6f9b5bbd (patch) | |
| tree | 0b0dc0fe40e9049986e6d2170d645f029e1bc442 | |
| parent | 0e232b5f526168af6bb0b52244f79dfacb43a9b7 (diff) | |
| download | freeipa-dc38d53de1eff71570ec5ef55db6de2c6f9b5bbd.tar.gz freeipa-dc38d53de1eff71570ec5ef55db6de2c6f9b5bbd.tar.xz freeipa-dc38d53de1eff71570ec5ef55db6de2c6f9b5bbd.zip | |
install: merge all CA install code paths into one
Merge CA install code paths use in ipa-server-install, ipa-replica-install
in either domain level and ipa-ca-install into one.
https://fedorahosted.org/freeipa/ticket/6392
Reviewed-By: Stanislav Laznicka <slaznick@redhat.com>
| -rwxr-xr-x | install/tools/ipa-ca-install | 26 | ||||
| -rw-r--r-- | ipaserver/install/ca.py | 127 | ||||
| -rw-r--r-- | ipaserver/install/cainstance.py | 203 | ||||
| -rw-r--r-- | ipaserver/install/server/replicainstall.py | 18 |
4 files changed, 111 insertions, 263 deletions
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install index aaacf447d..043ab322b 100755 --- a/install/tools/ipa-ca-install +++ b/install/tools/ipa-ca-install @@ -25,11 +25,10 @@ import tempfile from ipapython import ipautil from ipaserver.install import installutils -from ipaserver.install import certs from ipaserver.install.installutils import create_replica_config from ipaserver.install.installutils import check_creds, ReplicaConfig -from ipaserver.install import bindinstance, dsinstance, ca -from ipaserver.install import cainstance, custodiainstance, service +from ipaserver.install import dsinstance, ca +from ipaserver.install import cainstance, service from ipapython import version from ipalib import api from ipalib.constants import DOMAIN_LEVEL_0 @@ -175,26 +174,7 @@ def install_replica(safe_options, options, filename): options.ca_cert_file = None ca.install_check(True, config, options) - if options.promote: - ca_data = (os.path.join(config.dir, 'cacert.p12'), - config.dirman_password) - custodia = custodiainstance.CustodiaInstance(config.host_name, - config.realm_name) - custodia.get_ca_keys(config.ca_host_name, ca_data[0], ca_data[1]) - - CA = cainstance.CAInstance(config.realm_name, certs.NSS_DIR, - host_name=config.host_name) - CA.configure_replica(config.ca_host_name, - config.dirman_password, - subject_base=config.subject_base, - ca_cert_bundle=ca_data) - # Install CA DNS records - if bindinstance.dns_container_exists(api.env.host, api.env.basedn, - ldapi=True, realm=api.env.realm): - bind = bindinstance.BindInstance() - bind.update_system_records() - else: - ca.install(True, config, options) + ca.install(True, config, options) def install_master(safe_options, options): diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py index cd594c21d..50c27e944 100644 --- a/ipaserver/install/ca.py +++ b/ipaserver/install/ca.py @@ -4,7 +4,9 @@ from __future__ import print_function -from ipaserver.install import cainstance, dsinstance, bindinstance +import os.path + +from ipaserver.install import cainstance, custodiainstance, dsinstance, bindinstance from ipapython import ipautil, certdb from ipapython.admintool import ScriptError from ipaplatform import services @@ -31,8 +33,8 @@ def install_check(standalone, replica_config, options): if standalone and api.env.ra_plugin == 'selfsign': raise ScriptError('A selfsign CA can not be added') - if ((not options.promote - and not ipautil.file_exists(replica_config.dir + "/cacert.p12"))): + cafile = os.path.join(replica_config.dir, 'cacert.p12') + if not options.promote and not ipautil.file_exists(cafile): raise ScriptError('CA cannot be installed in CA-less setup.') if standalone and not options.skip_conncheck: @@ -42,10 +44,10 @@ def install_check(standalone, replica_config, options): replica_config.ca_ds_port, options.admin_password, principal=principal, ca_cert_file=options.ca_cert_file) - if options.skip_schema_check or options.promote: + if options.skip_schema_check: root_logger.info("Skipping CA DS schema check") else: - cainstance.replica_ca_install_check(replica_config) + cainstance.replica_ca_install_check(replica_config, options.promote) return @@ -119,40 +121,70 @@ def install_step_0(standalone, replica_config, options): realm_name = options.realm_name dm_password = options.dm_password host_name = options.host_name - subject_base = options.subject - if replica_config is not None: - # Configure the CA if necessary - cainstance.install_replica_ca(replica_config, standalone, - ra_p12=getattr(options, 'ra_p12', None)) - return + if replica_config is None: + subject_base = options.subject - if options.external_cert_files: - external = 2 - elif options.external_ca: - external = 1 + ca_signing_algorithm = options.ca_signing_algorithm + if options.external_ca: + ca_type = options.external_ca_type + csr_file = paths.ROOT_IPA_CSR + else: + ca_type = None + csr_file = None + if options.external_cert_files: + cert_file = external_cert_file.name + cert_chain_file = external_ca_file.name + else: + cert_file = None + cert_chain_file = None + + pkcs12_info = None + master_host = None + master_replication_port = None + ra_p12 = None + promote = False else: - external = 0 - - ca = cainstance.CAInstance(realm_name, certs.NSS_DIR) - if standalone: + cafile = os.path.join(replica_config.dir, 'cacert.p12') + if options.promote: + custodia = custodiainstance.CustodiaInstance( + replica_config.host_name, + replica_config.realm_name) + custodia.get_ca_keys( + replica_config.ca_host_name, + cafile, + replica_config.dirman_password) + + subject_base = replica_config.subject_base + + ca_signing_algorithm = None + ca_type = None + csr_file = None + cert_file = None + cert_chain_file = None + + pkcs12_info = (cafile,) + master_host = replica_config.ca_host_name + master_replication_port = replica_config.ca_ds_port + ra_p12 = os.path.join(replica_config.dir, 'ra.p12') + promote = options.promote + + ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, + host_name=host_name) + if standalone or replica_config is not None: ca.create_ra_agent_db = False - if external == 0: - ca.configure_instance(host_name, dm_password, - dm_password, subject_base=subject_base, - ca_signing_algorithm=options.ca_signing_algorithm) - elif external == 1: - ca.configure_instance(host_name, dm_password, - dm_password, csr_file=paths.ROOT_IPA_CSR, - subject_base=subject_base, - ca_signing_algorithm=options.ca_signing_algorithm, - ca_type=options.external_ca_type) - else: - ca.configure_instance(host_name, dm_password, dm_password, - cert_file=external_cert_file.name, - cert_chain_file=external_ca_file.name, - subject_base=subject_base, - ca_signing_algorithm=options.ca_signing_algorithm) + ca.configure_instance(host_name, dm_password, dm_password, + subject_base=subject_base, + ca_signing_algorithm=ca_signing_algorithm, + ca_type=ca_type, + csr_file=csr_file, + cert_file=cert_file, + cert_chain_file=cert_chain_file, + pkcs12_info=pkcs12_info, + master_host=master_host, + master_replication_port=master_replication_port, + ra_p12=ra_p12, + promote=promote) def install_step_1(standalone, replica_config, options): @@ -165,15 +197,7 @@ def install_step_1(standalone, replica_config, options): ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, host_name=host_name) - if standalone: - ca.stop('pki-tomcat') - - # We need to ldap_enable the CA now that DS is up and running - if replica_config is None: - config = ['caRenewalMaster'] - else: - config = [] - ca.ldap_enable('CA', host_name, dm_password, basedn, config) + ca.stop('pki-tomcat') # This is done within stopped_service context, which restarts CA ca.enable_client_auth_to_db(paths.CA_CS_CFG_PATH) @@ -185,8 +209,9 @@ def install_step_1(standalone, replica_config, options): # ca.setup_lightweight_ca_key_retrieval() + serverid = installutils.realm_to_serverid(realm_name) + if standalone and replica_config is None: - serverid = installutils.realm_to_serverid(realm_name) dirname = dsinstance.config_dirname(serverid) # Store the new IPA CA cert chain in DS NSS database and LDAP @@ -207,8 +232,6 @@ def install_step_1(standalone, replica_config, options): cert, nickname, trust_flags[nickname], config_ipa=True, config_compat=True) - installutils.restart_dirsrv() - # Store DS CA cert in Dogtag NSS database dogtagdb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR) trust_flags = dict(reversed(dsdb.list_certs())) @@ -218,12 +241,14 @@ def install_step_1(standalone, replica_config, options): cert = dsdb.get_cert_from_db(nickname) dogtagdb.add_cert(cert, nickname, trust_flags[nickname]) - if standalone: - ca.start('pki-tomcat') + installutils.restart_dirsrv() - # We need to restart apache as we drop a new config file in there - services.knownservices.httpd.restart(capture_output=True) + ca.start('pki-tomcat') + # We need to restart apache as we drop a new config file in there + services.knownservices.httpd.restart(capture_output=True) + + if standalone: # Install CA DNS records if bindinstance.dns_container_exists(host_name, basedn, dm_password): bind = bindinstance.BindInstance() diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index d7dffbe0e..be5adb553 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -57,7 +57,6 @@ from ipapython.certdb import get_ca_nickname from ipapython.dn import DN from ipapython.ipa_log_manager import log_mgr,\ standard_logging_setup, root_logger -from ipapython.admintool import ScriptError from ipapython.secrets.kem import IPAKEMKeys from ipaserver.install import certs @@ -65,7 +64,6 @@ from ipaserver.install import dsinstance from ipaserver.install import installutils from ipaserver.install import ldapupdate from ipaserver.install import replication -from ipaserver.install import service from ipaserver.install import sysupgrade from ipaserver.install.dogtaginstance import (export_kra_agent_pem, DogtagInstance) @@ -332,7 +330,7 @@ class CAInstance(DogtagInstance): cert_file=None, cert_chain_file=None, master_replication_port=None, subject_base=None, ca_signing_algorithm=None, - ca_type=None, ra_p12=None): + ca_type=None, ra_p12=None, promote=False): """Create a CA instance. To create a clone, pass in pkcs12_info. @@ -345,6 +343,7 @@ class CAInstance(DogtagInstance): self.fqdn = host_name self.dm_password = dm_password self.admin_user = "admin" + self.admin_groups = ADMIN_GROUPS self.admin_password = admin_password self.pkcs12_info = pkcs12_info if self.pkcs12_info is not None: @@ -363,6 +362,7 @@ class CAInstance(DogtagInstance): self.ca_type = ca_type else: self.ca_type = 'generic' + self.no_db_setup = promote # Determine if we are installing as an externally-signed CA and # what stage we're in. @@ -375,6 +375,11 @@ class CAInstance(DogtagInstance): self.external = 2 self.step("creating certificate server user", create_ca_user) + if promote: + # Setup Database + self.step("creating certificate server db", self.__create_ds_db) + self.step("setting up initial replication", self.__setup_replication) + self.step("creating installation admin user", self.setup_admin) self.step("configuring certificate server instance", self.__spawn_instance) self.step("stopping certificate server instance to update CS.cfg", self.stop_instance) @@ -382,6 +387,8 @@ class CAInstance(DogtagInstance): self.step("disabling nonces", self.__disable_nonce) self.step("set up CRL publishing", self.__enable_crl_publish) self.step("enable PKIX certificate path discovery and validation", self.enable_pkix) + if promote: + self.step("destroying installation admin user", self.teardown_admin) self.step("starting certificate server instance", self.start_instance) # Step 1 of external is getting a CSR so we don't need to do these # steps until we get a cert back from the external CA. @@ -397,7 +404,7 @@ class CAInstance(DogtagInstance): self.step("exporting RA agent certificate", lambda: export_kra_agent_pem()) self.step("adding RA agent as a trusted user", self.__create_ca_agent) - elif ra_p12 is not None: + elif not promote and ra_p12 is not None: self.step("importing RA certificate from PKCS #12 file", lambda: self.import_ra_cert(ra_p12, configure_renewal=False)) self.step("authorizing RA to modify profiles", configure_profiles_acl) @@ -410,14 +417,20 @@ class CAInstance(DogtagInstance): self.step("Configure HTTP to proxy connections", self.http_proxy) self.step("restarting certificate server", self.restart_instance) - self.step("migrating certificate profiles to LDAP", - migrate_profiles_to_ldap) - self.step("importing IPA certificate profiles", - import_included_profiles) - self.step("adding default CA ACL", ensure_default_caacl) - self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry) + if not promote: + self.step("migrating certificate profiles to LDAP", + migrate_profiles_to_ldap) + self.step("importing IPA certificate profiles", + import_included_profiles) + self.step("adding default CA ACL", ensure_default_caacl) + self.step("adding 'ipa' CA entry", ensure_ipa_authority_entry) self.step("updating IPA configuration", update_ipa_conf) + self.step("enabling CA instance", self.__enable_instance) + + self.step("configuring certmonger renewal for lightweight CAs", + self.__add_lightweight_ca_tracking_requests) + self.start_creation(runtime=210) def __spawn_instance(self): @@ -1170,94 +1183,13 @@ class CAInstance(DogtagInstance): # Activate Topology for o=ipaca segments self.__update_topology() - def __client_auth_to_db(self): - self.enable_client_auth_to_db(paths.CA_CS_CFG_PATH) - - def __restart_http_instance(self): - # We need to restart apache as we drop a new config file in there - services.knownservices.httpd.restart(capture_output=True) - def __enable_instance(self): basedn = ipautil.realm_to_suffix(self.realm) - self.ldap_enable('CA', self.fqdn, None, basedn) - - def configure_replica(self, master_host, dm_password, subject_base=None, - ca_cert_bundle=None, ca_signing_algorithm=None, - ca_type=None): - """Creates a replica CA, creating a local DS backend and using - the topology plugin to manage replication. - Requires domain_level >= DOMAIN_LEVEL_1 and custodia on the master. - """ - self.master_host = master_host - self.dm_password = dm_password - self.master_replication_port = 389 - if subject_base is None: - self.subject_base = DN(('O', self.realm)) - else: - self.subject_base = subject_base - if ca_signing_algorithm is None: - self.ca_signing_algorithm = 'SHA256withRSA' - else: - self.ca_signing_algorithm = ca_signing_algorithm - if ca_type is not None: - self.ca_type = ca_type + if not self.clone: + config = ['caRenewalMaster'] else: - self.ca_type = 'generic' - - self.admin_groups = ADMIN_GROUPS - self.pkcs12_info = ca_cert_bundle - self.no_db_setup = True - self.clone = True - - # TODO: deal with "Externally signed CA setups" - - # Set up steps - self.step("creating certificate server user", create_ca_user) - - # Setup Database - self.step("creating certificate server db", self.__create_ds_db) - self.step("setting up initial replication", self.__setup_replication) - - self.step("creating installation admin user", self.setup_admin) - - # Setup instance - self.step("setting up certificate server", self.__spawn_instance) - self.step("stopping instance to update CS.cfg", self.stop_instance) - self.step("backing up CS.cfg", self.backup_config) - self.step("disabling nonces", self.__disable_nonce) - self.step("set up CRL publishing", self.__enable_crl_publish) - self.step("enable PKIX certificate path discovery and validation", - self.enable_pkix) - self.step("set up client auth to db", self.__client_auth_to_db) - self.step("destroying installation admin user", self.teardown_admin) - self.step("Ensure lightweight CAs container exists", - ensure_lightweight_cas_container) - self.step("Configure lightweight CA key retrieval", - self.setup_lightweight_ca_key_retrieval) - self.step("starting instance", self.start_instance) - - self.step("importing CA chain to RA certificate database", - self.__import_ca_chain) - self.step("setting up signing cert profile", self.__setup_sign_profile) - self.step("setting audit signing renewal to 2 years", - self.set_audit_renewal) - - self.step("configure certificate renewals", - self.configure_renewal) - self.step("configure Server-Cert certificate renewal", - self.track_servercert) - self.step("Configure HTTP to proxy connections", - self.http_proxy) - self.step("updating IPA configuration", update_ipa_conf) - self.step("Restart HTTP server to pick up changes", - self.__restart_http_instance) - - self.step("enabling CA instance", self.__enable_instance) - - self.step("configuring certmonger renewal for lightweight CAs", - self.__add_lightweight_ca_tracking_requests) - - self.start_creation(runtime=210) + config = [] + self.ldap_enable('CA', self.fqdn, None, basedn, config) def setup_lightweight_ca_key_retrieval(self): if sysupgrade.get_upgrade_state('dogtag', 'setup_lwca_key_retrieval'): @@ -1334,18 +1266,8 @@ class CAInstance(DogtagInstance): "Did not find any lightweight CAs; nothing to track") -def replica_ca_install_check(config): - if not config.setup_ca: - return - - cafile = config.dir + "/cacert.p12" - if not ipautil.file_exists(cafile): - # Replica of old "self-signed" master - CA won't be installed - return - - if config.ca_ds_port != 7389: - root_logger.debug( - 'Installing CA Replica from master with a merged database') +def replica_ca_install_check(config, promote): + if promote: return # Check if the master has the necessary schema in its CA instance @@ -1381,73 +1303,6 @@ def replica_ca_install_check(config): exit('IPA schema missing on master CA directory server') -def install_replica_ca(config, postinstall=False, ra_p12=None): - """ - Install a CA on a replica. - - There are two modes of doing this controlled: - - While the replica is being installed - - Post-replica installation - - config is a ReplicaConfig object - - Returns a tuple of the CA and CADS instances - """ - cafile = config.dir + "/cacert.p12" - - if not ipautil.file_exists(cafile): - # Replica of old "self-signed" master - skip installing CA - return None - - ca = CAInstance(config.realm_name, certs.NSS_DIR) - ca.dm_password = config.dirman_password - ca.subject_base = config.subject_base - - if not config.setup_ca: - # We aren't configuring the CA in this step but we still need - # a minimum amount of information on the CA for this IPA install. - return ca - - if ca.is_installed(): - raise ScriptError("A CA is already configured on this system.") - - if postinstall: - # If installing this afterward the Apache NSS database already - # exists, don't remove it. - ca.create_ra_agent_db = False - ca.configure_instance(config.host_name, - config.dirman_password, config.dirman_password, - pkcs12_info=(cafile,), ra_p12=ra_p12, - master_host=config.ca_host_name, - master_replication_port=config.ca_ds_port, - subject_base=config.subject_base) - - # Restart httpd since we changed it's config and added ipa-pki-proxy.conf - # Without the restart, CA service status check would fail due to missing - # proxy - if postinstall: - services.knownservices.httpd.restart() - - - # The dogtag DS instance needs to be restarted after installation. - # The procedure for this is: stop dogtag, stop DS, start DS, start - # dogtag - # - # - # The service_name trickery is due to the service naming we do - # internally. In the case of the dogtag DS the name doesn't match the - # unix service. - - service.print_msg("Restarting the directory and certificate servers") - ca.stop('pki-tomcat') - - installutils.restart_dirsrv() - - ca.start('pki-tomcat') - - return ca - - def backup_config(): """ Create a backup copy of CS.cfg diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 05718a515..86bf30c67 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -820,10 +820,6 @@ def install(installer): options.realm_name = config.realm_name options.domain_name = config.domain_name options.host_name = config.host_name - - if ca_enabled: - options.ra_p12 = config.dir + "/ra.p12" - ca.install_step_0(False, config, options) krb = install_krb(config, setup_pkinit=not options.no_pkinit) @@ -1043,6 +1039,7 @@ def promote_check(installer): config.master_host_name = api.env.server config.ca_host_name = api.env.ca_host config.kra_host_name = config.ca_host_name + config.ca_ds_port = 389 config.setup_ca = options.setup_ca config.setup_kra = options.setup_kra config.dir = installer._top_dir @@ -1295,7 +1292,7 @@ def promote_check(installer): options.realm_name = config.realm_name options.host_name = config.host_name options.subject = config.subject_base - ca.install_check(False, None, options) + ca.install_check(False, config, options) if config.setup_kra: try: @@ -1510,16 +1507,7 @@ def promote(installer): options.domain_name = config.domain_name options.host_name = config.host_name options.dm_password = config.dirman_password - ca_data = (os.path.join(config.dir, 'cacert.p12'), - config.dirman_password) - custodia.get_ca_keys(config.ca_host_name, ca_data[0], ca_data[1]) - - ca = cainstance.CAInstance(config.realm_name, certs.NSS_DIR, - host_name=config.host_name) - ca.configure_replica(config.ca_host_name, - config.dirman_password, - subject_base=config.subject_base, - ca_cert_bundle=ca_data) + ca.install(False, config, options) if options.setup_kra: ca_data = (os.path.join(config.dir, 'kracert.p12'), |
