From 1b940d39f3908c3ce18a16c45c6ac06c9b704d8e 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 --- .../dogtag-ipa-ca-renew-agent-submit | 89 +++++++++++-------- ipa-client/ipaclient/ipa_certupdate.py | 6 +- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit index ca4380c33..9a01eb3a0 100755 --- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit +++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit @@ -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') diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py index 7ef11d058..031a34c3a 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)