URL: https://github.com/freeipa/freeipa/pull/446 Author: stlaz Title: #446: No NSS database passwords in ipa-client-install Action: synchronized
To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/446/head:pr446 git checkout pr446
From 5f074ff8bced43ef88dc892baa8946ee21ec085a Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Tue, 6 Dec 2016 09:14:54 +0100 Subject: [PATCH 1/3] Add password to certutil calls in NSSDatabase NSSDatabases should have the ability to run certutil with a password if location of the file containing it is known. https://fedorahosted.org/freeipa/ticket/5695 --- install/tools/ipa-replica-conncheck | 11 +++-------- ipaclient/install/client.py | 23 ++++++++++++----------- ipapython/certdb.py | 19 +++++++++++++------ ipaserver/install/certs.py | 2 +- ipaserver/install/installutils.py | 18 ++++++++---------- ipaserver/install/ipa_cacert_manage.py | 8 ++++---- ipaserver/install/ipa_server_certinstall.py | 7 +++---- ipaserver/install/kra.py | 7 ++++--- 8 files changed, 48 insertions(+), 47 deletions(-) diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck index 04e23de..896fddc 100755 --- a/install/tools/ipa-replica-conncheck +++ b/install/tools/ipa-replica-conncheck @@ -542,12 +542,9 @@ def main(): with certdb.NSSDatabase(nss_dir) as nss_db: if options.ca_cert_file: - nss_dir = nss_db.secdir - - password = ipautil.ipa_generate_password() - password_file = ipautil.write_tmp_file(password) - nss_db.create_db(password_file.name) - + nss_db.create_passwd_file( + ipautil.ipa_generate_password()) + nss_db.create_db() ca_certs = x509.load_certificate_list_from_file( options.ca_cert_file) for ca_cert in ca_certs: @@ -555,8 +552,6 @@ def main(): serialization.Encoding.DER) nss_db.add_cert( data, str(DN(ca_cert.subject)), 'C,,') - else: - nss_dir = None api.bootstrap(context='client', confdir=paths.ETC_IPA, diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py index aa3449c..abb5e1a 100644 --- a/ipaclient/install/client.py +++ b/ipaclient/install/client.py @@ -2288,26 +2288,26 @@ def install_check(options): def create_ipa_nssdb(): - db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR) - pwdfile = os.path.join(db.secdir, 'pwdfile.txt') + db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR, + os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')) - ipautil.backup_file(pwdfile) + ipautil.backup_file(db.password_file) ipautil.backup_file(os.path.join(db.secdir, 'cert8.db')) ipautil.backup_file(os.path.join(db.secdir, 'key3.db')) ipautil.backup_file(os.path.join(db.secdir, 'secmod.db')) - with open(pwdfile, 'w') as f: - f.write(ipautil.ipa_generate_password()) - os.chmod(pwdfile, 0o600) + db.create_passwd_file(ipautil.ipa_generate_password()) + os.chmod(db.password_file, 0o600) - db.create_db(pwdfile) + db.create_db() os.chmod(os.path.join(db.secdir, 'cert8.db'), 0o644) os.chmod(os.path.join(db.secdir, 'key3.db'), 0o644) os.chmod(os.path.join(db.secdir, 'secmod.db'), 0o644) def update_ipa_nssdb(): - ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR) + ipa_db = certdb.NSSDatabase( + paths.IPA_NSSDB_DIR, os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')) sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR) if not os.path.exists(os.path.join(ipa_db.secdir, 'cert8.db')): @@ -2672,8 +2672,8 @@ def _install(options): for cert in ca_certs ] try: - pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password()) - tmp_db.create_db(pwd_file.name) + tmp_db.create_passwd_file(ipautil.ipa_generate_password()) + tmp_db.create_db() for i, cert in enumerate(ca_certs): tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), 'C,,') @@ -3031,7 +3031,8 @@ def uninstall(options): if hostname is None: hostname = socket.getfqdn() - ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR) + ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR, + os.path.join('pwdfile.txt')) sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR) cmonger = services.knownservices.certmonger diff --git a/ipapython/certdb.py b/ipapython/certdb.py index 9481326..88fbcbb 100644 --- a/ipapython/certdb.py +++ b/ipapython/certdb.py @@ -83,13 +83,14 @@ class NSSDatabase(object): # got too tied to IPA server details, killing reusability. # BaseCertDB is a class that knows nothing about IPA. # Generic NSS DB code should be moved here. - def __init__(self, nssdir=None): + def __init__(self, nssdir=None, password_file=None): if nssdir is None: self.secdir = tempfile.mkdtemp() self._is_temporary = True else: self.secdir = nssdir self._is_temporary = False + self.password_file = password_file def close(self): if self._is_temporary: @@ -104,14 +105,20 @@ def __exit__(self, type, value, tb): def run_certutil(self, args, stdin=None, **kwargs): new_args = [CERTUTIL, "-d", self.secdir] new_args = new_args + args + if self.password_file is not None: + new_args.extend(['-f', self.password_file]) return ipautil.run(new_args, stdin, **kwargs) - def create_db(self, password_filename): - """Create cert DB + def create_passwd_file(self, passwd): + if self.password_file is None: + self.password_file = os.path.join(self.secdir, 'passwd.txt') + with open(self.password_file, 'w') as psswdfile: + psswdfile.write(passwd) - :param password_filename: Name of file containing the database password - """ - self.run_certutil(["-N", "-f", password_filename]) + def create_db(self): + """Create cert DB""" + assert os.path.exists(self.password_file) + self.run_certutil(["-N"]) def list_certs(self): """Return nicknames and cert flags for all certs in the database diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py index 80918d4..7528e83 100644 --- a/ipaserver/install/certs.py +++ b/ipaserver/install/certs.py @@ -199,7 +199,7 @@ def create_certdbs(self): ipautil.backup_file(self.certdb_fname) ipautil.backup_file(self.keydb_fname) ipautil.backup_file(self.secmod_fname) - self.nssdb.create_db(self.passwd_fname) + self.nssdb.create_db() self.set_perms(self.passwd_fname, write=True) def list_certs(self): diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index ab2596c..c1851b6 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -1003,19 +1003,18 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files, the CA certificate of the CA that issued the server certificate """ with certs.NSSDatabase() as nssdb: - db_password = ipautil.ipa_generate_password() - db_pwdfile = ipautil.write_tmp_file(db_password) - nssdb.create_db(db_pwdfile.name) + nssdb.create_passwd_file(ipautil.ipa_generate_password()) + nssdb.create_db() try: - nssdb.import_files(cert_files, db_pwdfile.name, + nssdb.import_files(cert_files, nssdb.password_file, True, key_password, key_nickname) except RuntimeError as e: raise ScriptError(str(e)) if ca_cert_files: try: - nssdb.import_files(ca_cert_files, db_pwdfile.name) + nssdb.import_files(ca_cert_files, nssdb.password_file) except RuntimeError as e: raise ScriptError(str(e)) @@ -1068,7 +1067,7 @@ def load_pkcs12(cert_files, key_password, key_nickname, ca_cert_files, '-o', out_file.name, '-n', key_nickname, '-d', nssdb.secdir, - '-k', db_pwdfile.name, + '-k', nssdb.password_file, '-w', out_pwdfile.name, ] ipautil.run(args) @@ -1143,12 +1142,11 @@ def load_external_cert(files, ca_subject): with the external CA certificate chain """ with certs.NSSDatabase() as nssdb: - db_password = ipautil.ipa_generate_password() - db_pwdfile = ipautil.write_tmp_file(db_password) - nssdb.create_db(db_pwdfile.name) + nssdb.create_passwd_file(ipautil.ipa_generate_password) + nssdb.create_db() try: - nssdb.import_files(files, db_pwdfile.name) + nssdb.import_files(files, nssdb.password_file) except RuntimeError as e: raise ScriptError(str(e)) diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py index 1d1ae2f..7c819c4 100644 --- a/ipaserver/install/ipa_cacert_manage.py +++ b/ipaserver/install/ipa_cacert_manage.py @@ -230,8 +230,8 @@ def renew_external_step_2(self, ca, old_cert_der): "troubleshooting guide)") with certs.NSSDatabase() as tmpdb: - pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) - tmpdb.create_db(pw.name) + tmpdb.create_passwd_file(ipautil.ipa_generate_password()) + tmpdb.create_db() tmpdb.add_cert(old_cert_der, 'IPA CA', 'C,,') try: @@ -330,8 +330,8 @@ def install(self): False) with certs.NSSDatabase() as tmpdb: - pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) - tmpdb.create_db(pw.name) + tmpdb.create_passwd_file(ipautil.ipa_generate_password()) + tmpdb.create_db() tmpdb.add_cert(cert, nickname, 'C,,') for ca_cert, ca_nickname, ca_trust_flags in ca_certs: tmpdb.add_cert(ca_cert, ca_nickname, ca_trust_flags) diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py index d07c7de..6a76b2d 100644 --- a/ipaserver/install/ipa_server_certinstall.py +++ b/ipaserver/install/ipa_server_certinstall.py @@ -164,14 +164,13 @@ def install_http_cert(self): def check_chain(self, pkcs12_filename, pkcs12_pin, nssdb): # create a temp nssdb with NSSDatabase() as tempnssdb: - db_password = ipautil.ipa_generate_password() - db_pwdfile = ipautil.write_tmp_file(db_password) - tempnssdb.create_db(db_pwdfile.name) + tempnssdb.create_passwd_file(ipautil.ipa_generate_password()) + tempnssdb.create_db() # import the PKCS12 file, then delete all CA certificates # this leaves only the server certs in the temp db tempnssdb.import_pkcs12( - pkcs12_filename, db_pwdfile.name, pkcs12_pin) + pkcs12_filename, tempnssdb.password_filename, pkcs12_pin) for nickname, flags in tempnssdb.list_certs(): if 'u' not in flags: while tempnssdb.has_nickname(nickname): diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py index 0d1ed8e..649eb47 100644 --- a/ipaserver/install/kra.py +++ b/ipaserver/install/kra.py @@ -54,9 +54,10 @@ def install_check(api, replica_config, options): return with certdb.NSSDatabase() as tmpdb: - pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) - tmpdb.create_db(pw.name) - tmpdb.import_pkcs12(replica_config.dir + "/cacert.p12", pw.name, + tmpdb.create_passwd_file(ipautil.ipa_generate_password()) + tmpdb.create_db() + tmpdb.import_pkcs12(replica_config.dir + "/cacert.p12", + tmpdb.password_file, replica_config.dirman_password) kra_cert_nicknames = [ "storageCert cert-pki-kra", "transportCert cert-pki-kra", From ddbf12a2512485dbec5bee21a79395e5b6837fbc Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Fri, 6 Jan 2017 14:19:12 +0100 Subject: [PATCH 2/3] custodiainstance: don't use IPA-specific CertDB Replaced CertDB with NSSDatabase. CertDB expects the password to be stored in nss_dir/passwd.txt but custodia creates its temporary NSS database with a different password file. --- ipaserver/install/custodiainstance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py index a0bb399..31c02a1 100644 --- a/ipaserver/install/custodiainstance.py +++ b/ipaserver/install/custodiainstance.py @@ -2,12 +2,12 @@ from ipaserver.secrets.kem import IPAKEMKeys from ipaserver.secrets.client import CustodiaClient -from ipaserver.install.certs import CertDB from ipaplatform.paths import paths from ipaplatform.constants import constants from ipaserver.install.service import SimpleServiceInstance from ipapython import ipautil from ipapython.ipa_log_manager import root_logger +from ipapython.certdb import NSSDatabase from ipaserver.install import installutils from ipaserver.install import ldapupdate from ipaserver.install import sysupgrade @@ -159,7 +159,7 @@ def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data): '-w', pk12pwfile]) # Add CA certificates - tmpdb = CertDB(self.realm, nssdir=tmpnssdir) + tmpdb = NSSDatabase(tmpnssdir, password_file=nsspwfile) self.suffix = ipautil.realm_to_suffix(self.realm) self.import_ca_certs(tmpdb, True) From 5d7079fd93aed30e0bf1e707f0b37bdd732778c3 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka <slazn...@redhat.com> Date: Wed, 8 Feb 2017 16:03:05 +0100 Subject: [PATCH 3/3] Don't prompt for NSS database psswd during client-install In FIPS, the client-installation prompts for NSS database password when it tries to add a certificate to this database. Since NSSDatabase now accepts password_filename to grab the password from, use this instead. https://fedorahosted.org/freeipa/ticket/5695 --- ipaserver/install/certs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py index 7528e83..e29fda2 100644 --- a/ipaserver/install/certs.py +++ b/ipaserver/install/certs.py @@ -83,8 +83,6 @@ class CertDB(object): def __init__( self, realm, nssdir=NSS_DIR, fstore=None, host_name=None, subject_base=None, ca_subject=None): - self.nssdb = NSSDatabase(nssdir) - self.secdir = nssdir self.realm = realm @@ -97,6 +95,9 @@ def __init__( self.pk12_fname = self.secdir + "/cacert.p12" self.pin_fname = self.secdir + "/pin.txt" self.pwd_conf = paths.HTTPD_PASSWORD_CONF + self.nssdb = NSSDatabase( + self.secdir, password_file=self.passwd_fname) + self.reqdir = None self.certreq_fname = None self.certder_fname = None
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code