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