URL: https://github.com/freeipa/freeipa/pull/957 Author: rcritten Title: #957: Detect the backend crypto library that curl uses Action: opened
PR body: """ In Fedora 27 curl is proposing to switch to using OpenSSL as the crypto backend instead of NSS. This requires a new set of arguments to certmonger to bootstrap fetching the IPA RA cert. Debian/Ubuntu are still currently using an NSS-backed curl so support both methods for now. https://pagure.io/freeipa/issue/7076 """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/957/head:pr957 git checkout pr957
From 3c7b8afa44df2998154ab58dee64227a1d5f1ebb Mon Sep 17 00:00:00 2001 From: Rob Crittenden <rcrit...@redhat.com> Date: Thu, 3 Aug 2017 17:49:44 -0400 Subject: [PATCH] Detect the backend crypto library that curl uses In Fedora 27 curl is proposing to switch to using OpenSSL as the crypto backend instead of NSS. This requires a new set of arguments to certmonger to bootstrap fetching the IPA RA cert. Debian/Ubuntu are still currently using an NSS-backed curl so support both methods for now. https://pagure.io/freeipa/issue/7076 --- ipaserver/install/cainstance.py | 108 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 11 deletions(-) diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index b0e9e8757e..591c342400 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -811,13 +811,54 @@ def __export_ca_chain(self): ipaca_pem.write('\n') def __request_ra_certificate(self): - # create a temp file storing the pwd - agent_file = tempfile.NamedTemporaryFile( + """ + Request the IPA RA certificate from dogtag. + + dogtag automatically generates an admin certificate that + in a usual deployment would be used in the UI to handle + administrative duties. IPA does not use this certificate + except as a bootstrap to generate the RA. + + To do this it bends over backwards a bit by modifying the + way typical certificates are retrieved using certmonger by + forcing it to call dogtag-submit directly. + + The switch of curl from NSS to OpenSSL complicates this a + little because the arguments to certmonger and the + certificate format differ. Screen scraping of the curl -V + output is used to determine the crypt library. The output + format is loosely document at + http://curl.haxx.se/libcurl/c/curl_version_info.html + + NOTE: we could also import python-pycurl and use + pycurl.version or pycurl.version_info() but the overhead of + a fork vs yet another package import seems worth it. + """ + # Determine whether curl uses NSS or OpenSSL for crypto + result = ipautil.run( + [paths.BIN_CURL, '-V'], + raiseonerr=False, + capture_output=True) + if result.returncode == 0: + cryptolib = result.output.split()[4] + else: + raise RuntimeError( + 'Unable to determine crypto engine curl uses: %s' % result) + + # Note that this leaves the door open to use GnuTLS or another + # crypto backend that can use PEM files. + if 'NSS' in cryptolib: + use_nss = True + else: + use_nss = False + + # create a temp file storing the agent password + agent_pwdfile = tempfile.NamedTemporaryFile( mode="w", dir=paths.VAR_LIB_IPA, delete=False) - agent_file.write(self.tmp_agent_pwd) - agent_file.close() + agent_pwdfile.write(self.tmp_agent_pwd) + agent_pwdfile.close() - # create a temp pem file storing the CA chain + # create a temp PEM file storing the CA chain chain_file = tempfile.NamedTemporaryFile( mode="w", dir=paths.VAR_LIB_IPA, delete=False) chain_file.close() @@ -833,14 +874,56 @@ def __request_ra_certificate(self): "-out", chain_file.name, ], stdin=data, capture_output=False) + if not use_nss: + # Not NSS means we have to pass everything as PEM files. + + # A temp PKCS#12 file storing the CA agent + agent_p12 = tempfile.NamedTemporaryFile( + mode="w", dir=paths.VAR_LIB_IPA, delete=False) + agent_p12.close() + + # CA agent cert in PEM form + agent_cert = tempfile.NamedTemporaryFile( + mode="w", dir=paths.VAR_LIB_IPA, delete=False) + agent_cert.close() + + # CA agent key in PEM form + agent_key = tempfile.NamedTemporaryFile( + mode="w", dir=paths.VAR_LIB_IPA, delete=False) + agent_key.close() + # Create a PKCS#12 file of the CA agent then extra the + # cert and key as discrete PEM files. + with open(agent_pwdfile.name) as f: + agent_pwd = f.read() + + tmpdb = certs.CertDB(self.realm, nssdir=self.tmp_agent_db) + tmpdb.nssdb.pwd_file = agent_pwdfile.name + tmpdb.export_pkcs12(agent_p12.name, + agent_pwdfile.name, + "ipa-ca-agent") + certs.install_pem_from_p12(agent_p12.name, + agent_pwd, + agent_cert.name) + certs.install_key_from_p12(agent_p12.name, + agent_pwd, + agent_key.name) + agent_args = [paths.CERTMONGER_DOGTAG_SUBMIT, - "--dbdir", self.tmp_agent_db, - "--nickname", "ipa-ca-agent", "--cafile", chain_file.name, "--ee-url", 'http://%s:8080/ca/ee/ca/' % self.fqdn, "--agent-url", - 'https://%s:8443/ca/agent/ca/' % self.fqdn, - "--sslpinfile", agent_file.name] + 'https://%s:8443/ca/agent/ca/' % self.fqdn,] + + if use_nss: + backend_args = ["--dbdir", self.tmp_agent_db, + "--nickname", "ipa-ca-agent", + "--sslpinfile", agent_pwdfile.name,] + else: + backend_args = ["--certfile", agent_cert.name, + "--keyfile", agent_key.name,] + + agent_args += backend_args + helper = " ".join(agent_args) # configure certmonger renew agent to use temporary agent cert @@ -868,8 +951,11 @@ def __request_ra_certificate(self): # we can restore the helper parameters certmonger.modify_ca_helper( ipalib.constants.RENEWAL_CA_NAME, old_helper) - # remove the pwdfile - for f in (agent_file, chain_file): + # remove any temporary files + files = (agent_pwdfile, chain_file) + if not use_nss: + files += (agent_p12, agent_cert, agent_key) + for f in files: try: os.remove(f.name) except OSError:
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org