summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorDavid Kupka <dkupka@redhat.com>2015-06-08 05:23:56 +0000
committerJan Cholasta <jcholast@redhat.com>2015-06-08 06:22:54 +0000
commit2acedb2d5d4a4c0987c670e14eb04b8bd9ffc034 (patch)
tree6342b69ba31cbf2ea98a6f676c9224a9682e186b /ipaserver
parenta57998f51eb8b62052fe021a68503eed4714c6d3 (diff)
downloadfreeipa-2acedb2d5d4a4c0987c670e14eb04b8bd9ffc034.tar.gz
freeipa-2acedb2d5d4a4c0987c670e14eb04b8bd9ffc034.tar.xz
freeipa-2acedb2d5d4a4c0987c670e14eb04b8bd9ffc034.zip
Move CA installation code into single module.
https://fedorahosted.org/freeipa/ticket/4468 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/install/ca.py267
-rw-r--r--ipaserver/install/server/install.py101
-rw-r--r--ipaserver/install/server/replicainstall.py53
3 files changed, 303 insertions, 118 deletions
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
new file mode 100644
index 000000000..8a8214c68
--- /dev/null
+++ b/ipaserver/install/ca.py
@@ -0,0 +1,267 @@
+#
+# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
+#
+
+import sys
+import os.path
+
+from ipaserver.install import cainstance, dsinstance, bindinstance
+from ipapython import dogtag, ipautil, certdb
+from ipaplatform import services
+from ipaplatform.paths import paths
+from ipaserver.install import installutils, certs
+from ipaserver.install.replication import replica_conn_check
+from ipalib import api, certstore, x509
+from ConfigParser import RawConfigParser
+from ipapython.dn import DN
+from ipapython.ipa_log_manager import root_logger
+
+
+def install_check(standalone, replica_config, options):
+ global external_cert_file
+ global external_ca_file
+
+ realm_name = options.realm_name
+ host_name = options.host_name
+ subject_base = options.subject
+
+ if replica_config is None and options.external_cert_files:
+ return
+
+ if replica_config is not None:
+ if standalone and api.env.ra_plugin == 'selfsign':
+ sys.exit('A selfsign CA can not be added')
+
+ if not ipautil.file_exists(replica_config.dir + "/cacert.p12"):
+ print 'CA cannot be installed in CA-less setup.'
+ sys.exit(1)
+
+ if standalone and not options.skip_conncheck:
+ replica_conn_check(
+ replica_config.master_host_name, host_name, realm_name, True,
+ replica_config.ca_ds_port, options.admin_password)
+
+ if options.skip_schema_check:
+ root_logger.info("Skipping CA DS schema check")
+ else:
+ cainstance.replica_ca_install_check(replica_config)
+
+ return
+
+ if standalone and api.Command.ca_is_enabled()['result']:
+ sys.exit("CA is already installed.\n")
+
+ if options.external_ca:
+ if cainstance.is_step_one_done():
+ print("CA is already installed.\nRun the installer with "
+ "--external-cert-file.")
+ sys.exit(1)
+ if ipautil.file_exists(paths.ROOT_IPA_CSR):
+ print("CA CSR file %s already exists.\nIn order to continue "
+ "remove the file and run the installer again." %
+ paths.ROOT_IPA_CSR)
+ sys.exit(1)
+ elif options.external_cert_files:
+ if not cainstance.is_step_one_done():
+ # This can happen if someone passes external_ca_file without
+ # already having done the first stage of the CA install.
+ print("CA is not installed yet. To install with an external CA "
+ "is a two-stage process.\nFirst run the installer with "
+ "--external-ca.")
+ sys.exit(1)
+
+ external_cert_file, external_ca_file = installutils.load_external_cert(
+ options.external_cert_files, options.subject)
+
+ if not cainstance.check_port():
+ print ("IPA requires port 8443 for PKI but it is currently in use.")
+ sys.exit("Aborting installation")
+
+ if standalone:
+ dirname = dsinstance.config_dirname(
+ installutils.realm_to_serverid(realm_name))
+ cadb = certs.CertDB(realm_name, subject_base=subject_base)
+ dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base)
+
+ for db in (cadb, dsdb):
+ for nickname, trust_flags in db.list_certs():
+ if nickname in (certdb.get_ca_nickname(realm_name),
+ 'ipaCert',
+ 'Signing-Cert'):
+ print ("Certificate with nickname %s is present in %s, "
+ "cannot continue." % (nickname, db.secdir))
+ sys.exit(1)
+
+ cert = db.get_cert_from_db(nickname)
+ if not cert:
+ continue
+ subject = DN(str(x509.get_subject(cert)))
+ if subject in (DN('CN=Certificate Authority', subject_base),
+ DN('CN=IPA RA', subject_base),
+ DN('CN=Object Signing Cert', subject_base)):
+ print ("Certificate with subject %s is present in %s, "
+ "cannot continue." % (subject, db.secdir))
+ sys.exit(1)
+
+
+def install(standalone, replica_config, options):
+ install_step_0(standalone, replica_config, options)
+ install_step_1(standalone, replica_config, options)
+
+
+def install_step_0(standalone, replica_config, options):
+ realm_name = options.realm_name
+ domain_name = options.domain_name
+ dm_password = options.dm_password
+ host_name = options.host_name
+ subject_base = options.subject
+
+ dogtag_constants = dogtag.install_constants
+
+ if replica_config is not None:
+ # Configure the CA if necessary
+ if standalone:
+ postinstall = True
+ else:
+ postinstall = False
+ ca = cainstance.install_replica_ca(replica_config, postinstall)
+
+ if not standalone:
+ ca.configure_certmonger_renewal()
+ ca.import_ra_cert(replica_config.dir + "/ra.p12")
+ ca.fix_ra_perms()
+
+ return
+
+ if options.external_cert_files:
+ external = 2
+ elif options.external_ca:
+ external = 1
+ else:
+ external = 0
+
+ ca = cainstance.CAInstance(realm_name, certs.NSS_DIR,
+ dogtag_constants=dogtag_constants)
+ if standalone:
+ ca.create_ra_agent_db = False
+ if external == 0:
+ ca.configure_instance(host_name, domain_name, dm_password,
+ dm_password, subject_base=subject_base,
+ ca_signing_algorithm=options.ca_signing_algorithm)
+ elif external == 1:
+ ca.configure_instance(host_name, domain_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, domain_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)
+
+
+def install_step_1(standalone, replica_config, options):
+ realm_name = options.realm_name
+ domain_name = options.domain_name
+ dm_password = options.dm_password
+ host_name = options.host_name
+ subject_base = options.subject
+
+ basedn = ipautil.realm_to_suffix(realm_name)
+
+ dogtag_constants = dogtag.install_constants
+
+ ca = cainstance.CAInstance(realm_name, certs.NSS_DIR,
+ dogtag_constants=dogtag_constants)
+
+ if standalone:
+ ca.stop(ca.dogtag_constants.PKI_INSTANCE_NAME)
+
+ # We need to ldap_enable the CA now that DS is up and running
+ ca.ldap_enable('CA', host_name, dm_password, basedn, ['caRenewalMaster'])
+
+ # This is done within stopped_service context, which restarts CA
+ ca.enable_client_auth_to_db(dogtag_constants.CS_CFG_PATH)
+
+ 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
+ cadb = certs.CertDB(realm_name, subject_base=subject_base)
+ dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base)
+ trust_flags = dict(reversed(cadb.list_certs()))
+ trust_chain = cadb.find_root_cert('ipaCert')[:-1]
+ for nickname in trust_chain[:-1]:
+ cert = cadb.get_cert_from_db(nickname, pem=False)
+ dsdb.add_cert(cert, nickname, trust_flags[nickname])
+ certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
+ cert, nickname, trust_flags[nickname])
+
+ nickname = trust_chain[-1]
+ cert = cadb.get_cert_from_db(nickname, pem=False)
+ dsdb.add_cert(cert, nickname, trust_flags[nickname])
+ certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
+ cert, nickname, trust_flags[nickname],
+ config_ipa=True, config_compat=True)
+
+
+ api.Backend.ldap2.disconnect()
+
+ # Restart DS
+ services.knownservices.dirsrv.restart(serverid)
+
+ api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
+ bind_pw=dm_password)
+
+ # Store DS CA cert in Dogtag NSS database
+ dogtagdb = certs.CertDB(realm_name, nssdir=dogtag_constants.ALIAS_DIR)
+ trust_flags = dict(reversed(dsdb.list_certs()))
+ server_certs = dsdb.find_server_certs()
+ trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
+ nickname = trust_chain[-1]
+ cert = dsdb.get_cert_from_db(nickname)
+ dogtagdb.add_cert(cert, nickname, trust_flags[nickname])
+
+ if standalone:
+ ca.start(ca.dogtag_constants.PKI_INSTANCE_NAME)
+
+ # Update config file
+ try:
+ parser = RawConfigParser()
+ parser.read(paths.IPA_DEFAULT_CONF)
+ parser.set('global', 'enable_ra', 'True')
+ parser.set('global', 'ra_plugin', 'dogtag')
+ parser.set('global', 'dogtag_version',
+ str(dogtag_constants.DOGTAG_VERSION))
+ with open(paths.IPA_DEFAULT_CONF, 'w') as f:
+ parser.write(f)
+ except IOError, e:
+ print "Failed to update /etc/ipa/default.conf"
+ root_logger.error(str(e))
+ sys.exit(1)
+
+ # We need to restart apache as we drop a new config file in there
+ services.knownservices.httpd.restart(capture_output=True)
+
+ # Install CA DNS records
+ if bindinstance.dns_container_exists(host_name, basedn, dm_password):
+ bind = bindinstance.BindInstance(dm_password=dm_password)
+ bind.add_ipa_ca_dns_records(host_name, domain_name)
+
+
+def uninstall(dogtag_constants):
+ if not dogtag_constants.SHARED_DB:
+ cads_instance = cainstance.CADSInstance(
+ dogtag_constants=dogtag_constants)
+ if cads_instance.is_configured():
+ cads_instance.uninstall()
+
+ ca_instance = cainstance.CAInstance(
+ api.env.realm, certs.NSS_DIR, dogtag_constants=dogtag_constants)
+ ca_instance.stop_tracking_certificates()
+ if ca_instance.is_configured():
+ ca_instance.uninstall()
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 999766d67..5be10f54a 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -23,12 +23,12 @@ from ipalib.constants import CACERT
from ipalib.util import validate_domain_name
import ipaclient.ntpconf
from ipaserver.install import (
- bindinstance, cainstance, certs, dns, dsinstance, httpinstance,
+ bindinstance, ca, cainstance, certs, dns, dsinstance, httpinstance,
installutils, kra, krbinstance, memcacheinstance, ntpinstance,
otpdinstance, replication, service, sysupgrade)
from ipaserver.install.installutils import (
IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address,
- is_ipa_configured, load_external_cert, load_pkcs12, private_ccache,
+ is_ipa_configured, load_pkcs12, private_ccache,
read_password, verify_fqdn)
from ipaserver.plugins.ldap2 import ldap2
try:
@@ -360,25 +360,6 @@ def install_check(options):
global sstore
sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH)
- if options.external_ca:
- if cainstance.is_step_one_done():
- print("CA is already installed.\nRun the installer with "
- "--external-cert-file.")
- sys.exit(1)
- if ipautil.file_exists(paths.ROOT_IPA_CSR):
- print("CA CSR file %s already exists.\nIn order to continue "
- "remove the file and run the installer again." %
- paths.ROOT_IPA_CSR)
- sys.exit(1)
- elif options.external_cert_files:
- if not cainstance.is_step_one_done():
- # This can happen if someone passes external_ca_file without
- # already having done the first stage of the CA install.
- print("CA is not installed yet. To install with an external CA "
- "is a two-stage process.\nFirst run the installer with "
- "--external-ca.")
- sys.exit(1)
-
# This will override any settings passed in on the cmdline
if ipautil.file_exists(paths.ROOT_IPA_CACHE):
if options.dm_password is not None:
@@ -392,10 +373,6 @@ def install_check(options):
except Exception, e:
sys.exit("Cannot process the cache file: %s" % str(e))
- if options.external_cert_files:
- external_cert_file, external_ca_file = load_external_cert(
- options.external_cert_files, options.subject)
-
# We only set up the CA if the PKCS#12 options are not given.
if options.dirsrv_cert_files:
setup_ca = False
@@ -442,11 +419,7 @@ def install_check(options):
# Make sure the 389-ds ports are available
check_dirsrv(options.unattended)
- if setup_ca:
- if not cainstance.check_port():
- print("IPA requires port 8443 for PKI but it is currently in "
- "use.")
- sys.exit("Aborting installation")
+ ca.install_check(False, None, options)
if options.conf_ntp:
try:
@@ -684,6 +657,8 @@ def install(options):
global ds
global installation_cleanup
+ dogtag_constants = dogtag.install_constants
+
# Installation has started. No IPA sysrestore items are restored in case of
# failure to enable root cause investigation
installation_cleanup = False
@@ -696,15 +671,6 @@ def install(options):
debug=options.debug
)
- # Figure out what external CA step we're in. See cainstance.py for more
- # info on the 3 states.
- if options.external_cert_files:
- external = 2
- elif options.external_ca:
- external = 1
- else:
- external = 0
-
# Create the management framework config file and finalize api
target_fname = paths.IPA_DEFAULT_CONF
fd = open(target_fname, "w")
@@ -719,8 +685,7 @@ def install(options):
if setup_ca:
fd.write("enable_ra=True\n")
fd.write("ra_plugin=dogtag\n")
- fd.write("dogtag_version=%s\n" %
- dogtag.install_constants.DOGTAG_VERSION)
+ fd.write("dogtag_version=%s\n" % dogtag_constants.DOGTAG_VERSION)
else:
fd.write("enable_ra=False\n")
fd.write("ra_plugin=none\n")
@@ -757,7 +722,7 @@ def install(options):
dsinstance.create_ds_user()
# Create a directory server instance
- if external != 2:
+ if not options.external_cert_files:
# Configure ntpd
if options.conf_ntp:
ipaclient.ntpconf.force_ntpd(sstore)
@@ -789,14 +754,7 @@ def install(options):
options.subject, 1101, 1100, None)
if setup_ca:
- ca = cainstance.CAInstance(realm_name, certs.NSS_DIR,
- dogtag_constants=dogtag.install_constants)
- if external == 0:
- ca.configure_instance(
- host_name, domain_name, dm_password, dm_password,
- subject_base=options.subject,
- ca_signing_algorithm=options.ca_signing_algorithm)
- elif external == 1:
+ if options.external_ca:
# stage 1 of external CA installation
options.realm_name = realm_name
options.domain_name = domain_name
@@ -808,23 +766,13 @@ def install(options):
options.forwarders = dns.dns_forwarders
options.reverse_zones = dns.reverse_zones
write_cache(vars(options))
- ca.configure_instance(
- host_name, domain_name, dm_password, dm_password,
- csr_file=paths.ROOT_IPA_CSR,
- subject_base=options.subject,
- ca_signing_algorithm=options.ca_signing_algorithm,
- ca_type=options.external_ca_type)
- else:
- # stage 2 of external CA installation
- ca.configure_instance(
- host_name, domain_name, dm_password, dm_password,
- cert_file=external_cert_file.name,
- cert_chain_file=external_ca_file.name,
- subject_base=options.subject,
- ca_signing_algorithm=options.ca_signing_algorithm)
+
+ ca.install_step_0(False, None, options)
# Now put the CA cert where other instances exepct it
- ca.publish_ca_cert(CACERT)
+ ca_instance = cainstance.CAInstance(realm_name, certs.NSS_DIR,
+ dogtag_constants=dogtag_constants)
+ ca_instance.publish_ca_cert(CACERT)
else:
# Put the CA cert where other instances expect it
x509.write_certificate(http_ca_cert, CACERT)
@@ -834,13 +782,7 @@ def install(options):
ds.enable_ssl()
if setup_ca:
- # We need to ldap_enable the CA now that DS is up and running
- ca.ldap_enable('CA', host_name, dm_password,
- ipautil.realm_to_suffix(realm_name),
- ['caRenewalMaster'])
-
- # This is done within stopped_service context, which restarts CA
- ca.enable_client_auth_to_db(ca.dogtag_constants.CS_CFG_PATH)
+ ca.install_step_1(False, None, options)
krb = krbinstance.KrbInstance(fstore)
if options.pkinit_cert_files:
@@ -903,8 +845,8 @@ def install(options):
krb.restart()
if setup_ca:
- service.print_msg("Restarting the certificate server")
- ca.restart(dogtag.configured_constants().PKI_INSTANCE_NAME)
+ dogtag_service = services.knownservices[dogtag_constants.SERVICE_NAME]
+ dogtag_service.restart(dogtag_constants.PKI_INSTANCE_NAME)
if options.setup_dns:
api.Backend.ldap2.connect(autobind=True)
@@ -1125,19 +1067,10 @@ def uninstall(options):
print "ipa-client-install returned: " + str(e)
ntpinstance.NTPInstance(fstore).uninstall()
- if not dogtag_constants.SHARED_DB:
- cads_instance = cainstance.CADSInstance(
- dogtag_constants=dogtag_constants)
- if cads_instance.is_configured():
- cads_instance.uninstall()
kra.uninstall()
- ca_instance = cainstance.CAInstance(
- api.env.realm, certs.NSS_DIR, dogtag_constants=dogtag_constants)
- ca_instance.stop_tracking_certificates()
- if ca_instance.is_configured():
- ca_instance.uninstall()
+ ca.uninstall(dogtag_constants)
dns.uninstall()
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index dc8efd48d..e27d285ea 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -20,7 +20,7 @@ from ipaplatform.paths import paths
from ipalib import api, certstore, constants, create_api, errors, x509
import ipaclient.ntpconf
from ipaserver.install import (
- bindinstance, cainstance, dns, dsinstance, httpinstance, installutils, kra,
+ bindinstance, ca, dns, dsinstance, httpinstance, installutils, kra,
krbinstance, memcacheinstance, ntpinstance, otpdinstance, service)
from ipaserver.install.installutils import create_replica_config
from ipaserver.install.replication import (
@@ -326,11 +326,6 @@ def install_check(filename, options):
check_dirsrv()
- if options.setup_ca:
- if not cainstance.check_port():
- print "IPA requires port 8443 for PKI but it is currently in use."
- sys.exit("Aborting installation")
-
if options.conf_ntp:
try:
ipaclient.ntpconf.check_timedate_services()
@@ -356,12 +351,14 @@ def install_check(filename, options):
global REPLICA_INFO_TOP_DIR
REPLICA_INFO_TOP_DIR = config.top_dir
config.setup_ca = options.setup_ca
+ config.setup_kra = options.setup_kra
- if config.setup_ca and not ipautil.file_exists(config.dir + "/cacert.p12"):
- print 'CA cannot be installed in CA-less setup.'
- sys.exit(1)
+ if options.setup_ca:
+ options.realm_name = config.realm_name
+ options.host_name = config.host_name
+ options.subject = config.subject_base
+ ca.install_check(False, config, options)
- config.setup_kra = options.setup_kra
if config.setup_kra:
try:
kra.install_check(config, options, False,
@@ -398,6 +395,8 @@ def install_check(filename, options):
def install(filename, options):
global config
+ dogtag_constants = dogtag.install_constants
+
# Create the management framework config file
# Note: We must do this before bootstraping and finalizing ipalib.api
old_umask = os.umask(022) # must be readable for httpd
@@ -416,8 +415,7 @@ def install(filename, options):
if ipautil.file_exists(config.dir + "/cacert.p12"):
fd.write("enable_ra=True\n")
fd.write("ra_plugin=dogtag\n")
- fd.write("dogtag_version=%s\n" %
- dogtag.install_constants.DOGTAG_VERSION)
+ fd.write("dogtag_version=%s\n" % dogtag_constants.DOGTAG_VERSION)
else:
fd.write("enable_ra=False\n")
fd.write("ra_plugin=none\n")
@@ -538,11 +536,6 @@ def install(filename, options):
if replman and replman.conn:
replman.conn.unbind()
- if options.skip_schema_check:
- root_logger.info("Skipping CA DS schema check")
- else:
- cainstance.replica_ca_install_check(config)
-
# Configure ntpd
if options.conf_ntp:
ipaclient.ntpconf.force_ntpd(sstore)
@@ -552,22 +545,19 @@ def install(filename, options):
# Configure dirsrv
ds = install_replica_ds(config)
- # Configure the CA if necessary
- CA = cainstance.install_replica_ca(config)
-
# Always try to install DNS records
install_dns_records(config, options, remote_api)
finally:
if conn.isconnected():
conn.disconnect()
- # We need to ldap_enable the CA now that DS is up and running
- if CA and config.setup_ca:
- CA.ldap_enable('CA', config.host_name, config.dirman_password,
- ipautil.realm_to_suffix(config.realm_name))
+ if config.setup_ca:
+ options.realm_name = config.realm_name
+ options.domain_name = config.domain_name
+ options.dm_password = config.dirman_password
+ options.host_name = config.host_name
- # This is done within stopped_service context, which restarts CA
- CA.enable_client_auth_to_db(CA.dogtag_constants.CS_CFG_PATH)
+ ca.install(False, config, options)
krb = install_krb(config, setup_pkinit=options.setup_pkinit)
http = install_http(config, auto_redirect=options.ui_redirect)
@@ -576,11 +566,6 @@ def install(filename, options):
otpd.create_instance('OTPD', config.host_name, config.dirman_password,
ipautil.realm_to_suffix(config.realm_name))
- if CA:
- CA.configure_certmonger_renewal()
- CA.import_ra_cert(config.dir + "/ra.p12")
- CA.fix_ra_perms()
-
# The DS instance is created before the keytab, add the SSL cert we
# generated
ds.add_cert_to_service()
@@ -598,9 +583,9 @@ def install(filename, options):
service.print_msg("Restarting the KDC")
krb.restart()
- if CA and config.setup_ca:
- service.print_msg("Restarting the certificate server")
- CA.restart(dogtag.configured_constants().PKI_INSTANCE_NAME)
+ if config.setup_ca:
+ dogtag_service = services.knownservices[dogtag_constants.SERVICE_NAME]
+ dogtag_service.restart(dogtag_constants.PKI_INSTANCE_NAME)
if options.setup_dns:
api.Backend.ldap2.connect(autobind=True)