Use dogtag-ipa-ca-renew-agent to track certificates on master CA.

Before, dogtag-ipa-renew-agent was used to track the certificates and the
certificates were stored to LDAP in renew_ca_cert and renew_ra_cert. Since
dogtag-ipa-ca-renew-agent can store the certificates itself, the storage code
was removed from renew_ca_cert and renew_ra_cert.

Reviewed-By: Petr Viktorin <pviktori@redhat.com>
This commit is contained in:
Jan Cholasta 2013-10-16 08:40:31 +00:00 committed by Petr Viktorin
parent a356c3806b
commit 6a19738a45
4 changed files with 53 additions and 121 deletions

View File

@ -2,8 +2,9 @@
#
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Jan Cholasta <jcholast@redhat.com>
#
# Copyright (C) 2012 Red Hat
# Copyright (C) 2013 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
@ -19,29 +20,18 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
import shutil
import tempfile
import os
import syslog
import random
import time
import tempfile
import shutil
import traceback
from ipalib import api
from ipapython.dn import DN
from ipalib import errors
from ipapython import services as ipaservices
from ipapython import ipautil
from ipapython import dogtag
from ipaserver.install import certs
from ipaserver.install.cainstance import update_people_entry
from ipaserver.plugins.ldap2 import ldap2
from ipaserver.install.cainstance import update_cert_config
from ipapython import certmonger
# This script a post-cert-install command for certmonger. When certmonger
# has renewed a CA subsystem certificate a copy is put into the replicated
# tree so it can be shared with the other IPA servers.
from ipapython import dogtag, certmonger, ipautil
from ipapython import services as ipaservices
from ipalib import api, errors, x509, util
from ipaserver.install import certs, cainstance, installutils
from ipaserver.plugins.ldap2 import ldap2
def main():
nickname = sys.argv[1]
@ -57,40 +47,13 @@ def main():
# Fetch the new certificate
db = certs.CertDB(api.env.realm, nssdir=alias_dir)
cert = db.get_cert_from_db(nickname, pem=False)
if not cert:
syslog.syslog(syslog.LOG_ERR, 'No certificate %s found.' % nickname)
sys.exit(1)
# Update or add it
tmpdir = tempfile.mkdtemp(prefix = "tmp-")
try:
dn = DN(('cn',nickname), ('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
conn.connect(ccache=ccache)
try:
entry_attrs = conn.get_entry(dn, ['usercertificate'])
entry_attrs['usercertificate'] = cert
conn.update_entry(entry_attrs)
except errors.NotFound:
entry_attrs = conn.make_entry(
dn,
objectclass=['top', 'pkiuser', 'nscontainer'],
usercertificate=[cert])
conn.add_entry(entry_attrs)
except errors.EmptyModlist:
pass
conn.disconnect()
except Exception, e:
syslog.syslog(syslog.LOG_ERR, 'Updating renewal certificate failed: %s' % e)
finally:
shutil.rmtree(tmpdir)
# Done withing stopped_service context, CA restarted here
update_cert_config(nickname, cert)
update_people_entry(cert)
cainstance.update_cert_config(nickname, cert, configured_constants)
cainstance.update_people_entry(cert)
if nickname == 'auditSigningCert cert-pki-ca':
# Fix trust on the audit cert

View File

@ -2,8 +2,9 @@
#
# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Jan Cholasta <jcholast@redhat.com>
#
# Copyright (C) 2012 Red Hat
# Copyright (C) 2013 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
@ -20,19 +21,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import shutil
import tempfile
import syslog
import time
import traceback
from ipapython import services as ipaservices
from ipapython import ipautil
from ipaserver.install import certs
from ipaserver.install.cainstance import update_people_entry
from ipalib import api
from ipapython.dn import DN
from ipalib import errors
from ipaserver.plugins.ldap2 import ldap2
from ipaserver.install import certs, cainstance
nickname = 'ipaCert'
def main():
api.bootstrap(context='restart')
@ -40,58 +36,22 @@ def main():
# Fetch the new certificate
db = certs.CertDB(api.env.realm)
dercert = db.get_cert_from_db('ipaCert', pem=False)
# Load it into dogtag
update_people_entry(dercert)
attempts = 0
updated = False
# Store it in the IPA LDAP server
while attempts < 10:
conn = None
tmpdir = None
try:
tmpdir = tempfile.mkdtemp(prefix="tmp-")
dn = DN(('cn','ipaCert'), ('cn', 'ca_renewal'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
principal = str('host/%s@%s' % (api.env.host, api.env.realm))
ccache = ipautil.kinit_hostprincipal('/etc/krb5.keytab', tmpdir, principal)
conn = ldap2(shared_instance=False, ldap_uri=api.env.ldap_uri)
conn.connect(ccache=ccache)
try:
entry_attrs = conn.get_entry(dn, ['usercertificate'])
entry_attrs['usercertificate'] = dercert
conn.update_entry(entry_attrs)
except errors.NotFound:
entry_attrs = conn.make_entry(
dn,
objectclass=['top', 'pkiuser', 'nscontainer'],
usercertificate=[dercert])
conn.add_entry(entry_attrs)
except errors.EmptyModlist:
pass
updated = True
break
except Exception, e:
syslog.syslog(syslog.LOG_ERR, 'Updating renewal certificate failed: %s. Sleeping 30s' % e)
time.sleep(30)
attempts += 1
finally:
if conn is not None and conn.isconnected():
conn.disconnect()
if tmpdir is not None:
shutil.rmtree(tmpdir)
if not updated:
syslog.syslog(syslog.LOG_ERR, '%s: Giving up. This script may be safely re-executed.' % sys.argv[0])
dercert = db.get_cert_from_db(nickname, pem=False)
if not dercert:
syslog.syslog(syslog.LOG_ERR, 'No certificate %s found.' % nickname)
sys.exit(1)
# Load it into dogtag
cainstance.update_people_entry(dercert)
# Now restart Apache so the new certificate is available
syslog.syslog(syslog.LOG_NOTICE, "Restarting httpd")
try:
ipaservices.knownservices.httpd.restart()
except Exception, e:
syslog.syslog(syslog.LOG_ERR, "Cannot restart httpd: %s" % str(e))
syslog.syslog(syslog.LOG_ERR, "Cannot restart httpd: %s" % e)
else:
syslog.syslog(syslog.LOG_NOTICE, "Restarted httpd")
try:
main()

View File

@ -607,10 +607,10 @@ def enable_certificate_renewal(ca):
return False
if not sysupgrade.get_upgrade_state('dogtag', 'renewal_configured'):
ca.configure_certmonger_renewal()
if ca.is_master():
ca.configure_renewal()
else:
ca.configure_certmonger_renewal()
ca.configure_clone_renewal()
ca.configure_agent_renewal()
ca.track_servercert()
@ -656,10 +656,10 @@ def certificate_renewal_stop_ca(ca):
# Ok, now we need to stop tracking, then we can start tracking them
# again with new configuration:
cainstance.stop_tracking_certificates(dogtag.configured_constants())
ca.configure_certmonger_renewal()
if ca.is_master():
ca.configure_renewal()
else:
ca.configure_certmonger_renewal()
ca.configure_clone_renewal()
ca.configure_agent_renewal()
ca.track_servercert()

View File

@ -470,9 +470,10 @@ class CAInstance(service.Service):
self.step("requesting RA certificate from CA", self.__request_ra_certificate)
self.step("issuing RA agent certificate", self.__issue_ra_cert)
self.step("adding RA agent as a trusted user", self.__configure_ra)
self.step("configure certmonger for renewals", self.configure_certmonger_renewal)
if not self.clone:
self.step("configure certificate renewals", self.configure_renewal)
else:
self.step("configure certmonger for renewals", self.configure_certmonger_renewal)
self.step("configure clone certificate renewals", self.configure_clone_renewal)
self.step("configure Server-Cert certificate renewal", self.track_servercert)
self.step("Configure HTTP to proxy connections", self.__http_proxy)
@ -1428,11 +1429,6 @@ class CAInstance(service.Service):
"certmonger failed to start tracking certificate: %s" % str(e))
def configure_renewal(self):
cmonger = ipaservices.knownservices.certmonger
cmonger.enable()
ipaservices.knownservices.messagebus.start()
cmonger.start()
pin = self.__get_ca_pin()
# Server-Cert cert-pki-ca is renewed per-server
@ -1441,28 +1437,41 @@ class CAInstance(service.Service):
'subsystemCert cert-pki-ca']:
try:
certmonger.dogtag_start_tracking(
'dogtag-ipa-renew-agent', nickname, pin, None,
self.dogtag_constants.ALIAS_DIR, 'stop_pkicad', 'renew_ca_cert "%s"' % nickname)
ca='dogtag-ipa-ca-renew-agent',
nickname=nickname,
pin=pin,
pinfile=None,
secdir=self.dogtag_constants.ALIAS_DIR,
pre_command='stop_pkicad',
post_command='renew_ca_cert "%s"' % nickname)
except (ipautil.CalledProcessError, RuntimeError), e:
root_logger.error(
"certmonger failed to start tracking certificate: %s" % str(e))
"certmonger failed to start tracking certificate: "
"%s" % e)
# Set up the agent cert for renewal
try:
certmonger.dogtag_start_tracking('dogtag-ipa-renew-agent', 'ipaCert', None, '/etc/httpd/alias/pwdfile.txt', '/etc/httpd/alias', None, 'renew_ra_cert')
certmonger.dogtag_start_tracking(
ca='dogtag-ipa-ca-renew-agent',
nickname='ipaCert',
pin=None,
pinfile='/etc/httpd/alias/pwdfile.txt',
secdir='/etc/httpd/alias',
pre_command=None,
post_command='renew_ra_cert')
except (ipautil.CalledProcessError, RuntimeError), e:
root_logger.error(
"certmonger failed to start tracking certificate: %s" % str(e))
root_logger.error(
"certmonger failed to start tracking certificate: %s" % e)
def configure_certmonger_renewal(self):
"""
Create a new CA type for certmonger that will retrieve updated
certificates from the dogtag master server.
"""
ipaservices.knownservices.messagebus.start()
cmonger = ipaservices.knownservices.certmonger
cmonger.enable()
ipaservices.knownservices.messagebus.start()
cmonger.restart()
cmonger.start()
bus = dbus.SystemBus()
obj = bus.get_object('org.fedorahosted.certmonger',