From ca457eb5ce12291f555f1bf771114d6d7d191987 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka Date: Tue, 6 Dec 2016 09:14:54 +0100 Subject: [PATCH] Add password to certutil calls in NSSDatabase NSSDatabases should call certutil with a password. Also, removed `password_filename` argument from `.create_db()`. https://fedorahosted.org/freeipa/ticket/5695 Reviewed-By: Tomas Krizek Reviewed-By: Jan Cholasta --- install/tools/ipa-replica-conncheck | 9 +-------- ipaclient/install/client.py | 17 +++-------------- ipapython/certdb.py | 20 +++++++------------- ipaserver/install/cainstance.py | 23 +++++++++++++++++++++++ ipaserver/install/ipa_cacert_manage.py | 6 ++---- ipaserver/install/server/upgrade.py | 6 ++++++ 6 files changed, 42 insertions(+), 39 deletions(-) diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck index 04e23ded5..fdbd4f32d 100755 --- a/install/tools/ipa-replica-conncheck +++ b/install/tools/ipa-replica-conncheck @@ -542,12 +542,7 @@ 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_db() ca_certs = x509.load_certificate_list_from_file( options.ca_cert_file) for ca_cert in ca_certs: @@ -555,8 +550,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 2b01b0dfa..e43ec7bb6 100644 --- a/ipaclient/install/client.py +++ b/ipaclient/install/client.py @@ -2284,18 +2284,8 @@ def install_check(options): def create_ipa_nssdb(): db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR) - pwdfile = os.path.join(db.secdir, 'pwdfile.txt') - - ipautil.backup_file(pwdfile) - 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_db(pwdfile) + db.create_db(backup=True) + os.chmod(db.pwd_file, 0o600) 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) @@ -2667,8 +2657,7 @@ 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_db() for i, cert in enumerate(ca_certs): tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), 'C,,') diff --git a/ipapython/certdb.py b/ipapython/certdb.py index a6bfcbc3e..73387cf58 100644 --- a/ipapython/certdb.py +++ b/ipapython/certdb.py @@ -17,7 +17,6 @@ # along with this program. If not, see . # -import binascii import os import io import pwd @@ -112,13 +111,12 @@ class NSSDatabase(object): def run_certutil(self, args, stdin=None, **kwargs): new_args = [CERTUTIL, "-d", self.secdir] new_args = new_args + args + new_args.extend(['-f', self.pwd_file]) return ipautil.run(new_args, stdin, **kwargs) - def create_db(self, password_filename=None, user=None, group=None, - mode=None, backup=False): + def create_db(self, user=None, group=None, mode=None, backup=False): """Create cert DB - :param password_filename: Name of file containing the database password :param user: User owner the secdir :param group: Group owner of the secdir :param mode: Mode of the secdir @@ -145,19 +143,15 @@ class NSSDatabase(object): if not os.path.exists(self.secdir): os.makedirs(self.secdir, dirmode) - if password_filename is None: - password_filename = self.pwd_file - - if not os.path.exists(password_filename): + if not os.path.exists(self.pwd_file): # Create the password file for this db - hex_str = binascii.hexlify(os.urandom(10)) - with io.open(os.open(password_filename, + with io.open(os.open(self.pwd_file, os.O_CREAT | os.O_WRONLY, - filemode), 'wb', closefd=True) as f: - f.write(hex_str) + filemode), 'w', closefd=True) as f: + f.write(ipautil.ipa_generate_password()) f.flush() - self.run_certutil(["-N", "-f", password_filename]) + self.run_certutil(["-N", "-f", self.pwd_file]) # Finally fix up perms os.chown(self.secdir, uid, gid) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 1b7ada456..52485b97b 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -394,6 +394,8 @@ class CAInstance(DogtagInstance): self.step("creating installation admin user", self.setup_admin) self.step("configuring certificate server instance", self.__spawn_instance) + self.step("exporting Dogtag certificate store pin", + self.create_certstore_passwdfile) self.step("stopping certificate server instance to update CS.cfg", self.stop_instance) self.step("backing up CS.cfg", self.backup_config) self.step("disabling nonces", self.__disable_nonce) @@ -627,6 +629,27 @@ class CAInstance(DogtagInstance): except Exception as e: root_logger.warning("Failed to backup CS.cfg: %s", e) + def create_certstore_passwdfile(self): + """ + This method creates a 'pwdfile.txt' file in the Dogtag certificate + store so that this file can be assumed and used for NSSDatabase/CertDB + operations in 'certutil' calls. + """ + passwd = None + token = 'internal' + with open(paths.PKI_TOMCAT_PASSWORD_CONF, 'r') as f: + for line in f: + (tok, pin) = line.split('=', 1) + if token == tok: + passwd = pin.strip() + break + else: + raise RuntimeError( + "The password to the 'internal' token of the Dogtag " + "certificate store was not found.") + db = certs.CertDB(self.realm, nssdir=paths.PKI_TOMCAT_ALIAS_DIR) + db.create_passwd_file(passwd) + def __update_topology(self): ld = ldapupdate.LDAPUpdate(ldapi=True, sub_dict={ 'SUFFIX': api.env.basedn, diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py index e47d10467..dc448364d 100644 --- a/ipaserver/install/ipa_cacert_manage.py +++ b/ipaserver/install/ipa_cacert_manage.py @@ -230,8 +230,7 @@ class CACertManage(admintool.AdminTool): "troubleshooting guide)") with certs.NSSDatabase() as tmpdb: - pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) - tmpdb.create_db(pw.name) + tmpdb.create_db() tmpdb.add_cert(old_cert_der, 'IPA CA', 'C,,') try: @@ -330,8 +329,7 @@ class CACertManage(admintool.AdminTool): False) with certs.NSSDatabase() as tmpdb: - pw = ipautil.write_tmp_file(ipautil.ipa_generate_password()) - tmpdb.create_db(pw.name) + 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/server/upgrade.py b/ipaserver/install/server/upgrade.py index 41da723fa..e65592c19 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -1543,6 +1543,12 @@ def upgrade_configuration(): api.env.realm, paths.IPA_RADB_DIR, host_name=api.env.host) ca_running = ca.is_running() + # create passswd.txt file in PKI_TOMCAT_ALIAS_DIR if it does not exist + # this file will be required on most actions over this NSS DB in FIPS + if not os.path.exists(os.path.join( + paths.PKI_TOMCAT_ALIAS_DIR, 'pwdfile.txt')): + ca.create_certstore_passwdfile() + with installutils.stopped_service('pki-tomcatd', 'pki-tomcat'): # Dogtag must be stopped to be able to backup CS.cfg config ca.backup_config()