Blame SOURCES/0006-fix-iPAddress-cert-issuance-for-1-host-service_rhbz#1846352.patch

5144c6
From 128500198d3782a76616cf1d971d5aeb17e8c1da Mon Sep 17 00:00:00 2001
5144c6
From: Fraser Tweedale <ftweedal@redhat.com>
5144c6
Date: Thu, 11 Jun 2020 22:42:38 +1000
5144c6
Subject: [PATCH] fix iPAddress cert issuance for >1 host/service
5144c6
5144c6
The 'cert_request' command accumulates DNS names from the CSR,
5144c6
before checking that all IP addresses in the CSR are reachable from
5144c6
those DNS names.  Before adding a DNS name to the set, we check that
5144c6
that it corresponds to the FQDN of a known host/service principal
5144c6
(including principal aliases).  When a DNS name maps to a
5144c6
"alternative" principal (i.e.  not the one given via the 'principal'
5144c6
argument), this check was not being performed correctly.
5144c6
Specifically, we were looking for the 'krbprincipalname' field on
5144c6
the RPC response object directly, instead of its 'result' field.
5144c6
5144c6
To resolve the issue, dereference the RPC response to its 'result'
5144c6
field before invoking the '_dns_name_matches_principal' subroutine.
5144c6
5144c6
Fixes: https://pagure.io/freeipa/issue/8368
5144c6
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
5144c6
---
5144c6
 ipaserver/plugins/cert.py                     |  6 +-
5144c6
 .../test_cert_request_ip_address.py           | 62 +++++++++++++++++--
5144c6
 2 files changed, 61 insertions(+), 7 deletions(-)
5144c6
5144c6
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
5144c6
index d353bc3ea..fe7ea34f5 100644
5144c6
--- a/ipaserver/plugins/cert.py
5144c6
+++ b/ipaserver/plugins/cert.py
5144c6
@@ -827,13 +827,13 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
5144c6
                 try:
5144c6
                     if principal_type == HOST:
5144c6
                         alt_principal_obj = api.Command['host_show'](
5144c6
-                            name, all=True)
5144c6
+                            name, all=True)['result']
5144c6
                     elif principal_type == KRBTGT:
5144c6
                         alt_principal = kerberos.Principal(
5144c6
                             (u'host', name), principal.realm)
5144c6
                     elif principal_type == SERVICE:
5144c6
                         alt_principal_obj = api.Command['service_show'](
5144c6
-                            alt_principal, all=True)
5144c6
+                            alt_principal, all=True)['result']
5144c6
                 except errors.NotFound:
5144c6
                     # We don't want to issue any certificates referencing
5144c6
                     # machines we don't know about. Nothing is stored in this
5144c6
@@ -866,7 +866,7 @@ class cert_request(Create, BaseCertMethod, VirtualCommand):
5144c6
                         pass
5144c6
 
5144c6
                     # Now check write access and caacl
5144c6
-                    altdn = alt_principal_obj['result']['dn']
5144c6
+                    altdn = alt_principal_obj['dn']
5144c6
                     if not ldap.can_write(altdn, "usercertificate"):
5144c6
                         raise errors.ACIError(info=_(
5144c6
                             "Insufficient privilege to create a certificate "
5144c6
diff --git a/ipatests/test_xmlrpc/test_cert_request_ip_address.py b/ipatests/test_xmlrpc/test_cert_request_ip_address.py
5144c6
index bf4de05bf..c0475d30d 100644
5144c6
--- a/ipatests/test_xmlrpc/test_cert_request_ip_address.py
5144c6
+++ b/ipatests/test_xmlrpc/test_cert_request_ip_address.py
5144c6
@@ -28,10 +28,16 @@ from ipatests.test_xmlrpc.tracker.host_plugin import HostTracker
5144c6
 from ipatests.test_xmlrpc.tracker.user_plugin import UserTracker
5144c6
 from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
5144c6
 
5144c6
-host_fqdn = f'iptest.{api.env.domain}'
5144c6
+host_shortname = 'iptest'
5144c6
+host_fqdn = f'{host_shortname}.{api.env.domain}'
5144c6
 host_princ = f'host/{host_fqdn}'
5144c6
 host_ptr = f'{host_fqdn}.'
5144c6
 
5144c6
+host2_shortname = 'iptest2'
5144c6
+host2_fqdn = f'{host2_shortname}.{api.env.domain}'
5144c6
+host2_princ = f'host/{host2_fqdn}'
5144c6
+host2_ptr = f'{host2_fqdn}.'
5144c6
+
5144c6
 other_fqdn = f'other.{api.env.domain}'
5144c6
 other_ptr = f'{other_fqdn}.'
5144c6
 
5144c6
@@ -39,6 +45,10 @@ ipv4_address = '169.254.0.42'
5144c6
 ipv4_revzone_s = '0.254.169.in-addr.arpa.'
5144c6
 ipv4_revrec_s = '42'
5144c6
 
5144c6
+host2_ipv4_address = '169.254.0.43'
5144c6
+host2_ipv4_revzone_s = '0.254.169.in-addr.arpa.'
5144c6
+host2_ipv4_revrec_s = '43'
5144c6
+
5144c6
 ipv6_address = 'fe80::8f18:bdab:4299:95fa'
5144c6
 ipv6_revzone_s = '0.0.0.0.0.0.0.0.0.0.0.0.0.8.e.f.ip6.arpa.'
5144c6
 ipv6_revrec_s = 'a.f.5.9.9.9.2.4.b.a.d.b.8.1.f.8'
5144c6
@@ -46,7 +56,13 @@ ipv6_revrec_s = 'a.f.5.9.9.9.2.4.b.a.d.b.8.1.f.8'
5144c6
 
5144c6
 @pytest.fixture(scope='class')
5144c6
 def host(request, xmlrpc_setup):
5144c6
-    tr = HostTracker('iptest')
5144c6
+    tr = HostTracker(host_shortname)
5144c6
+    return tr.make_fixture(request)
5144c6
+
5144c6
+
5144c6
+@pytest.fixture(scope='class')
5144c6
+def host2(request, xmlrpc_setup):
5144c6
+    tr = HostTracker(host2_shortname)
5144c6
     return tr.make_fixture(request)
5144c6
 
5144c6
 
5144c6
@@ -88,6 +104,12 @@ def ipv6_revzone(host):
5144c6
     yield from _zone_setup(host, ipv6_revzone_s)
5144c6
 
5144c6
 
5144c6
+@pytest.fixture(scope='class')
5144c6
+def host2_ipv4_ptr(host2, ipv4_revzone):
5144c6
+    yield from _record_setup(
5144c6
+        host2, ipv4_revzone, host2_ipv4_revrec_s, ptrrecord=host2_ptr)
5144c6
+
5144c6
+
5144c6
 @pytest.fixture(scope='class')
5144c6
 def ipv4_ptr(host, ipv4_revzone):
5144c6
     yield from _record_setup(
5144c6
@@ -100,16 +122,22 @@ def ipv6_ptr(host, ipv6_revzone):
5144c6
         host, ipv6_revzone, ipv6_revrec_s, ptrrecord=host_ptr)
5144c6
 
5144c6
 
5144c6
+@pytest.fixture(scope='class')
5144c6
+def host2_ipv4_a(host2):
5144c6
+    yield from _record_setup(
5144c6
+        host2, api.env.domain, host2_shortname, arecord=host2_ipv4_address)
5144c6
+
5144c6
+
5144c6
 @pytest.fixture(scope='class')
5144c6
 def ipv4_a(host):
5144c6
     yield from _record_setup(
5144c6
-        host, api.env.domain, 'iptest', arecord=ipv4_address)
5144c6
+        host, api.env.domain, host_shortname, arecord=ipv4_address)
5144c6
 
5144c6
 
5144c6
 @pytest.fixture(scope='class')
5144c6
 def ipv6_aaaa(host):
5144c6
     yield from _record_setup(
5144c6
-        host, api.env.domain, 'iptest', aaaarecord=ipv6_address)
5144c6
+        host, api.env.domain, host_shortname, aaaarecord=ipv6_address)
5144c6
 
5144c6
 
5144c6
 @pytest.fixture(scope='class')
5144c6
@@ -210,6 +238,12 @@ csr_cname2 = csr([
5144c6
     x509.DNSName(f'cname2.{api.env.domain}'),
5144c6
     x509.IPAddress(ipaddress.ip_address(ipv4_address)),
5144c6
 ])
5144c6
+csr_two_dnsname_two_ip = csr([
5144c6
+    x509.DNSName(host_fqdn),
5144c6
+    x509.IPAddress(ipaddress.ip_address(ipv4_address)),
5144c6
+    x509.DNSName(host2_fqdn),
5144c6
+    x509.IPAddress(ipaddress.ip_address(host2_ipv4_address)),
5144c6
+])
5144c6
 
5144c6
 
5144c6
 @pytest.fixture
5144c6
@@ -449,3 +483,23 @@ class TestIPAddressCNAME(XMLRPC_test):
5144c6
     def test_two_levels(self, host, csr_cname2):
5144c6
         with pytest.raises(errors.ValidationError, match=PAT_FWD):
5144c6
             host.run_command('cert_request', csr_cname2, principal=host_princ)
5144c6
+
5144c6
+
5144c6
+@pytest.mark.tier1
5144c6
+class TestTwoHostsTwoIPAddresses(XMLRPC_test):
5144c6
+    """
5144c6
+    Test certificate issuance with CSR containing two hosts
5144c6
+    and two IP addresses (one for each host).
5144c6
+
5144c6
+    """
5144c6
+    def test_host_exists(
5144c6
+        self, host, host2, ipv4_a, ipv4_ptr, host2_ipv4_a, host2_ipv4_ptr,
5144c6
+    ):
5144c6
+        # for convenience, this test also establishes the DNS
5144c6
+        # record fixtures, which have class scope
5144c6
+        host.ensure_exists()
5144c6
+        host2.ensure_exists()
5144c6
+
5144c6
+    def test_issuance(self, host, csr_two_dnsname_two_ip):
5144c6
+        host.run_command(
5144c6
+            'cert_request', csr_two_dnsname_two_ip, principal=host_princ)
5144c6
-- 
5144c6
2.26.2
5144c6