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 <slaznick@redhat.com>
This commit is contained in:
Florence Blanc-Renaud 2016-06-21 16:34:21 +02:00 committed by Petr Vobornik
parent f3858be6e3
commit 025cfd911b

View File

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