Blame SOURCES/0005-Add-check-for-IPA-KRA-Agent.patch

6457ff
From 3f6ed4393dfa9ddf982e326065a3ea160bef90b6 Mon Sep 17 00:00:00 2001
6457ff
From: Antonio Torres <antorres@redhat.com>
6457ff
Date: Tue, 23 Feb 2021 16:11:59 +0100
6457ff
Subject: [PATCH] Add check for IPA KRA Agent
6457ff
6457ff
Add check to validate KRA Agent in case KRA is installed, including
6457ff
checking for the KRA Agent LDAP entry.
6457ff
6457ff
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1894781
6457ff
Signed-off-by: Antonio Torres <antorres@redhat.com>
6457ff
---
6457ff
 README.md                       |  16 ++-
6457ff
 src/ipahealthcheck/ipa/certs.py | 167 +++++++++++++++++++-------------
6457ff
 2 files changed, 112 insertions(+), 71 deletions(-)
6457ff
6457ff
diff --git a/README.md b/README.md
6457ff
index b9c60a2..0f3ed6a 100644
6457ff
--- a/README.md
6457ff
+++ b/README.md
6457ff
@@ -547,7 +547,21 @@ Verify the description and userCertificate values in uid=ipara,ou=People,o=ipaca
6457ff
       "kw": {
6457ff
         "expected": "2;125;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST",
6457ff
         "got": "2;7;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST",
6457ff
-        "msg": "RA agent description does not match 2;7;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST in LDAP and expected 2;125;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST"
6457ff
+        "msg": "RA agent description does not match. Found 2;7;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST in LDAP and expected 2;125;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST"
6457ff
+      }
6457ff
+    }
6457ff
+
6457ff
+### IPAKRAAgent
6457ff
+Verify the description and userCertificate values in uid=ipakra,ou=people,o=kra,o=ipaca.
6457ff
+
6457ff
+    {
6457ff
+      "source": "ipahealthcheck.ipa.certs",
6457ff
+      "check": "IPAKRAAgent",
6457ff
+      "result": "ERROR",
6457ff
+      "kw": {
6457ff
+        "expected": "2;125;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST",
6457ff
+        "got": "2;7;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST",
6457ff
+        "msg": "KRA agent description does not match. Found 2;7;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST in LDAP and expected 2;125;CN=Certificate Authority,O=EXAMPLE.TEST;CN=IPA RA,O=EXAMPLE.TEST"
6457ff
       }
6457ff
     }
6457ff
 
6457ff
diff --git a/src/ipahealthcheck/ipa/certs.py b/src/ipahealthcheck/ipa/certs.py
6457ff
index d3043d0..32c0d76 100644
6457ff
--- a/src/ipahealthcheck/ipa/certs.py
6457ff
+++ b/src/ipahealthcheck/ipa/certs.py
6457ff
@@ -724,6 +724,83 @@ class IPAOpenSSLChainValidation(IPAPlugin):
6457ff
                         self, constants.SUCCESS, key=cert)
6457ff
 
6457ff
 
6457ff
+def check_agent(plugin, base_dn, agent_type):
6457ff
+    """Check RA/KRA Agent"""
6457ff
+
6457ff
+    try:
6457ff
+        cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
6457ff
+    except Exception as e:
6457ff
+        yield Result(plugin, constants.ERROR,
6457ff
+                     error=str(e),
6457ff
+                     msg='Unable to load RA cert: {error}')
6457ff
+        return
6457ff
+    serial_number = cert.serial_number
6457ff
+    subject = DN(cert.subject)
6457ff
+    issuer = DN(cert.issuer)
6457ff
+    description = '2;%d;%s;%s' % (serial_number, issuer, subject)
6457ff
+    logger.debug('%s agent description should be %s', agent_type, description)
6457ff
+    db_filter = ldap2.ldap2.combine_filters(
6457ff
+        [
6457ff
+            ldap2.ldap2.make_filter({'objectClass': 'inetOrgPerson'}),
6457ff
+            ldap2.ldap2.make_filter(
6457ff
+                {'description': ';%s;%s' % (issuer, subject)},
6457ff
+                exact=False, trailing_wildcard=False),
6457ff
+        ],
6457ff
+        ldap2.ldap2.MATCH_ALL)
6457ff
+    try:
6457ff
+        entries = plugin.conn.get_entries(base_dn,
6457ff
+                                          plugin.conn.SCOPE_SUBTREE,
6457ff
+                                          db_filter)
6457ff
+    except errors.NotFound:
6457ff
+        yield Result(plugin, constants.ERROR,
6457ff
+                     description=description,
6457ff
+                     msg='%s agent not found in LDAP' % agent_type)
6457ff
+        return
6457ff
+    except Exception as e:
6457ff
+        yield Result(plugin, constants.ERROR,
6457ff
+                     error=str(e),
6457ff
+                     msg='Retrieving %s agent from LDAP failed {error}'
6457ff
+                         % agent_type)
6457ff
+        return
6457ff
+    else:
6457ff
+        logger.debug('%s agent description is %s', agent_type, description)
6457ff
+        if len(entries) != 1:
6457ff
+            yield Result(plugin, constants.ERROR,
6457ff
+                         found=len(entries),
6457ff
+                         msg='Too many %s agent entries found, {found}'
6457ff
+                             % agent_type)
6457ff
+            return
6457ff
+        entry = entries[0]
6457ff
+        raw_desc = entry.get('description')
6457ff
+        if raw_desc is None:
6457ff
+            yield Result(plugin, constants.ERROR,
6457ff
+                         msg='%s agent is missing the description '
6457ff
+                             'attribute or it is not readable' % agent_type)
6457ff
+            return
6457ff
+        ra_desc = raw_desc[0]
6457ff
+        ra_certs = entry.get('usercertificate')
6457ff
+        if ra_desc != description:
6457ff
+            yield Result(plugin, constants.ERROR,
6457ff
+                         expected=description,
6457ff
+                         got=ra_desc,
6457ff
+                         msg='%s agent description does not match. Found '
6457ff
+                         '{got} in LDAP and expected {expected}' % agent_type)
6457ff
+            return
6457ff
+        found = False
6457ff
+        for candidate in ra_certs:
6457ff
+            if candidate == cert:
6457ff
+                found = True
6457ff
+                break
6457ff
+        if not found:
6457ff
+            yield Result(plugin, constants.ERROR,
6457ff
+                         certfile=paths.RA_AGENT_PEM,
6457ff
+                         dn=str(entry.dn),
6457ff
+                         msg='%s agent certificate in {certfile} not '
6457ff
+                             'found in LDAP userCertificate attribute '
6457ff
+                             'for the entry {dn}' % agent_type)
6457ff
+        yield Result(plugin, constants.SUCCESS)
6457ff
+
6457ff
+
6457ff
 @registry
6457ff
 class IPARAAgent(IPAPlugin):
6457ff
     """Validate the RA Agent used to talk to the CA
6457ff
@@ -739,82 +816,32 @@ class IPARAAgent(IPAPlugin):
6457ff
             logger.debug('CA is not configured, skipping RA Agent check')
6457ff
             return
6457ff
 
6457ff
-        try:
6457ff
-            cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
6457ff
-        except Exception as e:
6457ff
-            yield Result(self, constants.ERROR,
6457ff
-                         error=str(e),
6457ff
-                         msg='Unable to load RA cert: {error}')
6457ff
-            return
6457ff
+        base_dn = DN('uid=ipara,ou=people,o=ipaca')
6457ff
+        yield from check_agent(self, base_dn, 'RA')
6457ff
 
6457ff
-        serial_number = cert.serial_number
6457ff
-        subject = DN(cert.subject)
6457ff
-        issuer = DN(cert.issuer)
6457ff
-        description = '2;%d;%s;%s' % (serial_number, issuer, subject)
6457ff
 
6457ff
-        logger.debug('RA agent description should be %s', description)
6457ff
+@registry
6457ff
+class IPAKRAAgent(IPAPlugin):
6457ff
+    """Validate the KRA Agent
6457ff
 
6457ff
-        db_filter = ldap2.ldap2.combine_filters(
6457ff
-            [
6457ff
-                ldap2.ldap2.make_filter({'objectClass': 'inetOrgPerson'}),
6457ff
-                ldap2.ldap2.make_filter({'sn': 'ipara'}),
6457ff
-                ldap2.ldap2.make_filter(
6457ff
-                    {'description': ';%s;%s' % (issuer, subject)},
6457ff
-                    exact=False, trailing_wildcard=False),
6457ff
-            ],
6457ff
-            ldap2.ldap2.MATCH_ALL)
6457ff
+       Compare the description and usercertificate values.
6457ff
+    """
6457ff
 
6457ff
-        base_dn = DN(('o', 'ipaca'))
6457ff
-        try:
6457ff
-            entries = self.conn.get_entries(base_dn,
6457ff
-                                            self.conn.SCOPE_SUBTREE,
6457ff
-                                            db_filter)
6457ff
-        except errors.NotFound:
6457ff
-            yield Result(self, constants.ERROR,
6457ff
-                         description=description,
6457ff
-                         msg='RA agent not found in LDAP')
6457ff
+    requires = ('dirsrv',)
6457ff
+
6457ff
+    @duration
6457ff
+    def check(self):
6457ff
+        if not self.ca.is_configured():
6457ff
+            logger.debug('CA is not configured, skipping KRA Agent check')
6457ff
             return
6457ff
-        except Exception as e:
6457ff
-            yield Result(self, constants.ERROR,
6457ff
-                         error=str(e),
6457ff
-                         msg='Retrieving RA agent from LDAP failed {error}')
6457ff
+
6457ff
+        kra = krainstance.KRAInstance(api.env.realm)
6457ff
+        if not kra.is_installed():
6457ff
+            logger.debug('KRA is not installed, skipping KRA Agent check')
6457ff
             return
6457ff
-        else:
6457ff
-            logger.debug('RA agent description is %s', description)
6457ff
-            if len(entries) != 1:
6457ff
-                yield Result(self, constants.ERROR,
6457ff
-                             found=len(entries),
6457ff
-                             msg='Too many RA agent entries found, {found}')
6457ff
-                return
6457ff
-            entry = entries[0]
6457ff
-            raw_desc = entry.get('description')
6457ff
-            if raw_desc is None:
6457ff
-                yield Result(self, constants.ERROR,
6457ff
-                             msg='RA agent is missing the description '
6457ff
-                                 'attribute or it is not readable')
6457ff
-                return
6457ff
-            ra_desc = raw_desc[0]
6457ff
-            ra_certs = entry.get('usercertificate')
6457ff
-            if ra_desc != description:
6457ff
-                yield Result(self, constants.ERROR,
6457ff
-                             expected=description,
6457ff
-                             got=ra_desc,
6457ff
-                             msg='RA agent description does not match. Found '
6457ff
-                             '{got} in LDAP and expected {expected}')
6457ff
-                return
6457ff
-            found = False
6457ff
-            for candidate in ra_certs:
6457ff
-                if candidate == cert:
6457ff
-                    found = True
6457ff
-                    break
6457ff
-            if not found:
6457ff
-                yield Result(self, constants.ERROR,
6457ff
-                             certfile=paths.RA_AGENT_PEM,
6457ff
-                             dn=str(entry.dn),
6457ff
-                             msg='RA agent certificate in {certfile} not '
6457ff
-                                 'found in LDAP userCertificate attribute '
6457ff
-                                 'for the entry {dn}')
6457ff
-            yield Result(self, constants.SUCCESS)
6457ff
+
6457ff
+        base_dn = DN('uid=ipakra,ou=people,o=kra,o=ipaca')
6457ff
+        yield from check_agent(self, base_dn, 'KRA')
6457ff
 
6457ff
 
6457ff
 @registry
6457ff
-- 
6457ff
2.26.2
6457ff