From 74e09087ed0ebf75936d5045eaaad69d71c678d6 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Wed, 24 Apr 2019 13:13:45 +0200 Subject: [PATCH] Globally disable softhsm2 in p11-kit-proxy The p11-kit configuration injects p11-kit-proxy into all NSS databases. Amongst other p11-kit loads SoftHSM2 PKCS#11 provider. This interferes with 389-DS, certmonger, Dogtag and other services. For example certmonger tries to open OpenDNSSEC's SoftHSM2 token, although it doesn't use it at all. It also breaks Dogtag HSM support testing with SoftHSM2. IPA server does neither need nor use SoftHSM2 proxied by p11-kit. Related: https://pagure.io/freeipa/issue/7810 Signed-off-by: Christian Heimes Reviewed-By: Alexander Bokovoy --- ipaplatform/base/paths.py | 1 + ipaplatform/base/tasks.py | 19 ++++++ ipaplatform/debian/tasks.py | 6 ++ ipaplatform/redhat/tasks.py | 58 +++++++++++++++++++ ipaserver/install/server/install.py | 5 ++ ipaserver/install/server/replicainstall.py | 3 + ipaserver/install/server/upgrade.py | 3 + .../test_integration/test_installation.py | 9 +++ 8 files changed, 104 insertions(+) diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py index fb7ff4fde..619b5fc89 100644 --- a/ipaplatform/base/paths.py +++ b/ipaplatform/base/paths.py @@ -371,6 +371,7 @@ class BasePathNamespace: AUTHCONFIG = None AUTHSELECT = None SYSCONF_NETWORK = None + ETC_PKCS11_MODULES_DIR = "/etc/pkcs11/modules" # 389 DS related commands. DSCREATE = '/usr/sbin/dscreate' DSCTL = '/usr/sbin/dsctl' diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py index a7587a58d..436c984b0 100644 --- a/ipaplatform/base/tasks.py +++ b/ipaplatform/base/tasks.py @@ -306,5 +306,24 @@ class BaseTaskNamespace: return ipautil.run(cmd, **kwargs) + def configure_pkcs11_modules(self, fstore): + """Disable p11-kit modules + + The p11-kit configuration injects p11-kit-proxy into all NSS + databases. Amongst other p11-kit loads SoftHSM2 PKCS#11 provider. + This interferes with 389-DS, certmonger, Dogtag and other services. + For example certmonger tries to open OpenDNSSEC's SoftHSM2 token, + although it doesn't use it at all. It also breaks Dogtag HSM support + testing with SoftHSM2. + + IPA server does neither need nor use SoftHSM2 proxied by p11-kit. + """ + raise NotImplementedError + + def restore_pkcs11_modules(self, fstore): + """Restore global p11-kit modules for NSS + """ + raise NotImplementedError + tasks = BaseTaskNamespace() diff --git a/ipaplatform/debian/tasks.py b/ipaplatform/debian/tasks.py index 11b0a94f6..4a2b81d8e 100644 --- a/ipaplatform/debian/tasks.py +++ b/ipaplatform/debian/tasks.py @@ -73,5 +73,11 @@ class DebianTaskNamespace(RedHatTaskNamespace): # Debian handles httpd logging differently pass + def configure_pkcs11_modules(self, fstore): + # Debian doesn't use p11-kit + pass + + def restore_pkcs11_modules(self, fstore): + pass tasks = DebianTaskNamespace() diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py index 6d57e4970..061109d3d 100644 --- a/ipaplatform/redhat/tasks.py +++ b/ipaplatform/redhat/tasks.py @@ -54,6 +54,14 @@ from ipaplatform.base.tasks import BaseTaskNamespace logger = logging.getLogger(__name__) +# /etc/pkcs11/modules override +# base filen ame, module, list of disabled-in +# 'p11-kit-proxy' disables proxying of module, see man(5) pkcs11.conf +PKCS11_MODULES = [ + ('softhsm2', paths.LIBSOFTHSM2_SO, ['p11-kit-proxy']), +] + + NM_IPA_CONF = textwrap.dedent(""" # auto-generated by IPA installer [main] @@ -679,5 +687,55 @@ class RedHatTaskNamespace(BaseTaskNamespace): if nm.is_enabled(): nm.reload_or_restart() + def configure_pkcs11_modules(self, fstore): + """Disable global p11-kit configuration for NSS + """ + filenames = [] + for name, module, disabled_in in PKCS11_MODULES: + filename = os.path.join( + paths.ETC_PKCS11_MODULES_DIR, + "{}.module".format(name) + ) + if os.path.isfile(filename): + # Only back up if file is not yet backed up and it does not + # look like a file that is generated by IPA. + with open(filename) as f: + content = f.read() + is_ipa_file = "IPA" in content + if not is_ipa_file and not fstore.has_file(filename): + logger.debug("Backing up existing '%s'.", filename) + fstore.backup_file(filename) + + with open(filename, "w") as f: + f.write("# created by IPA installer\n") + f.write("module: {}\n".format(module)) + # see man(5) pkcs11.conf + f.write("disable-in: {}\n".format(", ".join(disabled_in))) + os.fchmod(f.fileno(), 0o644) + logger.debug("Created PKCS#11 module config '%s'.", filename) + filenames.append(filename) + + return filenames + + def restore_pkcs11_modules(self, fstore): + """Restore global p11-kit configuration for NSS + """ + filenames = [] + for name, _module, _disabled_in in PKCS11_MODULES: + filename = os.path.join( + paths.ETC_PKCS11_MODULES_DIR, + "{}.module".format(name) + ) + try: + os.unlink(filename) + except OSError: + pass + else: + filenames.append(filename) + + if fstore.has_file(filename): + fstore.restore_file(filename) + + return filenames tasks = RedHatTaskNamespace() diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index b56bbe685..78180b4f5 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -772,6 +772,9 @@ def install(installer): if installer._update_hosts_file: update_hosts_file(ip_addresses, host_name, fstore) + if tasks.configure_pkcs11_modules(fstore): + print("Disabled p11-kit-proxy") + # Create a directory server instance if not options.external_cert_files: # We have to sync time before certificate handling on master. @@ -1151,6 +1154,8 @@ def uninstall(installer): # remove upgrade state file sysupgrade.remove_upgrade_file() + tasks.restore_pkcs11_modules(fstore) + if fstore.has_files(): logger.error('Some files have not been restored, see ' '%s/sysrestore.index', SYSRESTORE_DIR_PATH) diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py index 3cb19ace5..fe7363a89 100644 --- a/ipaserver/install/server/replicainstall.py +++ b/ipaserver/install/server/replicainstall.py @@ -1167,6 +1167,9 @@ def install(installer): conn = remote_api.Backend.ldap2 ccache = os.environ['KRB5CCNAME'] + if tasks.configure_pkcs11_modules(fstore): + print("Disabled p11-kit-proxy") + if installer._add_to_ipaservers: try: conn.connect(ccache=installer._ccache) diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index 58e4f8a1d..39f697e78 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -1841,6 +1841,9 @@ def upgrade_configuration(): if not sysupgrade.get_upgrade_state('ntpd', 'ntpd_cleaned'): ntpd_cleanup(fqdn, fstore) + if tasks.configure_pkcs11_modules(fstore): + print("Disabled p11-kit-proxy") + check_certs() fix_permissions() diff --git a/ipatests/test_integration/test_installation.py b/ipatests/test_integration/test_installation.py index 7a40d8871..dd917adc2 100644 --- a/ipatests/test_integration/test_installation.py +++ b/ipatests/test_integration/test_installation.py @@ -468,6 +468,15 @@ class TestInstallMaster(IntegrationTest): assert key_size == 2048 assert cert.signature_hash_algorithm.name == hashes.SHA256.name + def test_p11_kit_softhsm2(self): + # check that p11-kit-proxy does not inject SoftHSM2 + result = self.master.run_command([ + "modutil", "-dbdir", paths.PKI_TOMCAT_ALIAS_DIR, "-list" + ]) + assert "softhsm" not in result.stdout_text.lower() + assert "opendnssec" not in result.stdout_text.lower() + + class TestInstallMasterKRA(IntegrationTest):