mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Get CA certs for system-wide store from cert store in ipa-client-install.
All of the certificates and associated key policy are now stored in /etc/pki/ca-trust/source/ipa.p11-kit. Part of https://fedorahosted.org/freeipa/ticket/3259 Part of https://fedorahosted.org/freeipa/ticket/3520 Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
committed by
Petr Viktorin
parent
24932b2d91
commit
55d3bab57b
@@ -771,7 +771,7 @@ def uninstall(options, env):
|
||||
'as it can cause subsequent installation to fail.')
|
||||
|
||||
# Remove the CA cert from the systemwide certificate store
|
||||
tasks.remove_ca_cert_from_systemwide_ca_store(CACERT)
|
||||
tasks.remove_ca_certs_from_systemwide_ca_store()
|
||||
|
||||
# Remove the CA cert
|
||||
try:
|
||||
@@ -2545,9 +2545,6 @@ def install(options, env, fstore, statestore):
|
||||
return CLIENT_INSTALL_ERROR
|
||||
root_logger.info("Configured /etc/sssd/sssd.conf")
|
||||
|
||||
# Add the CA to the platform-dependant systemwide CA store
|
||||
tasks.insert_ca_cert_into_systemwide_ca_store(CACERT)
|
||||
|
||||
host_principal = 'host/%s@%s' % (hostname, cli_realm)
|
||||
if options.on_master:
|
||||
# If on master assume kerberos is already configured properly.
|
||||
@@ -2649,6 +2646,13 @@ def install(options, env, fstore, statestore):
|
||||
if not remote_env['enable_ra']:
|
||||
disable_ra()
|
||||
|
||||
# Get CA certificates from the certificate store
|
||||
ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm,
|
||||
remote_env['enable_ra'])
|
||||
|
||||
# Add the CA to the platform-dependant systemwide CA store
|
||||
tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)
|
||||
|
||||
# Add the CA to the default NSS database and trust it
|
||||
if not purge_ipa_certs():
|
||||
root_logger.info(
|
||||
@@ -2662,8 +2666,6 @@ def install(options, env, fstore, statestore):
|
||||
root_logger.error("Failed to open /etc/pki/nssdb/ipa.txt: %s", e)
|
||||
return CLIENT_INSTALL_ERROR
|
||||
|
||||
ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm,
|
||||
remote_env['enable_ra'])
|
||||
for cert, nickname, trusted, ext_key_usage in ca_certs:
|
||||
try:
|
||||
root_logger.debug("Attempting to add CA directly to the "
|
||||
|
||||
@@ -80,7 +80,7 @@ class BasePathNamespace(object):
|
||||
PAM_LDAP_CONF = "/etc/pam_ldap.conf"
|
||||
PASSWD = "/etc/passwd"
|
||||
ETC_PKI_CA_DIR = "/etc/pki-ca"
|
||||
SYSTEMWIDE_CA_STORE = "/etc/pki/ca-trust/source/anchors/"
|
||||
IPA_P11_KIT = "/etc/pki/ca-trust/source/ipa.p11-kit"
|
||||
NSS_DB_DIR = "/etc/pki/nssdb"
|
||||
NSSDB_CERT8_DB = "/etc/pki/nssdb/cert8.db"
|
||||
NSSDB_KEY3_DB = "/etc/pki/nssdb/key3.db"
|
||||
|
||||
@@ -49,9 +49,9 @@ class BaseTaskNamespace(object):
|
||||
|
||||
return
|
||||
|
||||
def insert_ca_cert_into_systemwide_ca_store(self, path):
|
||||
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
|
||||
"""
|
||||
Adds the CA certificate located at 'path' to the systemwide CA store
|
||||
Adds CA certificates from 'ca_certs' to the systemwide CA store
|
||||
(if available on the platform).
|
||||
|
||||
Returns True if the operation succeeded, False otherwise.
|
||||
@@ -59,10 +59,10 @@ class BaseTaskNamespace(object):
|
||||
|
||||
return True
|
||||
|
||||
def remove_ca_cert_from_systemwide_ca_store(self, path):
|
||||
def remove_ca_certs_from_systemwide_ca_store(self):
|
||||
"""
|
||||
Removes the CA certificate located at 'path' from the systemwide CA
|
||||
store (if available on the platform).
|
||||
Removes IPA CA certificates from the systemwide CA store
|
||||
(if available on the platform).
|
||||
|
||||
Returns True if the operation succeeded, False otherwise.
|
||||
"""
|
||||
|
||||
@@ -28,12 +28,18 @@ import shutil
|
||||
import stat
|
||||
import socket
|
||||
import sys
|
||||
import urllib
|
||||
import base64
|
||||
|
||||
from subprocess import CalledProcessError
|
||||
from nss.error import NSPRError
|
||||
from pyasn1.error import PyAsn1Error
|
||||
|
||||
from ipapython.ipa_log_manager import root_logger
|
||||
from ipapython import ipautil
|
||||
|
||||
from ipalib import x509 # FIXME: do not import from ipalib
|
||||
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform.fedora.authconfig import FedoraAuthConfig
|
||||
from ipaplatform.base.tasks import BaseTaskNamespace
|
||||
@@ -148,19 +154,88 @@ class FedoraTaskNamespace(BaseTaskNamespace):
|
||||
auth_config.add_option("nostart")
|
||||
auth_config.execute()
|
||||
|
||||
def insert_ca_cert_into_systemwide_ca_store(self, cacert_path):
|
||||
# Add the 'ipa-' prefix to cert name to avoid name collisions
|
||||
cacert_name = os.path.basename(cacert_path)
|
||||
new_cacert_path = os.path.join(paths.SYSTEMWIDE_CA_STORE,
|
||||
'ipa-%s' % cacert_name)
|
||||
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
|
||||
new_cacert_path = paths.IPA_P11_KIT
|
||||
|
||||
try:
|
||||
f = open(new_cacert_path, 'w')
|
||||
except IOError, e:
|
||||
root_logger.info("Failed to open %s: %s" % (new_cacert_path, e))
|
||||
return False
|
||||
|
||||
f.write("# This file was created by IPA. Do not edit.\n"
|
||||
"\n")
|
||||
|
||||
has_eku = set()
|
||||
for cert, nickname, trusted, ext_key_usage in ca_certs:
|
||||
try:
|
||||
subject = x509.get_der_subject(cert, x509.DER)
|
||||
issuer = x509.get_der_issuer(cert, x509.DER)
|
||||
serial_number = x509.get_der_serial_number(cert, x509.DER)
|
||||
public_key_info = x509.get_der_public_key_info(cert, x509.DER)
|
||||
except (NSPRError, PyAsn1Error), e:
|
||||
root_logger.warning(
|
||||
"Failed to decode certificate \"%s\": %s", nickname, e)
|
||||
continue
|
||||
|
||||
label = urllib.quote(nickname)
|
||||
subject = urllib.quote(subject)
|
||||
issuer = urllib.quote(issuer)
|
||||
serial_number = urllib.quote(serial_number)
|
||||
public_key_info = urllib.quote(public_key_info)
|
||||
|
||||
cert = base64.b64encode(cert)
|
||||
cert = x509.make_pem(cert)
|
||||
|
||||
obj = ("[p11-kit-object-v1]\n"
|
||||
"class: certificate\n"
|
||||
"certificate-type: x-509\n"
|
||||
"certificate-category: authority\n"
|
||||
"label: \"%(label)s\"\n"
|
||||
"subject: \"%(subject)s\"\n"
|
||||
"issuer: \"%(issuer)s\"\n"
|
||||
"serial-number: \"%(serial_number)s\"\n"
|
||||
"x-public-key-info: \"%(public_key_info)s\"\n" %
|
||||
dict(label=label,
|
||||
subject=subject,
|
||||
issuer=issuer,
|
||||
serial_number=serial_number,
|
||||
public_key_info=public_key_info))
|
||||
if trusted is True:
|
||||
obj += "trusted: true\n"
|
||||
elif trusted is False:
|
||||
obj += "x-distrusted: true\n"
|
||||
obj += "%s\n\n" % cert
|
||||
f.write(obj)
|
||||
|
||||
if ext_key_usage is not None and public_key_info not in has_eku:
|
||||
if not ext_key_usage:
|
||||
ext_key_usage = {x509.EKU_PLACEHOLDER}
|
||||
try:
|
||||
ext_key_usage = x509.encode_ext_key_usage(ext_key_usage)
|
||||
except PyAsn1Error, e:
|
||||
root_logger.warning(
|
||||
"Failed to encode extended key usage for \"%s\": %s",
|
||||
nickname, e)
|
||||
continue
|
||||
value = urllib.quote(ext_key_usage)
|
||||
obj = ("[p11-kit-object-v1]\n"
|
||||
"class: x-certificate-extension\n"
|
||||
"label: \"ExtendedKeyUsage for %(label)s\"\n"
|
||||
"x-public-key-info: \"%(public_key_info)s\"\n"
|
||||
"object-id: 2.5.29.37\n"
|
||||
"value: \"%(value)s\"\n\n" %
|
||||
dict(label=label,
|
||||
public_key_info=public_key_info,
|
||||
value=value))
|
||||
f.write(obj)
|
||||
has_eku.add(public_key_info)
|
||||
|
||||
f.close()
|
||||
|
||||
# Add the CA to the systemwide CA trust database
|
||||
try:
|
||||
shutil.copy(cacert_path, new_cacert_path)
|
||||
ipautil.run([paths.UPDATE_CA_TRUST])
|
||||
except OSError, e:
|
||||
root_logger.info("Failed to copy %s to %s" % (cacert_path,
|
||||
new_cacert_path))
|
||||
except CalledProcessError, e:
|
||||
root_logger.info("Failed to add CA to the systemwide "
|
||||
"CA trust database: %s" % str(e))
|
||||
@@ -171,11 +246,8 @@ class FedoraTaskNamespace(BaseTaskNamespace):
|
||||
|
||||
return False
|
||||
|
||||
def remove_ca_cert_from_systemwide_ca_store(self, cacert_path):
|
||||
# Derive the certificate name in the store
|
||||
cacert_name = os.path.basename(cacert_path)
|
||||
new_cacert_path = os.path.join(paths.SYSTEMWIDE_CA_STORE,
|
||||
'ipa-%s' % cacert_name)
|
||||
def remove_ca_certs_from_systemwide_ca_store(self):
|
||||
new_cacert_path = paths.IPA_P11_KIT
|
||||
|
||||
# Remove CA cert from systemwide store
|
||||
if os.path.exists(new_cacert_path):
|
||||
|
||||
Reference in New Issue
Block a user