mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Get CA certs for /etc/pki/nssdb from certificate store in ipa-client-install.
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:
parent
eaebefe5f6
commit
b5471a9f3e
@ -30,6 +30,7 @@ try:
|
|||||||
import getpass
|
import getpass
|
||||||
from ConfigParser import RawConfigParser
|
from ConfigParser import RawConfigParser
|
||||||
from optparse import SUPPRESS_HELP, OptionGroup, OptionValueError
|
from optparse import SUPPRESS_HELP, OptionGroup, OptionValueError
|
||||||
|
import shutil
|
||||||
|
|
||||||
import nss.nss as nss
|
import nss.nss as nss
|
||||||
import SSSDConfig
|
import SSSDConfig
|
||||||
@ -233,6 +234,42 @@ def nickname_exists(nickname):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def purge_ipa_certs(additional=[]):
|
||||||
|
filename = paths.NSSDB_IPA_TXT
|
||||||
|
if file_exists(filename):
|
||||||
|
try:
|
||||||
|
with open(filename, 'r') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
except IOError, e:
|
||||||
|
root_logger.error("Failed to open %s: %s", filename, e)
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
os.unlink(filename)
|
||||||
|
except OSError, e:
|
||||||
|
root_logger.error("Failed to remove %s: %s", filename, e)
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
lines = []
|
||||||
|
|
||||||
|
nicknames = set(additional)
|
||||||
|
for line in lines:
|
||||||
|
nickname = line.strip()
|
||||||
|
if nickname:
|
||||||
|
nicknames.add(nickname)
|
||||||
|
|
||||||
|
for nickname in nicknames:
|
||||||
|
while nickname_exists(nickname):
|
||||||
|
try:
|
||||||
|
run([paths.CERTUTIL, "-D",
|
||||||
|
"-d", paths.NSS_DB_DIR,
|
||||||
|
"-n", nickname])
|
||||||
|
except Exception, e:
|
||||||
|
root_logger.error(
|
||||||
|
"Failed to remove %s from /etc/pki/nssdb: %s", nickname, e)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def cert_summary(msg, certs, indent=' '):
|
def cert_summary(msg, certs, indent=' '):
|
||||||
if msg:
|
if msg:
|
||||||
s = '%s\n' % msg
|
s = '%s\n' % msg
|
||||||
@ -485,18 +522,6 @@ def uninstall(options, env):
|
|||||||
|
|
||||||
client_nss_nickname = client_nss_nickname_format % hostname
|
client_nss_nickname = client_nss_nickname_format % hostname
|
||||||
|
|
||||||
# Remove our host cert and CA cert
|
|
||||||
for nickname in ('IPA CA', 'External CA cert'):
|
|
||||||
if not nickname_exists(nickname):
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
run([paths.CERTUTIL, "-D",
|
|
||||||
"-d", paths.NSS_DB_DIR,
|
|
||||||
"-n", nickname])
|
|
||||||
except Exception, e:
|
|
||||||
root_logger.error(
|
|
||||||
"Failed to remove %s from /etc/pki/nssdb: %s", nickname, e)
|
|
||||||
|
|
||||||
# Always start certmonger. We can't untrack something if it isn't
|
# Always start certmonger. We can't untrack something if it isn't
|
||||||
# running
|
# running
|
||||||
messagebus = services.knownservices.messagebus
|
messagebus = services.knownservices.messagebus
|
||||||
@ -517,12 +542,8 @@ def uninstall(options, env):
|
|||||||
root_logger.error("%s failed to stop tracking certificate: %s",
|
root_logger.error("%s failed to stop tracking certificate: %s",
|
||||||
cmonger.service_name, str(e))
|
cmonger.service_name, str(e))
|
||||||
|
|
||||||
if nickname_exists(client_nss_nickname):
|
# Remove our host cert and CA cert
|
||||||
try:
|
purge_ipa_certs({client_nss_nickname, 'IPA CA', 'External CA cert'})
|
||||||
run([paths.CERTUTIL, "-D", "-d", paths.NSS_DB_DIR, "-n", client_nss_nickname])
|
|
||||||
except Exception, e:
|
|
||||||
root_logger.error("Failed to remove %s from /etc/pki/nssdb: %s",
|
|
||||||
client_nss_nickname, str(e))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmonger.stop()
|
cmonger.stop()
|
||||||
@ -1670,6 +1691,22 @@ def print_port_conf_info():
|
|||||||
" TCP: 464\n"
|
" TCP: 464\n"
|
||||||
" UDP: 464, 123 (if NTP enabled)")
|
" UDP: 464, 123 (if NTP enabled)")
|
||||||
|
|
||||||
|
def get_certs_from_ldap(server, base_dn, realm, enable_ra):
|
||||||
|
conn = ipaldap.IPAdmin(server, sasl_nocanon=True)
|
||||||
|
try:
|
||||||
|
conn.do_sasl_gssapi_bind()
|
||||||
|
certs = certstore.get_ca_certs(conn, base_dn, realm, enable_ra)
|
||||||
|
except errors.NotFound:
|
||||||
|
raise errors.NoCertificateError(entry=server)
|
||||||
|
except errors.NetworkError, e:
|
||||||
|
raise errors.NetworkError(uri=conn.ldap_uri, error=str(e))
|
||||||
|
except Exception, e:
|
||||||
|
raise errors.LDAPError(str(e))
|
||||||
|
finally:
|
||||||
|
conn.unbind()
|
||||||
|
|
||||||
|
return certs
|
||||||
|
|
||||||
def get_ca_certs_from_file(url):
|
def get_ca_certs_from_file(url):
|
||||||
'''
|
'''
|
||||||
Get the CA cert from a user supplied file and write it into the
|
Get the CA cert from a user supplied file and write it into the
|
||||||
@ -1744,20 +1781,11 @@ def get_ca_certs_from_ldap(server, basedn, realm):
|
|||||||
|
|
||||||
root_logger.debug("trying to retrieve CA cert via LDAP from %s", server)
|
root_logger.debug("trying to retrieve CA cert via LDAP from %s", server)
|
||||||
|
|
||||||
conn = ipaldap.IPAdmin(server, sasl_nocanon=True)
|
|
||||||
try:
|
try:
|
||||||
conn.do_sasl_gssapi_bind()
|
certs = get_certs_from_ldap(server, basedn, realm, False)
|
||||||
certs = certstore.get_ca_certs(conn, basedn, realm, False)
|
|
||||||
except errors.NotFound, e:
|
|
||||||
root_logger.debug("get_ca_certs_from_ldap() error: %s", e)
|
|
||||||
raise errors.NoCertificateError(entry=server)
|
|
||||||
|
|
||||||
except errors.NetworkError, e:
|
|
||||||
root_logger.debug("get_ca_certs_from_ldap() error: %s", e)
|
|
||||||
raise errors.NetworkError(uri=conn.ldap_uri, error=str(e))
|
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
root_logger.debug("get_ca_certs_from_ldap() error: %s", e)
|
root_logger.debug("get_ca_certs_from_ldap() error: %s", e)
|
||||||
raise errors.LDAPError(str(e))
|
raise
|
||||||
|
|
||||||
certs = [x509.load_certificate(c[0], x509.DER) for c in certs
|
certs = [x509.load_certificate(c[0], x509.DER) for c in certs
|
||||||
if c[2] is not False]
|
if c[2] is not False]
|
||||||
@ -2520,18 +2548,6 @@ def install(options, env, fstore, statestore):
|
|||||||
# Add the CA to the platform-dependant systemwide CA store
|
# Add the CA to the platform-dependant systemwide CA store
|
||||||
tasks.insert_ca_cert_into_systemwide_ca_store(CACERT)
|
tasks.insert_ca_cert_into_systemwide_ca_store(CACERT)
|
||||||
|
|
||||||
# Add the CA to the default NSS database and trust it
|
|
||||||
try:
|
|
||||||
root_logger.debug("Attempting to add CA directly to the "
|
|
||||||
"default NSS database.")
|
|
||||||
run([paths.CERTUTIL, "-A", "-d", paths.NSS_DB_DIR,
|
|
||||||
"-n", "IPA CA", "-t", "CT,C,C", "-a", "-i", CACERT])
|
|
||||||
except CalledProcessError, e:
|
|
||||||
root_logger.info("Failed to add CA to the default NSS database.")
|
|
||||||
return CLIENT_INSTALL_ERROR
|
|
||||||
else:
|
|
||||||
root_logger.info('Added the CA to the default NSS database.')
|
|
||||||
|
|
||||||
host_principal = 'host/%s@%s' % (hostname, cli_realm)
|
host_principal = 'host/%s@%s' % (hostname, cli_realm)
|
||||||
if options.on_master:
|
if options.on_master:
|
||||||
# If on master assume kerberos is already configured properly.
|
# If on master assume kerberos is already configured properly.
|
||||||
@ -2566,10 +2582,30 @@ def install(options, env, fstore, statestore):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Add CA certs to a temporary NSS database
|
||||||
|
try:
|
||||||
|
os.mkdir(paths.IPA_NSSDB_DIR)
|
||||||
|
pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
|
||||||
|
run([paths.CERTUTIL, '-N',
|
||||||
|
'-d', paths.IPA_NSSDB_DIR,
|
||||||
|
'-f', pwd_file.name])
|
||||||
|
|
||||||
|
ca_certs = x509.load_certificate_list_from_file(CACERT)
|
||||||
|
ca_certs = [cert.der_data for cert in ca_certs]
|
||||||
|
for i, cert in enumerate(ca_certs):
|
||||||
|
run([paths.CERTUTIL, '-A',
|
||||||
|
'-d', paths.IPA_NSSDB_DIR,
|
||||||
|
'-n', 'CA certificate %d' % (i + 1),
|
||||||
|
'-t', 'C,,'],
|
||||||
|
stdin=cert)
|
||||||
|
except CalledProcessError, e:
|
||||||
|
root_logger.info("Failed to add CA to temporary NSS database.")
|
||||||
|
return CLIENT_INSTALL_ERROR
|
||||||
|
|
||||||
# Now, let's try to connect to the server's XML-RPC interface
|
# Now, let's try to connect to the server's XML-RPC interface
|
||||||
connected = False
|
connected = False
|
||||||
try:
|
try:
|
||||||
api.Backend.rpcclient.connect()
|
api.Backend.rpcclient.connect(nss_dir=paths.IPA_NSSDB_DIR)
|
||||||
connected = True
|
connected = True
|
||||||
root_logger.debug('Try RPC connection')
|
root_logger.debug('Try RPC connection')
|
||||||
api.Backend.rpcclient.forward('ping')
|
api.Backend.rpcclient.forward('ping')
|
||||||
@ -2579,7 +2615,7 @@ def install(options, env, fstore, statestore):
|
|||||||
root_logger.info('Cannot connect to the server due to ' +
|
root_logger.info('Cannot connect to the server due to ' +
|
||||||
'Kerberos error: %s. Trying with delegate=True', str(e))
|
'Kerberos error: %s. Trying with delegate=True', str(e))
|
||||||
try:
|
try:
|
||||||
api.Backend.rpcclient.connect(delegate=True)
|
api.Backend.rpcclient.connect(delegate=True, nss_dir=paths.IPA_NSSDB_DIR)
|
||||||
root_logger.debug('Try RPC connection')
|
root_logger.debug('Try RPC connection')
|
||||||
api.Backend.rpcclient.forward('ping')
|
api.Backend.rpcclient.forward('ping')
|
||||||
|
|
||||||
@ -2613,6 +2649,43 @@ def install(options, env, fstore, statestore):
|
|||||||
if not remote_env['enable_ra']:
|
if not remote_env['enable_ra']:
|
||||||
disable_ra()
|
disable_ra()
|
||||||
|
|
||||||
|
# Add the CA to the default NSS database and trust it
|
||||||
|
if not purge_ipa_certs():
|
||||||
|
root_logger.info(
|
||||||
|
"Failed to remove old IPA certificates from the default NSS "
|
||||||
|
"database.")
|
||||||
|
return CLIENT_INSTALL_ERROR
|
||||||
|
|
||||||
|
try:
|
||||||
|
list_file = open(paths.NSSDB_IPA_TXT, 'w')
|
||||||
|
except IOError, e:
|
||||||
|
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 "
|
||||||
|
"default NSS database.")
|
||||||
|
trust_flags = certstore.key_policy_to_trust_flags(
|
||||||
|
trusted, True, ext_key_usage)
|
||||||
|
run([paths.CERTUTIL,
|
||||||
|
"-A",
|
||||||
|
"-d", paths.NSS_DB_DIR,
|
||||||
|
"-n", nickname,
|
||||||
|
"-t", trust_flags],
|
||||||
|
stdin=cert)
|
||||||
|
except CalledProcessError, e:
|
||||||
|
root_logger.info("Failed to add CA to the default NSS database.")
|
||||||
|
list_file.close()
|
||||||
|
return CLIENT_INSTALL_ERROR
|
||||||
|
else:
|
||||||
|
root_logger.info('Added the CA to the default NSS database.')
|
||||||
|
list_file.write(nickname + '\n')
|
||||||
|
|
||||||
|
list_file.close()
|
||||||
|
|
||||||
if not options.on_master:
|
if not options.on_master:
|
||||||
client_dns(cli_server[0], hostname, options.dns_updates)
|
client_dns(cli_server[0], hostname, options.dns_updates)
|
||||||
configure_certmonger(fstore, subject_base, cli_realm, hostname,
|
configure_certmonger(fstore, subject_base, cli_realm, hostname,
|
||||||
@ -2837,3 +2910,7 @@ finally:
|
|||||||
os.remove(CCACHE_FILE)
|
os.remove(CCACHE_FILE)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
shutil.rmtree(paths.IPA_NSSDB_DIR)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
@ -63,6 +63,7 @@ class BasePathNamespace(object):
|
|||||||
IPA_DNS_UPDATE_TXT = "/etc/ipa/.dns_update.txt"
|
IPA_DNS_UPDATE_TXT = "/etc/ipa/.dns_update.txt"
|
||||||
IPA_CA_CRT = "/etc/ipa/ca.crt"
|
IPA_CA_CRT = "/etc/ipa/ca.crt"
|
||||||
IPA_DEFAULT_CONF = "/etc/ipa/default.conf"
|
IPA_DEFAULT_CONF = "/etc/ipa/default.conf"
|
||||||
|
IPA_NSSDB_DIR = "/etc/ipa/.nssdb"
|
||||||
KRB5_CONF = "/etc/krb5.conf"
|
KRB5_CONF = "/etc/krb5.conf"
|
||||||
KRB5_KEYTAB = "/etc/krb5.keytab"
|
KRB5_KEYTAB = "/etc/krb5.keytab"
|
||||||
LDAP_CONF = "/etc/ldap.conf"
|
LDAP_CONF = "/etc/ldap.conf"
|
||||||
@ -84,6 +85,7 @@ class BasePathNamespace(object):
|
|||||||
NSSDB_CERT8_DB = "/etc/pki/nssdb/cert8.db"
|
NSSDB_CERT8_DB = "/etc/pki/nssdb/cert8.db"
|
||||||
NSSDB_KEY3_DB = "/etc/pki/nssdb/key3.db"
|
NSSDB_KEY3_DB = "/etc/pki/nssdb/key3.db"
|
||||||
NSSDB_SECMOD_DB = "/etc/pki/nssdb/secmod.db"
|
NSSDB_SECMOD_DB = "/etc/pki/nssdb/secmod.db"
|
||||||
|
NSSDB_IPA_TXT = "/etc/pki/nssdb/ipa.txt"
|
||||||
PKI_TOMCAT = "/etc/pki/pki-tomcat"
|
PKI_TOMCAT = "/etc/pki/pki-tomcat"
|
||||||
PKI_TOMCAT_ALIAS_DIR = "/etc/pki/pki-tomcat/alias/"
|
PKI_TOMCAT_ALIAS_DIR = "/etc/pki/pki-tomcat/alias/"
|
||||||
PKI_TOMCAT_PASSWORD_CONF = "/etc/pki/pki-tomcat/password.conf"
|
PKI_TOMCAT_PASSWORD_CONF = "/etc/pki/pki-tomcat/password.conf"
|
||||||
|
Loading…
Reference in New Issue
Block a user