summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2016-10-24 14:33:19 +0200
committerJan Cholasta <jcholast@redhat.com>2016-11-11 12:13:56 +0100
commitdc38d53de1eff71570ec5ef55db6de2c6f9b5bbd (patch)
tree0b0dc0fe40e9049986e6d2170d645f029e1bc442
parent0e232b5f526168af6bb0b52244f79dfacb43a9b7 (diff)
downloadfreeipa-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-xinstall/tools/ipa-ca-install26
-rw-r--r--ipaserver/install/ca.py127
-rw-r--r--ipaserver/install/cainstance.py203
-rw-r--r--ipaserver/install/server/replicainstall.py18
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'),