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):