mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Read passwords from stdin when importing PKCS#12 files with pk12util.
This works around pk12util refusing to use empty password files, which prevents the use of PKCS#12 files with empty password. https://fedorahosted.org/freeipa/ticket/3897
This commit is contained in:
committed by
Petr Viktorin
parent
46b3588112
commit
c123264ac7
@@ -149,16 +149,31 @@ def set_owner(config, dir):
|
||||
pw = pwd.getpwnam(dsinstance.DS_USER)
|
||||
os.chown(dir, pw.pw_uid, pw.pw_gid)
|
||||
|
||||
|
||||
def make_pkcs12_info(directory, cert_name, password_name):
|
||||
"""Make pkcs12_info
|
||||
|
||||
:param directory: Base directory (config.dir)
|
||||
:param cert_name: Cert filename (e.g. "dscert.p12")
|
||||
:param password_name: Cert filename (e.g. "dirsrv_pin.txt")
|
||||
:return: a (full cert path, password) tuple, or None if cert is not found
|
||||
"""
|
||||
cert_path = os.path.join(directory, cert_name)
|
||||
if ipautil.file_exists(cert_path):
|
||||
password_file = os.path.join(directory, password_name)
|
||||
password = open(password_file).read().strip()
|
||||
return cert_path, password
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def install_replica_ds(config):
|
||||
dsinstance.check_ports()
|
||||
|
||||
# if we have a pkcs12 file, create the cert db from
|
||||
# that. Otherwise the ds setup will create the CA
|
||||
# cert
|
||||
pkcs12_info = None
|
||||
if ipautil.file_exists(config.dir + "/dscert.p12"):
|
||||
pkcs12_info = (config.dir + "/dscert.p12",
|
||||
config.dir + "/dirsrv_pin.txt")
|
||||
pkcs12_info = make_pkcs12_info(config.dir, "dscert.p12", "dirsrv_pin.txt")
|
||||
|
||||
ds = dsinstance.DsInstance()
|
||||
ds.create_replica(
|
||||
@@ -178,10 +193,8 @@ def install_krb(config, setup_pkinit=False):
|
||||
krb = krbinstance.KrbInstance()
|
||||
|
||||
#pkinit files
|
||||
pkcs12_info = None
|
||||
if ipautil.file_exists(config.dir + "/pkinitcert.p12"):
|
||||
pkcs12_info = (config.dir + "/pkinitcert.p12",
|
||||
config.dir + "/pkinit_pin.txt")
|
||||
pkcs12_info = make_pkcs12_info(config.dir, "pkinitcert.p12",
|
||||
"pkinit_pin.txt")
|
||||
|
||||
krb.create_replica(config.realm_name,
|
||||
config.master_host_name, config.host_name,
|
||||
@@ -206,10 +219,7 @@ def install_http(config, auto_redirect):
|
||||
# if we have a pkcs12 file, create the cert db from
|
||||
# that. Otherwise the ds setup will create the CA
|
||||
# cert
|
||||
pkcs12_info = None
|
||||
if ipautil.file_exists(config.dir + "/httpcert.p12"):
|
||||
pkcs12_info = (config.dir + "/httpcert.p12",
|
||||
config.dir + "/http_pin.txt")
|
||||
pkcs12_info = make_pkcs12_info(config.dir, "httpcert.p12", "http_pin.txt")
|
||||
|
||||
memcache = memcacheinstance.MemcacheInstance()
|
||||
memcache.create_instance('MEMCACHE', config.host_name, config.dirman_password, ipautil.realm_to_suffix(config.realm_name))
|
||||
|
||||
@@ -882,8 +882,7 @@ def main():
|
||||
confirm=False, validate=False)
|
||||
if options.http_pin is None:
|
||||
sys.exit("%s unlock password required" % options.http_pkcs12)
|
||||
http_pin_file = ipautil.write_tmp_file(options.http_pin)
|
||||
http_pkcs12_info = (options.http_pkcs12, http_pin_file.name)
|
||||
http_pkcs12_info = (options.http_pkcs12, options.http_pin)
|
||||
http_cert_name = installutils.check_pkcs12(
|
||||
http_pkcs12_info, ca_file, host_name)
|
||||
|
||||
@@ -894,8 +893,7 @@ def main():
|
||||
confirm=False, validate=False)
|
||||
if options.dirsrv_pin is None:
|
||||
sys.exit("%s unlock password required" % options.dirsrv_pkcs12)
|
||||
dirsrv_pin_file = ipautil.write_tmp_file(options.dirsrv_pin)
|
||||
dirsrv_pkcs12_info = (options.dirsrv_pkcs12, dirsrv_pin_file.name)
|
||||
dirsrv_pkcs12_info = (options.dirsrv_pkcs12, options.dirsrv_pin)
|
||||
dirsrv_cert_name = installutils.check_pkcs12(
|
||||
dirsrv_pkcs12_info, ca_file, host_name)
|
||||
|
||||
@@ -906,8 +904,7 @@ def main():
|
||||
confirm=False, validate=False)
|
||||
if options.pkinit_pin is None:
|
||||
sys.exit("%s unlock password required" % options.pkinit_pkcs12)
|
||||
pkinit_pin_file = ipautil.write_tmp_file(options.pkinit_pin)
|
||||
pkinit_pkcs12_info = (options.pkinit_pkcs12, pkinit_pin_file.name)
|
||||
pkinit_pkcs12_info = (options.pkinit_pkcs12, options.pkinit_pin)
|
||||
|
||||
if not options.dm_password:
|
||||
dm_password = read_dm_password()
|
||||
|
||||
@@ -176,14 +176,15 @@ class NSSDatabase(object):
|
||||
return root_nicknames
|
||||
|
||||
def import_pkcs12(self, pkcs12_filename, db_password_filename,
|
||||
pkcs_password_filename=None):
|
||||
pkcs12_passwd=None):
|
||||
args = ["/usr/bin/pk12util", "-d", self.secdir,
|
||||
"-i", pkcs12_filename,
|
||||
"-k", db_password_filename, '-v']
|
||||
if pkcs_password_filename:
|
||||
args = args + ["-w", pkcs_password_filename]
|
||||
if pkcs12_passwd is not None:
|
||||
pkcs12_passwd = pkcs12_passwd + '\n'
|
||||
args = args + ["-w", "/dev/stdin"]
|
||||
try:
|
||||
ipautil.run(args)
|
||||
ipautil.run(args, stdin=pkcs12_passwd)
|
||||
except ipautil.CalledProcessError, e:
|
||||
if e.returncode == 17:
|
||||
raise RuntimeError("incorrect password for pkcs#12 file %s" %
|
||||
@@ -770,9 +771,9 @@ class CertDB(object):
|
||||
def find_server_certs(self):
|
||||
return self.nssdb.find_server_certs()
|
||||
|
||||
def import_pkcs12(self, pkcs12_fname, passwd_fname=None):
|
||||
def import_pkcs12(self, pkcs12_fname, pkcs12_passwd=None):
|
||||
return self.nssdb.import_pkcs12(pkcs12_fname, self.passwd_fname,
|
||||
pkcs_password_filename=passwd_fname)
|
||||
pkcs12_passwd=pkcs12_passwd)
|
||||
|
||||
def export_pkcs12(self, pkcs12_fname, pkcs12_pwd_fname, nickname=None):
|
||||
if nickname is None:
|
||||
@@ -814,7 +815,7 @@ class CertDB(object):
|
||||
self.create_certdbs()
|
||||
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_passwd, passwd=None,
|
||||
ca_file=None):
|
||||
"""Create a new NSS database using the certificates in a PKCS#12 file.
|
||||
|
||||
@@ -831,7 +832,7 @@ class CertDB(object):
|
||||
self.create_noise_file()
|
||||
self.create_passwd_file(passwd)
|
||||
self.create_certdbs()
|
||||
self.import_pkcs12(pkcs12_fname, pkcs12_pwd_fname)
|
||||
self.import_pkcs12(pkcs12_fname, pkcs12_passwd)
|
||||
server_certs = self.find_server_certs()
|
||||
if len(server_certs) == 0:
|
||||
raise RuntimeError("Could not find a suitable server cert in import in %s" % pkcs12_fname)
|
||||
@@ -854,10 +855,11 @@ class CertDB(object):
|
||||
self.create_pin_file()
|
||||
self.export_ca_cert(nickname, False)
|
||||
|
||||
def install_pem_from_p12(self, p12_fname, p12_pwd_fname, pem_fname):
|
||||
def install_pem_from_p12(self, p12_fname, p12_passwd, pem_fname):
|
||||
pwd = ipautil.write_tmp_file(p12_passwd)
|
||||
ipautil.run(["/usr/bin/openssl", "pkcs12", "-nodes",
|
||||
"-in", p12_fname, "-out", pem_fname,
|
||||
"-passin", "file:" + p12_pwd_fname])
|
||||
"-passin", "file:" + pwd.name])
|
||||
|
||||
def publish_ca_cert(self, location):
|
||||
shutil.copy(self.cacert_fname, location)
|
||||
|
||||
@@ -720,7 +720,7 @@ def check_pkcs12(pkcs12_info, ca_file, hostname):
|
||||
|
||||
Return a (server cert name, CA cert names) tuple
|
||||
"""
|
||||
pkcs12_filename, pin_filename = pkcs12_info
|
||||
pkcs12_filename, pkcs12_passwd = pkcs12_info
|
||||
root_logger.debug('Checking PKCS#12 certificate %s', pkcs12_filename)
|
||||
db_pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
|
||||
with certs.NSSDatabase() as nssdb:
|
||||
@@ -735,7 +735,7 @@ def check_pkcs12(pkcs12_info, ca_file, hostname):
|
||||
raise ScriptError(str(e))
|
||||
|
||||
# Import everything in the PKCS#12
|
||||
nssdb.import_pkcs12(pkcs12_filename, db_pwd_file.name, pin_filename)
|
||||
nssdb.import_pkcs12(pkcs12_filename, db_pwd_file.name, pkcs12_passwd)
|
||||
|
||||
# Check we have exactly one server cert (one with a private key)
|
||||
server_certs = nssdb.find_server_certs()
|
||||
|
||||
@@ -137,9 +137,8 @@ class ReplicaPrepare(admintool.AdminTool):
|
||||
"could not find directory instance: %s" % config_dir)
|
||||
|
||||
def check_pkcs12(self, pkcs12_file, pkcs12_pin):
|
||||
pin_file = ipautil.write_tmp_file(pkcs12_pin)
|
||||
installutils.check_pkcs12(
|
||||
pkcs12_info=(pkcs12_file, pin_file.name),
|
||||
pkcs12_info=(pkcs12_file, pkcs12_pin),
|
||||
ca_file='/etc/ipa/ca.crt',
|
||||
hostname=self.replica_fqdn)
|
||||
|
||||
|
||||
@@ -155,9 +155,8 @@ class ServerCertInstall(admintool.AdminTool):
|
||||
os.chown(os.path.join(dirname, 'secmod.db'), 0, pent.pw_gid)
|
||||
|
||||
def import_cert(self, dirname, pkcs12_passwd, old_cert, principal, command):
|
||||
pw = write_tmp_file(pkcs12_passwd)
|
||||
server_cert = installutils.check_pkcs12(
|
||||
pkcs12_info=(self.pkcs12_fname, pw.name),
|
||||
pkcs12_info=(self.pkcs12_fname, pkcs12_passwd),
|
||||
ca_file=CACERT,
|
||||
hostname=api.env.host)
|
||||
|
||||
@@ -167,7 +166,7 @@ class ServerCertInstall(admintool.AdminTool):
|
||||
cdb.untrack_server_cert(old_cert)
|
||||
|
||||
cdb.delete_cert(old_cert)
|
||||
cdb.import_pkcs12(self.pkcs12_fname, pw.name)
|
||||
cdb.import_pkcs12(self.pkcs12_fname, pkcs12_passwd)
|
||||
|
||||
if api.env.enable_ra:
|
||||
cdb.track_server_cert(server_cert, principal, cdb.passwd_fname,
|
||||
|
||||
Reference in New Issue
Block a user