From 47cf159f118de42ba703ad5fa0b47f5fa0bbb894 Mon Sep 17 00:00:00 2001 From: Stanislav Laznicka Date: Fri, 23 Mar 2018 14:34:41 +0100 Subject: [PATCH] Fix upgrading of FreeIPA HTTPD With the recent encryption of the HTTPD keys, it's also necessary to count with this scenario during upgrade and create the password for the HTTPD private key along the cert/key pair. This commit also moves the HTTPD_PASSWD_FILE_FMT from ipalib.constants to ipaplatform.paths as it proved to be too hard to be used that way. https://pagure.io/freeipa/issue/7421 Reviewed-By: Christian Heimes --- ipalib/constants.py | 1 - ipaplatform/base/paths.py | 2 +- ipaserver/install/certs.py | 17 ++++++++++++----- ipaserver/install/httpinstance.py | 21 +++++++++++++-------- ipaserver/install/ipa_server_certinstall.py | 6 +----- 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/ipalib/constants.py b/ipalib/constants.py index 891623089..e161d65ad 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -319,4 +319,3 @@ USER_CACHE_PATH = ( ) SOFTHSM_DNSSEC_TOKEN_LABEL = u'ipaDNSSEC' -HTTPD_PASSWD_FILE_FMT = "{host}-443-RSA" diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py index 0e37c7151..2689c162b 100644 --- a/ipaplatform/base/paths.py +++ b/ipaplatform/base/paths.py @@ -53,7 +53,7 @@ class BasePathNamespace(object): HTTPD_SSL_CONF = "/etc/httpd/conf.d/ssl.conf" HTTPD_CERT_FILE = "/var/lib/ipa/certs/httpd.crt" HTTPD_KEY_FILE = "/var/lib/ipa/private/httpd.key" - IPA_PASSWD_DIR = "/var/lib/ipa/passwds" + HTTPD_PASSWD_FILE_FMT = "/var/lib/ipa/passwds/{host}-443-RSA" # only used on Fedora HTTPD_IPA_WSGI_MODULES_CONF = None OLD_IPA_KEYTAB = "/etc/httpd/conf/ipa.keytab" diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py index 50b971645..e2b3c4fc7 100644 --- a/ipaserver/install/certs.py +++ b/ipaserver/install/certs.py @@ -72,12 +72,19 @@ def install_pem_from_p12(p12_fname, p12_passwd, pem_fname): "-passin", "file:" + pwd.name]) -def install_key_from_p12(p12_fname, p12_passwd, pem_fname): +def install_key_from_p12( + p12_fname, p12_passwd, pem_fname, out_passwd_fname=None): pwd = ipautil.write_tmp_file(p12_passwd) - ipautil.run([paths.OPENSSL, "pkcs12", "-nodes", "-nocerts", - "-in", p12_fname, "-out", pem_fname, - "-passin", "file:" + pwd.name], - umask=0o077) + args = [ + paths.OPENSSL, "pkcs12", "-nocerts", + "-in", p12_fname, "-out", pem_fname, + "-passin", "file:" + pwd.name] + if out_passwd_fname is not None: + args.extend(['-passout', 'file:{}'.format(out_passwd_fname)]) + else: + args.append('-nodes') + + ipautil.run(args, umask=0o077) def export_pem_p12(pkcs12_fname, pkcs12_pwd_fname, nickname, pem_fname): diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index 91de4071c..dbbb4000f 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -43,7 +43,7 @@ from ipapython.dn import DN import ipapython.errors from ipaserver.install import sysupgrade from ipalib import api, x509 -from ipalib.constants import IPAAPI_USER, HTTPD_PASSWD_FILE_FMT +from ipalib.constants import IPAAPI_USER from ipaplatform.constants import constants from ipaplatform.tasks import tasks from ipaplatform.paths import paths @@ -306,10 +306,7 @@ class HTTPInstance(service.Service): certmonger.stop() def __setup_ssl(self): - key_passwd_file = os.path.join( - paths.IPA_PASSWD_DIR, - HTTPD_PASSWD_FILE_FMT.format(host=api.env.host) - ) + key_passwd_file = paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host) with open(key_passwd_file, 'wb') as f: os.fchmod(f.fileno(), 0o600) pkey_passwd = ipautil.ipa_generate_password().encode('utf-8') @@ -516,8 +513,7 @@ class HTTPInstance(service.Service): paths.HTTP_CCACHE, paths.HTTPD_CERT_FILE, paths.HTTPD_KEY_FILE, - os.path.join(paths.IPA_PASSWD_DIR, - HTTPD_PASSWD_FILE_FMT.format(host=api.env.host)), + paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host), paths.HTTPD_IPA_REWRITE_CONF, paths.HTTPD_IPA_CONF, paths.HTTPD_IPA_PKI_PROXY_CONF, @@ -613,9 +609,18 @@ class HTTPInstance(service.Service): certs.install_pem_from_p12(temp.name, pk12_password, paths.HTTPD_CERT_FILE) + + passwd_fname = paths.HTTPD_PASSWD_FILE_FMT.format( + host=api.env.host) + with open(passwd_fname, 'wb') as passwd_file: + os.fchmod(passwd_file.fileno(), 0o600) + passwd_file.write( + ipautil.ipa_generate_password().encode('utf-8')) + certs.install_key_from_p12(temp.name, pk12_password, - paths.HTTPD_KEY_FILE) + paths.HTTPD_KEY_FILE, + out_passwd_fname=passwd_fname) self.backup_ssl_conf() self.configure_mod_ssl_certs() diff --git a/ipaserver/install/ipa_server_certinstall.py b/ipaserver/install/ipa_server_certinstall.py index ec4b8d266..ddd0d65cf 100644 --- a/ipaserver/install/ipa_server_certinstall.py +++ b/ipaserver/install/ipa_server_certinstall.py @@ -25,7 +25,6 @@ import tempfile import optparse # pylint: disable=deprecated-module from ipalib import x509 -from ipalib.constants import HTTPD_PASSWD_FILE_FMT from ipalib.install import certmonger from ipaplatform.paths import paths from ipapython import admintool @@ -157,10 +156,7 @@ class ServerCertInstall(admintool.AdminTool): host_name=api.env.host ) - key_passwd_path = os.path.join( - paths.IPA_PASSWD_DIR, - HTTPD_PASSWD_FILE_FMT.format(host=api.env.host) - ) + key_passwd_path = paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host) req_id = self.replace_key_cert_files( cert, key,