Do not wait for new CA certificate to appear in LDAP in ipa-certupdate

If new certificate is not available, reuse the old one, instead of waiting
indefinitely for the new certificate to appear.

https://fedorahosted.org/freeipa/ticket/4628

Reviewed-By: David Kupka <dkupka@redhat.com>
This commit is contained in:
Jan Cholasta 2014-10-14 11:12:55 +02:00 committed by Petr Viktorin
parent a649a84a1b
commit 35947c6e10
2 changed files with 54 additions and 41 deletions

View File

@ -279,6 +279,38 @@ def request_and_store_cert():
else:
return result
def retrieve_or_reuse_cert():
"""
Retrieve certificate from LDAP. If the certificate is not available, reuse
the old certificate.
"""
csr = os.environ.get('CERTMONGER_CSR')
if not csr:
return (UNCONFIGURED, "Certificate request not provided")
nickname = pkcs10.get_friendlyname(csr)
if not nickname:
return (REJECTED, "No friendly name in the certificate request")
cert = os.environ.get('CERTMONGER_CERTIFICATE')
if not cert:
return (REJECTED, "New certificate requests not supported")
with ldap_connect() as conn:
try:
entry = conn.get_entry(
DN(('cn', nickname), ('cn', 'ca_renewal'),
('cn', 'ipa'), ('cn', 'etc'), api.env.basedn),
['usercertificate'])
except errors.NotFound:
pass
else:
cert = entry.single_value['usercertificate']
cert = base64.b64encode(cert)
cert = x509.make_pem(cert)
return (ISSUED, cert)
def retrieve_cert():
"""
Retrieve new certificate from LDAP.
@ -298,45 +330,23 @@ def retrieve_cert():
else:
return (OPERATION_NOT_SUPPORTED_BY_HELPER,)
csr = os.environ.get('CERTMONGER_CSR')
if not csr:
return (UNCONFIGURED, "Certificate request not provided")
nickname = pkcs10.get_friendlyname(csr)
if not nickname:
return (REJECTED, "No friendly name in the certificate request")
old_cert = os.environ.get('CERTMONGER_CERTIFICATE')
if not old_cert:
return (REJECTED, "New certificate requests not supported")
old_cert = x509.normalize_certificate(old_cert)
if old_cert:
old_cert = x509.normalize_certificate(old_cert)
syslog.syslog(syslog.LOG_NOTICE, "Updating certificate for %s" % nickname)
result = call_handler(retrieve_or_reuse_cert)
if result[0] != ISSUED:
return result
with ldap_connect() as conn:
try:
entry = conn.get_entry(
DN(('cn', nickname), ('cn', 'ca_renewal'),
('cn', 'ipa'), ('cn', 'etc'), api.env.basedn),
['usercertificate'])
except errors.NotFound:
cert = old_cert
else:
cert = entry.single_value['usercertificate']
new_cert = x509.normalize_certificate(result[1])
if new_cert == old_cert:
attempts += 1
if attempts < 4:
syslog.syslog(syslog.LOG_INFO, "Updated certificate not available")
# No cert available yet, tell certmonger to wait another 8 hours
return (WAIT_WITH_DELAY, 8 * 60 * 60, str(attempts))
if cert == old_cert:
attempts += 1
if attempts < 4:
syslog.syslog(
syslog.LOG_INFO,
"Updated certificate for %s not available" % nickname)
# No cert available yet, tell certmonger to wait another 8 hours
return (WAIT_WITH_DELAY, 8 * 60 * 60, str(attempts))
cert = base64.b64encode(cert)
cert = x509.make_pem(cert)
return (ISSUED, cert)
return result
def export_csr():
"""
@ -414,10 +424,11 @@ def renew_ca_cert():
def main():
handlers = {
'ipaStorage': store_cert,
'ipaRetrieval': retrieve_cert,
'ipaCSRExport': export_csr,
'ipaCACertRenewal': renew_ca_cert,
'ipaStorage': store_cert,
'ipaRetrievalOrReuse': retrieve_or_reuse_cert,
'ipaRetrieval': retrieve_cert,
'ipaCSRExport': export_csr,
'ipaCACertRenewal': renew_ca_cert,
}
api.bootstrap(context='renew')

View File

@ -143,14 +143,16 @@ class CertUpdate(admintool.AdminTool):
timeout = api.env.startup_timeout + 60
self.log.debug("resubmitting certmonger request '%s'", request_id)
certmonger.resubmit_request(request_id, profile='ipaRetrieval')
certmonger.resubmit_request(
request_id, profile='ipaRetrievalOrReuse')
try:
state = certmonger.wait_for_request(request_id, timeout)
except RuntimeError:
raise admintool.ScriptError(
"Resubmitting certmonger request '%s' timed out, "
"please check the request manually" % request_id)
if state != 'MONITORING':
ca_error = certmonger.get_request_value(request_id, 'ca-error')
if state != 'MONITORING' or ca_error:
raise admintool.ScriptError(
"Error resubmitting certmonger request '%s', "
"please check the request manually" % request_id)