mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Move CA installation code into single module.
https://fedorahosted.org/freeipa/ticket/4468 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
committed by
Jan Cholasta
parent
a57998f51e
commit
2acedb2d5d
@@ -21,26 +21,18 @@
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
from ConfigParser import RawConfigParser
|
||||
from ipapython import ipautil
|
||||
|
||||
from ipaserver.install import installutils
|
||||
from ipaserver.install import certs
|
||||
from ipaserver.install.installutils import (HostnameLocalhost, ReplicaConfig,
|
||||
expand_replica_info, read_replica_info, get_host_name, BadHostError,
|
||||
private_ccache, read_replica_info_dogtag_port, load_external_cert,
|
||||
create_replica_config)
|
||||
from ipaserver.install import dsinstance, cainstance, bindinstance
|
||||
from ipaserver.install.replication import replica_conn_check
|
||||
from ipaserver.install.installutils import (private_ccache,
|
||||
create_replica_config)
|
||||
from ipaserver.install import dsinstance, ca
|
||||
from ipapython import version
|
||||
from ipalib import api, certstore, x509
|
||||
from ipalib import api
|
||||
from ipapython.dn import DN
|
||||
from ipapython.config import IPAOptionParser
|
||||
from ipapython import sysrestore
|
||||
from ipapython import dogtag
|
||||
from ipapython import certdb
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
log_file_name = paths.IPAREPLICA_CA_INSTALL_LOG
|
||||
@@ -86,6 +78,9 @@ def parse_options():
|
||||
if len(args) != 1:
|
||||
parser.error("you must provide a file generated by "
|
||||
"ipa-replica-prepare")
|
||||
|
||||
options.external_ca = None
|
||||
options.external_cert_files = None
|
||||
else:
|
||||
filename = None
|
||||
|
||||
@@ -106,31 +101,6 @@ def get_dirman_password():
|
||||
"Directory Manager (existing master)", confirm=False, validate=False)
|
||||
|
||||
|
||||
def check_ca():
|
||||
if not cainstance.check_port():
|
||||
print "IPA requires port 8443 for PKI but it is currently in use."
|
||||
sys.exit(1)
|
||||
|
||||
def install_dns_records(config, options):
|
||||
|
||||
if not bindinstance.dns_container_exists(config.master_host_name,
|
||||
ipautil.realm_to_suffix(config.realm_name),
|
||||
dm_password=config.dirman_password):
|
||||
return
|
||||
|
||||
bind = bindinstance.BindInstance(dm_password=config.dirman_password)
|
||||
disconnect = False
|
||||
try:
|
||||
if not api.Backend.ldap2.isconnected():
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
|
||||
bind_pw=config.dirman_password)
|
||||
disconnect = True
|
||||
bind.add_ipa_ca_dns_records(config.host_name, config.domain_name)
|
||||
finally:
|
||||
if api.Backend.ldap2.isconnected() and disconnect:
|
||||
api.Backend.ldap2.disconnect()
|
||||
|
||||
|
||||
def install_replica(safe_options, options, filename):
|
||||
standard_logging_setup(log_file_name, debug=options.debug)
|
||||
|
||||
@@ -141,18 +111,12 @@ def install_replica(safe_options, options, filename):
|
||||
if not ipautil.file_exists(filename):
|
||||
sys.exit("Replica file %s does not exist" % filename)
|
||||
|
||||
global sstore
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
if not dsinstance.DsInstance().is_configured():
|
||||
sys.exit("IPA server is not configured on this system.\n")
|
||||
|
||||
api.bootstrap(in_server=True)
|
||||
api.finalize()
|
||||
|
||||
if api.env.ra_plugin == 'selfsign':
|
||||
sys.exit('A selfsign CA can not be added')
|
||||
|
||||
# get the directory manager password
|
||||
dirman_password = options.password
|
||||
if not dirman_password:
|
||||
@@ -174,48 +138,17 @@ def install_replica(safe_options, options, filename):
|
||||
REPLICA_INFO_TOP_DIR = config.top_dir
|
||||
config.setup_ca = True
|
||||
|
||||
if not ipautil.file_exists(config.dir + "/cacert.p12"):
|
||||
print 'CA cannot be installed in CA-less setup.'
|
||||
sys.exit(1)
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
|
||||
bind_pw=dirman_password)
|
||||
|
||||
if not options.skip_conncheck:
|
||||
replica_conn_check(
|
||||
config.master_host_name, config.host_name, config.realm_name, True,
|
||||
config.ca_ds_port, options.admin_password)
|
||||
options.realm_name = config.realm_name
|
||||
options.domain_name = config.domain_name
|
||||
options.dm_password = config.dirman_password
|
||||
options.host_name = config.host_name
|
||||
options.subject = config.subject_base
|
||||
|
||||
if options.skip_schema_check:
|
||||
root_logger.info("Skipping CA DS schema check")
|
||||
else:
|
||||
cainstance.replica_ca_install_check(config)
|
||||
|
||||
check_ca()
|
||||
|
||||
# Configure the CA if necessary
|
||||
CA = cainstance.install_replica_ca(config, postinstall=True)
|
||||
|
||||
# We need to ldap_enable the CA now that DS is up and running
|
||||
CA.ldap_enable('CA', config.host_name, config.dirman_password,
|
||||
ipautil.realm_to_suffix(config.realm_name))
|
||||
|
||||
# This is done within stopped_service context, which restarts CA
|
||||
CA.enable_client_auth_to_db(CA.dogtag_constants.CS_CFG_PATH)
|
||||
|
||||
# Install CA DNS records
|
||||
install_dns_records(config, options)
|
||||
|
||||
# We need to restart apache as we drop a new config file in there
|
||||
services.knownservices.httpd.restart(capture_output=True)
|
||||
|
||||
#update dogtag version in config file
|
||||
try:
|
||||
fd = open(paths.IPA_DEFAULT_CONF, "a")
|
||||
fd.write(
|
||||
"dogtag_version=%s\n" % dogtag.install_constants.DOGTAG_VERSION)
|
||||
fd.close()
|
||||
except IOError, e:
|
||||
print "Failed to update /etc/ipa/default.conf"
|
||||
root_logger.error(str(e))
|
||||
sys.exit(1)
|
||||
ca.install_check(True, config, options)
|
||||
ca.install(True, config, options)
|
||||
|
||||
|
||||
def install_master(safe_options, options):
|
||||
@@ -225,9 +158,6 @@ def install_master(safe_options, options):
|
||||
"%s was invoked with options: %s", sys.argv[0], safe_options)
|
||||
root_logger.debug("IPA version %s", version.VENDOR_VERSION)
|
||||
|
||||
global sstore
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
if not dsinstance.DsInstance().is_configured():
|
||||
sys.exit("IPA server is not configured on this system.\n")
|
||||
|
||||
@@ -248,150 +178,17 @@ def install_master(safe_options, options):
|
||||
api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
|
||||
bind_pw=dm_password)
|
||||
|
||||
if api.Command.ca_is_enabled()['result']:
|
||||
sys.exit("CA is already installed.\n")
|
||||
|
||||
config = api.Command['config_show']()['result']
|
||||
subject_base = config['ipacertificatesubjectbase'][0]
|
||||
|
||||
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)
|
||||
elif options.external_cert_files:
|
||||
if not cainstance.is_step_one_done():
|
||||
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)
|
||||
options.realm_name = api.env.realm
|
||||
options.domain_name = api.env.domain
|
||||
options.dm_password = dm_password
|
||||
options.host_name = api.env.host
|
||||
options.subject = subject_base
|
||||
|
||||
external_cert_file, external_ca_file = load_external_cert(
|
||||
options.external_cert_files, subject_base)
|
||||
|
||||
if options.external_cert_files:
|
||||
external = 2
|
||||
elif options.external_ca:
|
||||
external = 1
|
||||
else:
|
||||
external = 0
|
||||
|
||||
realm_name = api.env.realm
|
||||
domain_name = api.env.domain
|
||||
host_name = api.env.host
|
||||
|
||||
if external != 2:
|
||||
check_ca()
|
||||
|
||||
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)
|
||||
|
||||
ca = cainstance.CAInstance(
|
||||
realm_name, certs.NSS_DIR,
|
||||
dogtag_constants=dogtag.install_constants)
|
||||
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)
|
||||
|
||||
ca.stop(ca.dogtag_constants.PKI_INSTANCE_NAME)
|
||||
|
||||
ca.ldap_enable('CA', host_name, dm_password,
|
||||
ipautil.realm_to_suffix(realm_name), ['caRenewalMaster'])
|
||||
|
||||
ca.enable_client_auth_to_db(ca.dogtag_constants.CS_CFG_PATH)
|
||||
|
||||
# Install CA DNS records
|
||||
config = ReplicaConfig()
|
||||
config.realm_name = realm_name
|
||||
config.domain_name = domain_name
|
||||
config.host_name = config.master_host_name = host_name
|
||||
config.dirman_password = dm_password
|
||||
install_dns_records(config, options)
|
||||
|
||||
# We need to restart apache as we drop a new config file in there
|
||||
services.knownservices.httpd.restart(capture_output=True)
|
||||
|
||||
# Update config file
|
||||
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(ca.dogtag_constants.DOGTAG_VERSION))
|
||||
with open(paths.IPA_DEFAULT_CONF, 'w') as f:
|
||||
parser.write(f)
|
||||
|
||||
# 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)
|
||||
|
||||
# Restart DS
|
||||
ds = dsinstance.DsInstance()
|
||||
ds.init_info(realm_name, host_name, domain_name, dm_password, subject_base,
|
||||
1101, 1100, None)
|
||||
ds.restart(ds.serverid)
|
||||
|
||||
# Store DS CA cert in Dogtag NSS database
|
||||
dogtagdb = certs.CertDB(realm_name, nssdir=ca.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])
|
||||
|
||||
ca.start(ca.dogtag_constants.PKI_INSTANCE_NAME)
|
||||
ca.install_check(True, None, options)
|
||||
ca.install(True, None, options)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -128,6 +128,9 @@ def parse_options():
|
||||
elif options.reverse_zones and options.no_reverse:
|
||||
parser.error("You cannot specify a --reverse-zone option together with --no-reverse")
|
||||
|
||||
options.external_ca = None
|
||||
options.external_cert_files = None
|
||||
|
||||
options.zonemgr = None
|
||||
options.dnssec_master = False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user