Hi,

the attached patches fix <https://fedorahosted.org/freeipa/ticket/3897>.

Honza

--
Jan Cholasta
>From 494773e32198ab3416a96a70afdc8c0477409d6b Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 25 Sep 2013 08:33:35 +0000
Subject: [PATCH 1/2] 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
---
 install/tools/ipa-server-install            |  9 +++------
 ipaserver/install/certs.py                  | 22 ++++++++++++----------
 ipaserver/install/installutils.py           |  4 ++--
 ipaserver/install/ipa_replica_prepare.py    |  3 +--
 ipaserver/install/ipa_server_certinstall.py |  5 ++---
 5 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 028cca0..18f3a0f 100644
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -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()
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index f1b92fd..9ee854e 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -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)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 67c3fa9..67eabc2 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -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()
diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
index 904b872..55b81ee 100644
--- a/ipaserver/install/ipa_replica_prepare.py
+++ b/ipaserver/install/ipa_replica_prepare.py
@@ -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)
 
diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
index a9563e0..1aa27b2 100644
--- a/ipaserver/install/ipa_server_certinstall.py
+++ b/ipaserver/install/ipa_server_certinstall.py
@@ -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,
-- 
1.8.3.1

>From 27b6d28a5e50ff779a5c2f8eafe85921cc21eed2 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 25 Sep 2013 08:40:05 +0000
Subject: [PATCH 2/2] Allow PKCS#12 files with empty password in install tools.

https://fedorahosted.org/freeipa/ticket/3897
---
 install/tools/ipa-server-install            | 6 +++---
 ipaserver/install/ipa_replica_prepare.py    | 8 ++++----
 ipaserver/install/ipa_server_certinstall.py | 2 +-
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 18f3a0f..68e8ea8 100644
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -876,7 +876,7 @@ def main():
     ca_file = options.root_ca_file
 
     if options.http_pkcs12:
-        if not options.http_pin:
+        if options.http_pin is None:
             options.http_pin = installutils.read_password(
                 "Enter %s unlock" % options.http_pkcs12,
                 confirm=False, validate=False)
@@ -887,7 +887,7 @@ def main():
             http_pkcs12_info, ca_file, host_name)
 
     if options.dirsrv_pkcs12:
-        if not options.dirsrv_pin:
+        if options.dirsrv_pin is None:
             options.dirsrv_pin = installutils.read_password(
                 "Enter %s unlock" % options.dirsrv_pkcs12,
                 confirm=False, validate=False)
@@ -898,7 +898,7 @@ def main():
             dirsrv_pkcs12_info, ca_file, host_name)
 
     if options.pkinit_pkcs12:
-        if not options.pkinit_pin:
+        if options.pkinit_pin is None:
             options.pkinit_pin = installutils.read_password(
                 "Enter %s unlock" % options.pkinit_pkcs12,
                 confirm=False, validate=False)
diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
index 55b81ee..36d078a 100644
--- a/ipaserver/install/ipa_replica_prepare.py
+++ b/ipaserver/install/ipa_replica_prepare.py
@@ -209,7 +209,7 @@ class ReplicaPrepare(admintool.AdminTool):
                 raise admintool.ScriptError("Invalid reverse zone")
 
         if options.http_pkcs12:
-            if not options.http_pin:
+            if options.http_pin is None:
                 options.http_pin = installutils.read_password(
                     "Enter %s unlock" % options.http_pkcs12,
                     confirm=False, validate=False)
@@ -219,7 +219,7 @@ class ReplicaPrepare(admintool.AdminTool):
             self.check_pkcs12(options.http_pkcs12, options.http_pin)
 
         if options.dirsrv_pkcs12:
-            if not options.dirsrv_pin:
+            if options.dirsrv_pin is None:
                 options.dirsrv_pin = installutils.read_password(
                     "Enter %s unlock" % options.dirsrv_pkcs12,
                     confirm=False, validate=False)
@@ -229,7 +229,7 @@ class ReplicaPrepare(admintool.AdminTool):
             self.check_pkcs12(options.dirsrv_pkcs12, options.dirsrv_pin)
 
         if options.pkinit_pkcs12:
-            if not options.pkinit_pin:
+            if options.pkinit_pin is None:
                 options.pkinit_pin = installutils.read_password(
                     "Enter %s unlock" % options.pkinit_pkcs12,
                     confirm=False, validate=False)
@@ -239,7 +239,7 @@ class ReplicaPrepare(admintool.AdminTool):
 
         if (not ipautil.file_exists(
                     dogtag.configured_constants().CS_CFG_PATH) and
-                not options.dirsrv_pin):
+                options.dirsrv_pin is None):
             self.log.info("If you installed IPA with your own certificates "
                 "using PKCS#12 files you must provide PKCS#12 files for any "
                 "replicas you create as well.")
diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
index 1aa27b2..87c4eaf 100644
--- a/ipaserver/install/ipa_server_certinstall.py
+++ b/ipaserver/install/ipa_server_certinstall.py
@@ -87,7 +87,7 @@ class ServerCertInstall(admintool.AdminTool):
                 raise admintool.ScriptError(
                     "Directory Manager password required")
 
-        if not self.options.pin:
+        if self.options.pin is None:
             self.options.pin = installutils.read_password(
                 "Enter %s unlock" % self.args[0], confirm=False, validate=False)
             if self.options.pin is None:
-- 
1.8.3.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to