From 5fa2b9d411c7c35266fa1c9726d91243ba2b02d6 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jcholast@redhat.com>
Date: Tue, 14 Oct 2014 11:12:55 +0200
Subject: [PATCH] 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>
---
.../certmonger/dogtag-ipa-ca-renew-agent-submit | 87 ++++++++++++----------
ipa-client/ipaclient/ipa_certupdate.py | 6 +-
2 files changed, 53 insertions(+), 40 deletions(-)
diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
index ca4380c331cc417c0a89eca17e987920118337d7..9a01eb3a08900a5c8d04953b41f4493f30c2b56f 100755
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
@@ -279,25 +279,11 @@ def request_and_store_cert():
else:
return result
-def retrieve_cert():
+def retrieve_or_reuse_cert():
"""
- Retrieve new certificate from LDAP.
+ Retrieve certificate from LDAP. If the certificate is not available, reuse
+ the old certificate.
"""
- operation = os.environ.get('CERTMONGER_OPERATION')
- if operation == 'SUBMIT':
- attempts = 0
- elif operation == 'POLL':
- cookie = os.environ.get('CERTMONGER_CA_COOKIE')
- if not cookie:
- return (UNCONFIGURED, "Cookie not provided")
-
- try:
- attempts = int(cookie)
- except ValueError:
- return (UNCONFIGURED, "Invalid cookie: %r" % cookie)
- else:
- return (OPERATION_NOT_SUPPORTED_BY_HELPER,)
-
csr = os.environ.get('CERTMONGER_CSR')
if not csr:
return (UNCONFIGURED, "Certificate request not provided")
@@ -306,12 +292,9 @@ def retrieve_cert():
if not nickname:
return (REJECTED, "No friendly name in the certificate request")
- old_cert = os.environ.get('CERTMONGER_CERTIFICATE')
- if not old_cert:
+ cert = os.environ.get('CERTMONGER_CERTIFICATE')
+ if not cert:
return (REJECTED, "New certificate requests not supported")
- old_cert = x509.normalize_certificate(old_cert)
-
- syslog.syslog(syslog.LOG_NOTICE, "Updating certificate for %s" % nickname)
with ldap_connect() as conn:
try:
@@ -320,23 +303,50 @@ def retrieve_cert():
('cn', 'ipa'), ('cn', 'etc'), api.env.basedn),
['usercertificate'])
except errors.NotFound:
- cert = old_cert
+ 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.
+ """
+ operation = os.environ.get('CERTMONGER_OPERATION')
+ if operation == 'SUBMIT':
+ attempts = 0
+ elif operation == 'POLL':
+ cookie = os.environ.get('CERTMONGER_CA_COOKIE')
+ if not cookie:
+ return (UNCONFIGURED, "Cookie not provided")
+
+ try:
+ attempts = int(cookie)
+ except ValueError:
+ return (UNCONFIGURED, "Invalid cookie: %r" % cookie)
+ else:
+ return (OPERATION_NOT_SUPPORTED_BY_HELPER,)
- 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))
+ old_cert = os.environ.get('CERTMONGER_CERTIFICATE')
+ if old_cert:
+ old_cert = x509.normalize_certificate(old_cert)
- cert = base64.b64encode(cert)
- cert = x509.make_pem(cert)
+ result = call_handler(retrieve_or_reuse_cert)
+ if result[0] != ISSUED:
+ return result
- return (ISSUED, cert)
+ 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))
+
+ 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')
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index 7ef11d058eeeb47dc47d46aa7cbe73578c42d131..031a34c3a54a02d43978eedcb794678a1550702b 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -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)
--
2.1.0