Blob Blame History Raw
From e4084fc1608cd13e73ce201471ff518105f4b9f5 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Fri, 22 Jun 2018 12:17:23 +0200
Subject: [PATCH] Ensure that public cert and CA bundle are readable

In CIS hardened mode, the process umask is 027. This results in some
files not being world readable. Ensure that write_certificate_list()
calls in client installer, server installer, and upgrader create cert
bundles with permission bits 0644.

Fixes: https://pagure.io/freeipa/issue/7594
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Tibor Dudlak <tdudlak@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
 ipaclient/install/client.py                | 10 +++++++---
 ipaclient/install/ipa_certupdate.py        |  4 ++--
 ipalib/x509.py                             |  5 ++++-
 ipaserver/install/cainstance.py            |  2 +-
 ipaserver/install/httpinstance.py          |  2 +-
 ipaserver/install/installutils.py          |  6 +++++-
 ipaserver/install/krbinstance.py           |  2 +-
 ipaserver/install/server/replicainstall.py |  2 +-
 8 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
index 0fbe31b762561b3e2ee2f35a666a93de8857bced..a1c74b41f790917a302ab32f6be7a4d23a989708 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -1837,7 +1837,7 @@ def get_ca_certs(fstore, options, server, basedn, realm):
 
     if ca_certs is not None:
         try:
-            x509.write_certificate_list(ca_certs, ca_file)
+            x509.write_certificate_list(ca_certs, ca_file, mode=0o644)
         except Exception as e:
             if os.path.exists(ca_file):
                 try:
@@ -2775,10 +2775,14 @@ def _install(options):
 
     x509.write_certificate_list(
         [c for c, n, t, u in ca_certs if t is not False],
-        paths.KDC_CA_BUNDLE_PEM)
+        paths.KDC_CA_BUNDLE_PEM,
+        mode=0o644
+    )
     x509.write_certificate_list(
         [c for c, n, t, u in ca_certs if t is not False],
-        paths.CA_BUNDLE_PEM)
+        paths.CA_BUNDLE_PEM,
+        mode=0o644
+    )
 
     # Add the CA certificates to the IPA NSS database
     logger.debug("Adding CA certificates to the IPA NSS database.")
diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
index 875cd7000c09aee044c5141a889617c9195182b1..878af250428fbf122c048d612fefc17e4ea674ff 100644
--- a/ipaclient/install/ipa_certupdate.py
+++ b/ipaclient/install/ipa_certupdate.py
@@ -187,10 +187,10 @@ def update_server(certs):
     update_file(paths.CACERT_PEM, certs)
 
 
-def update_file(filename, certs, mode=0o444):
+def update_file(filename, certs, mode=0o644):
     certs = (c[0] for c in certs if c[2] is not False)
     try:
-        x509.write_certificate_list(certs, filename)
+        x509.write_certificate_list(certs, filename, mode=mode)
     except Exception as e:
         logger.error("failed to update %s: %s", filename, e)
 
diff --git a/ipalib/x509.py b/ipalib/x509.py
index 67a9af4c5d3456f8cdd6d966373be75d7036f1b7..cfacfa6fc784a4bc1559d68da0cc505874346e22 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -36,6 +36,7 @@ import datetime
 import ipaddress
 import ssl
 import base64
+import os
 import re
 
 from cryptography import x509 as crypto_x509
@@ -519,7 +520,7 @@ def write_certificate(cert, filename):
         raise errors.FileError(reason=str(e))
 
 
-def write_certificate_list(certs, filename):
+def write_certificate_list(certs, filename, mode=None):
     """
     Write a list of certificates to a file in PEM format.
 
@@ -529,6 +530,8 @@ def write_certificate_list(certs, filename):
 
     try:
         with open(filename, 'wb') as f:
+            if mode is not None:
+                os.fchmod(f.fileno(), mode)
             for cert in certs:
                 f.write(cert.public_bytes(Encoding.PEM))
     except (IOError, OSError) as e:
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index ffcebd719a16ebc5a991b35507b96411ad31eb10..d6e467097808594756d947fa721b8cf10fe7d043 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -848,7 +848,7 @@ class CAInstance(DogtagInstance):
         for path in [paths.IPA_CA_CRT,
                      paths.KDC_CA_BUNDLE_PEM,
                      paths.CA_BUNDLE_PEM]:
-            x509.write_certificate_list(certlist, path)
+            x509.write_certificate_list(certlist, path, mode=0o644)
 
     def __request_ra_certificate(self):
         """
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 3f83248dd89118aeecfbf458c5079dde8b2cb93d..05b88998353597aebc39b6dad5e1a688dca84f49 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -481,7 +481,7 @@ class HTTPInstance(service.Service):
             raise RuntimeError("HTTPD cert was issued by an unknown CA.")
         # at this time we can assume any CA cert will be valid since this is
         # only run during installation
-        x509.write_certificate_list(certlist, paths.CA_CRT)
+        x509.write_certificate_list(certlist, paths.CA_CRT, mode=0o644)
 
     def is_kdcproxy_configured(self):
         """Check if KDC proxy has already been configured in the past"""
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 6614da69a0a046cdfa1b309f77972ead9de1279f..64beeffaebc4bcfe2b11dbf1109e54d7a9479d67 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -1314,7 +1314,11 @@ def load_external_cert(files, ca_subject):
     cert_file.flush()
 
     ca_file = tempfile.NamedTemporaryFile()
-    x509.write_certificate_list(ca_cert_chain[1:], ca_file.name)
+    x509.write_certificate_list(
+        ca_cert_chain[1:],
+        ca_file.name,
+        mode=0o644
+    )
     ca_file.flush()
 
     return cert_file, ca_file
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index 09cafb7b84623594fe88083f5b914cee0f050409..a3079bd6304a41116f9aa5e78b6c6c71d72d7aa6 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -495,7 +495,7 @@ class KrbInstance(service.Service):
                                           self.api.env.realm,
                                           False)
         ca_certs = [c for c, _n, t, _u in ca_certs if t is not False]
-        x509.write_certificate_list(ca_certs, paths.CACERT_PEM)
+        x509.write_certificate_list(ca_certs, paths.CACERT_PEM, mode=0o644)
 
     def issue_selfsigned_pkinit_certs(self):
         self._call_certmonger(certmonger_ca="SelfSign")
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 525a62c474c7429b7efee4853eb71e487e656bba..eb354f81ba6e4cbc3848f9c24338fb85cc7639ae 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -147,7 +147,7 @@ def install_ca_cert(ldap, base_dn, realm, cafile, destfile=paths.IPA_CA_CRT):
                 pass
         else:
             certs = [c[0] for c in certs if c[2] is not False]
-            x509.write_certificate_list(certs, destfile)
+            x509.write_certificate_list(certs, destfile, mode=0o644)
     except Exception as e:
         raise ScriptError("error copying files: " + str(e))
     return destfile
-- 
2.17.1