From 025cfd911bce6214ef2b4311b16c5b6df6ad173a Mon Sep 17 00:00:00 2001 From: Florence Blanc-Renaud Date: Jun 30 2016 12:53:37 +0000 Subject: 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 Reviewed-By: Stanislav Laznicka --- diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py index a7af319..5ab4730 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))