f65af0
From e4084fc1608cd13e73ce201471ff518105f4b9f5 Mon Sep 17 00:00:00 2001
f65af0
From: Christian Heimes <cheimes@redhat.com>
f65af0
Date: Fri, 22 Jun 2018 12:17:23 +0200
f65af0
Subject: [PATCH] Ensure that public cert and CA bundle are readable
f65af0
f65af0
In CIS hardened mode, the process umask is 027. This results in some
f65af0
files not being world readable. Ensure that write_certificate_list()
f65af0
calls in client installer, server installer, and upgrader create cert
f65af0
bundles with permission bits 0644.
f65af0
f65af0
Fixes: https://pagure.io/freeipa/issue/7594
f65af0
Signed-off-by: Christian Heimes <cheimes@redhat.com>
f65af0
Reviewed-By: Tibor Dudlak <tdudlak@redhat.com>
f65af0
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
f65af0
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
f65af0
---
f65af0
 ipaclient/install/client.py                | 10 +++++++---
f65af0
 ipaclient/install/ipa_certupdate.py        |  4 ++--
f65af0
 ipalib/x509.py                             |  5 ++++-
f65af0
 ipaserver/install/cainstance.py            |  2 +-
f65af0
 ipaserver/install/httpinstance.py          |  2 +-
f65af0
 ipaserver/install/installutils.py          |  6 +++++-
f65af0
 ipaserver/install/krbinstance.py           |  2 +-
f65af0
 ipaserver/install/server/replicainstall.py |  2 +-
f65af0
 8 files changed, 22 insertions(+), 11 deletions(-)
f65af0
f65af0
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
f65af0
index 0fbe31b762561b3e2ee2f35a666a93de8857bced..a1c74b41f790917a302ab32f6be7a4d23a989708 100644
f65af0
--- a/ipaclient/install/client.py
f65af0
+++ b/ipaclient/install/client.py
f65af0
@@ -1837,7 +1837,7 @@ def get_ca_certs(fstore, options, server, basedn, realm):
f65af0
 
f65af0
     if ca_certs is not None:
f65af0
         try:
f65af0
-            x509.write_certificate_list(ca_certs, ca_file)
f65af0
+            x509.write_certificate_list(ca_certs, ca_file, mode=0o644)
f65af0
         except Exception as e:
f65af0
             if os.path.exists(ca_file):
f65af0
                 try:
f65af0
@@ -2775,10 +2775,14 @@ def _install(options):
f65af0
 
f65af0
     x509.write_certificate_list(
f65af0
         [c for c, n, t, u in ca_certs if t is not False],
f65af0
-        paths.KDC_CA_BUNDLE_PEM)
f65af0
+        paths.KDC_CA_BUNDLE_PEM,
f65af0
+        mode=0o644
f65af0
+    )
f65af0
     x509.write_certificate_list(
f65af0
         [c for c, n, t, u in ca_certs if t is not False],
f65af0
-        paths.CA_BUNDLE_PEM)
f65af0
+        paths.CA_BUNDLE_PEM,
f65af0
+        mode=0o644
f65af0
+    )
f65af0
 
f65af0
     # Add the CA certificates to the IPA NSS database
f65af0
     logger.debug("Adding CA certificates to the IPA NSS database.")
f65af0
diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
f65af0
index 875cd7000c09aee044c5141a889617c9195182b1..878af250428fbf122c048d612fefc17e4ea674ff 100644
f65af0
--- a/ipaclient/install/ipa_certupdate.py
f65af0
+++ b/ipaclient/install/ipa_certupdate.py
f65af0
@@ -187,10 +187,10 @@ def update_server(certs):
f65af0
     update_file(paths.CACERT_PEM, certs)
f65af0
 
f65af0
 
f65af0
-def update_file(filename, certs, mode=0o444):
f65af0
+def update_file(filename, certs, mode=0o644):
f65af0
     certs = (c[0] for c in certs if c[2] is not False)
f65af0
     try:
f65af0
-        x509.write_certificate_list(certs, filename)
f65af0
+        x509.write_certificate_list(certs, filename, mode=mode)
f65af0
     except Exception as e:
f65af0
         logger.error("failed to update %s: %s", filename, e)
f65af0
 
f65af0
diff --git a/ipalib/x509.py b/ipalib/x509.py
f65af0
index 67a9af4c5d3456f8cdd6d966373be75d7036f1b7..cfacfa6fc784a4bc1559d68da0cc505874346e22 100644
f65af0
--- a/ipalib/x509.py
f65af0
+++ b/ipalib/x509.py
f65af0
@@ -36,6 +36,7 @@ import datetime
f65af0
 import ipaddress
f65af0
 import ssl
f65af0
 import base64
f65af0
+import os
f65af0
 import re
f65af0
 
f65af0
 from cryptography import x509 as crypto_x509
f65af0
@@ -519,7 +520,7 @@ def write_certificate(cert, filename):
f65af0
         raise errors.FileError(reason=str(e))
f65af0
 
f65af0
 
f65af0
-def write_certificate_list(certs, filename):
f65af0
+def write_certificate_list(certs, filename, mode=None):
f65af0
     """
f65af0
     Write a list of certificates to a file in PEM format.
f65af0
 
f65af0
@@ -529,6 +530,8 @@ def write_certificate_list(certs, filename):
f65af0
 
f65af0
     try:
f65af0
         with open(filename, 'wb') as f:
f65af0
+            if mode is not None:
f65af0
+                os.fchmod(f.fileno(), mode)
f65af0
             for cert in certs:
f65af0
                 f.write(cert.public_bytes(Encoding.PEM))
f65af0
     except (IOError, OSError) as e:
f65af0
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
f65af0
index ffcebd719a16ebc5a991b35507b96411ad31eb10..d6e467097808594756d947fa721b8cf10fe7d043 100644
f65af0
--- a/ipaserver/install/cainstance.py
f65af0
+++ b/ipaserver/install/cainstance.py
f65af0
@@ -848,7 +848,7 @@ class CAInstance(DogtagInstance):
f65af0
         for path in [paths.IPA_CA_CRT,
f65af0
                      paths.KDC_CA_BUNDLE_PEM,
f65af0
                      paths.CA_BUNDLE_PEM]:
f65af0
-            x509.write_certificate_list(certlist, path)
f65af0
+            x509.write_certificate_list(certlist, path, mode=0o644)
f65af0
 
f65af0
     def __request_ra_certificate(self):
f65af0
         """
f65af0
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
f65af0
index 3f83248dd89118aeecfbf458c5079dde8b2cb93d..05b88998353597aebc39b6dad5e1a688dca84f49 100644
f65af0
--- a/ipaserver/install/httpinstance.py
f65af0
+++ b/ipaserver/install/httpinstance.py
f65af0
@@ -481,7 +481,7 @@ class HTTPInstance(service.Service):
f65af0
             raise RuntimeError("HTTPD cert was issued by an unknown CA.")
f65af0
         # at this time we can assume any CA cert will be valid since this is
f65af0
         # only run during installation
f65af0
-        x509.write_certificate_list(certlist, paths.CA_CRT)
f65af0
+        x509.write_certificate_list(certlist, paths.CA_CRT, mode=0o644)
f65af0
 
f65af0
     def is_kdcproxy_configured(self):
f65af0
         """Check if KDC proxy has already been configured in the past"""
f65af0
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
f65af0
index 6614da69a0a046cdfa1b309f77972ead9de1279f..64beeffaebc4bcfe2b11dbf1109e54d7a9479d67 100644
f65af0
--- a/ipaserver/install/installutils.py
f65af0
+++ b/ipaserver/install/installutils.py
f65af0
@@ -1314,7 +1314,11 @@ def load_external_cert(files, ca_subject):
f65af0
     cert_file.flush()
f65af0
 
f65af0
     ca_file = tempfile.NamedTemporaryFile()
f65af0
-    x509.write_certificate_list(ca_cert_chain[1:], ca_file.name)
f65af0
+    x509.write_certificate_list(
f65af0
+        ca_cert_chain[1:],
f65af0
+        ca_file.name,
f65af0
+        mode=0o644
f65af0
+    )
f65af0
     ca_file.flush()
f65af0
 
f65af0
     return cert_file, ca_file
f65af0
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
f65af0
index 09cafb7b84623594fe88083f5b914cee0f050409..a3079bd6304a41116f9aa5e78b6c6c71d72d7aa6 100644
f65af0
--- a/ipaserver/install/krbinstance.py
f65af0
+++ b/ipaserver/install/krbinstance.py
f65af0
@@ -495,7 +495,7 @@ class KrbInstance(service.Service):
f65af0
                                           self.api.env.realm,
f65af0
                                           False)
f65af0
         ca_certs = [c for c, _n, t, _u in ca_certs if t is not False]
f65af0
-        x509.write_certificate_list(ca_certs, paths.CACERT_PEM)
f65af0
+        x509.write_certificate_list(ca_certs, paths.CACERT_PEM, mode=0o644)
f65af0
 
f65af0
     def issue_selfsigned_pkinit_certs(self):
f65af0
         self._call_certmonger(certmonger_ca="SelfSign")
f65af0
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
f65af0
index 525a62c474c7429b7efee4853eb71e487e656bba..eb354f81ba6e4cbc3848f9c24338fb85cc7639ae 100644
f65af0
--- a/ipaserver/install/server/replicainstall.py
f65af0
+++ b/ipaserver/install/server/replicainstall.py
f65af0
@@ -147,7 +147,7 @@ def install_ca_cert(ldap, base_dn, realm, cafile, destfile=paths.IPA_CA_CRT):
f65af0
                 pass
f65af0
         else:
f65af0
             certs = [c[0] for c in certs if c[2] is not False]
f65af0
-            x509.write_certificate_list(certs, destfile)
f65af0
+            x509.write_certificate_list(certs, destfile, mode=0o644)
f65af0
     except Exception as e:
f65af0
         raise ScriptError("error copying files: " + str(e))
f65af0
     return destfile
f65af0
-- 
f65af0
2.17.1
f65af0