From 5d8cb1dd1fbfbdb7feb7f33c60eb6066f48aa563 Mon Sep 17 00:00:00 2001 From: Antonio Torres Date: Mon, 8 Feb 2021 16:59:53 +0100 Subject: [PATCH] ipa-cacert-manage: add prune option Add prune option to ipa-cacert-manage, allowing to remove all expired certificates from the certificate store. Related: https://pagure.io/freeipa/issue/7404 Signed-off-by: Antonio Torres Reviewed-By: Rob Crittenden --- install/tools/man/ipa-cacert-manage.1 | 9 ++++++ ipaserver/install/ipa_cacert_manage.py | 42 ++++++++++++++++++++------ 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/install/tools/man/ipa-cacert-manage.1 b/install/tools/man/ipa-cacert-manage.1 index c9923846b..8913fe5d2 100644 --- a/install/tools/man/ipa-cacert-manage.1 +++ b/install/tools/man/ipa-cacert-manage.1 @@ -27,6 +27,8 @@ ipa\-cacert\-manage \- Manage CA certificates in IPA \fBipa\-cacert\-manage\fR [\fIOPTIONS\fR...] delete \fINICKNAME\fR .br \fBipa\-cacert\-manage\fR [\fIOPTIONS\fR...] list +.br +\fBipa\-cacert\-manage\fR [\fIOPTIONS\fR...] prune .SH "DESCRIPTION" \fBipa\-cacert\-manage\fR can be used to manage CA certificates in IPA. .SH "COMMANDS" @@ -72,6 +74,13 @@ Please do not forget to run ipa-certupdate on the master, all the replicas and a .RS Display a list of the nicknames or subjects of the CA certificates that have been installed. .RE +.TP +\fBprune\fR +\- Prune the stored CA certificates +.sp +.RS +Removes installed CA certificates that are expired. +.RE .SH "COMMON OPTIONS" .TP \fB\-\-version\fR diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py index e57f78c80..28facc353 100644 --- a/ipaserver/install/ipa_cacert_manage.py +++ b/ipaserver/install/ipa_cacert_manage.py @@ -19,6 +19,7 @@ from __future__ import print_function, absolute_import +import datetime import logging import os from optparse import OptionGroup # pylint: disable=deprecated-module @@ -46,7 +47,7 @@ class CACertManage(admintool.AdminTool): command_name = 'ipa-cacert-manage' usage = "%prog renew [options]\n%prog install [options] CERTFILE\n" \ - "%prog delete [options] NICKNAME\n%prog list" + "%prog delete [options] NICKNAME\n%prog list\n%prog prune" description = "Manage CA certificates." @@ -115,18 +116,14 @@ class CACertManage(admintool.AdminTool): command = self.command = self.args[0] - if command == 'renew': - pass + if command not in ('renew', 'list', 'install', 'delete', 'prune'): + parser.error("unknown command \"%s\"" % command) elif command == 'install': if len(self.args) < 2: parser.error("certificate file name not provided") - elif command == 'list': - pass elif command == 'delete': if len(self.args) < 2: parser.error("nickname not provided") - else: - parser.error("unknown command \"%s\"" % command) def run(self): command = self.command @@ -145,6 +142,8 @@ class CACertManage(admintool.AdminTool): return self.list() elif command == 'delete': return self.delete() + elif command == 'prune': + return self.prune() else: raise NotImplementedError finally: @@ -481,9 +480,7 @@ class CACertManage(admintool.AdminTool): for _ca_cert, ca_nickname, _ca_trust_flags in ca_certs: print(ca_nickname) - def delete(self): - options = self.options - nickname = self.args[1] + def _delete_by_nickname(self, nickname, options): conn = api.Backend.ldap2 ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, @@ -546,6 +543,31 @@ class CACertManage(admintool.AdminTool): conn.delete_entry(dn) return + def delete(self): + nickname = self.args[1] + self._delete_by_nickname(nickname, self.options) + + def prune(self): + expired_certs = [] + ca_certs = certstore.get_ca_certs_nss(api.Backend.ldap2, + api.env.basedn, + api.env.realm, + False) + + now = datetime.datetime.utcnow() + for ca_cert, ca_nickname, _ca_trust_flags in ca_certs: + if ca_cert.not_valid_after < now: + expired_certs.append(ca_nickname) + self._delete_by_nickname(ca_nickname, self.options) + + if expired_certs: + print("Expired certificates deleted:") + for nickname in expired_certs: + print(nickname) + print("Run ipa-certupdate on enrolled machines to apply changes.") + else: + print("No certificates were deleted") + def update_ipa_ca_entry(api, cert): """