483b06
From 6bfb11f2110f5fbaecc2d6a27d89289c58edc171 Mon Sep 17 00:00:00 2001
483b06
From: Martin Babinsky <mbabinsk@redhat.com>
483b06
Date: Thu, 22 Jun 2017 10:06:21 +0200
483b06
Subject: [PATCH] Allow to pass in multiple CA cert paths to the smart card
483b06
 advises
483b06
483b06
If the user has a series of CA certificates required to verify smart
483b06
card certs (e.g. intermediary CAs and root CA) it is convenient to allow
483b06
for passing them to the advise scripts as a series of PEM files.
483b06
483b06
https://pagure.io/freeipa/issue/7036
483b06
483b06
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
483b06
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
483b06
---
483b06
 ipaserver/advise/plugins/smart_card_auth.py | 69 +++++++++++++++++++----------
483b06
 1 file changed, 46 insertions(+), 23 deletions(-)
483b06
483b06
diff --git a/ipaserver/advise/plugins/smart_card_auth.py b/ipaserver/advise/plugins/smart_card_auth.py
483b06
index 0217bd190778f1235981a49e7b0764b8b9cdf582..16c01204444883ed949db73b2314ba5c404124df 100644
483b06
--- a/ipaserver/advise/plugins/smart_card_auth.py
483b06
+++ b/ipaserver/advise/plugins/smart_card_auth.py
483b06
@@ -18,7 +18,8 @@ class common_smart_card_auth_config(Advice):
483b06
     """
483b06
 
483b06
     systemwide_nssdb = paths.NSS_DB_DIR
483b06
-    smart_card_ca_cert_variable_name = "SC_CA_CERT"
483b06
+    smart_card_ca_certs_variable_name = "SC_CA_CERTS"
483b06
+    single_ca_cert_variable_name = 'ca_cert'
483b06
 
483b06
     def check_ccache_not_empty(self):
483b06
         self.log.comment('Check whether the credential cache is not empty')
483b06
@@ -29,35 +30,58 @@ class common_smart_card_auth_config(Advice):
483b06
                 'Use kinit as privileged user to obtain Kerberos credentials'
483b06
             ])
483b06
 
483b06
+    def check_and_set_ca_cert_paths(self):
483b06
+        ca_paths_variable = self.smart_card_ca_certs_variable_name
483b06
+        single_ca_path_variable = self.single_ca_cert_variable_name
483b06
 
483b06
-    def check_and_set_ca_cert_path(self):
483b06
-        ca_path_variable = self.smart_card_ca_cert_variable_name
483b06
-        self.log.command("{}=$1".format(ca_path_variable))
483b06
+        self.log.command("{}=$@".format(ca_paths_variable))
483b06
         self.log.exit_on_predicate(
483b06
-            '[ -z "${}" ]'.format(ca_path_variable),
483b06
-            ['You need to provide the path to the PEM file containing CA '
483b06
-             'signing the Smart Cards']
483b06
+            '[ -z "${}" ]'.format(ca_paths_variable),
483b06
+            ['You need to provide one or more paths to the PEM files '
483b06
+             'containing CAs signing the Smart Cards']
483b06
         )
483b06
+        self.log.command(
483b06
+            "for {} in ${}".format(
483b06
+                single_ca_path_variable, ca_paths_variable))
483b06
+        self.log.command("do")
483b06
         self.log.exit_on_predicate(
483b06
-            '[ ! -f "${}" ]'.format(ca_path_variable),
483b06
-            ['Invalid CA certificate filename: ${}'.format(ca_path_variable),
483b06
-             'Please check that the path exists and is a valid file']
483b06
+            '[ ! -f "${}" ]'.format(single_ca_path_variable),
483b06
+            ['Invalid CA certificate filename: ${}'.format(
483b06
+                single_ca_path_variable),
483b06
+             'Please check that the path exists and is a valid file'],
483b06
+            indent_spaces=2
483b06
         )
483b06
+        self.log.command("done")
483b06
 
483b06
-    def upload_smartcard_ca_certificate_to_systemwide_db(self):
483b06
+    def upload_smartcard_ca_certificates_to_systemwide_db(self):
483b06
+        self.log.command(
483b06
+            "for {} in ${}".format(
483b06
+                self.single_ca_cert_variable_name,
483b06
+                self.smart_card_ca_certs_variable_name))
483b06
+        self.log.command("do")
483b06
         self.log.command(
483b06
-            'certutil -d {} -A -i ${} -n "Smart Card CA" -t CT,C,C'.format(
483b06
-                self.systemwide_nssdb, self.smart_card_ca_cert_variable_name
483b06
-            )
483b06
+            'certutil -d {} -A -i ${} -n "Smart Card CA $(uuidgen)" '
483b06
+            '-t CT,C,C'.format(
483b06
+                self.systemwide_nssdb, self.single_ca_cert_variable_name
483b06
+            ),
483b06
+            indent_spaces=2
483b06
         )
483b06
+        self.log.command("done")
483b06
 
483b06
-    def install_smart_card_signing_ca_cert(self):
483b06
+    def install_smart_card_signing_ca_certs(self):
483b06
+        self.log.command(
483b06
+            "for {} in ${}".format(
483b06
+                self.single_ca_cert_variable_name,
483b06
+                self.smart_card_ca_certs_variable_name))
483b06
+        self.log.command("do")
483b06
         self.log.exit_on_failed_command(
483b06
             'ipa-cacert-manage install ${} -t CT,C,C'.format(
483b06
-                self.smart_card_ca_cert_variable_name
483b06
+                self.single_ca_cert_variable_name
483b06
             ),
483b06
-            ['Failed to install external CA certificate to IPA']
483b06
+            ['Failed to install external CA certificate to IPA'],
483b06
+            indent_spaces=2
483b06
         )
483b06
+        self.log.command("done")
483b06
 
483b06
     def update_ipa_ca_certificate_store(self):
483b06
         self.log.exit_on_failed_command(
483b06
@@ -85,7 +109,7 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
483b06
 
483b06
     def get_info(self):
483b06
         self.log.exit_on_nonroot_euid()
483b06
-        self.check_and_set_ca_cert_path()
483b06
+        self.check_and_set_ca_cert_paths()
483b06
         self.check_ccache_not_empty()
483b06
         self.check_hostname_is_in_masters()
483b06
         self.resolve_ipaca_records()
483b06
@@ -95,7 +119,8 @@ class config_server_for_smart_card_auth(common_smart_card_auth_config):
483b06
         self.record_httpd_ocsp_status()
483b06
         self.check_and_enable_pkinit()
483b06
         self.enable_ok_to_auth_as_delegate_on_http_principal()
483b06
-        self.upload_smartcard_ca_certificate_to_systemwide_db()
483b06
+        self.upload_smartcard_ca_certificates_to_systemwide_db()
483b06
+        self.install_smart_card_signing_ca_certs()
483b06
         self.update_ipa_ca_certificate_store()
483b06
         self.restart_kdc()
483b06
 
483b06
@@ -234,18 +259,16 @@ class config_client_for_smart_card_auth(common_smart_card_auth_config):
483b06
     pkcs11_shared_lib = '/usr/lib64/opensc-pkcs11.so'
483b06
     smart_card_service_file = 'pcscd.service'
483b06
     smart_card_socket = 'pcscd.socket'
483b06
-    systemwide_nssdb = paths.NSS_DB_DIR
483b06
 
483b06
     def get_info(self):
483b06
         self.log.exit_on_nonroot_euid()
483b06
-        self.check_and_set_ca_cert_path()
483b06
+        self.check_and_set_ca_cert_paths()
483b06
         self.check_ccache_not_empty()
483b06
         self.check_and_remove_pam_pkcs11()
483b06
         self.install_opensc_and_dconf_packages()
483b06
         self.start_enable_smartcard_daemon()
483b06
         self.add_pkcs11_module_to_systemwide_db()
483b06
-        self.upload_smartcard_ca_certificate_to_systemwide_db()
483b06
-        self.install_smart_card_signing_ca_cert()
483b06
+        self.upload_smartcard_ca_certificates_to_systemwide_db()
483b06
         self.update_ipa_ca_certificate_store()
483b06
         self.run_authconfig_to_configure_smart_card_auth()
483b06
         self.restart_sssd()
483b06
-- 
483b06
2.9.4
483b06