URL: https://github.com/freeipa/freeipa/pull/1297
Author: tiran
 Title: #1297: Remove Custodia keys on uninstall
Action: opened

PR body:
"""
Keys are removed from disk and LDAP

https://pagure.io/freeipa/issue/7253

Signed-off-by: Christian Heimes <chei...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1297/head:pr1297
git checkout pr1297
From c0dde9ab0599ca54d56367f1a19050532f9ce7cc Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Thu, 16 Nov 2017 17:01:55 +0100
Subject: [PATCH] Remove Custodia keys on uninstall

Keys are removed from disk and LDAP

https://pagure.io/freeipa/issue/7253

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 ipaserver/install/cainstance.py       |  6 +++++
 ipaserver/install/custodiainstance.py | 19 ++++++++++---
 ipaserver/secrets/kem.py              | 51 ++++++++++++++++++++++++++++++-----
 3 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 8e0e69888a..6165fd1922 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -1280,6 +1280,12 @@ def __setup_lightweight_ca_key_retrieval_custodia(self):
         os.chmod(keyfile, 0o600)
         os.chown(keyfile, pent.pw_uid, pent.pw_gid)
 
+    def __remove_lightweight_ca_key_retrieval_custodia(self):
+        keyfile = os.path.join(paths.PKI_TOMCAT,
+                               self.service_prefix + '.keys')
+        keystore = IPAKEMKeys({'server_keys': keyfile})
+        keystore.remove_keys(self.service_prefix)
+
     def add_lightweight_ca_tracking_requests(self):
         try:
             lwcas = api.Backend.ldap2.get_entries(
diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
index 7ca23b4083..98431b45e7 100644
--- a/ipaserver/install/custodiainstance.py
+++ b/ipaserver/install/custodiainstance.py
@@ -2,6 +2,7 @@
 
 from __future__ import print_function
 
+import errno
 import logging
 
 from ipaserver.secrets.kem import IPAKEMKeys, KEMLdap
@@ -64,10 +65,22 @@ def create_instance(self):
                                                       realm=self.realm)
         sysupgrade.set_upgrade_state('custodia', 'installed', True)
 
+    def uninstall(self):
+        keystore = IPAKEMKeys({
+            'server_keys': self.server_keys,
+            'ldap_uri': self.ldap_uri
+        })
+        keystore.remove_server_keys()
+        installutils.remove_file(self.config_file)
+        sysupgrade.set_upgrade_state('custodia', 'installed', False)
+        super(CustodiaInstance, self).uninstall()
+
     def __gen_keys(self):
-        KeyStore = IPAKEMKeys({'server_keys': self.server_keys,
-                               'ldap_uri': self.ldap_uri})
-        KeyStore.generate_server_keys()
+        keystore = IPAKEMKeys({
+            'server_keys': self.server_keys,
+            'ldap_uri': self.ldap_uri
+        })
+        keystore.generate_server_keys()
 
     def upgrade_instance(self):
         if not sysupgrade.get_upgrade_state("custodia", "installed"):
diff --git a/ipaserver/secrets/kem.py b/ipaserver/secrets/kem.py
index 8fecd5bb58..28991e097a 100644
--- a/ipaserver/secrets/kem.py
+++ b/ipaserver/secrets/kem.py
@@ -1,6 +1,8 @@
 # Copyright (C) 2015  IPA Project Contributors, see COPYING for license
 
 from __future__ import print_function
+
+import errno
 import os
 
 # pylint: disable=import-error
@@ -124,6 +126,12 @@ def _format_public_key(self, key):
             encoding=serialization.Encoding.DER,
             format=serialization.PublicFormat.SubjectPublicKeyInfo)
 
+    def _get_dn(self, usage, principal):
+        servicename, host = principal.split('@')[0].split('/')
+        name = '%s/%s' % (KEY_USAGE_MAP[usage], host)
+        service_rdn = ('cn', servicename) if servicename != 'host' else DN()
+        return DN(('cn', name), service_rdn, self.keysbase)
+
     def set_key(self, usage, principal, key):
         """
         Write key for the host or service.
@@ -137,24 +145,35 @@ def set_key(self, usage, principal, key):
 
         """
         public_key = self._format_public_key(key)
+        dn = self._get_name(usage, principal)
         conn = self.connect()
-        servicename, host = principal.split('@')[0].split('/')
-        name = '%s/%s' % (KEY_USAGE_MAP[usage], host)
-        service_rdn = ('cn', servicename) if servicename != 'host' else DN()
-        dn = str(DN(('cn', name), service_rdn, self.keysbase))
         try:
             mods = [('objectClass', [b'nsContainer',
                                      b'ipaKeyPolicy',
                                      b'ipaPublicKeyObject',
                                      b'groupOfPrincipals']),
-                    ('cn', name.encode('utf-8')),
+                    ('cn', dn[0].value.encode('utf-8')),
                     ('ipaKeyUsage', RFC5280_USAGE_MAP[usage].encode('utf-8')),
                     ('memberPrincipal', principal.encode('utf-8')),
                     ('ipaPublicKey', public_key)]
-            conn.add_s(dn, mods)
+            conn.add_s(str(dn), mods)
         except ldap.ALREADY_EXISTS:
             mods = [(ldap.MOD_REPLACE, 'ipaPublicKey', public_key)]
-            conn.modify_s(dn, mods)
+            conn.modify_s(str(dn), mods)
+
+    def del_key(self, usage, principal):
+        """Delete key for host or service
+
+        :returns: DN of removed key or None when key was not found
+        """
+        dn = self._get_dn(usage, principal)
+        conn = self.connect()
+        try:
+            conn.delete_s(str(dn))
+        except ldap.NO_SUCH_OBJECT:
+            return None
+        else:
+            return dn
 
 
 def newServerKeys(path, keyid):
@@ -216,6 +235,24 @@ def generate_keys(self, servicename):
         ldapconn.set_key(KEY_USAGE_SIG, principal, pubkeys[0])
         ldapconn.set_key(KEY_USAGE_ENC, principal, pubkeys[1])
 
+    def remove_server_keys(self):
+        """Remove keys from LDAP and disk
+        """
+        self.remove_keys('host')
+
+    def remove_keys(self, servicename):
+        """Remove keys from LDAP and disk
+        """
+        principal = '%s/%s@%s' % (servicename, self.host, self.realm)
+        ldapconn = KEMLdap(self.ldap_uri)
+        ldapconn.del_key(KEY_USAGE_SIG, principal)
+        ldapconn.del_key(KEY_USAGE_ENC, principal)
+        try:
+            os.unlink(self.config['server_keys'])
+        except OSError as e:
+            if e.errno != errno.ENOENT:
+                raise
+
     @property
     def server_keys(self):
         if self._server_keys is None:
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to