Hi,

This patch fixes ipa-server-certinstall when used with 3rd-party certs.
The scenario is the following:
- install the server with an embedded CA
- use ipa-cacert-manage to install a 3rd party CA
- use ipa-certupdate to put the 3rd party CA cert in the relevant NSS databases (/etc/ipa/nssdb /etc/httpd/alias /etc/pki/pki-tomcat/alias and /etc/dirsrv/slapd-XXX) - use ipa-server-certinstall to replace the Directory/Apache server certificates with a cert signed by the 3rd party CA.

Note that I had to run ipa-certupdate after putting selinux mode to permissive (otherwise the cert does not get into /etc/pki/pki-tomcat/alias) and a bz has been opened against selinux-policy to solve this issue.

https://fedorahosted.org/freeipa/ticket/4785
https://fedorahosted.org/freeipa/ticket/4786
>From 031c26cd4a3fc9c8cbcf40544e256b2cdfea639f Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <fren...@redhat.com>
Date: Tue, 21 Jun 2016 16:34:21 +0200
Subject: [PATCH] Fix ipa-server-certinstall with certs signed by 3rd-party CA

Multiple issues fixed:
- when untracking a certificate, the path to the NSS directory must be
exactly identical (no trailing /), otherwise the request is not found
and the old certificate is still tracked.

- when a cert is issued by a 3rd party CA, no need to track it

- the server_cert should not be found using cdb.find_server_certs()[0][0]
because this function can return multiple server certificates. For
instance, /etc/httpd/alias contains ipaCert, Server-Cert and Signing-Cert
with the trust flags u,u,u. This leads to trying to track ipaCert (which is
already tracked).
The workaround is looking for server certs before and after the import,
and extract server-cert as the certificate in the second list but not in the
first list.

https://fedorahosted.org/freeipa/ticket/4785
https://fedorahosted.org/freeipa/ticket/4786
---
 ipaserver/install/ipa_server_certinstall.py | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py
index a7af319c62a5d25cfa16400375807f1762a6b933..5ab47303add479c7c492c251b0cf6646de681a4b 100644
--- a/ipaserver/install/ipa_server_certinstall.py
+++ b/ipaserver/install/ipa_server_certinstall.py
@@ -26,6 +26,7 @@ import optparse
 from ipaplatform.constants import constants
 from ipaplatform.paths import paths
 from ipapython import admintool
+from ipapython.certdb import get_ca_nickname
 from ipapython.dn import DN
 from ipalib import api, errors
 from ipalib.constants import CACERT
@@ -163,6 +164,7 @@ class ServerCertInstall(admintool.AdminTool):
             ca_cert_files=[CACERT],
             host_name=api.env.host)
 
+        dirname = os.path.normpath(dirname)
         cdb = certs.CertDB(api.env.realm, nssdir=dirname)
         try:
             ca_enabled = api.Command.ca_is_enabled()['result']
@@ -170,12 +172,24 @@ class ServerCertInstall(admintool.AdminTool):
                 cdb.untrack_server_cert(old_cert)
 
             cdb.delete_cert(old_cert)
+            prevs = cdb.find_server_certs()
             cdb.import_pkcs12(pkcs12_file.name, pin)
-            server_cert = cdb.find_server_certs()[0][0]
+            news = cdb.find_server_certs()
+            server_certs = [item for item in news if item not in prevs]
+            server_cert = server_certs[0][0]
 
             if ca_enabled:
-                cdb.track_server_cert(server_cert, principal, cdb.passwd_fname,
-                                      command)
+                # Start tracking only if the cert was issued by IPA CA
+                # Retrieve IPA CA
+                ipa_ca_cert = cdb.get_cert_from_db(
+                    get_ca_nickname(api.env.realm),
+                    pem=False)
+                # And compare with the CA which signed this certificate
+                if ca_cert == ipa_ca_cert:
+                    cdb.track_server_cert(server_cert,
+                                          principal,
+                                          cdb.passwd_fname,
+                                          command)
         except RuntimeError as e:
             raise admintool.ScriptError(str(e))
 
-- 
2.7.4

-- 
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

Reply via email to