From 5fa2b9d411c7c35266fa1c9726d91243ba2b02d6 Mon Sep 17 00:00:00 2001 From: Jan Cholasta 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 --- .../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