Load the CA cert into server NSS databases

The CA cert was not loaded, so if it was missing from the PKCS#12 file,
installation would fail.
Pass the cert filename to the server installers and include it in
the NSS DB.

Part of the work for: https://fedorahosted.org/freeipa/ticket/3363
This commit is contained in:
Petr Viktorin 2013-03-26 15:31:07 +01:00 committed by Martin Kosek
parent 03a2c66eda
commit 1bc892c02d
6 changed files with 32 additions and 15 deletions

View File

@ -164,7 +164,7 @@ def install_replica_ds(config):
ds.create_replica(config.realm_name, ds.create_replica(config.realm_name,
config.master_host_name, config.host_name, config.master_host_name, config.host_name,
config.domain_name, config.dirman_password, config.domain_name, config.dirman_password,
pkcs12_info) pkcs12_info, ca_file = config.dir + "/ca.crt")
return ds return ds
@ -209,7 +209,10 @@ def install_http(config, auto_redirect):
memcache.create_instance('MEMCACHE', config.host_name, config.dirman_password, ipautil.realm_to_suffix(config.realm_name)) memcache.create_instance('MEMCACHE', config.host_name, config.dirman_password, ipautil.realm_to_suffix(config.realm_name))
http = httpinstance.HTTPInstance() http = httpinstance.HTTPInstance()
http.create_instance(config.realm_name, config.host_name, config.domain_name, config.dirman_password, False, pkcs12_info, self_signed_ca=True, auto_redirect=auto_redirect) http.create_instance(
config.realm_name, config.host_name, config.domain_name,
config.dirman_password, False, pkcs12_info,
auto_redirect=auto_redirect, ca_file = config.dir + "/ca.crt")
# Now copy the autoconfiguration files # Now copy the autoconfiguration files
if ipautil.file_exists(config.dir + "/preferences.html"): if ipautil.file_exists(config.dir + "/preferences.html"):

View File

@ -991,7 +991,8 @@ def main():
dm_password, dirsrv_pkcs12_info, dm_password, dirsrv_pkcs12_info,
idstart=options.idstart, idmax=options.idmax, idstart=options.idstart, idmax=options.idmax,
subject_base=options.subject, subject_base=options.subject,
hbac_allow=not options.hbac_allow) hbac_allow=not options.hbac_allow,
ca_file=ca_file)
else: else:
ds = dsinstance.DsInstance(fstore=fstore) ds = dsinstance.DsInstance(fstore=fstore)
ds.create_instance(realm_name, host_name, domain_name, ds.create_instance(realm_name, host_name, domain_name,
@ -1122,7 +1123,7 @@ def main():
http.create_instance( http.create_instance(
realm_name, host_name, domain_name, dm_password, autoconfig=False, realm_name, host_name, domain_name, dm_password, autoconfig=False,
pkcs12_info=http_pkcs12_info, subject_base=options.subject, pkcs12_info=http_pkcs12_info, subject_base=options.subject,
auto_redirect=options.ui_redirect) auto_redirect=options.ui_redirect, ca_file=ca_file)
else: else:
http.create_instance( http.create_instance(
realm_name, host_name, domain_name, dm_password, autoconfig=True, realm_name, host_name, domain_name, dm_password, autoconfig=True,

View File

@ -375,7 +375,8 @@ class NSSDatabase(object):
except RuntimeError: except RuntimeError:
pass pass
else: else:
raise ValueError('%s contains more than one certificate') raise ValueError('%s contains more than one certificate' %
location)
def add_single_pem_cert(self, nick, flags, cert): def add_single_pem_cert(self, nick, flags, cert):
"""Import a cert in PEM format""" """Import a cert in PEM format"""
@ -1127,7 +1128,8 @@ class CertDB(object):
self.create_certdbs() self.create_certdbs()
self.load_cacert(cacert_fname) self.load_cacert(cacert_fname)
def create_from_pkcs12(self, pkcs12_fname, pkcs12_pwd_fname, passwd=None): def create_from_pkcs12(self, pkcs12_fname, pkcs12_pwd_fname, passwd=None,
ca_file=None):
"""Create a new NSS database using the certificates in a PKCS#12 file. """Create a new NSS database using the certificates in a PKCS#12 file.
pkcs12_fname: the filename of the PKCS#12 file pkcs12_fname: the filename of the PKCS#12 file
@ -1137,6 +1139,8 @@ class CertDB(object):
The global CA may be added as well in case it wasn't included in the The global CA may be added as well in case it wasn't included in the
PKCS#12 file. Extra certs won't hurt in any case. PKCS#12 file. Extra certs won't hurt in any case.
The global CA may be specified in ca_file, as a PEM filename.
""" """
self.create_noise_file() self.create_noise_file()
self.create_passwd_file(passwd) self.create_passwd_file(passwd)
@ -1146,6 +1150,9 @@ class CertDB(object):
if len(server_certs) == 0: if len(server_certs) == 0:
raise RuntimeError("Could not find a suitable server cert in import in %s" % pkcs12_fname) raise RuntimeError("Could not find a suitable server cert in import in %s" % pkcs12_fname)
if ca_file:
self.nssdb.import_pem_cert('CA', 'CT,CT,', ca_file)
# We only handle one server cert # We only handle one server cert
nickname = server_certs[0][0] nickname = server_certs[0][0]

View File

@ -228,7 +228,8 @@ class DsInstance(service.Service):
self.step("configuring directory to start on boot", self.__enable) self.step("configuring directory to start on boot", self.__enable)
def init_info(self, realm_name, fqdn, domain_name, dm_password, def init_info(self, realm_name, fqdn, domain_name, dm_password,
self_signed_ca, subject_base, idstart, idmax, pkcs12_info): self_signed_ca, subject_base, idstart, idmax, pkcs12_info,
ca_file=None):
self.realm_name = realm_name.upper() self.realm_name = realm_name.upper()
self.serverid = realm_to_serverid(self.realm_name) self.serverid = realm_to_serverid(self.realm_name)
self.suffix = ipautil.realm_to_suffix(self.realm_name) self.suffix = ipautil.realm_to_suffix(self.realm_name)
@ -241,16 +242,17 @@ class DsInstance(service.Service):
self.idstart = idstart self.idstart = idstart
self.idmax = idmax self.idmax = idmax
self.pkcs12_info = pkcs12_info self.pkcs12_info = pkcs12_info
self.ca_file = ca_file
self.__setup_sub_dict() self.__setup_sub_dict()
def create_instance(self, realm_name, fqdn, domain_name, def create_instance(self, realm_name, fqdn, domain_name,
dm_password, pkcs12_info=None, self_signed_ca=False, dm_password, pkcs12_info=None, self_signed_ca=False,
idstart=1100, idmax=999999, subject_base=None, idstart=1100, idmax=999999, subject_base=None,
hbac_allow=True): hbac_allow=True, ca_file=None):
self.init_info( self.init_info(
realm_name, fqdn, domain_name, dm_password, self_signed_ca, realm_name, fqdn, domain_name, dm_password, self_signed_ca,
subject_base, idstart, idmax, pkcs12_info) subject_base, idstart, idmax, pkcs12_info, ca_file=ca_file)
self.__common_setup() self.__common_setup()
@ -270,7 +272,8 @@ class DsInstance(service.Service):
self.start_creation(runtime=60) self.start_creation(runtime=60)
def create_replica(self, realm_name, master_fqdn, fqdn, def create_replica(self, realm_name, master_fqdn, fqdn,
domain_name, dm_password, pkcs12_info=None): domain_name, dm_password, pkcs12_info=None,
ca_file=None):
# idstart and idmax are configured so that the range is seen as # idstart and idmax are configured so that the range is seen as
# depleted by the DNA plugin and the replica will go and get a # depleted by the DNA plugin and the replica will go and get a
# new range from the master. # new range from the master.
@ -280,7 +283,7 @@ class DsInstance(service.Service):
self.init_info( self.init_info(
realm_name, fqdn, domain_name, dm_password, None, None, realm_name, fqdn, domain_name, dm_password, None, None,
idstart, idmax, pkcs12_info) idstart, idmax, pkcs12_info, ca_file=ca_file)
self.master_fqdn = master_fqdn self.master_fqdn = master_fqdn
self.__common_setup(True) self.__common_setup(True)
@ -533,7 +536,8 @@ class DsInstance(service.Service):
dirname = config_dirname(self.serverid) dirname = config_dirname(self.serverid)
dsdb = certs.CertDB(self.realm_name, nssdir=dirname, subject_base=self.subject_base) dsdb = certs.CertDB(self.realm_name, nssdir=dirname, subject_base=self.subject_base)
if self.pkcs12_info: if self.pkcs12_info:
dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1]) dsdb.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
ca_file=self.ca_file)
server_certs = dsdb.find_server_certs() server_certs = dsdb.find_server_certs()
if len(server_certs) == 0: if len(server_certs) == 0:
raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0]) raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0])

View File

@ -64,7 +64,7 @@ class HTTPInstance(service.Service):
def create_instance(self, realm, fqdn, domain_name, dm_password=None, def create_instance(self, realm, fqdn, domain_name, dm_password=None,
autoconfig=True, pkcs12_info=None, autoconfig=True, pkcs12_info=None,
self_signed_ca=False, subject_base=None, self_signed_ca=False, subject_base=None,
auto_redirect=True): auto_redirect=True, ca_file=None):
self.fqdn = fqdn self.fqdn = fqdn
self.realm = realm self.realm = realm
self.domain = domain_name self.domain = domain_name
@ -82,6 +82,7 @@ class HTTPInstance(service.Service):
AUTOREDIR='' if auto_redirect else '#', AUTOREDIR='' if auto_redirect else '#',
CRL_PUBLISH_PATH=dogtag.install_constants.CRL_PUBLISH_PATH, CRL_PUBLISH_PATH=dogtag.install_constants.CRL_PUBLISH_PATH,
) )
self.ca_file = ca_file
# get a connection to the DS # get a connection to the DS
self.ldap_connect() self.ldap_connect()
@ -244,7 +245,8 @@ class HTTPInstance(service.Service):
db = certs.CertDB(self.realm, subject_base=self.subject_base) db = certs.CertDB(self.realm, subject_base=self.subject_base)
if self.pkcs12_info: if self.pkcs12_info:
db.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1], passwd=None) db.create_from_pkcs12(self.pkcs12_info[0], self.pkcs12_info[1],
passwd=None, ca_file=self.ca_file)
server_certs = db.find_server_certs() server_certs = db.find_server_certs()
if len(server_certs) == 0: if len(server_certs) == 0:
raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0]) raise RuntimeError("Could not find a suitable server cert in import in %s" % self.pkcs12_info[0])

View File

@ -340,7 +340,7 @@ class ReplicaPrepare(admintool.AdminTool):
def copy_misc_files(self): def copy_misc_files(self):
self.log.info("Copying additional files") self.log.info("Copying additional files")
self.copy_info_file("/usr/share/ipa/html/ca.crt", "ca.crt") self.copy_info_file("/etc/ipa/ca.crt", "ca.crt")
preferences_filename = "/usr/share/ipa/html/preferences.html" preferences_filename = "/usr/share/ipa/html/preferences.html"
if ipautil.file_exists(preferences_filename): if ipautil.file_exists(preferences_filename):
self.copy_info_file(preferences_filename, "preferences.html") self.copy_info_file(preferences_filename, "preferences.html")