Hi,
the attached patch fixes https://fedorahosted.org/freeipa/ticket/4629.
It depends on my patches 333 and 334, which are also attached.
(The original patch was posted at
http://www.redhat.com/archives/freeipa-devel/2014-September/msg00454.html.)
How to test:
1. install server
2. kinit as admin
3. run ipa-cacert-manage renew --external-ca, it will produce a CSR
4. sign the CSR with some external CA to get new IPA CA certificate
5. run while true; do ldapdelete -H ldap://$HOSTNAME -Y GSSAPI
'cn=caSigningCert cert-pki-ca,cn=ca_renewal,cn=ipa,cn=etc,suffix';
done in background
6. run ipa-cacert-manage renew --external-cert-file=path to new IPA
CA certificate --external-cert-file=path to external CA certificate
chain
7. stop the loop from step 5
8. run getcert list -d /etc/pki/pki-tomcat/alias -n 'caSigningCert
cert-pki-ca', the request should be in MONITORING state, there should
be no ca-error
Honza
--
Jan Cholasta
From 6ac462b18d0a31d8eb697e949bc909327f41d618 Mon Sep 17 00:00:00 2001
From: Jan Cholasta jchol...@redhat.com
Date: Tue, 14 Oct 2014 10:30:07 +0200
Subject: [PATCH] Handle profile changes in dogtag-ipa-ca-renew-agent
To update the CA certificate in the Dogtag NSS database, the
ipa-cacert-manage renew and ipa-certupdate commands temporarily change
the profile of the CA certificate certmonger request, resubmit it and
change the profile back to the original one.
When something goes wrong while resubmitting the request, it needs to be
modified and resubmitted again manually. This might fail with invalid
cookie error, because changing the profile does not change the internal
state of the request.
Detect this in dogtag-ipa-ca-renew-agent and reset the internal state when
profile is changed.
https://fedorahosted.org/freeipa/ticket/4627
---
.../certmonger/dogtag-ipa-ca-renew-agent-submit| 87 --
1 file changed, 80 insertions(+), 7 deletions(-)
diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
index 4f0b78a..ca4380c 100755
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
@@ -31,6 +31,7 @@ import tempfile
import shutil
import base64
import contextlib
+import json
from ipapython import ipautil
from ipapython.dn import DN
@@ -64,6 +65,78 @@ def ldap_connect():
if conn is not None and conn.isconnected():
conn.disconnect()
+def call_handler(_handler, *args, **kwargs):
+
+Request handler call wrapper
+
+Before calling the handler, get the original profile name and cookie from
+the provided cookie, if there is one. If the profile name does not match
+the requested profile name, drop the cookie and restart the request.
+
+After calling the handler, put the requested profile name and cookie
+returned by the handler in a new cookie and return it.
+
+operation = os.environ['CERTMONGER_OPERATION']
+if operation == 'POLL':
+cookie = os.environ.pop('CERTMONGER_CA_COOKIE', None)
+if cookie is not None:
+try:
+context = json.loads(cookie)
+if not isinstance(context, dict):
+raise TypeError
+except (TypeError, ValueError):
+return (UNCONFIGURED, Invalid cookie: %r % cookie)
+else:
+return (UNCONFIGURED, Cookie not provided)
+
+if 'profile' in context:
+profile = context.pop('profile')
+try:
+if profile is not None:
+if not isinstance(profile, unicode):
+raise TypeError
+profile = profile.encode('raw_unicode_escape')
+except (TypeError, UnicodeEncodeError):
+return (UNCONFIGURED,
+Invalid 'profile' in cookie: %r % profile)
+else:
+return (UNCONFIGURED, No 'profile' in cookie)
+
+# If profile has changed between SUBMIT and POLL, restart request
+if os.environ.get('CERTMONGER_CA_PROFILE') != profile:
+os.environ['CERTMONGER_OPERATION'] = 'SUBMIT'
+context = {}
+
+if 'cookie' in context:
+cookie = context.pop('cookie')
+try:
+if not isinstance(cookie, unicode):
+raise TypeError
+cookie = cookie.encode('raw_unicode_escape')
+except (TypeError, UnicodeEncodeError):
+return (UNCONFIGURED,
+Invalid 'cookie' in cookie: %r % cookie)
+os.environ['CERTMONGER_CA_COOKIE'] = cookie
+else:
+context = {}
+
+result = _handler(*args, **kwargs)
+
+if result[0] in (WAIT, WAIT_WITH_DELAY):
+context['cookie'] = result[-1].decode('raw_unicode_escape')
+
+profile = os.environ.get('CERTMONGER_CA_PROFILE')
+if profile is not None:
+profile