mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Moving ipaCert from HTTPD_ALIAS_DIR
The "ipaCert" nicknamed certificate is not required to be in /var/lib/ipa/radb NSSDB anymore as we were keeping a copy of this file in a separate file anyway. Remove it from there and track only the file. Remove the IPA_RADB_DIR as well as it is not required anymore. https://fedorahosted.org/freeipa/ticket/5695 https://fedorahosted.org/freeipa/ticket/6680 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
committed by
Jan Cholasta
parent
24b134c633
commit
5ab85b365a
@@ -217,10 +217,12 @@ def request_cert():
|
|||||||
syslog.syslog(syslog.LOG_NOTICE,
|
syslog.syslog(syslog.LOG_NOTICE,
|
||||||
"Forwarding request to dogtag-ipa-renew-agent")
|
"Forwarding request to dogtag-ipa-renew-agent")
|
||||||
|
|
||||||
path = paths.DOGTAG_IPA_RENEW_AGENT_SUBMIT
|
args = ([paths.DOGTAG_IPA_RENEW_AGENT_SUBMIT,
|
||||||
args = [path, '--dbdir', paths.IPA_RADB_DIR]
|
"--cafile", paths.IPA_CA_CRT,
|
||||||
args.extend(sys.argv[1:])
|
"--certfile", paths.RA_AGENT_PEM,
|
||||||
args.extend(['--submit-option', "requestor_name=IPA"])
|
"--keyfile", paths.RA_AGENT_KEY] +
|
||||||
|
sys.argv[1:] +
|
||||||
|
['--submit-option', "requestor_name=IPA"])
|
||||||
if os.environ.get('CERTMONGER_CA_PROFILE') == 'caCACert':
|
if os.environ.get('CERTMONGER_CA_PROFILE') == 'caCACert':
|
||||||
args += ['-N', '-O', 'bypassCAnotafter=true']
|
args += ['-N', '-O', 'bypassCAnotafter=true']
|
||||||
result = ipautil.run(args, raiseonerr=False, env=os.environ,
|
result = ipautil.run(args, raiseonerr=False, env=os.environ,
|
||||||
|
|||||||
@@ -27,15 +27,15 @@ import tempfile
|
|||||||
import shutil
|
import shutil
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
|
||||||
from ipalib.install.kinit import kinit_keytab
|
from ipalib.install.kinit import kinit_keytab
|
||||||
from ipalib import api
|
from ipalib import api, x509
|
||||||
from ipaserver.install import certs, cainstance, dogtaginstance
|
from ipaserver.install import certs, cainstance
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
|
|
||||||
|
|
||||||
def _main():
|
def _main():
|
||||||
nickname = 'ipaCert'
|
|
||||||
|
|
||||||
api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
|
api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
|
||||||
api.finalize()
|
api.finalize()
|
||||||
api.Backend.ldap2.connect()
|
api.Backend.ldap2.connect()
|
||||||
@@ -48,20 +48,28 @@ def _main():
|
|||||||
os.environ['KRB5CCNAME'] = ccache_filename
|
os.environ['KRB5CCNAME'] = ccache_filename
|
||||||
|
|
||||||
ca = cainstance.CAInstance(host_name=api.env.host)
|
ca = cainstance.CAInstance(host_name=api.env.host)
|
||||||
|
ra_certpath = paths.RA_AGENT_PEM
|
||||||
if ca.is_renewal_master():
|
if ca.is_renewal_master():
|
||||||
# Fetch the new certificate
|
# Fetch the new certificate
|
||||||
db = certs.CertDB(api.env.realm)
|
try:
|
||||||
dercert = db.get_cert_from_db(nickname, pem=False)
|
cert = x509.load_certificate_from_file(ra_certpath)
|
||||||
if not dercert:
|
except IOError as e:
|
||||||
syslog.syslog(
|
syslog.syslog(
|
||||||
syslog.LOG_ERR, "No certificate %s found." % nickname)
|
syslog.LOG_ERR, "Can't open '{certpath}': {err}"
|
||||||
|
.format(certpath=ra_certpath, err=e)
|
||||||
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
syslog.syslog(
|
||||||
|
syslog.LOG_ERR, "'{certpath}' is not a valid certificate "
|
||||||
|
"file".format(certpath=ra_certpath)
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
dercert = cert.public_bytes(serialization.Encoding.DER)
|
||||||
|
|
||||||
# Load it into dogtag
|
# Load it into dogtag
|
||||||
cainstance.update_people_entry(dercert)
|
cainstance.update_people_entry(dercert)
|
||||||
|
|
||||||
if api.Command.kra_is_enabled()['result']:
|
|
||||||
dogtaginstance.export_ra_agent_pem()
|
|
||||||
finally:
|
finally:
|
||||||
shutil.rmtree(tmpdir)
|
shutil.rmtree(tmpdir)
|
||||||
api.Backend.ldap2.disconnect()
|
api.Backend.ldap2.disconnect()
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ class CertUpdate(admintool.AdminTool):
|
|||||||
services.knownservices.dirsrv.restart(instance)
|
services.knownservices.dirsrv.restart(instance)
|
||||||
|
|
||||||
self.update_db(paths.HTTPD_ALIAS_DIR, certs)
|
self.update_db(paths.HTTPD_ALIAS_DIR, certs)
|
||||||
self.update_db(paths.IPA_RADB_DIR, certs)
|
|
||||||
if services.knownservices.httpd.is_running():
|
if services.knownservices.httpd.is_running():
|
||||||
services.knownservices.httpd.restart()
|
services.knownservices.httpd.restart()
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ class BasePathNamespace(object):
|
|||||||
ETC_HTTPD_DIR = "/etc/httpd"
|
ETC_HTTPD_DIR = "/etc/httpd"
|
||||||
HTTPD_ALIAS_DIR = "/etc/httpd/alias"
|
HTTPD_ALIAS_DIR = "/etc/httpd/alias"
|
||||||
OLD_KRA_AGENT_PEM = "/etc/httpd/alias/kra-agent.pem"
|
OLD_KRA_AGENT_PEM = "/etc/httpd/alias/kra-agent.pem"
|
||||||
IPA_RADB_DIR = "/var/lib/ipa/radb"
|
|
||||||
HTTPD_CONF_D_DIR = "/etc/httpd/conf.d/"
|
HTTPD_CONF_D_DIR = "/etc/httpd/conf.d/"
|
||||||
HTTPD_IPA_KDCPROXY_CONF = "/etc/ipa/kdcproxy/ipa-kdc-proxy.conf"
|
HTTPD_IPA_KDCPROXY_CONF = "/etc/ipa/kdcproxy/ipa-kdc-proxy.conf"
|
||||||
HTTPD_IPA_KDCPROXY_CONF_SYMLINK = "/etc/httpd/conf.d/ipa-kdc-proxy.conf"
|
HTTPD_IPA_KDCPROXY_CONF_SYMLINK = "/etc/httpd/conf.d/ipa-kdc-proxy.conf"
|
||||||
@@ -140,6 +139,7 @@ class BasePathNamespace(object):
|
|||||||
ROOT_PKI = "/root/.pki"
|
ROOT_PKI = "/root/.pki"
|
||||||
DOGTAG_ADMIN_P12 = "/root/ca-agent.p12"
|
DOGTAG_ADMIN_P12 = "/root/ca-agent.p12"
|
||||||
RA_AGENT_PEM = "/var/lib/ipa/ra-agent.pem"
|
RA_AGENT_PEM = "/var/lib/ipa/ra-agent.pem"
|
||||||
|
RA_AGENT_KEY = "/var/lib/ipa/ra-agent.key"
|
||||||
CACERT_P12 = "/root/cacert.p12"
|
CACERT_P12 = "/root/cacert.p12"
|
||||||
ROOT_IPA_CSR = "/root/ipa.csr"
|
ROOT_IPA_CSR = "/root/ipa.csr"
|
||||||
NAMED_PID = "/run/named/named.pid"
|
NAMED_PID = "/run/named/named.pid"
|
||||||
@@ -195,6 +195,7 @@ class BasePathNamespace(object):
|
|||||||
PAM_KRB5_SO_64 = "/usr/lib64/security/pam_krb5.so"
|
PAM_KRB5_SO_64 = "/usr/lib64/security/pam_krb5.so"
|
||||||
DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT = "/usr/libexec/certmonger/dogtag-ipa-ca-renew-agent-submit"
|
DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT = "/usr/libexec/certmonger/dogtag-ipa-ca-renew-agent-submit"
|
||||||
DOGTAG_IPA_RENEW_AGENT_SUBMIT = "/usr/libexec/certmonger/dogtag-ipa-renew-agent-submit"
|
DOGTAG_IPA_RENEW_AGENT_SUBMIT = "/usr/libexec/certmonger/dogtag-ipa-renew-agent-submit"
|
||||||
|
CERTMONGER_DOGTAG_SUBMIT = "/usr/libexec/certmonger/dogtag-submit"
|
||||||
IPA_SERVER_GUARD = "/usr/libexec/certmonger/ipa-server-guard"
|
IPA_SERVER_GUARD = "/usr/libexec/certmonger/ipa-server-guard"
|
||||||
GENERATE_RNDC_KEY = "/usr/libexec/generate-rndc-key.sh"
|
GENERATE_RNDC_KEY = "/usr/libexec/generate-rndc-key.sh"
|
||||||
IPA_DNSKEYSYNCD_REPLICA = "/usr/libexec/ipa/ipa-dnskeysync-replica"
|
IPA_DNSKEYSYNCD_REPLICA = "/usr/libexec/ipa/ipa-dnskeysync-replica"
|
||||||
|
|||||||
@@ -131,8 +131,9 @@ def ca_status(ca_host=None):
|
|||||||
return _parse_ca_status(body)
|
return _parse_ca_status(body)
|
||||||
|
|
||||||
|
|
||||||
def https_request(host, port, url, cafile, client_certfile,
|
def https_request(
|
||||||
method='POST', headers=None, body=None, **kw):
|
host, port, url, cafile, client_certfile, client_keyfile,
|
||||||
|
method='POST', headers=None, body=None, **kw):
|
||||||
"""
|
"""
|
||||||
:param method: HTTP request method (defalut: 'POST')
|
:param method: HTTP request method (defalut: 'POST')
|
||||||
:param url: The path (not complete URL!) to post to.
|
:param url: The path (not complete URL!) to post to.
|
||||||
@@ -149,6 +150,7 @@ def https_request(host, port, url, cafile, client_certfile,
|
|||||||
host, port,
|
host, port,
|
||||||
cafile=cafile,
|
cafile=cafile,
|
||||||
client_certfile=client_certfile,
|
client_certfile=client_certfile,
|
||||||
|
client_keyfile=client_keyfile,
|
||||||
tls_version_min=api.env.tls_version_min,
|
tls_version_min=api.env.tls_version_min,
|
||||||
tls_version_max=api.env.tls_version_max)
|
tls_version_max=api.env.tls_version_max)
|
||||||
|
|
||||||
|
|||||||
@@ -177,14 +177,14 @@ def install_check(standalone, replica_config, options):
|
|||||||
if standalone:
|
if standalone:
|
||||||
dirname = dsinstance.config_dirname(
|
dirname = dsinstance.config_dirname(
|
||||||
installutils.realm_to_serverid(realm_name))
|
installutils.realm_to_serverid(realm_name))
|
||||||
cadb = certs.CertDB(realm_name, subject_base=options._subject_base)
|
cadb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
|
||||||
|
subject_base=options._subject_base)
|
||||||
dsdb = certs.CertDB(
|
dsdb = certs.CertDB(
|
||||||
realm_name, nssdir=dirname, subject_base=options._subject_base)
|
realm_name, nssdir=dirname, subject_base=options._subject_base)
|
||||||
|
|
||||||
for db in (cadb, dsdb):
|
for db in (cadb, dsdb):
|
||||||
for nickname, _trust_flags in db.list_certs():
|
for nickname, _trust_flags in db.list_certs():
|
||||||
if nickname in (certdb.get_ca_nickname(realm_name),
|
if nickname == certdb.get_ca_nickname(realm_name):
|
||||||
'ipaCert'):
|
|
||||||
raise ScriptError(
|
raise ScriptError(
|
||||||
"Certificate with nickname %s is present in %s, "
|
"Certificate with nickname %s is present in %s, "
|
||||||
"cannot continue." % (nickname, db.secdir))
|
"cannot continue." % (nickname, db.secdir))
|
||||||
@@ -193,8 +193,7 @@ def install_check(standalone, replica_config, options):
|
|||||||
if not cert:
|
if not cert:
|
||||||
continue
|
continue
|
||||||
subject = DN(x509.load_certificate(cert).subject)
|
subject = DN(x509.load_certificate(cert).subject)
|
||||||
if subject in (DN(options._ca_subject),
|
if subject == DN(options._ca_subject):
|
||||||
DN('CN=IPA RA', options._subject_base)):
|
|
||||||
raise ScriptError(
|
raise ScriptError(
|
||||||
"Certificate with subject %s is present in %s, "
|
"Certificate with subject %s is present in %s, "
|
||||||
"cannot continue." % (subject, db.secdir))
|
"cannot continue." % (subject, db.secdir))
|
||||||
@@ -312,31 +311,26 @@ def install_step_1(standalone, replica_config, options):
|
|||||||
dirname = dsinstance.config_dirname(serverid)
|
dirname = dsinstance.config_dirname(serverid)
|
||||||
|
|
||||||
# Store the new IPA CA cert chain in DS NSS database and LDAP
|
# Store the new IPA CA cert chain in DS NSS database and LDAP
|
||||||
cadb = certs.CertDB(realm_name, subject_base=subject_base)
|
cadb = certs.CertDB(
|
||||||
dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base)
|
realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
|
||||||
trust_flags = dict(reversed(cadb.list_certs()))
|
subject_base=subject_base)
|
||||||
trust_chain = cadb.find_root_cert('ipaCert')[:-1]
|
dsdb = certs.CertDB(
|
||||||
for nickname in trust_chain[:-1]:
|
realm_name, nssdir=dirname, subject_base=subject_base)
|
||||||
cert = cadb.get_cert_from_db(nickname, pem=False)
|
cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca', pem=False)
|
||||||
dsdb.add_cert(cert, nickname, trust_flags[nickname])
|
nickname = certdb.get_ca_nickname(realm_name)
|
||||||
certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
|
trust_flags = 'CT,C,C'
|
||||||
cert, nickname, trust_flags[nickname])
|
dsdb.add_cert(cacert, nickname, trust_flags)
|
||||||
|
|
||||||
nickname = trust_chain[-1]
|
|
||||||
cert = cadb.get_cert_from_db(nickname, pem=False)
|
|
||||||
dsdb.add_cert(cert, nickname, trust_flags[nickname])
|
|
||||||
certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
|
certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
|
||||||
cert, nickname, trust_flags[nickname],
|
cacert, nickname, trust_flags,
|
||||||
config_ipa=True, config_compat=True)
|
config_ipa=True, config_compat=True)
|
||||||
|
|
||||||
# Store DS CA cert in Dogtag NSS database
|
# Store DS CA cert in Dogtag NSS database
|
||||||
dogtagdb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
|
|
||||||
trust_flags = dict(reversed(dsdb.list_certs()))
|
trust_flags = dict(reversed(dsdb.list_certs()))
|
||||||
server_certs = dsdb.find_server_certs()
|
server_certs = dsdb.find_server_certs()
|
||||||
trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
|
trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
|
||||||
nickname = trust_chain[-1]
|
nickname = trust_chain[-1]
|
||||||
cert = dsdb.get_cert_from_db(nickname)
|
cert = dsdb.get_cert_from_db(nickname)
|
||||||
dogtagdb.add_cert(cert, nickname, trust_flags[nickname])
|
cadb.add_cert(cert, nickname, trust_flags[nickname])
|
||||||
|
|
||||||
installutils.restart_dirsrv()
|
installutils.restart_dirsrv()
|
||||||
|
|
||||||
@@ -356,6 +350,8 @@ def install_step_1(standalone, replica_config, options):
|
|||||||
def uninstall():
|
def uninstall():
|
||||||
ca_instance = cainstance.CAInstance(api.env.realm)
|
ca_instance = cainstance.CAInstance(api.env.realm)
|
||||||
ca_instance.stop_tracking_certificates()
|
ca_instance.stop_tracking_certificates()
|
||||||
|
installutils.remove_file(paths.RA_AGENT_PEM)
|
||||||
|
installutils.remove_file(paths.RA_AGENT_KEY)
|
||||||
if ca_instance.is_configured():
|
if ca_instance.is_configured():
|
||||||
ca_instance.uninstall()
|
ca_instance.uninstall()
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import dbus
|
|||||||
import ldap
|
import ldap
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
|
import grp
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
@@ -37,6 +38,7 @@ import six
|
|||||||
# pylint: disable=import-error
|
# pylint: disable=import-error
|
||||||
from six.moves.configparser import ConfigParser, RawConfigParser
|
from six.moves.configparser import ConfigParser, RawConfigParser
|
||||||
# pylint: enable=import-error
|
# pylint: enable=import-error
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
from ipalib import x509
|
from ipalib import x509
|
||||||
@@ -64,8 +66,7 @@ from ipaserver.install import installutils
|
|||||||
from ipaserver.install import ldapupdate
|
from ipaserver.install import ldapupdate
|
||||||
from ipaserver.install import replication
|
from ipaserver.install import replication
|
||||||
from ipaserver.install import sysupgrade
|
from ipaserver.install import sysupgrade
|
||||||
from ipaserver.install.dogtaginstance import (
|
from ipaserver.install.dogtaginstance import DogtagInstance
|
||||||
DogtagInstance, export_ra_agent_pem)
|
|
||||||
from ipaserver.plugins import ldap2
|
from ipaserver.plugins import ldap2
|
||||||
|
|
||||||
# We need to reset the template because the CA uses the regular boot
|
# We need to reset the template because the CA uses the regular boot
|
||||||
@@ -314,8 +315,6 @@ class CAInstance(DogtagInstance):
|
|||||||
self.canickname = get_ca_nickname(realm)
|
self.canickname = get_ca_nickname(realm)
|
||||||
else:
|
else:
|
||||||
self.canickname = None
|
self.canickname = None
|
||||||
self.ra_agent_db = paths.IPA_RADB_DIR
|
|
||||||
self.ra_agent_pwd = os.path.join(self.ra_agent_db, "pwdfile.txt")
|
|
||||||
self.ra_cert = None
|
self.ra_cert = None
|
||||||
self.requestId = None
|
self.requestId = None
|
||||||
self.log = log_mgr.get_logger(self)
|
self.log = log_mgr.get_logger(self)
|
||||||
@@ -378,8 +377,7 @@ class CAInstance(DogtagInstance):
|
|||||||
self.external = 2
|
self.external = 2
|
||||||
|
|
||||||
if self.clone:
|
if self.clone:
|
||||||
cert_db = certs.CertDB(self.realm)
|
has_ra_cert = os.path.exists(paths.RA_AGENT_PEM)
|
||||||
has_ra_cert = (cert_db.get_cert_from_db('ipaCert') != '')
|
|
||||||
else:
|
else:
|
||||||
has_ra_cert = False
|
has_ra_cert = False
|
||||||
|
|
||||||
@@ -415,16 +413,14 @@ class CAInstance(DogtagInstance):
|
|||||||
else:
|
else:
|
||||||
self.step("importing RA certificate from PKCS #12 file",
|
self.step("importing RA certificate from PKCS #12 file",
|
||||||
lambda: self.import_ra_cert(ra_p12))
|
lambda: self.import_ra_cert(ra_p12))
|
||||||
self.step("exporting RA agent cert", export_ra_agent_pem)
|
|
||||||
|
|
||||||
if not ra_only:
|
if not ra_only:
|
||||||
self.step("importing CA chain to RA certificate database", self.__import_ca_chain)
|
|
||||||
self.step("setting up signing cert profile", self.__setup_sign_profile)
|
self.step("setting up signing cert profile", self.__setup_sign_profile)
|
||||||
self.step("setting audit signing renewal to 2 years", self.set_audit_renewal)
|
self.step("setting audit signing renewal to 2 years", self.set_audit_renewal)
|
||||||
self.step("restarting certificate server", self.restart_instance)
|
self.step("restarting certificate server", self.restart_instance)
|
||||||
if not self.clone:
|
if not self.clone:
|
||||||
self.step("publishing the CA certificate",
|
self.step("publishing the CA certificate",
|
||||||
self.__publish_ca_cert)
|
self.__export_ca_chain)
|
||||||
self.step("adding RA agent as a trusted user", self.__create_ca_agent)
|
self.step("adding RA agent as a trusted user", self.__create_ca_agent)
|
||||||
self.step("authorizing RA to modify profiles", configure_profiles_acl)
|
self.step("authorizing RA to modify profiles", configure_profiles_acl)
|
||||||
self.step("authorizing RA to manage lightweight CAs",
|
self.step("authorizing RA to manage lightweight CAs",
|
||||||
@@ -683,13 +679,22 @@ class CAInstance(DogtagInstance):
|
|||||||
|
|
||||||
Used when setting up replication
|
Used when setting up replication
|
||||||
"""
|
"""
|
||||||
# Add the new RA cert into the RA database
|
# get the private key from the file
|
||||||
with tempfile.NamedTemporaryFile(mode="w") as agent_file:
|
ipautil.run([paths.OPENSSL,
|
||||||
agent_file.write(self.dm_password)
|
"pkcs12",
|
||||||
agent_file.flush()
|
"-in", rafile,
|
||||||
|
"-nocerts", "-nodes",
|
||||||
|
"-out", paths.RA_AGENT_KEY,
|
||||||
|
"-passin", "pass:"])
|
||||||
|
|
||||||
import_pkcs12(
|
# get the certificate from the pkcs12 file
|
||||||
rafile, agent_file.name, self.ra_agent_db, self.ra_agent_pwd)
|
ipautil.run([paths.OPENSSL,
|
||||||
|
"pkcs12",
|
||||||
|
"-in", rafile,
|
||||||
|
"-clcerts", "-nokeys",
|
||||||
|
"-out", paths.RA_AGENT_PEM,
|
||||||
|
"-passin", "pass:"])
|
||||||
|
self.__set_ra_cert_perms()
|
||||||
|
|
||||||
self.configure_agent_renewal()
|
self.configure_agent_renewal()
|
||||||
|
|
||||||
@@ -697,18 +702,28 @@ class CAInstance(DogtagInstance):
|
|||||||
custodia = custodiainstance.CustodiaInstance(host_name=self.fqdn,
|
custodia = custodiainstance.CustodiaInstance(host_name=self.fqdn,
|
||||||
realm=self.realm)
|
realm=self.realm)
|
||||||
custodia.import_ra_key(self.master_host)
|
custodia.import_ra_key(self.master_host)
|
||||||
|
self.__set_ra_cert_perms()
|
||||||
|
|
||||||
self.configure_agent_renewal()
|
self.configure_agent_renewal()
|
||||||
|
|
||||||
|
def __set_ra_cert_perms(self):
|
||||||
|
"""
|
||||||
|
Sets the correct permissions for the RA_AGENT_PEM, RA_AGENT_KEY files
|
||||||
|
"""
|
||||||
|
ipaapi_gid = grp.getgrnam(ipalib.constants.IPAAPI_GROUP).gr_gid
|
||||||
|
for fname in (paths.RA_AGENT_PEM, paths.RA_AGENT_KEY):
|
||||||
|
os.chown(fname, -1, ipaapi_gid)
|
||||||
|
os.chmod(fname, 0o440)
|
||||||
|
tasks.restore_context(fname)
|
||||||
|
|
||||||
def __create_ca_agent(self):
|
def __create_ca_agent(self):
|
||||||
"""
|
"""
|
||||||
Create CA agent, assign a certificate, and add the user to
|
Create CA agent, assign a certificate, and add the user to
|
||||||
the appropriate groups for accessing CA services.
|
the appropriate groups for accessing CA services.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# get ipaCert certificate
|
# get RA certificate
|
||||||
cert_data = base64.b64decode(self.ra_cert)
|
cert_data = self.ra_cert.public_bytes(serialization.Encoding.DER)
|
||||||
cert = x509.load_certificate(cert_data, x509.DER)
|
|
||||||
|
|
||||||
# connect to CA database
|
# connect to CA database
|
||||||
server_id = installutils.realm_to_serverid(api.env.realm)
|
server_id = installutils.realm_to_serverid(api.env.realm)
|
||||||
@@ -716,7 +731,7 @@ class CAInstance(DogtagInstance):
|
|||||||
conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
|
conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
|
||||||
conn.connect(autobind=True)
|
conn.connect(autobind=True)
|
||||||
|
|
||||||
# create ipara user with ipaCert certificate
|
# create ipara user with RA certificate
|
||||||
user_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
|
user_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
|
||||||
entry = conn.make_entry(
|
entry = conn.make_entry(
|
||||||
user_dn,
|
user_dn,
|
||||||
@@ -729,7 +744,7 @@ class CAInstance(DogtagInstance):
|
|||||||
userstate=["1"],
|
userstate=["1"],
|
||||||
userCertificate=[cert_data],
|
userCertificate=[cert_data],
|
||||||
description=['2;%s;%s;%s' % (
|
description=['2;%s;%s;%s' % (
|
||||||
cert.serial_number,
|
self.ra_cert.serial_number,
|
||||||
DN(self.ca_subject),
|
DN(self.ca_subject),
|
||||||
DN(('CN', 'IPA RA'), self.subject_base))])
|
DN(('CN', 'IPA RA'), self.subject_base))])
|
||||||
conn.add_entry(entry)
|
conn.add_entry(entry)
|
||||||
@@ -746,57 +761,30 @@ class CAInstance(DogtagInstance):
|
|||||||
|
|
||||||
conn.disconnect()
|
conn.disconnect()
|
||||||
|
|
||||||
def __publish_ca_cert(self):
|
|
||||||
db = certs.CertDB(self.realm)
|
|
||||||
db.publish_ca_cert(paths.IPA_CA_CRT)
|
|
||||||
|
|
||||||
def __get_ca_chain(self):
|
def __get_ca_chain(self):
|
||||||
try:
|
try:
|
||||||
return dogtag.get_ca_certchain(ca_host=self.fqdn)
|
return dogtag.get_ca_certchain(ca_host=self.fqdn)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise RuntimeError("Unable to retrieve CA chain: %s" % str(e))
|
raise RuntimeError("Unable to retrieve CA chain: %s" % str(e))
|
||||||
|
|
||||||
def __import_ca_chain(self):
|
def __export_ca_chain(self):
|
||||||
# Backup NSS trust flags of all already existing certificates
|
"""
|
||||||
certdb = certs.CertDB(self.realm)
|
Get the CA chain from Dogtag NSS DB and write it to paths.IPA_CA_CRT
|
||||||
cert_backup_list = certdb.list_certs()
|
"""
|
||||||
|
# Getting Dogtag CA chain
|
||||||
chain = self.__get_ca_chain()
|
chain = self.__get_ca_chain()
|
||||||
|
|
||||||
# If this chain contains multiple certs then certutil will only import
|
|
||||||
# the first one. So we have to pull them all out and import them
|
|
||||||
# separately. Unfortunately no NSS tool can do this so we have to
|
|
||||||
# use openssl.
|
|
||||||
|
|
||||||
# Convert to DER because the chain comes back as one long string which
|
# Convert to DER because the chain comes back as one long string which
|
||||||
# makes openssl throw up.
|
# makes openssl throw up.
|
||||||
data = base64.b64decode(chain)
|
data = base64.b64decode(chain)
|
||||||
|
|
||||||
|
# Get list of PEM certificates
|
||||||
certlist = x509.pkcs7_to_pems(data, x509.DER)
|
certlist = x509.pkcs7_to_pems(data, x509.DER)
|
||||||
|
|
||||||
# Ok, now we have all the certificates in certs, walk through it
|
# We have all the certificates in certlist, write them to a PEM file
|
||||||
# and pull out each certificate and add it to our database
|
|
||||||
|
|
||||||
ca_dn = DN(self.ca_subject)
|
|
||||||
for cert in certlist:
|
for cert in certlist:
|
||||||
with tempfile.NamedTemporaryFile(mode="w") as chain_file:
|
with open(paths.IPA_CA_CRT, 'w') as ipaca_pem:
|
||||||
chain_file.write(cert)
|
ipaca_pem.write(cert)
|
||||||
chain_file.flush()
|
|
||||||
(_rdn, subject_dn) = certs.get_cert_nickname(cert)
|
|
||||||
if subject_dn == ca_dn:
|
|
||||||
nick = get_ca_nickname(self.realm)
|
|
||||||
trust_flags = 'CT,C,C'
|
|
||||||
else:
|
|
||||||
nick = str(subject_dn)
|
|
||||||
trust_flags = ',,'
|
|
||||||
certdb.run_certutil(
|
|
||||||
['-A', '-t', trust_flags, '-n', nick, '-a',
|
|
||||||
'-i', chain_file.name]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Restore NSS trust flags of all previously existing certificates
|
|
||||||
for nick, trust_flags in cert_backup_list:
|
|
||||||
certdb.trust_root_cert(nick, trust_flags)
|
|
||||||
|
|
||||||
def __request_ra_certificate(self):
|
def __request_ra_certificate(self):
|
||||||
# create a temp file storing the pwd
|
# create a temp file storing the pwd
|
||||||
@@ -812,7 +800,7 @@ class CAInstance(DogtagInstance):
|
|||||||
|
|
||||||
chain = self.__get_ca_chain()
|
chain = self.__get_ca_chain()
|
||||||
data = base64.b64decode(chain)
|
data = base64.b64decode(chain)
|
||||||
result = ipautil.run(
|
ipautil.run(
|
||||||
[paths.OPENSSL,
|
[paths.OPENSSL,
|
||||||
"pkcs7",
|
"pkcs7",
|
||||||
"-inform",
|
"-inform",
|
||||||
@@ -839,24 +827,19 @@ class CAInstance(DogtagInstance):
|
|||||||
# The certificate must be requested using caServerCert profile
|
# The certificate must be requested using caServerCert profile
|
||||||
# because this profile does not require agent authentication
|
# because this profile does not require agent authentication
|
||||||
reqId = certmonger.request_and_wait_for_cert(
|
reqId = certmonger.request_and_wait_for_cert(
|
||||||
certpath=self.ra_agent_db,
|
certpath=(paths.RA_AGENT_PEM, paths.RA_AGENT_KEY),
|
||||||
nickname='ipaCert',
|
|
||||||
principal='host/%s' % self.fqdn,
|
principal='host/%s' % self.fqdn,
|
||||||
passwd_fname=self.ra_agent_pwd,
|
|
||||||
subject=str(DN(('CN', 'IPA RA'), self.subject_base)),
|
subject=str(DN(('CN', 'IPA RA'), self.subject_base)),
|
||||||
ca=ipalib.constants.RENEWAL_CA_NAME,
|
ca=ipalib.constants.RENEWAL_CA_NAME,
|
||||||
profile='caServerCert',
|
profile='caServerCert',
|
||||||
pre_command='renew_ra_cert_pre',
|
pre_command='renew_ra_cert_pre',
|
||||||
post_command='renew_ra_cert')
|
post_command='renew_ra_cert',
|
||||||
|
storage="FILE")
|
||||||
|
self.__set_ra_cert_perms()
|
||||||
|
|
||||||
self.requestId = str(reqId)
|
self.requestId = str(reqId)
|
||||||
certdb = certs.CertDB(self.realm)
|
self.ra_cert = x509.load_certificate_from_file(
|
||||||
result = certdb.run_certutil(
|
paths.RA_AGENT_PEM)
|
||||||
['-L', '-n', 'ipaCert', '-a'], capture_output=True)
|
|
||||||
self.ra_cert = x509.strip_header(result.output)
|
|
||||||
self.ra_cert = "\n".join(
|
|
||||||
line.strip() for line
|
|
||||||
in self.ra_cert.splitlines() if line.strip())
|
|
||||||
finally:
|
finally:
|
||||||
# we can restore the helper parameters
|
# we can restore the helper parameters
|
||||||
certmonger.modify_ca_helper(
|
certmonger.modify_ca_helper(
|
||||||
@@ -1013,12 +996,11 @@ class CAInstance(DogtagInstance):
|
|||||||
def configure_agent_renewal(self):
|
def configure_agent_renewal(self):
|
||||||
try:
|
try:
|
||||||
certmonger.start_tracking(
|
certmonger.start_tracking(
|
||||||
certpath=self.ra_agent_db,
|
certpath=(paths.RA_AGENT_PEM, paths.RA_AGENT_KEY),
|
||||||
ca='dogtag-ipa-ca-renew-agent',
|
ca='dogtag-ipa-ca-renew-agent',
|
||||||
nickname='ipaCert',
|
|
||||||
pinfile=self.ra_agent_pwd,
|
|
||||||
pre_command='renew_ra_cert_pre',
|
pre_command='renew_ra_cert_pre',
|
||||||
post_command='renew_ra_cert')
|
post_command='renew_ra_cert',
|
||||||
|
storage='FILE')
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
self.log.error(
|
self.log.error(
|
||||||
"certmonger failed to start tracking certificate: %s", e)
|
"certmonger failed to start tracking certificate: %s", e)
|
||||||
@@ -1035,7 +1017,7 @@ class CAInstance(DogtagInstance):
|
|||||||
certmonger.stop_tracking(self.nss_db, nickname=nickname)
|
certmonger.stop_tracking(self.nss_db, nickname=nickname)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
certmonger.stop_tracking(self.ra_agent_db, nickname='ipaCert')
|
certmonger.stop_tracking(certfile=paths.RA_AGENT_PEM)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
root_logger.error(
|
root_logger.error(
|
||||||
"certmonger failed to stop tracking certificate: %s", e)
|
"certmonger failed to stop tracking certificate: %s", e)
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class CertDB(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
# TODO: Remove all selfsign code
|
# TODO: Remove all selfsign code
|
||||||
def __init__(self, realm, nssdir=paths.IPA_RADB_DIR, fstore=None,
|
def __init__(self, realm, nssdir, fstore=None,
|
||||||
host_name=None, subject_base=None, ca_subject=None,
|
host_name=None, subject_base=None, ca_subject=None,
|
||||||
user=None, group=None, mode=None, truncate=False):
|
user=None, group=None, mode=None, truncate=False):
|
||||||
self.nssdb = NSSDatabase(nssdir)
|
self.nssdb = NSSDatabase(nssdir)
|
||||||
@@ -417,6 +417,7 @@ class CertDB(object):
|
|||||||
url="/ca/ee/ca/profileSubmitSSLClient",
|
url="/ca/ee/ca/profileSubmitSSLClient",
|
||||||
cafile=api.env.tls_ca_cert,
|
cafile=api.env.tls_ca_cert,
|
||||||
client_certfile=paths.RA_AGENT_PEM,
|
client_certfile=paths.RA_AGENT_PEM,
|
||||||
|
client_keyfile=paths.RA_AGENT_KEY,
|
||||||
**params)
|
**params)
|
||||||
http_status, _http_headers, http_body = result
|
http_status, _http_headers, http_body = result
|
||||||
root_logger.debug("CA answer: %s", http_body)
|
root_logger.debug("CA answer: %s", http_body)
|
||||||
@@ -471,6 +472,7 @@ class CertDB(object):
|
|||||||
url="/ca/ee/ca/profileSubmitSSLClient",
|
url="/ca/ee/ca/profileSubmitSSLClient",
|
||||||
cafile=api.env.tls_ca_cert,
|
cafile=api.env.tls_ca_cert,
|
||||||
client_certfile=paths.RA_AGENT_PEM,
|
client_certfile=paths.RA_AGENT_PEM,
|
||||||
|
client_keyfile=paths.RA_AGENT_KEY,
|
||||||
**params)
|
**params)
|
||||||
http_status, _http_headers, http_body = result
|
http_status, _http_headers, http_body = result
|
||||||
if http_status != 200:
|
if http_status != 200:
|
||||||
|
|||||||
@@ -112,6 +112,10 @@ class CustodiaInstance(SimpleServiceInstance):
|
|||||||
|
|
||||||
def import_ra_key(self, master_host_name):
|
def import_ra_key(self, master_host_name):
|
||||||
cli = self.__CustodiaClient(server=master_host_name)
|
cli = self.__CustodiaClient(server=master_host_name)
|
||||||
|
# please note that ipaCert part has to stay here for historical
|
||||||
|
# reasons (old servers expect you to ask for ra/ipaCert during
|
||||||
|
# replication as they store the RA agent cert in an NSS database
|
||||||
|
# with this nickname)
|
||||||
cli.fetch_key('ra/ipaCert')
|
cli.fetch_key('ra/ipaCert')
|
||||||
|
|
||||||
def import_dm_password(self, master_host_name):
|
def import_dm_password(self, master_host_name):
|
||||||
|
|||||||
@@ -21,17 +21,13 @@ import base64
|
|||||||
import ldap
|
import ldap
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
|
||||||
import traceback
|
import traceback
|
||||||
import dbus
|
import dbus
|
||||||
import pwd
|
|
||||||
|
|
||||||
from pki.client import PKIConnection
|
from pki.client import PKIConnection
|
||||||
import pki.system
|
import pki.system
|
||||||
|
|
||||||
from ipalib import api, errors
|
from ipalib import api, errors
|
||||||
|
|
||||||
from ipalib.constants import IPAAPI_USER
|
|
||||||
from ipalib.install import certmonger
|
from ipalib.install import certmonger
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
from ipaplatform.constants import constants
|
from ipaplatform.constants import constants
|
||||||
@@ -72,27 +68,6 @@ def is_installing_replica(sys_type):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def export_ra_agent_pem():
|
|
||||||
"""
|
|
||||||
Export ipaCert with private key for client authentication.
|
|
||||||
"""
|
|
||||||
fd, filename = tempfile.mkstemp(dir=paths.IPA_RADB_DIR)
|
|
||||||
os.close(fd)
|
|
||||||
|
|
||||||
args = ["/usr/bin/pki",
|
|
||||||
"-d", paths.IPA_RADB_DIR,
|
|
||||||
"-C", os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt'),
|
|
||||||
"client-cert-show", "ipaCert",
|
|
||||||
"--client-cert", filename]
|
|
||||||
ipautil.run(args)
|
|
||||||
|
|
||||||
pent = pwd.getpwnam(IPAAPI_USER)
|
|
||||||
os.chown(filename, 0, pent.pw_gid)
|
|
||||||
os.chmod(filename, 0o440)
|
|
||||||
|
|
||||||
os.rename(filename, paths.RA_AGENT_PEM)
|
|
||||||
|
|
||||||
|
|
||||||
class DogtagInstance(service.Service):
|
class DogtagInstance(service.Service):
|
||||||
"""
|
"""
|
||||||
This is the base class for a Dogtag 10+ instance, which uses a
|
This is the base class for a Dogtag 10+ instance, which uses a
|
||||||
|
|||||||
@@ -811,13 +811,14 @@ class DsInstance(service.Service):
|
|||||||
'restart_dirsrv %s' % self.serverid)
|
'restart_dirsrv %s' % self.serverid)
|
||||||
else:
|
else:
|
||||||
dsdb.create_from_cacert()
|
dsdb.create_from_cacert()
|
||||||
ca_args = ['/usr/libexec/certmonger/dogtag-submit',
|
ca_args = [
|
||||||
'--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
|
paths.CERTMONGER_DOGTAG_SUBMIT,
|
||||||
'--dbdir', paths.IPA_RADB_DIR,
|
'--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
|
||||||
'--nickname', 'ipaCert',
|
'--certfile', paths.RA_AGENT_PEM,
|
||||||
'--sslpinfile', os.path.join(paths.IPA_RADB_DIR,
|
'--keyfile', paths.RA_AGENT_KEY,
|
||||||
'pwdfile.txt'),
|
'--cafile', paths.IPA_CA_CRT,
|
||||||
'--agent-submit']
|
'--agent-submit'
|
||||||
|
]
|
||||||
helper = " ".join(ca_args)
|
helper = " ".join(ca_args)
|
||||||
prev_helper = certmonger.modify_ca_helper('IPA', helper)
|
prev_helper = certmonger.modify_ca_helper('IPA', helper)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -384,14 +384,13 @@ class HTTPInstance(service.Service):
|
|||||||
if not self.promote:
|
if not self.promote:
|
||||||
self.create_password_conf()
|
self.create_password_conf()
|
||||||
ca_args = [
|
ca_args = [
|
||||||
'/usr/libexec/certmonger/dogtag-submit',
|
paths.CERTMONGER_DOGTAG_SUBMIT,
|
||||||
'--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
|
'--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
|
||||||
'--dbdir', paths.IPA_RADB_DIR,
|
'--certfile', paths.RA_AGENT_PEM,
|
||||||
'--nickname', 'ipaCert',
|
'--keyfile', paths.RA_AGENT_KEY,
|
||||||
'--sslpinfile', os.path.join(paths.IPA_RADB_DIR,
|
'--cafile', paths.IPA_CA_CRT,
|
||||||
'pwdfile.txt'),
|
|
||||||
'--agent-submit'
|
'--agent-submit'
|
||||||
]
|
]
|
||||||
helper = " ".join(ca_args)
|
helper = " ".join(ca_args)
|
||||||
prev_helper = certmonger.modify_ca_helper('IPA', helper)
|
prev_helper = certmonger.modify_ca_helper('IPA', helper)
|
||||||
|
|
||||||
@@ -419,10 +418,6 @@ class HTTPInstance(service.Service):
|
|||||||
raise RuntimeError("Could not find a suitable server cert.")
|
raise RuntimeError("Could not find a suitable server cert.")
|
||||||
|
|
||||||
def __import_ca_certs(self):
|
def __import_ca_certs(self):
|
||||||
# first for the RA DB
|
|
||||||
db = certs.CertDB(self.realm, subject_base=self.subject_base)
|
|
||||||
self.import_ca_certs(db, self.ca_is_configured)
|
|
||||||
# and then also for the HTTPD DB
|
|
||||||
db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
|
db = certs.CertDB(self.realm, nssdir=paths.HTTPD_ALIAS_DIR,
|
||||||
subject_base=self.subject_base)
|
subject_base=self.subject_base)
|
||||||
self.import_ca_certs(db, self.ca_is_configured)
|
self.import_ca_certs(db, self.ca_is_configured)
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ class Backup(admintool.AdminTool):
|
|||||||
paths.PKI_TOMCAT,
|
paths.PKI_TOMCAT,
|
||||||
paths.SYSCONFIG_PKI,
|
paths.SYSCONFIG_PKI,
|
||||||
paths.HTTPD_ALIAS_DIR,
|
paths.HTTPD_ALIAS_DIR,
|
||||||
paths.IPA_RADB_DIR,
|
|
||||||
paths.VAR_LIB_PKI_DIR,
|
paths.VAR_LIB_PKI_DIR,
|
||||||
paths.SYSRESTORE,
|
paths.SYSRESTORE,
|
||||||
paths.IPA_CLIENT_SYSRESTORE,
|
paths.IPA_CLIENT_SYSRESTORE,
|
||||||
@@ -159,6 +158,7 @@ class Backup(admintool.AdminTool):
|
|||||||
paths.SAMBA_KEYTAB,
|
paths.SAMBA_KEYTAB,
|
||||||
paths.DOGTAG_ADMIN_P12,
|
paths.DOGTAG_ADMIN_P12,
|
||||||
paths.RA_AGENT_PEM,
|
paths.RA_AGENT_PEM,
|
||||||
|
paths.RA_AGENT_KEY,
|
||||||
paths.CACERT_P12,
|
paths.CACERT_P12,
|
||||||
paths.KRACERT_P12,
|
paths.KRACERT_P12,
|
||||||
paths.KRB5KDC_KDC_CONF,
|
paths.KRB5KDC_KDC_CONF,
|
||||||
|
|||||||
@@ -631,18 +631,16 @@ class ReplicaPrepare(admintool.AdminTool):
|
|||||||
raise admintool.ScriptError(str(e))
|
raise admintool.ScriptError(str(e))
|
||||||
|
|
||||||
def export_ra_pkcs12(self):
|
def export_ra_pkcs12(self):
|
||||||
agent_fd, agent_name = tempfile.mkstemp()
|
if (os.path.exists(paths.RA_AGENT_PEM) and
|
||||||
os.write(agent_fd, self.dirman_password)
|
os.path.exists(paths.RA_AGENT_KEY)):
|
||||||
os.close(agent_fd)
|
ipautil.run([
|
||||||
|
paths.OPENSSL,
|
||||||
try:
|
"pkcs12", "-export",
|
||||||
db = certs.CertDB(api.env.realm, host_name=api.env.host)
|
"-inkey", paths.RA_AGENT_KEY,
|
||||||
|
"-in", paths.RA_AGENT_PEM,
|
||||||
if db.has_nickname("ipaCert"):
|
"-out", os.path.join(self.dir, "ra.p12"),
|
||||||
pkcs12_fname = os.path.join(self.dir, "ra.p12")
|
"-passout", "pass:"
|
||||||
db.export_pkcs12(pkcs12_fname, agent_name, "ipaCert")
|
])
|
||||||
finally:
|
|
||||||
os.remove(agent_name)
|
|
||||||
|
|
||||||
def update_pki_admin_password(self):
|
def update_pki_admin_password(self):
|
||||||
dn = DN('uid=admin', 'ou=people', 'o=ipaca')
|
dn = DN('uid=admin', 'ou=people', 'o=ipaca')
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ import six
|
|||||||
# pylint: disable=import-error
|
# pylint: disable=import-error
|
||||||
from six.moves.configparser import ConfigParser
|
from six.moves.configparser import ConfigParser
|
||||||
# pylint: enable=import-error
|
# pylint: enable=import-error
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
from ipalib import x509
|
from ipalib import x509
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipapython import certdb
|
|
||||||
from ipapython import ipautil
|
from ipapython import ipautil
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipaserver.install import cainstance
|
from ipaserver.install import cainstance
|
||||||
@@ -290,10 +290,9 @@ class KRAInstance(DogtagInstance):
|
|||||||
the appropriate groups for accessing KRA services.
|
the appropriate groups for accessing KRA services.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# get ipaCert certificate
|
# get RA agent certificate
|
||||||
with certdb.NSSDatabase(paths.IPA_RADB_DIR) as ipa_nssdb:
|
cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
|
||||||
cert_data = ipa_nssdb.get_cert("ipaCert")
|
cert_data = cert.public_bytes(serialization.Encoding.DER)
|
||||||
cert = x509.load_certificate(cert_data, x509.DER)
|
|
||||||
|
|
||||||
# connect to KRA database
|
# connect to KRA database
|
||||||
server_id = installutils.realm_to_serverid(api.env.realm)
|
server_id = installutils.realm_to_serverid(api.env.realm)
|
||||||
@@ -301,7 +300,7 @@ class KRAInstance(DogtagInstance):
|
|||||||
conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
|
conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
|
||||||
conn.connect(autobind=True)
|
conn.connect(autobind=True)
|
||||||
|
|
||||||
# create ipakra user with ipaCert certificate
|
# create ipakra user with RA agent certificate
|
||||||
user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
|
user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
|
||||||
entry = conn.make_entry(
|
entry = conn.make_entry(
|
||||||
user_dn,
|
user_dn,
|
||||||
|
|||||||
@@ -74,17 +74,16 @@ class update_ca_renewal_master(Updater):
|
|||||||
return False, []
|
return False, []
|
||||||
|
|
||||||
criteria = {
|
criteria = {
|
||||||
'cert-database': paths.HTTPD_ALIAS_DIR,
|
'cert-file': paths.RA_AGENT_PEM,
|
||||||
'cert-nickname': 'ipaCert',
|
|
||||||
}
|
}
|
||||||
request_id = certmonger.get_request_id(criteria)
|
request_id = certmonger.get_request_id(criteria)
|
||||||
if request_id is not None:
|
if request_id is not None:
|
||||||
self.debug("found certmonger request for ipaCert")
|
self.debug("found certmonger request for RA cert")
|
||||||
|
|
||||||
ca_name = certmonger.get_request_value(request_id, 'ca-name')
|
ca_name = certmonger.get_request_value(request_id, 'ca-name')
|
||||||
if ca_name is None:
|
if ca_name is None:
|
||||||
self.warning(
|
self.warning(
|
||||||
"certmonger request for ipaCert is missing ca_name, "
|
"certmonger request for RA cert is missing ca_name, "
|
||||||
"assuming local CA is renewal slave")
|
"assuming local CA is renewal slave")
|
||||||
return False, []
|
return False, []
|
||||||
ca_name = ca_name.strip()
|
ca_name = ca_name.strip()
|
||||||
@@ -97,11 +96,11 @@ class update_ca_renewal_master(Updater):
|
|||||||
return False, []
|
return False, []
|
||||||
else:
|
else:
|
||||||
self.warning(
|
self.warning(
|
||||||
"certmonger request for ipaCert has unknown ca_name '%s', "
|
"certmonger request for RA cert has unknown ca_name '%s', "
|
||||||
"assuming local CA is renewal slave", ca_name)
|
"assuming local CA is renewal slave", ca_name)
|
||||||
return False, []
|
return False, []
|
||||||
else:
|
else:
|
||||||
self.debug("certmonger request for ipaCert not found")
|
self.debug("certmonger request for RA cert not found")
|
||||||
|
|
||||||
config = installutils.get_directive(
|
config = installutils.get_directive(
|
||||||
paths.CA_CS_CFG_PATH, 'subsystem.select', '=')
|
paths.CA_CS_CFG_PATH, 'subsystem.select', '=')
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
||||||
#
|
#
|
||||||
|
|
||||||
import binascii
|
|
||||||
import os
|
import os
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from ipalib import Registry
|
from ipalib import Registry
|
||||||
from ipalib import Updater
|
from ipalib import Updater
|
||||||
from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
|
|
||||||
from ipalib.install import certmonger
|
from ipalib.install import certmonger
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipapython import certdb
|
from ipapython.certdb import NSSDatabase
|
||||||
|
from ipaserver.install import cainstance
|
||||||
|
|
||||||
register = Registry()
|
register = Registry()
|
||||||
|
|
||||||
@@ -18,58 +18,44 @@ register = Registry()
|
|||||||
@register()
|
@register()
|
||||||
class update_ra_cert_store(Updater):
|
class update_ra_cert_store(Updater):
|
||||||
"""
|
"""
|
||||||
Moves the cert store from /etc/httpd/alias to /var/lib/ipa/radb
|
Moves the ipaCert store from /etc/httpd/alias RA_AGENT_PEM, RA_AGENT_KEY
|
||||||
|
files
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def execute(self, **options):
|
def execute(self, **options):
|
||||||
|
ra_nick = 'ipaCert'
|
||||||
ca_enabled = self.api.Command.ca_is_enabled()['result']
|
ca_enabled = self.api.Command.ca_is_enabled()['result']
|
||||||
if not ca_enabled:
|
if not ca_enabled:
|
||||||
return False, []
|
return False, []
|
||||||
|
|
||||||
olddb = certdb.NSSDatabase(nssdir=paths.HTTPD_ALIAS_DIR)
|
certdb = NSSDatabase(nssdir=paths.HTTPD_ALIAS_DIR)
|
||||||
if not olddb.has_nickname('ipaCert'):
|
if not certdb.has_nickname(ra_nick):
|
||||||
# Nothign to do
|
# Nothign to do
|
||||||
return False, []
|
return False, []
|
||||||
|
elif os.path.exists(paths.RA_AGENT_PEM):
|
||||||
|
# even though the certificate file exists, we will overwrite it
|
||||||
|
# as it's probabably something wrong anyway
|
||||||
|
self.log.warning(
|
||||||
|
"A certificate with the nickname 'ipaCert' exists in "
|
||||||
|
"the old '{}' NSS database as well as in the new "
|
||||||
|
"PEM file '{}'"
|
||||||
|
.format(paths.HTTPD_ALIAS_DIR, paths.RA_AGENT_PEM))
|
||||||
|
|
||||||
newdb = certdb.NSSDatabase(nssdir=paths.IPA_RADB_DIR)
|
_fd, p12file = tempfile.mkstemp(dir=certdb.secdir)
|
||||||
if os.path.exists(paths.IPA_RADB_DIR):
|
# no password is necessary as we will be saving it in clear anyway
|
||||||
if newdb.has_nickname('ipaCert'):
|
certdb.export_pkcs12(ra_nick, p12file, pkcs12_passwd='')
|
||||||
self.log.warning(
|
|
||||||
"An 'ipaCert' nickname exists in both the old {} and the "
|
|
||||||
"new {} NSS Databases!".format(paths.HTTPD_ALIAS_DIR,
|
|
||||||
paths.IPA_RADB_DIR))
|
|
||||||
return False, []
|
|
||||||
else:
|
|
||||||
# Create the DB
|
|
||||||
newdb.create_db(user=IPAAPI_USER, group=IPAAPI_GROUP, backup=True)
|
|
||||||
|
|
||||||
# Import cert chain (ignore errors, as certs may already be imported)
|
# stop tracking the old cert and remove it
|
||||||
certlist = olddb.list_certs()
|
certmonger.stop_tracking(paths.HTTPD_ALIAS_DIR, nickname=ra_nick)
|
||||||
certflags = {}
|
certdb.delete_cert(ra_nick)
|
||||||
for name, flags in certlist:
|
if os.path.exists(paths.OLD_KRA_AGENT_PEM):
|
||||||
certflags[name] = flags
|
os.remove(paths.OLD_KRA_AGENT_PEM)
|
||||||
for name in olddb.get_trust_chain('ipaCert'):
|
|
||||||
if name == 'ipaCert':
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
cert = olddb.get_cert(name, pem=True)
|
|
||||||
newdb.add_cert(cert, name, certflags[name], pem=True)
|
|
||||||
except Exception as e: # pylint disable=broad-except
|
|
||||||
self.log.warning("Failed to import '{}' from trust "
|
|
||||||
"chain: {}".format(name, str(e)))
|
|
||||||
|
|
||||||
# As the last step export/import/delete the RA Cert
|
# get the private key and certificate from the file and start
|
||||||
pw = binascii.hexlify(os.urandom(10))
|
# tracking it in certmonger
|
||||||
p12file = os.path.join(paths.IPA_RADB_DIR, 'ipaCert.p12')
|
ca = cainstance.CAInstance()
|
||||||
olddb.export_pkcs12('ipaCert', p12file, pw)
|
ca.import_ra_cert(p12file)
|
||||||
newdb.import_pkcs12(p12file, pw)
|
|
||||||
|
|
||||||
certmonger.stop_tracking(secdir=olddb.secdir,
|
os.remove(p12file)
|
||||||
nickname='ipaCert')
|
|
||||||
certmonger.start_tracking(certpath=newdb.secdir,
|
|
||||||
nickname='ipaCert',
|
|
||||||
pinfile=newdb.pwd_file)
|
|
||||||
|
|
||||||
olddb.delete_cert('ipaCert')
|
|
||||||
|
|
||||||
return False, []
|
return False, []
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import textwrap
|
|||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
|
|
||||||
from ipalib.install import certmonger, sysrestore
|
from ipalib.install import certmonger, sysrestore
|
||||||
from ipapython import ipautil
|
from ipapython import ipautil
|
||||||
from ipapython.ipa_log_manager import root_logger
|
from ipapython.ipa_log_manager import root_logger
|
||||||
@@ -24,7 +23,8 @@ from ipapython.admintool import ScriptError
|
|||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipaplatform.tasks import tasks
|
from ipaplatform.tasks import tasks
|
||||||
from ipalib import api, constants, errors, x509
|
from ipalib import api, errors, x509
|
||||||
|
from ipalib.constants import DOMAIN_LEVEL_0
|
||||||
from ipalib.util import (
|
from ipalib.util import (
|
||||||
validate_domain_name,
|
validate_domain_name,
|
||||||
network_ip_address_warning,
|
network_ip_address_warning,
|
||||||
@@ -32,7 +32,7 @@ from ipalib.util import (
|
|||||||
)
|
)
|
||||||
import ipaclient.install.ntpconf
|
import ipaclient.install.ntpconf
|
||||||
from ipaserver.install import (
|
from ipaserver.install import (
|
||||||
bindinstance, ca, certs, dns, dsinstance,
|
bindinstance, ca, dns, dsinstance,
|
||||||
httpinstance, installutils, kra, krbinstance,
|
httpinstance, installutils, kra, krbinstance,
|
||||||
ntpinstance, otpdinstance, custodiainstance, replication, service,
|
ntpinstance, otpdinstance, custodiainstance, replication, service,
|
||||||
sysupgrade)
|
sysupgrade)
|
||||||
@@ -774,11 +774,6 @@ def install(installer):
|
|||||||
if n in options.__dict__}
|
if n in options.__dict__}
|
||||||
write_cache(cache_vars)
|
write_cache(cache_vars)
|
||||||
|
|
||||||
# Create RA DB
|
|
||||||
certs.CertDB(realm_name, nssdir=paths.IPA_RADB_DIR,
|
|
||||||
user=IPAAPI_USER, group=IPAAPI_GROUP,
|
|
||||||
truncate=True)
|
|
||||||
|
|
||||||
ca.install_step_0(False, None, options)
|
ca.install_step_0(False, None, options)
|
||||||
else:
|
else:
|
||||||
# Put the CA cert where other instances expect it
|
# Put the CA cert where other instances expect it
|
||||||
@@ -987,7 +982,7 @@ def uninstall_check(installer):
|
|||||||
else:
|
else:
|
||||||
dns.uninstall_check(options)
|
dns.uninstall_check(options)
|
||||||
|
|
||||||
if domain_level == constants.DOMAIN_LEVEL_0:
|
if domain_level == DOMAIN_LEVEL_0:
|
||||||
rm = replication.ReplicationManager(
|
rm = replication.ReplicationManager(
|
||||||
realm=api.env.realm,
|
realm=api.env.realm,
|
||||||
hostname=api.env.host,
|
hostname=api.env.host,
|
||||||
@@ -1102,8 +1097,7 @@ def uninstall(installer):
|
|||||||
# Note that this name will be wrong after the first uninstall.
|
# Note that this name will be wrong after the first uninstall.
|
||||||
dirname = dsinstance.config_dirname(
|
dirname = dsinstance.config_dirname(
|
||||||
installutils.realm_to_serverid(api.env.realm))
|
installutils.realm_to_serverid(api.env.realm))
|
||||||
dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR,
|
dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR]
|
||||||
paths.IPA_RADB_DIR]
|
|
||||||
ids = certmonger.check_state(dirs)
|
ids = certmonger.check_state(dirs)
|
||||||
if ids:
|
if ids:
|
||||||
root_logger.error('Some certificates may still be tracked by '
|
root_logger.error('Some certificates may still be tracked by '
|
||||||
@@ -1116,11 +1110,6 @@ def uninstall(installer):
|
|||||||
' # getcert stop-tracking -i <request_id>\n'
|
' # getcert stop-tracking -i <request_id>\n'
|
||||||
'for each id in: %s' % ', '.join(ids))
|
'for each id in: %s' % ', '.join(ids))
|
||||||
|
|
||||||
try:
|
|
||||||
shutil.rmtree(paths.IPA_RADB_DIR)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Remove the cert renewal lock file
|
# Remove the cert renewal lock file
|
||||||
try:
|
try:
|
||||||
os.remove(paths.IPA_RENEWAL_LOCK)
|
os.remove(paths.IPA_RENEWAL_LOCK)
|
||||||
|
|||||||
@@ -900,77 +900,72 @@ def certificate_renewal_update(ca, ds, http):
|
|||||||
|
|
||||||
template = paths.CERTMONGER_COMMAND_TEMPLATE
|
template = paths.CERTMONGER_COMMAND_TEMPLATE
|
||||||
serverid = installutils.realm_to_serverid(api.env.realm)
|
serverid = installutils.realm_to_serverid(api.env.realm)
|
||||||
dirsrv_dir = dsinstance.config_dirname(serverid)
|
|
||||||
|
|
||||||
# bump version when requests is changed
|
# bump version when requests is changed
|
||||||
version = 6
|
version = 6
|
||||||
requests = (
|
requests = [
|
||||||
(
|
{
|
||||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||||
'auditSigningCert cert-pki-ca',
|
'cert-nickname': 'auditSigningCert cert-pki-ca',
|
||||||
'dogtag-ipa-ca-renew-agent',
|
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||||
template % 'stop_pkicad',
|
'cert-presave-command': template % 'stop_pkicad',
|
||||||
'%s "auditSigningCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
'cert-postsave-command':
|
||||||
None,
|
(template % 'renew_ca_cert "auditSigningCert cert-pki-ca"'),
|
||||||
),
|
},
|
||||||
(
|
{
|
||||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||||
'ocspSigningCert cert-pki-ca',
|
'cert-nickname': 'ocspSigningCert cert-pki-ca',
|
||||||
'dogtag-ipa-ca-renew-agent',
|
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||||
template % 'stop_pkicad',
|
'cert-presave-command': template % 'stop_pkicad',
|
||||||
'%s "ocspSigningCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
'cert-postsave-command':
|
||||||
None,
|
(template % 'renew_ca_cert "ocspSigningCert cert-pki-ca"'),
|
||||||
),
|
},
|
||||||
(
|
{
|
||||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||||
'subsystemCert cert-pki-ca',
|
'cert-nickname': 'subsystemCert cert-pki-ca',
|
||||||
'dogtag-ipa-ca-renew-agent',
|
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||||
template % 'stop_pkicad',
|
'cert-presave-command': template % 'stop_pkicad',
|
||||||
'%s "subsystemCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
'cert-postsave-command':
|
||||||
None,
|
(template % 'renew_ca_cert "subsystemCert cert-pki-ca"'),
|
||||||
),
|
},
|
||||||
(
|
{
|
||||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||||
'caSigningCert cert-pki-ca',
|
'cert-nickname': 'caSigningCert cert-pki-ca',
|
||||||
'dogtag-ipa-ca-renew-agent',
|
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||||
template % 'stop_pkicad',
|
'cert-presave-command': template % 'stop_pkicad',
|
||||||
'%s "caSigningCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
'cert-postsave-command':
|
||||||
'ipaCACertRenewal',
|
(template % 'renew_ca_cert "caSigningCert cert-pki-ca"'),
|
||||||
),
|
'template-profile': 'ipaCACertRenewal',
|
||||||
(
|
},
|
||||||
paths.IPA_RADB_DIR,
|
{
|
||||||
'ipaCert',
|
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||||
'dogtag-ipa-ca-renew-agent',
|
'cert-nickname': 'Server-Cert cert-pki-ca',
|
||||||
template % 'renew_ra_cert_pre',
|
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||||
template % 'renew_ra_cert',
|
'cert-presave-command': template % 'stop_pkicad',
|
||||||
None,
|
'cert-postsave-command':
|
||||||
),
|
(template % 'renew_ca_cert "Server-Cert cert-pki-ca"'),
|
||||||
(
|
},
|
||||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
{
|
||||||
'Server-Cert cert-pki-ca',
|
'cert-file': paths.RA_AGENT_PEM,
|
||||||
'dogtag-ipa-ca-renew-agent',
|
'key-file': paths.RA_AGENT_KEY,
|
||||||
template % 'stop_pkicad',
|
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||||
'%s "Server-Cert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
'cert-presave-command': template % 'renew_ra_cert_pre',
|
||||||
None,
|
'cert-postsave-command': template % 'renew_ra_cert',
|
||||||
),
|
},
|
||||||
(
|
{
|
||||||
paths.HTTPD_ALIAS_DIR,
|
'cert-database': paths.HTTPD_ALIAS_DIR,
|
||||||
'Server-Cert',
|
'cert-nickname': 'Server-Cert',
|
||||||
'IPA',
|
'ca': 'IPA',
|
||||||
None,
|
'cert-postsave-command': template % 'restart_httpd',
|
||||||
template % 'restart_httpd',
|
},
|
||||||
None,
|
{
|
||||||
),
|
'cert-database': dsinstance.config_dirname(serverid),
|
||||||
(
|
'cert-nickname': 'Server-Cert',
|
||||||
dirsrv_dir,
|
'ca': 'IPA',
|
||||||
'Server-Cert',
|
'cert-postsave-command':
|
||||||
'IPA',
|
'%s %s' % (template % 'restart_dirsrv', serverid),
|
||||||
None,
|
}
|
||||||
'%s %s' % (template % 'restart_dirsrv', serverid),
|
]
|
||||||
None,
|
|
||||||
),
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
root_logger.info("[Update certmonger certificate renewal configuration to "
|
root_logger.info("[Update certmonger certificate renewal configuration to "
|
||||||
"version %d]" % version)
|
"version %d]" % version)
|
||||||
@@ -984,16 +979,7 @@ def certificate_renewal_update(ca, ds, http):
|
|||||||
|
|
||||||
# State not set, lets see if we are already configured
|
# State not set, lets see if we are already configured
|
||||||
for request in requests:
|
for request in requests:
|
||||||
nss_dir, nickname, ca_name, pre_command, post_command, profile = request
|
request_id = certmonger.get_request_id(request)
|
||||||
criteria = {
|
|
||||||
'cert-database': nss_dir,
|
|
||||||
'cert-nickname': nickname,
|
|
||||||
'ca-name': ca_name,
|
|
||||||
'template-profile': profile,
|
|
||||||
'cert-presave-command': pre_command,
|
|
||||||
'cert-postsave-command': post_command,
|
|
||||||
}
|
|
||||||
request_id = certmonger.get_request_id(criteria)
|
|
||||||
if request_id is None:
|
if request_id is None:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@@ -1402,24 +1388,6 @@ def fix_trust_flags():
|
|||||||
sysupgrade.set_upgrade_state('http', 'fix_trust_flags', True)
|
sysupgrade.set_upgrade_state('http', 'fix_trust_flags', True)
|
||||||
|
|
||||||
|
|
||||||
def export_ra_agent_pem():
|
|
||||||
root_logger.info('[Exporting KRA agent PEM file]')
|
|
||||||
|
|
||||||
# export_kra_agent_pem is the original name of this function
|
|
||||||
sysupgrade.remove_upgrade_state('http', 'export_kra_agent_pem')
|
|
||||||
|
|
||||||
if os.path.exists(paths.RA_AGENT_PEM):
|
|
||||||
root_logger.info("KRA agent PEM file already exported")
|
|
||||||
return
|
|
||||||
|
|
||||||
if not api.Command.kra_is_enabled()['result']:
|
|
||||||
root_logger.info("KRA is not enabled")
|
|
||||||
return
|
|
||||||
|
|
||||||
dogtaginstance.export_ra_agent_pem()
|
|
||||||
installutils.remove_file(paths.OLD_KRA_AGENT_PEM)
|
|
||||||
|
|
||||||
|
|
||||||
def update_mod_nss_protocol(http):
|
def update_mod_nss_protocol(http):
|
||||||
root_logger.info('[Updating mod_nss protocol versions]')
|
root_logger.info('[Updating mod_nss protocol versions]')
|
||||||
|
|
||||||
@@ -1663,7 +1631,6 @@ def upgrade_configuration():
|
|||||||
update_mod_nss_protocol(http)
|
update_mod_nss_protocol(http)
|
||||||
update_mod_nss_cipher_suite(http)
|
update_mod_nss_cipher_suite(http)
|
||||||
fix_trust_flags()
|
fix_trust_flags()
|
||||||
export_ra_agent_pem()
|
|
||||||
update_http_keytab(http)
|
update_http_keytab(http)
|
||||||
http.configure_gssproxy()
|
http.configure_gssproxy()
|
||||||
http.start()
|
http.start()
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ import datetime
|
|||||||
import json
|
import json
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
import time
|
import time
|
||||||
|
import contextlib
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from six.moves import urllib
|
from six.moves import urllib
|
||||||
@@ -250,8 +251,7 @@ from six.moves import urllib
|
|||||||
from ipalib import Backend, api
|
from ipalib import Backend, api
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
import ipapython.cookie
|
import ipapython.cookie
|
||||||
from ipapython import dogtag
|
from ipapython import dogtag, ipautil, certdb
|
||||||
from ipapython import ipautil
|
|
||||||
|
|
||||||
if api.env.in_server:
|
if api.env.in_server:
|
||||||
import pki
|
import pki
|
||||||
@@ -1242,8 +1242,12 @@ class RestClient(Backend):
|
|||||||
if api.env.in_tree:
|
if api.env.in_tree:
|
||||||
self.client_certfile = os.path.join(
|
self.client_certfile = os.path.join(
|
||||||
api.env.dot_ipa, 'ra-agent.pem')
|
api.env.dot_ipa, 'ra-agent.pem')
|
||||||
|
|
||||||
|
self.client_keyfile = os.path.join(
|
||||||
|
api.env.dot_ipa, 'ra-agent.key')
|
||||||
else:
|
else:
|
||||||
self.client_certfile = paths.RA_AGENT_PEM
|
self.client_certfile = paths.RA_AGENT_PEM
|
||||||
|
self.client_keyfile = paths.RA_AGENT_KEY
|
||||||
super(RestClient, self).__init__(api)
|
super(RestClient, self).__init__(api)
|
||||||
|
|
||||||
# session cookie
|
# session cookie
|
||||||
@@ -1279,6 +1283,7 @@ class RestClient(Backend):
|
|||||||
url='/ca/rest/account/login',
|
url='/ca/rest/account/login',
|
||||||
cafile=self.ca_cert,
|
cafile=self.ca_cert,
|
||||||
client_certfile=self.client_certfile,
|
client_certfile=self.client_certfile,
|
||||||
|
client_keyfile=self.client_keyfile,
|
||||||
method='GET'
|
method='GET'
|
||||||
)
|
)
|
||||||
cookies = ipapython.cookie.Cookie.parse(resp_headers.get('set-cookie', ''))
|
cookies = ipapython.cookie.Cookie.parse(resp_headers.get('set-cookie', ''))
|
||||||
@@ -1294,6 +1299,7 @@ class RestClient(Backend):
|
|||||||
url='/ca/rest/account/logout',
|
url='/ca/rest/account/logout',
|
||||||
cafile=self.ca_cert,
|
cafile=self.ca_cert,
|
||||||
client_certfile=self.client_certfile,
|
client_certfile=self.client_certfile,
|
||||||
|
client_keyfile=self.client_keyfile,
|
||||||
method='GET'
|
method='GET'
|
||||||
)
|
)
|
||||||
self.cookie = None
|
self.cookie = None
|
||||||
@@ -1337,6 +1343,7 @@ class RestClient(Backend):
|
|||||||
url=resource,
|
url=resource,
|
||||||
cafile=self.ca_cert,
|
cafile=self.ca_cert,
|
||||||
client_certfile=self.client_certfile,
|
client_certfile=self.client_certfile,
|
||||||
|
client_keyfile=self.client_keyfile,
|
||||||
method=method, headers=headers, body=body
|
method=method, headers=headers, body=body
|
||||||
)
|
)
|
||||||
if status < 200 or status >= 300:
|
if status < 200 or status >= 300:
|
||||||
@@ -1421,6 +1428,7 @@ class ra(rabase.rabase, RestClient):
|
|||||||
self.ca_host, port, url,
|
self.ca_host, port, url,
|
||||||
cafile=self.ca_cert,
|
cafile=self.ca_cert,
|
||||||
client_certfile=self.client_certfile,
|
client_certfile=self.client_certfile,
|
||||||
|
client_keyfile=self.client_keyfile,
|
||||||
**kw)
|
**kw)
|
||||||
|
|
||||||
def get_parse_result_xml(self, xml_text, parse_func):
|
def get_parse_result_xml(self, xml_text, parse_func):
|
||||||
@@ -1998,6 +2006,7 @@ class kra(Backend):
|
|||||||
else:
|
else:
|
||||||
return api.env.ca_host
|
return api.env.ca_host
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
def get_client(self):
|
def get_client(self):
|
||||||
"""
|
"""
|
||||||
Returns an authenticated KRA client to access KRA services.
|
Returns an authenticated KRA client to access KRA services.
|
||||||
@@ -2009,9 +2018,11 @@ class kra(Backend):
|
|||||||
# TODO: replace this with a more specific exception
|
# TODO: replace this with a more specific exception
|
||||||
raise RuntimeError('KRA service is not enabled')
|
raise RuntimeError('KRA service is not enabled')
|
||||||
|
|
||||||
|
tempdb = certdb.NSSDatabase()
|
||||||
|
tempdb.create_db()
|
||||||
crypto = cryptoutil.NSSCryptoProvider(
|
crypto = cryptoutil.NSSCryptoProvider(
|
||||||
paths.IPA_RADB_DIR,
|
tempdb.secdir,
|
||||||
password_file=os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt'))
|
password_file=tempdb.pwd_file)
|
||||||
|
|
||||||
# TODO: obtain KRA host & port from IPA service list or point to KRA load balancer
|
# TODO: obtain KRA host & port from IPA service list or point to KRA load balancer
|
||||||
# https://fedorahosted.org/freeipa/ticket/4557
|
# https://fedorahosted.org/freeipa/ticket/4557
|
||||||
@@ -2021,9 +2032,16 @@ class kra(Backend):
|
|||||||
str(self.kra_port),
|
str(self.kra_port),
|
||||||
'kra')
|
'kra')
|
||||||
|
|
||||||
connection.set_authentication_cert(paths.RA_AGENT_PEM)
|
connection.session.cert = (paths.RA_AGENT_PEM, paths.RA_AGENT_KEY)
|
||||||
|
# uncomment the following when this commit makes it to release
|
||||||
|
# https://git.fedorahosted.org/cgit/pki.git/commit/?id=71ae20c
|
||||||
|
# connection.set_authentication_cert(paths.RA_AGENT_PEM,
|
||||||
|
# paths.RA_AGENT_KEY)
|
||||||
|
|
||||||
return KRAClient(connection, crypto)
|
try:
|
||||||
|
yield KRAClient(connection, crypto)
|
||||||
|
finally:
|
||||||
|
tempdb.close()
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
|
|||||||
@@ -35,20 +35,22 @@ from ipalib import errors
|
|||||||
import os
|
import os
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
|
|
||||||
|
|
||||||
class rabase(Backend):
|
class rabase(Backend):
|
||||||
"""
|
"""
|
||||||
Request Authority backend plugin.
|
Request Authority backend plugin.
|
||||||
"""
|
"""
|
||||||
def __init__(self, api):
|
def __init__(self, api):
|
||||||
|
self.ca_cert = api.env.tls_ca_cert
|
||||||
if api.env.in_tree:
|
if api.env.in_tree:
|
||||||
self.sec_dir = api.env.dot_ipa + os.sep + 'alias'
|
self.client_certfile = os.path.join(
|
||||||
self.pwd_file = self.sec_dir + os.sep + '.pwd'
|
api.env.dot_ipa, 'ra-agent.pem')
|
||||||
|
self.client_keyfile = os.path.join(api.env.dot_ipa, 'ra-agent.key')
|
||||||
else:
|
else:
|
||||||
self.sec_dir = paths.IPA_RADB_DIR
|
self.client_certfile = paths.RA_AGENT_PEM
|
||||||
self.pwd_file = os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt')
|
self.client_keyfile = paths.RA_AGENT_KEY
|
||||||
super(rabase, self).__init__(api)
|
super(rabase, self).__init__(api)
|
||||||
|
|
||||||
|
|
||||||
def check_request_status(self, request_id):
|
def check_request_status(self, request_id):
|
||||||
"""
|
"""
|
||||||
Check status of a certificate signing request.
|
Check status of a certificate signing request.
|
||||||
|
|||||||
@@ -816,23 +816,22 @@ class vault_del(LDAPDelete):
|
|||||||
def post_callback(self, ldap, dn, *args, **options):
|
def post_callback(self, ldap, dn, *args, **options):
|
||||||
assert isinstance(dn, DN)
|
assert isinstance(dn, DN)
|
||||||
|
|
||||||
kra_client = self.api.Backend.kra.get_client()
|
with self.api.Backend.kra.get_client() as kra_client:
|
||||||
|
kra_account = pki.account.AccountClient(kra_client.connection)
|
||||||
|
kra_account.login()
|
||||||
|
|
||||||
kra_account = pki.account.AccountClient(kra_client.connection)
|
client_key_id = self.obj.get_key_id(dn)
|
||||||
kra_account.login()
|
|
||||||
|
|
||||||
client_key_id = self.obj.get_key_id(dn)
|
# deactivate vault record in KRA
|
||||||
|
response = kra_client.keys.list_keys(
|
||||||
|
client_key_id, pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
||||||
|
|
||||||
# deactivate vault record in KRA
|
for key_info in response.key_infos:
|
||||||
response = kra_client.keys.list_keys(
|
kra_client.keys.modify_key_status(
|
||||||
client_key_id, pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
key_info.get_key_id(),
|
||||||
|
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
||||||
|
|
||||||
for key_info in response.key_infos:
|
kra_account.logout()
|
||||||
kra_client.keys.modify_key_status(
|
|
||||||
key_info.get_key_id(),
|
|
||||||
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
|
||||||
|
|
||||||
kra_account.logout()
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -987,12 +986,12 @@ class vaultconfig_show(Retrieve):
|
|||||||
raise errors.InvocationError(
|
raise errors.InvocationError(
|
||||||
format=_('KRA service is not enabled'))
|
format=_('KRA service is not enabled'))
|
||||||
|
|
||||||
kra_client = self.api.Backend.kra.get_client()
|
with self.api.Backend.kra.get_client() as kra_client:
|
||||||
transport_cert = kra_client.system_certs.get_transport_cert()
|
transport_cert = kra_client.system_certs.get_transport_cert()
|
||||||
config = {'transport_cert': transport_cert.binary}
|
config = {'transport_cert': transport_cert.binary}
|
||||||
config.update(
|
config.update(
|
||||||
self.api.Backend.serverroles.config_retrieve("KRA server")
|
self.api.Backend.serverroles.config_retrieve("KRA server")
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'result': config,
|
'result': config,
|
||||||
@@ -1038,34 +1037,33 @@ class vault_archive_internal(PKQuery):
|
|||||||
vault = self.api.Command.vault_show(*args, **options)['result']
|
vault = self.api.Command.vault_show(*args, **options)['result']
|
||||||
|
|
||||||
# connect to KRA
|
# connect to KRA
|
||||||
kra_client = self.api.Backend.kra.get_client()
|
with self.api.Backend.kra.get_client() as kra_client:
|
||||||
|
kra_account = pki.account.AccountClient(kra_client.connection)
|
||||||
|
kra_account.login()
|
||||||
|
|
||||||
kra_account = pki.account.AccountClient(kra_client.connection)
|
client_key_id = self.obj.get_key_id(vault['dn'])
|
||||||
kra_account.login()
|
|
||||||
|
|
||||||
client_key_id = self.obj.get_key_id(vault['dn'])
|
# deactivate existing vault record in KRA
|
||||||
|
response = kra_client.keys.list_keys(
|
||||||
|
client_key_id,
|
||||||
|
pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
||||||
|
|
||||||
# deactivate existing vault record in KRA
|
for key_info in response.key_infos:
|
||||||
response = kra_client.keys.list_keys(
|
kra_client.keys.modify_key_status(
|
||||||
client_key_id,
|
key_info.get_key_id(),
|
||||||
pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
||||||
|
|
||||||
for key_info in response.key_infos:
|
# forward wrapped data to KRA
|
||||||
kra_client.keys.modify_key_status(
|
kra_client.keys.archive_encrypted_data(
|
||||||
key_info.get_key_id(),
|
client_key_id,
|
||||||
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
pki.key.KeyClient.PASS_PHRASE_TYPE,
|
||||||
|
wrapped_vault_data,
|
||||||
|
wrapped_session_key,
|
||||||
|
None,
|
||||||
|
nonce,
|
||||||
|
)
|
||||||
|
|
||||||
# forward wrapped data to KRA
|
kra_account.logout()
|
||||||
kra_client.keys.archive_encrypted_data(
|
|
||||||
client_key_id,
|
|
||||||
pki.key.KeyClient.PASS_PHRASE_TYPE,
|
|
||||||
wrapped_vault_data,
|
|
||||||
wrapped_session_key,
|
|
||||||
None,
|
|
||||||
nonce,
|
|
||||||
)
|
|
||||||
|
|
||||||
kra_account.logout()
|
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
'value': args[-1],
|
'value': args[-1],
|
||||||
@@ -1105,29 +1103,28 @@ class vault_retrieve_internal(PKQuery):
|
|||||||
vault = self.api.Command.vault_show(*args, **options)['result']
|
vault = self.api.Command.vault_show(*args, **options)['result']
|
||||||
|
|
||||||
# connect to KRA
|
# connect to KRA
|
||||||
kra_client = self.api.Backend.kra.get_client()
|
with self.api.Backend.kra.get_client() as kra_client:
|
||||||
|
kra_account = pki.account.AccountClient(kra_client.connection)
|
||||||
|
kra_account.login()
|
||||||
|
|
||||||
kra_account = pki.account.AccountClient(kra_client.connection)
|
client_key_id = self.obj.get_key_id(vault['dn'])
|
||||||
kra_account.login()
|
|
||||||
|
|
||||||
client_key_id = self.obj.get_key_id(vault['dn'])
|
# find vault record in KRA
|
||||||
|
response = kra_client.keys.list_keys(
|
||||||
|
client_key_id,
|
||||||
|
pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
||||||
|
|
||||||
# find vault record in KRA
|
if not len(response.key_infos):
|
||||||
response = kra_client.keys.list_keys(
|
raise errors.NotFound(reason=_('No archived data.'))
|
||||||
client_key_id,
|
|
||||||
pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
|
||||||
|
|
||||||
if not len(response.key_infos):
|
key_info = response.key_infos[0]
|
||||||
raise errors.NotFound(reason=_('No archived data.'))
|
|
||||||
|
|
||||||
key_info = response.key_infos[0]
|
# retrieve encrypted data from KRA
|
||||||
|
key = kra_client.keys.retrieve_key(
|
||||||
|
key_info.get_key_id(),
|
||||||
|
wrapped_session_key)
|
||||||
|
|
||||||
# retrieve encrypted data from KRA
|
kra_account.logout()
|
||||||
key = kra_client.keys.retrieve_key(
|
|
||||||
key_info.get_key_id(),
|
|
||||||
wrapped_session_key)
|
|
||||||
|
|
||||||
kra_account.logout()
|
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
'value': args[-1],
|
'value': args[-1],
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ def PKI_TOMCAT_password_callback():
|
|||||||
return password
|
return password
|
||||||
|
|
||||||
|
|
||||||
def HTTPD_password_callback():
|
|
||||||
with open(os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt')) as f:
|
|
||||||
password = f.read()
|
|
||||||
return password
|
|
||||||
|
|
||||||
|
|
||||||
class NSSWrappedCertDB(DBMAPHandler):
|
class NSSWrappedCertDB(DBMAPHandler):
|
||||||
'''
|
'''
|
||||||
Store that extracts private keys from an NSSDB, wrapped with the
|
Store that extracts private keys from an NSSDB, wrapped with the
|
||||||
@@ -193,11 +187,11 @@ class DMLDAP(DBMAPHandler):
|
|||||||
|
|
||||||
class PEMFileHandler(DBMAPHandler):
|
class PEMFileHandler(DBMAPHandler):
|
||||||
def __init__(self, config, dbmap, nickname=None):
|
def __init__(self, config, dbmap, nickname=None):
|
||||||
if 'type' not in dbmap or dbmap['type'] != 'OPENSSL':
|
if 'type' not in dbmap or dbmap['type'] != 'PEM':
|
||||||
raise ValueError('Invalid type "{t}", expected OPENSSL'
|
raise ValueError('Invalid type "{t}", expected PEM'
|
||||||
.format(t=dbmap['type']))
|
.format(t=dbmap['type']))
|
||||||
self.certfile = dbmap['certfile']
|
self.certfile = dbmap['certfile']
|
||||||
self.keyfile = dbmap.get(['keyfile'])
|
self.keyfile = dbmap.get('keyfile')
|
||||||
|
|
||||||
def export_key(self):
|
def export_key(self):
|
||||||
_fd, tmpfile = tempfile.mkstemp(dir=paths.TMP)
|
_fd, tmpfile = tempfile.mkstemp(dir=paths.TMP)
|
||||||
@@ -266,10 +260,10 @@ NAME_DB_MAP = {
|
|||||||
'wrap_nick': 'caSigningCert cert-pki-ca',
|
'wrap_nick': 'caSigningCert cert-pki-ca',
|
||||||
},
|
},
|
||||||
'ra': {
|
'ra': {
|
||||||
'type': 'NSSDB',
|
'type': 'PEM',
|
||||||
'path': paths.IPA_RADB_DIR,
|
'handler': PEMFileHandler,
|
||||||
'handler': NSSCertDB,
|
'certfile': paths.RA_AGENT_PEM,
|
||||||
'pwcallback': HTTPD_password_callback,
|
'keyfile': paths.RA_AGENT_KEY,
|
||||||
},
|
},
|
||||||
'dm': {
|
'dm': {
|
||||||
'type': 'DMLDAP',
|
'type': 'DMLDAP',
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ def makecert(reqdir, subject, principal):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
ra = rabase.rabase(api)
|
ra = rabase.rabase(api)
|
||||||
if (not os.path.exists(ra.sec_dir) and
|
if (not os.path.exists(ra.client_certfile) and
|
||||||
api.env.xmlrpc_uri == 'http://localhost:8888/ipa/xml'):
|
api.env.xmlrpc_uri == 'http://localhost:8888/ipa/xml'):
|
||||||
raise AssertionError('The self-signed CA is not configured, '
|
raise AssertionError('The self-signed CA is not configured, '
|
||||||
'see ipatests/test_xmlrpc/test_cert.py')
|
'see ipatests/test_xmlrpc/test_cert.py')
|
||||||
|
|||||||
Reference in New Issue
Block a user