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,
|
||||
"Forwarding request to dogtag-ipa-renew-agent")
|
||||
|
||||
path = paths.DOGTAG_IPA_RENEW_AGENT_SUBMIT
|
||||
args = [path, '--dbdir', paths.IPA_RADB_DIR]
|
||||
args.extend(sys.argv[1:])
|
||||
args.extend(['--submit-option', "requestor_name=IPA"])
|
||||
args = ([paths.DOGTAG_IPA_RENEW_AGENT_SUBMIT,
|
||||
"--cafile", paths.IPA_CA_CRT,
|
||||
"--certfile", paths.RA_AGENT_PEM,
|
||||
"--keyfile", paths.RA_AGENT_KEY] +
|
||||
sys.argv[1:] +
|
||||
['--submit-option', "requestor_name=IPA"])
|
||||
if os.environ.get('CERTMONGER_CA_PROFILE') == 'caCACert':
|
||||
args += ['-N', '-O', 'bypassCAnotafter=true']
|
||||
result = ipautil.run(args, raiseonerr=False, env=os.environ,
|
||||
|
||||
@@ -27,15 +27,15 @@ import tempfile
|
||||
import shutil
|
||||
import traceback
|
||||
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
from ipalib.install.kinit import kinit_keytab
|
||||
from ipalib import api
|
||||
from ipaserver.install import certs, cainstance, dogtaginstance
|
||||
from ipalib import api, x509
|
||||
from ipaserver.install import certs, cainstance
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
|
||||
def _main():
|
||||
nickname = 'ipaCert'
|
||||
|
||||
api.bootstrap(in_server=True, context='restart', confdir=paths.ETC_IPA)
|
||||
api.finalize()
|
||||
api.Backend.ldap2.connect()
|
||||
@@ -48,20 +48,28 @@ def _main():
|
||||
os.environ['KRB5CCNAME'] = ccache_filename
|
||||
|
||||
ca = cainstance.CAInstance(host_name=api.env.host)
|
||||
ra_certpath = paths.RA_AGENT_PEM
|
||||
if ca.is_renewal_master():
|
||||
# Fetch the new certificate
|
||||
db = certs.CertDB(api.env.realm)
|
||||
dercert = db.get_cert_from_db(nickname, pem=False)
|
||||
if not dercert:
|
||||
try:
|
||||
cert = x509.load_certificate_from_file(ra_certpath)
|
||||
except IOError as e:
|
||||
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)
|
||||
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
|
||||
cainstance.update_people_entry(dercert)
|
||||
|
||||
if api.Command.kra_is_enabled()['result']:
|
||||
dogtaginstance.export_ra_agent_pem()
|
||||
finally:
|
||||
shutil.rmtree(tmpdir)
|
||||
api.Backend.ldap2.disconnect()
|
||||
|
||||
@@ -139,7 +139,6 @@ class CertUpdate(admintool.AdminTool):
|
||||
services.knownservices.dirsrv.restart(instance)
|
||||
|
||||
self.update_db(paths.HTTPD_ALIAS_DIR, certs)
|
||||
self.update_db(paths.IPA_RADB_DIR, certs)
|
||||
if services.knownservices.httpd.is_running():
|
||||
services.knownservices.httpd.restart()
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ class BasePathNamespace(object):
|
||||
ETC_HTTPD_DIR = "/etc/httpd"
|
||||
HTTPD_ALIAS_DIR = "/etc/httpd/alias"
|
||||
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_IPA_KDCPROXY_CONF = "/etc/ipa/kdcproxy/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"
|
||||
DOGTAG_ADMIN_P12 = "/root/ca-agent.p12"
|
||||
RA_AGENT_PEM = "/var/lib/ipa/ra-agent.pem"
|
||||
RA_AGENT_KEY = "/var/lib/ipa/ra-agent.key"
|
||||
CACERT_P12 = "/root/cacert.p12"
|
||||
ROOT_IPA_CSR = "/root/ipa.csr"
|
||||
NAMED_PID = "/run/named/named.pid"
|
||||
@@ -195,6 +195,7 @@ class BasePathNamespace(object):
|
||||
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_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"
|
||||
GENERATE_RNDC_KEY = "/usr/libexec/generate-rndc-key.sh"
|
||||
IPA_DNSKEYSYNCD_REPLICA = "/usr/libexec/ipa/ipa-dnskeysync-replica"
|
||||
|
||||
@@ -131,8 +131,9 @@ def ca_status(ca_host=None):
|
||||
return _parse_ca_status(body)
|
||||
|
||||
|
||||
def https_request(host, port, url, cafile, client_certfile,
|
||||
method='POST', headers=None, body=None, **kw):
|
||||
def https_request(
|
||||
host, port, url, cafile, client_certfile, client_keyfile,
|
||||
method='POST', headers=None, body=None, **kw):
|
||||
"""
|
||||
:param method: HTTP request method (defalut: 'POST')
|
||||
: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,
|
||||
cafile=cafile,
|
||||
client_certfile=client_certfile,
|
||||
client_keyfile=client_keyfile,
|
||||
tls_version_min=api.env.tls_version_min,
|
||||
tls_version_max=api.env.tls_version_max)
|
||||
|
||||
|
||||
@@ -177,14 +177,14 @@ def install_check(standalone, replica_config, options):
|
||||
if standalone:
|
||||
dirname = dsinstance.config_dirname(
|
||||
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(
|
||||
realm_name, nssdir=dirname, subject_base=options._subject_base)
|
||||
|
||||
for db in (cadb, dsdb):
|
||||
for nickname, _trust_flags in db.list_certs():
|
||||
if nickname in (certdb.get_ca_nickname(realm_name),
|
||||
'ipaCert'):
|
||||
if nickname == certdb.get_ca_nickname(realm_name):
|
||||
raise ScriptError(
|
||||
"Certificate with nickname %s is present in %s, "
|
||||
"cannot continue." % (nickname, db.secdir))
|
||||
@@ -193,8 +193,7 @@ def install_check(standalone, replica_config, options):
|
||||
if not cert:
|
||||
continue
|
||||
subject = DN(x509.load_certificate(cert).subject)
|
||||
if subject in (DN(options._ca_subject),
|
||||
DN('CN=IPA RA', options._subject_base)):
|
||||
if subject == DN(options._ca_subject):
|
||||
raise ScriptError(
|
||||
"Certificate with subject %s is present in %s, "
|
||||
"cannot continue." % (subject, db.secdir))
|
||||
@@ -312,31 +311,26 @@ def install_step_1(standalone, replica_config, options):
|
||||
dirname = dsinstance.config_dirname(serverid)
|
||||
|
||||
# Store the new IPA CA cert chain in DS NSS database and LDAP
|
||||
cadb = certs.CertDB(realm_name, subject_base=subject_base)
|
||||
dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base)
|
||||
trust_flags = dict(reversed(cadb.list_certs()))
|
||||
trust_chain = cadb.find_root_cert('ipaCert')[:-1]
|
||||
for nickname in 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,
|
||||
cert, nickname, trust_flags[nickname])
|
||||
|
||||
nickname = trust_chain[-1]
|
||||
cert = cadb.get_cert_from_db(nickname, pem=False)
|
||||
dsdb.add_cert(cert, nickname, trust_flags[nickname])
|
||||
cadb = certs.CertDB(
|
||||
realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
subject_base=subject_base)
|
||||
dsdb = certs.CertDB(
|
||||
realm_name, nssdir=dirname, subject_base=subject_base)
|
||||
cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca', pem=False)
|
||||
nickname = certdb.get_ca_nickname(realm_name)
|
||||
trust_flags = 'CT,C,C'
|
||||
dsdb.add_cert(cacert, nickname, trust_flags)
|
||||
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)
|
||||
|
||||
# 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()))
|
||||
server_certs = dsdb.find_server_certs()
|
||||
trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
|
||||
nickname = trust_chain[-1]
|
||||
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()
|
||||
|
||||
@@ -356,6 +350,8 @@ def install_step_1(standalone, replica_config, options):
|
||||
def uninstall():
|
||||
ca_instance = cainstance.CAInstance(api.env.realm)
|
||||
ca_instance.stop_tracking_certificates()
|
||||
installutils.remove_file(paths.RA_AGENT_PEM)
|
||||
installutils.remove_file(paths.RA_AGENT_KEY)
|
||||
if ca_instance.is_configured():
|
||||
ca_instance.uninstall()
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import dbus
|
||||
import ldap
|
||||
import os
|
||||
import pwd
|
||||
import grp
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
@@ -37,6 +38,7 @@ import six
|
||||
# pylint: disable=import-error
|
||||
from six.moves.configparser import ConfigParser, RawConfigParser
|
||||
# pylint: enable=import-error
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
from ipalib import api
|
||||
from ipalib import x509
|
||||
@@ -64,8 +66,7 @@ from ipaserver.install import installutils
|
||||
from ipaserver.install import ldapupdate
|
||||
from ipaserver.install import replication
|
||||
from ipaserver.install import sysupgrade
|
||||
from ipaserver.install.dogtaginstance import (
|
||||
DogtagInstance, export_ra_agent_pem)
|
||||
from ipaserver.install.dogtaginstance import DogtagInstance
|
||||
from ipaserver.plugins import ldap2
|
||||
|
||||
# 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)
|
||||
else:
|
||||
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.requestId = None
|
||||
self.log = log_mgr.get_logger(self)
|
||||
@@ -378,8 +377,7 @@ class CAInstance(DogtagInstance):
|
||||
self.external = 2
|
||||
|
||||
if self.clone:
|
||||
cert_db = certs.CertDB(self.realm)
|
||||
has_ra_cert = (cert_db.get_cert_from_db('ipaCert') != '')
|
||||
has_ra_cert = os.path.exists(paths.RA_AGENT_PEM)
|
||||
else:
|
||||
has_ra_cert = False
|
||||
|
||||
@@ -415,16 +413,14 @@ class CAInstance(DogtagInstance):
|
||||
else:
|
||||
self.step("importing RA certificate from PKCS #12 file",
|
||||
lambda: self.import_ra_cert(ra_p12))
|
||||
self.step("exporting RA agent cert", export_ra_agent_pem)
|
||||
|
||||
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 audit signing renewal to 2 years", self.set_audit_renewal)
|
||||
self.step("restarting certificate server", self.restart_instance)
|
||||
if not self.clone:
|
||||
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("authorizing RA to modify profiles", configure_profiles_acl)
|
||||
self.step("authorizing RA to manage lightweight CAs",
|
||||
@@ -683,13 +679,22 @@ class CAInstance(DogtagInstance):
|
||||
|
||||
Used when setting up replication
|
||||
"""
|
||||
# Add the new RA cert into the RA database
|
||||
with tempfile.NamedTemporaryFile(mode="w") as agent_file:
|
||||
agent_file.write(self.dm_password)
|
||||
agent_file.flush()
|
||||
# get the private key from the file
|
||||
ipautil.run([paths.OPENSSL,
|
||||
"pkcs12",
|
||||
"-in", rafile,
|
||||
"-nocerts", "-nodes",
|
||||
"-out", paths.RA_AGENT_KEY,
|
||||
"-passin", "pass:"])
|
||||
|
||||
import_pkcs12(
|
||||
rafile, agent_file.name, self.ra_agent_db, self.ra_agent_pwd)
|
||||
# get the certificate from the pkcs12 file
|
||||
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()
|
||||
|
||||
@@ -697,18 +702,28 @@ class CAInstance(DogtagInstance):
|
||||
custodia = custodiainstance.CustodiaInstance(host_name=self.fqdn,
|
||||
realm=self.realm)
|
||||
custodia.import_ra_key(self.master_host)
|
||||
self.__set_ra_cert_perms()
|
||||
|
||||
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):
|
||||
"""
|
||||
Create CA agent, assign a certificate, and add the user to
|
||||
the appropriate groups for accessing CA services.
|
||||
"""
|
||||
|
||||
# get ipaCert certificate
|
||||
cert_data = base64.b64decode(self.ra_cert)
|
||||
cert = x509.load_certificate(cert_data, x509.DER)
|
||||
# get RA certificate
|
||||
cert_data = self.ra_cert.public_bytes(serialization.Encoding.DER)
|
||||
|
||||
# connect to CA database
|
||||
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.connect(autobind=True)
|
||||
|
||||
# create ipara user with ipaCert certificate
|
||||
# create ipara user with RA certificate
|
||||
user_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
|
||||
entry = conn.make_entry(
|
||||
user_dn,
|
||||
@@ -729,7 +744,7 @@ class CAInstance(DogtagInstance):
|
||||
userstate=["1"],
|
||||
userCertificate=[cert_data],
|
||||
description=['2;%s;%s;%s' % (
|
||||
cert.serial_number,
|
||||
self.ra_cert.serial_number,
|
||||
DN(self.ca_subject),
|
||||
DN(('CN', 'IPA RA'), self.subject_base))])
|
||||
conn.add_entry(entry)
|
||||
@@ -746,57 +761,30 @@ class CAInstance(DogtagInstance):
|
||||
|
||||
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):
|
||||
try:
|
||||
return dogtag.get_ca_certchain(ca_host=self.fqdn)
|
||||
except Exception as e:
|
||||
raise RuntimeError("Unable to retrieve CA chain: %s" % str(e))
|
||||
|
||||
def __import_ca_chain(self):
|
||||
# Backup NSS trust flags of all already existing certificates
|
||||
certdb = certs.CertDB(self.realm)
|
||||
cert_backup_list = certdb.list_certs()
|
||||
|
||||
def __export_ca_chain(self):
|
||||
"""
|
||||
Get the CA chain from Dogtag NSS DB and write it to paths.IPA_CA_CRT
|
||||
"""
|
||||
# Getting Dogtag 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
|
||||
# makes openssl throw up.
|
||||
data = base64.b64decode(chain)
|
||||
|
||||
# Get list of PEM certificates
|
||||
certlist = x509.pkcs7_to_pems(data, x509.DER)
|
||||
|
||||
# Ok, now we have all the certificates in certs, walk through it
|
||||
# and pull out each certificate and add it to our database
|
||||
|
||||
ca_dn = DN(self.ca_subject)
|
||||
# We have all the certificates in certlist, write them to a PEM file
|
||||
for cert in certlist:
|
||||
with tempfile.NamedTemporaryFile(mode="w") as chain_file:
|
||||
chain_file.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)
|
||||
with open(paths.IPA_CA_CRT, 'w') as ipaca_pem:
|
||||
ipaca_pem.write(cert)
|
||||
|
||||
def __request_ra_certificate(self):
|
||||
# create a temp file storing the pwd
|
||||
@@ -812,7 +800,7 @@ class CAInstance(DogtagInstance):
|
||||
|
||||
chain = self.__get_ca_chain()
|
||||
data = base64.b64decode(chain)
|
||||
result = ipautil.run(
|
||||
ipautil.run(
|
||||
[paths.OPENSSL,
|
||||
"pkcs7",
|
||||
"-inform",
|
||||
@@ -839,24 +827,19 @@ class CAInstance(DogtagInstance):
|
||||
# The certificate must be requested using caServerCert profile
|
||||
# because this profile does not require agent authentication
|
||||
reqId = certmonger.request_and_wait_for_cert(
|
||||
certpath=self.ra_agent_db,
|
||||
nickname='ipaCert',
|
||||
certpath=(paths.RA_AGENT_PEM, paths.RA_AGENT_KEY),
|
||||
principal='host/%s' % self.fqdn,
|
||||
passwd_fname=self.ra_agent_pwd,
|
||||
subject=str(DN(('CN', 'IPA RA'), self.subject_base)),
|
||||
ca=ipalib.constants.RENEWAL_CA_NAME,
|
||||
profile='caServerCert',
|
||||
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)
|
||||
certdb = certs.CertDB(self.realm)
|
||||
result = certdb.run_certutil(
|
||||
['-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())
|
||||
self.ra_cert = x509.load_certificate_from_file(
|
||||
paths.RA_AGENT_PEM)
|
||||
finally:
|
||||
# we can restore the helper parameters
|
||||
certmonger.modify_ca_helper(
|
||||
@@ -1013,12 +996,11 @@ class CAInstance(DogtagInstance):
|
||||
def configure_agent_renewal(self):
|
||||
try:
|
||||
certmonger.start_tracking(
|
||||
certpath=self.ra_agent_db,
|
||||
certpath=(paths.RA_AGENT_PEM, paths.RA_AGENT_KEY),
|
||||
ca='dogtag-ipa-ca-renew-agent',
|
||||
nickname='ipaCert',
|
||||
pinfile=self.ra_agent_pwd,
|
||||
pre_command='renew_ra_cert_pre',
|
||||
post_command='renew_ra_cert')
|
||||
post_command='renew_ra_cert',
|
||||
storage='FILE')
|
||||
except RuntimeError as e:
|
||||
self.log.error(
|
||||
"certmonger failed to start tracking certificate: %s", e)
|
||||
@@ -1035,7 +1017,7 @@ class CAInstance(DogtagInstance):
|
||||
certmonger.stop_tracking(self.nss_db, nickname=nickname)
|
||||
|
||||
try:
|
||||
certmonger.stop_tracking(self.ra_agent_db, nickname='ipaCert')
|
||||
certmonger.stop_tracking(certfile=paths.RA_AGENT_PEM)
|
||||
except RuntimeError as e:
|
||||
root_logger.error(
|
||||
"certmonger failed to stop tracking certificate: %s", e)
|
||||
|
||||
@@ -97,7 +97,7 @@ class CertDB(object):
|
||||
|
||||
"""
|
||||
# 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,
|
||||
user=None, group=None, mode=None, truncate=False):
|
||||
self.nssdb = NSSDatabase(nssdir)
|
||||
@@ -417,6 +417,7 @@ class CertDB(object):
|
||||
url="/ca/ee/ca/profileSubmitSSLClient",
|
||||
cafile=api.env.tls_ca_cert,
|
||||
client_certfile=paths.RA_AGENT_PEM,
|
||||
client_keyfile=paths.RA_AGENT_KEY,
|
||||
**params)
|
||||
http_status, _http_headers, http_body = result
|
||||
root_logger.debug("CA answer: %s", http_body)
|
||||
@@ -471,6 +472,7 @@ class CertDB(object):
|
||||
url="/ca/ee/ca/profileSubmitSSLClient",
|
||||
cafile=api.env.tls_ca_cert,
|
||||
client_certfile=paths.RA_AGENT_PEM,
|
||||
client_keyfile=paths.RA_AGENT_KEY,
|
||||
**params)
|
||||
http_status, _http_headers, http_body = result
|
||||
if http_status != 200:
|
||||
|
||||
@@ -112,6 +112,10 @@ class CustodiaInstance(SimpleServiceInstance):
|
||||
|
||||
def import_ra_key(self, 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')
|
||||
|
||||
def import_dm_password(self, master_host_name):
|
||||
|
||||
@@ -21,17 +21,13 @@ import base64
|
||||
import ldap
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import traceback
|
||||
import dbus
|
||||
import pwd
|
||||
|
||||
from pki.client import PKIConnection
|
||||
import pki.system
|
||||
|
||||
from ipalib import api, errors
|
||||
|
||||
from ipalib.constants import IPAAPI_USER
|
||||
from ipalib.install import certmonger
|
||||
from ipaplatform import services
|
||||
from ipaplatform.constants import constants
|
||||
@@ -72,27 +68,6 @@ def is_installing_replica(sys_type):
|
||||
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):
|
||||
"""
|
||||
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)
|
||||
else:
|
||||
dsdb.create_from_cacert()
|
||||
ca_args = ['/usr/libexec/certmonger/dogtag-submit',
|
||||
'--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
|
||||
'--dbdir', paths.IPA_RADB_DIR,
|
||||
'--nickname', 'ipaCert',
|
||||
'--sslpinfile', os.path.join(paths.IPA_RADB_DIR,
|
||||
'pwdfile.txt'),
|
||||
'--agent-submit']
|
||||
ca_args = [
|
||||
paths.CERTMONGER_DOGTAG_SUBMIT,
|
||||
'--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
|
||||
'--certfile', paths.RA_AGENT_PEM,
|
||||
'--keyfile', paths.RA_AGENT_KEY,
|
||||
'--cafile', paths.IPA_CA_CRT,
|
||||
'--agent-submit'
|
||||
]
|
||||
helper = " ".join(ca_args)
|
||||
prev_helper = certmonger.modify_ca_helper('IPA', helper)
|
||||
try:
|
||||
|
||||
@@ -384,14 +384,13 @@ class HTTPInstance(service.Service):
|
||||
if not self.promote:
|
||||
self.create_password_conf()
|
||||
ca_args = [
|
||||
'/usr/libexec/certmonger/dogtag-submit',
|
||||
paths.CERTMONGER_DOGTAG_SUBMIT,
|
||||
'--ee-url', 'https://%s:8443/ca/ee/ca' % self.fqdn,
|
||||
'--dbdir', paths.IPA_RADB_DIR,
|
||||
'--nickname', 'ipaCert',
|
||||
'--sslpinfile', os.path.join(paths.IPA_RADB_DIR,
|
||||
'pwdfile.txt'),
|
||||
'--certfile', paths.RA_AGENT_PEM,
|
||||
'--keyfile', paths.RA_AGENT_KEY,
|
||||
'--cafile', paths.IPA_CA_CRT,
|
||||
'--agent-submit'
|
||||
]
|
||||
]
|
||||
helper = " ".join(ca_args)
|
||||
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.")
|
||||
|
||||
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,
|
||||
subject_base=self.subject_base)
|
||||
self.import_ca_certs(db, self.ca_is_configured)
|
||||
|
||||
@@ -107,7 +107,6 @@ class Backup(admintool.AdminTool):
|
||||
paths.PKI_TOMCAT,
|
||||
paths.SYSCONFIG_PKI,
|
||||
paths.HTTPD_ALIAS_DIR,
|
||||
paths.IPA_RADB_DIR,
|
||||
paths.VAR_LIB_PKI_DIR,
|
||||
paths.SYSRESTORE,
|
||||
paths.IPA_CLIENT_SYSRESTORE,
|
||||
@@ -159,6 +158,7 @@ class Backup(admintool.AdminTool):
|
||||
paths.SAMBA_KEYTAB,
|
||||
paths.DOGTAG_ADMIN_P12,
|
||||
paths.RA_AGENT_PEM,
|
||||
paths.RA_AGENT_KEY,
|
||||
paths.CACERT_P12,
|
||||
paths.KRACERT_P12,
|
||||
paths.KRB5KDC_KDC_CONF,
|
||||
|
||||
@@ -631,18 +631,16 @@ class ReplicaPrepare(admintool.AdminTool):
|
||||
raise admintool.ScriptError(str(e))
|
||||
|
||||
def export_ra_pkcs12(self):
|
||||
agent_fd, agent_name = tempfile.mkstemp()
|
||||
os.write(agent_fd, self.dirman_password)
|
||||
os.close(agent_fd)
|
||||
|
||||
try:
|
||||
db = certs.CertDB(api.env.realm, host_name=api.env.host)
|
||||
|
||||
if db.has_nickname("ipaCert"):
|
||||
pkcs12_fname = os.path.join(self.dir, "ra.p12")
|
||||
db.export_pkcs12(pkcs12_fname, agent_name, "ipaCert")
|
||||
finally:
|
||||
os.remove(agent_name)
|
||||
if (os.path.exists(paths.RA_AGENT_PEM) and
|
||||
os.path.exists(paths.RA_AGENT_KEY)):
|
||||
ipautil.run([
|
||||
paths.OPENSSL,
|
||||
"pkcs12", "-export",
|
||||
"-inkey", paths.RA_AGENT_KEY,
|
||||
"-in", paths.RA_AGENT_PEM,
|
||||
"-out", os.path.join(self.dir, "ra.p12"),
|
||||
"-passout", "pass:"
|
||||
])
|
||||
|
||||
def update_pki_admin_password(self):
|
||||
dn = DN('uid=admin', 'ou=people', 'o=ipaca')
|
||||
|
||||
@@ -26,11 +26,11 @@ import six
|
||||
# pylint: disable=import-error
|
||||
from six.moves.configparser import ConfigParser
|
||||
# pylint: enable=import-error
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
from ipalib import api
|
||||
from ipalib import x509
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython import certdb
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
from ipaserver.install import cainstance
|
||||
@@ -290,10 +290,9 @@ class KRAInstance(DogtagInstance):
|
||||
the appropriate groups for accessing KRA services.
|
||||
"""
|
||||
|
||||
# get ipaCert certificate
|
||||
with certdb.NSSDatabase(paths.IPA_RADB_DIR) as ipa_nssdb:
|
||||
cert_data = ipa_nssdb.get_cert("ipaCert")
|
||||
cert = x509.load_certificate(cert_data, x509.DER)
|
||||
# get RA agent certificate
|
||||
cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
|
||||
cert_data = cert.public_bytes(serialization.Encoding.DER)
|
||||
|
||||
# connect to KRA database
|
||||
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.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)
|
||||
entry = conn.make_entry(
|
||||
user_dn,
|
||||
|
||||
@@ -74,17 +74,16 @@ class update_ca_renewal_master(Updater):
|
||||
return False, []
|
||||
|
||||
criteria = {
|
||||
'cert-database': paths.HTTPD_ALIAS_DIR,
|
||||
'cert-nickname': 'ipaCert',
|
||||
'cert-file': paths.RA_AGENT_PEM,
|
||||
}
|
||||
request_id = certmonger.get_request_id(criteria)
|
||||
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')
|
||||
if ca_name is None:
|
||||
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")
|
||||
return False, []
|
||||
ca_name = ca_name.strip()
|
||||
@@ -97,11 +96,11 @@ class update_ca_renewal_master(Updater):
|
||||
return False, []
|
||||
else:
|
||||
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)
|
||||
return False, []
|
||||
else:
|
||||
self.debug("certmonger request for ipaCert not found")
|
||||
self.debug("certmonger request for RA cert not found")
|
||||
|
||||
config = installutils.get_directive(
|
||||
paths.CA_CS_CFG_PATH, 'subsystem.select', '=')
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import binascii
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from ipalib import Registry
|
||||
from ipalib import Updater
|
||||
from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
|
||||
from ipalib.install import certmonger
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython import certdb
|
||||
from ipapython.certdb import NSSDatabase
|
||||
from ipaserver.install import cainstance
|
||||
|
||||
register = Registry()
|
||||
|
||||
@@ -18,58 +18,44 @@ register = Registry()
|
||||
@register()
|
||||
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):
|
||||
ra_nick = 'ipaCert'
|
||||
ca_enabled = self.api.Command.ca_is_enabled()['result']
|
||||
if not ca_enabled:
|
||||
return False, []
|
||||
|
||||
olddb = certdb.NSSDatabase(nssdir=paths.HTTPD_ALIAS_DIR)
|
||||
if not olddb.has_nickname('ipaCert'):
|
||||
certdb = NSSDatabase(nssdir=paths.HTTPD_ALIAS_DIR)
|
||||
if not certdb.has_nickname(ra_nick):
|
||||
# Nothign to do
|
||||
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)
|
||||
if os.path.exists(paths.IPA_RADB_DIR):
|
||||
if newdb.has_nickname('ipaCert'):
|
||||
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)
|
||||
_fd, p12file = tempfile.mkstemp(dir=certdb.secdir)
|
||||
# no password is necessary as we will be saving it in clear anyway
|
||||
certdb.export_pkcs12(ra_nick, p12file, pkcs12_passwd='')
|
||||
|
||||
# Import cert chain (ignore errors, as certs may already be imported)
|
||||
certlist = olddb.list_certs()
|
||||
certflags = {}
|
||||
for name, flags in certlist:
|
||||
certflags[name] = flags
|
||||
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)))
|
||||
# stop tracking the old cert and remove it
|
||||
certmonger.stop_tracking(paths.HTTPD_ALIAS_DIR, nickname=ra_nick)
|
||||
certdb.delete_cert(ra_nick)
|
||||
if os.path.exists(paths.OLD_KRA_AGENT_PEM):
|
||||
os.remove(paths.OLD_KRA_AGENT_PEM)
|
||||
|
||||
# As the last step export/import/delete the RA Cert
|
||||
pw = binascii.hexlify(os.urandom(10))
|
||||
p12file = os.path.join(paths.IPA_RADB_DIR, 'ipaCert.p12')
|
||||
olddb.export_pkcs12('ipaCert', p12file, pw)
|
||||
newdb.import_pkcs12(p12file, pw)
|
||||
# get the private key and certificate from the file and start
|
||||
# tracking it in certmonger
|
||||
ca = cainstance.CAInstance()
|
||||
ca.import_ra_cert(p12file)
|
||||
|
||||
certmonger.stop_tracking(secdir=olddb.secdir,
|
||||
nickname='ipaCert')
|
||||
certmonger.start_tracking(certpath=newdb.secdir,
|
||||
nickname='ipaCert',
|
||||
pinfile=newdb.pwd_file)
|
||||
|
||||
olddb.delete_cert('ipaCert')
|
||||
os.remove(p12file)
|
||||
|
||||
return False, []
|
||||
|
||||
@@ -14,7 +14,6 @@ import textwrap
|
||||
|
||||
import six
|
||||
|
||||
from ipalib.constants import IPAAPI_USER, IPAAPI_GROUP
|
||||
from ipalib.install import certmonger, sysrestore
|
||||
from ipapython import ipautil
|
||||
from ipapython.ipa_log_manager import root_logger
|
||||
@@ -24,7 +23,8 @@ from ipapython.admintool import ScriptError
|
||||
from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
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 (
|
||||
validate_domain_name,
|
||||
network_ip_address_warning,
|
||||
@@ -32,7 +32,7 @@ from ipalib.util import (
|
||||
)
|
||||
import ipaclient.install.ntpconf
|
||||
from ipaserver.install import (
|
||||
bindinstance, ca, certs, dns, dsinstance,
|
||||
bindinstance, ca, dns, dsinstance,
|
||||
httpinstance, installutils, kra, krbinstance,
|
||||
ntpinstance, otpdinstance, custodiainstance, replication, service,
|
||||
sysupgrade)
|
||||
@@ -774,11 +774,6 @@ def install(installer):
|
||||
if n in options.__dict__}
|
||||
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)
|
||||
else:
|
||||
# Put the CA cert where other instances expect it
|
||||
@@ -987,7 +982,7 @@ def uninstall_check(installer):
|
||||
else:
|
||||
dns.uninstall_check(options)
|
||||
|
||||
if domain_level == constants.DOMAIN_LEVEL_0:
|
||||
if domain_level == DOMAIN_LEVEL_0:
|
||||
rm = replication.ReplicationManager(
|
||||
realm=api.env.realm,
|
||||
hostname=api.env.host,
|
||||
@@ -1102,8 +1097,7 @@ def uninstall(installer):
|
||||
# Note that this name will be wrong after the first uninstall.
|
||||
dirname = dsinstance.config_dirname(
|
||||
installutils.realm_to_serverid(api.env.realm))
|
||||
dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR,
|
||||
paths.IPA_RADB_DIR]
|
||||
dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR]
|
||||
ids = certmonger.check_state(dirs)
|
||||
if ids:
|
||||
root_logger.error('Some certificates may still be tracked by '
|
||||
@@ -1116,11 +1110,6 @@ def uninstall(installer):
|
||||
' # getcert stop-tracking -i <request_id>\n'
|
||||
'for each id in: %s' % ', '.join(ids))
|
||||
|
||||
try:
|
||||
shutil.rmtree(paths.IPA_RADB_DIR)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Remove the cert renewal lock file
|
||||
try:
|
||||
os.remove(paths.IPA_RENEWAL_LOCK)
|
||||
|
||||
@@ -900,77 +900,72 @@ def certificate_renewal_update(ca, ds, http):
|
||||
|
||||
template = paths.CERTMONGER_COMMAND_TEMPLATE
|
||||
serverid = installutils.realm_to_serverid(api.env.realm)
|
||||
dirsrv_dir = dsinstance.config_dirname(serverid)
|
||||
|
||||
# bump version when requests is changed
|
||||
version = 6
|
||||
requests = (
|
||||
(
|
||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'auditSigningCert cert-pki-ca',
|
||||
'dogtag-ipa-ca-renew-agent',
|
||||
template % 'stop_pkicad',
|
||||
'%s "auditSigningCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
||||
None,
|
||||
),
|
||||
(
|
||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'ocspSigningCert cert-pki-ca',
|
||||
'dogtag-ipa-ca-renew-agent',
|
||||
template % 'stop_pkicad',
|
||||
'%s "ocspSigningCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
||||
None,
|
||||
),
|
||||
(
|
||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'subsystemCert cert-pki-ca',
|
||||
'dogtag-ipa-ca-renew-agent',
|
||||
template % 'stop_pkicad',
|
||||
'%s "subsystemCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
||||
None,
|
||||
),
|
||||
(
|
||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'caSigningCert cert-pki-ca',
|
||||
'dogtag-ipa-ca-renew-agent',
|
||||
template % 'stop_pkicad',
|
||||
'%s "caSigningCert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
||||
'ipaCACertRenewal',
|
||||
),
|
||||
(
|
||||
paths.IPA_RADB_DIR,
|
||||
'ipaCert',
|
||||
'dogtag-ipa-ca-renew-agent',
|
||||
template % 'renew_ra_cert_pre',
|
||||
template % 'renew_ra_cert',
|
||||
None,
|
||||
),
|
||||
(
|
||||
paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'Server-Cert cert-pki-ca',
|
||||
'dogtag-ipa-ca-renew-agent',
|
||||
template % 'stop_pkicad',
|
||||
'%s "Server-Cert cert-pki-ca"' % (template % 'renew_ca_cert'),
|
||||
None,
|
||||
),
|
||||
(
|
||||
paths.HTTPD_ALIAS_DIR,
|
||||
'Server-Cert',
|
||||
'IPA',
|
||||
None,
|
||||
template % 'restart_httpd',
|
||||
None,
|
||||
),
|
||||
(
|
||||
dirsrv_dir,
|
||||
'Server-Cert',
|
||||
'IPA',
|
||||
None,
|
||||
'%s %s' % (template % 'restart_dirsrv', serverid),
|
||||
None,
|
||||
),
|
||||
|
||||
)
|
||||
requests = [
|
||||
{
|
||||
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'cert-nickname': 'auditSigningCert cert-pki-ca',
|
||||
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||
'cert-presave-command': template % 'stop_pkicad',
|
||||
'cert-postsave-command':
|
||||
(template % 'renew_ca_cert "auditSigningCert cert-pki-ca"'),
|
||||
},
|
||||
{
|
||||
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'cert-nickname': 'ocspSigningCert cert-pki-ca',
|
||||
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||
'cert-presave-command': template % 'stop_pkicad',
|
||||
'cert-postsave-command':
|
||||
(template % 'renew_ca_cert "ocspSigningCert cert-pki-ca"'),
|
||||
},
|
||||
{
|
||||
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'cert-nickname': 'subsystemCert cert-pki-ca',
|
||||
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||
'cert-presave-command': template % 'stop_pkicad',
|
||||
'cert-postsave-command':
|
||||
(template % 'renew_ca_cert "subsystemCert cert-pki-ca"'),
|
||||
},
|
||||
{
|
||||
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'cert-nickname': 'caSigningCert cert-pki-ca',
|
||||
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||
'cert-presave-command': template % 'stop_pkicad',
|
||||
'cert-postsave-command':
|
||||
(template % 'renew_ca_cert "caSigningCert cert-pki-ca"'),
|
||||
'template-profile': 'ipaCACertRenewal',
|
||||
},
|
||||
{
|
||||
'cert-database': paths.PKI_TOMCAT_ALIAS_DIR,
|
||||
'cert-nickname': 'Server-Cert cert-pki-ca',
|
||||
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||
'cert-presave-command': template % 'stop_pkicad',
|
||||
'cert-postsave-command':
|
||||
(template % 'renew_ca_cert "Server-Cert cert-pki-ca"'),
|
||||
},
|
||||
{
|
||||
'cert-file': paths.RA_AGENT_PEM,
|
||||
'key-file': paths.RA_AGENT_KEY,
|
||||
'ca': 'dogtag-ipa-ca-renew-agent',
|
||||
'cert-presave-command': template % 'renew_ra_cert_pre',
|
||||
'cert-postsave-command': template % 'renew_ra_cert',
|
||||
},
|
||||
{
|
||||
'cert-database': paths.HTTPD_ALIAS_DIR,
|
||||
'cert-nickname': 'Server-Cert',
|
||||
'ca': 'IPA',
|
||||
'cert-postsave-command': template % 'restart_httpd',
|
||||
},
|
||||
{
|
||||
'cert-database': dsinstance.config_dirname(serverid),
|
||||
'cert-nickname': 'Server-Cert',
|
||||
'ca': 'IPA',
|
||||
'cert-postsave-command':
|
||||
'%s %s' % (template % 'restart_dirsrv', serverid),
|
||||
}
|
||||
]
|
||||
|
||||
root_logger.info("[Update certmonger certificate renewal configuration to "
|
||||
"version %d]" % version)
|
||||
@@ -984,16 +979,7 @@ def certificate_renewal_update(ca, ds, http):
|
||||
|
||||
# State not set, lets see if we are already configured
|
||||
for request in requests:
|
||||
nss_dir, nickname, ca_name, pre_command, post_command, profile = 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)
|
||||
request_id = certmonger.get_request_id(request)
|
||||
if request_id is None:
|
||||
break
|
||||
else:
|
||||
@@ -1402,24 +1388,6 @@ def fix_trust_flags():
|
||||
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):
|
||||
root_logger.info('[Updating mod_nss protocol versions]')
|
||||
|
||||
@@ -1663,7 +1631,6 @@ def upgrade_configuration():
|
||||
update_mod_nss_protocol(http)
|
||||
update_mod_nss_cipher_suite(http)
|
||||
fix_trust_flags()
|
||||
export_ra_agent_pem()
|
||||
update_http_keytab(http)
|
||||
http.configure_gssproxy()
|
||||
http.start()
|
||||
|
||||
@@ -243,6 +243,7 @@ import datetime
|
||||
import json
|
||||
from lxml import etree
|
||||
import time
|
||||
import contextlib
|
||||
|
||||
import six
|
||||
from six.moves import urllib
|
||||
@@ -250,8 +251,7 @@ from six.moves import urllib
|
||||
from ipalib import Backend, api
|
||||
from ipapython.dn import DN
|
||||
import ipapython.cookie
|
||||
from ipapython import dogtag
|
||||
from ipapython import ipautil
|
||||
from ipapython import dogtag, ipautil, certdb
|
||||
|
||||
if api.env.in_server:
|
||||
import pki
|
||||
@@ -1242,8 +1242,12 @@ class RestClient(Backend):
|
||||
if api.env.in_tree:
|
||||
self.client_certfile = os.path.join(
|
||||
api.env.dot_ipa, 'ra-agent.pem')
|
||||
|
||||
self.client_keyfile = os.path.join(
|
||||
api.env.dot_ipa, 'ra-agent.key')
|
||||
else:
|
||||
self.client_certfile = paths.RA_AGENT_PEM
|
||||
self.client_keyfile = paths.RA_AGENT_KEY
|
||||
super(RestClient, self).__init__(api)
|
||||
|
||||
# session cookie
|
||||
@@ -1279,6 +1283,7 @@ class RestClient(Backend):
|
||||
url='/ca/rest/account/login',
|
||||
cafile=self.ca_cert,
|
||||
client_certfile=self.client_certfile,
|
||||
client_keyfile=self.client_keyfile,
|
||||
method='GET'
|
||||
)
|
||||
cookies = ipapython.cookie.Cookie.parse(resp_headers.get('set-cookie', ''))
|
||||
@@ -1294,6 +1299,7 @@ class RestClient(Backend):
|
||||
url='/ca/rest/account/logout',
|
||||
cafile=self.ca_cert,
|
||||
client_certfile=self.client_certfile,
|
||||
client_keyfile=self.client_keyfile,
|
||||
method='GET'
|
||||
)
|
||||
self.cookie = None
|
||||
@@ -1337,6 +1343,7 @@ class RestClient(Backend):
|
||||
url=resource,
|
||||
cafile=self.ca_cert,
|
||||
client_certfile=self.client_certfile,
|
||||
client_keyfile=self.client_keyfile,
|
||||
method=method, headers=headers, body=body
|
||||
)
|
||||
if status < 200 or status >= 300:
|
||||
@@ -1421,6 +1428,7 @@ class ra(rabase.rabase, RestClient):
|
||||
self.ca_host, port, url,
|
||||
cafile=self.ca_cert,
|
||||
client_certfile=self.client_certfile,
|
||||
client_keyfile=self.client_keyfile,
|
||||
**kw)
|
||||
|
||||
def get_parse_result_xml(self, xml_text, parse_func):
|
||||
@@ -1998,6 +2006,7 @@ class kra(Backend):
|
||||
else:
|
||||
return api.env.ca_host
|
||||
|
||||
@contextlib.contextmanager
|
||||
def get_client(self):
|
||||
"""
|
||||
Returns an authenticated KRA client to access KRA services.
|
||||
@@ -2009,9 +2018,11 @@ class kra(Backend):
|
||||
# TODO: replace this with a more specific exception
|
||||
raise RuntimeError('KRA service is not enabled')
|
||||
|
||||
tempdb = certdb.NSSDatabase()
|
||||
tempdb.create_db()
|
||||
crypto = cryptoutil.NSSCryptoProvider(
|
||||
paths.IPA_RADB_DIR,
|
||||
password_file=os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt'))
|
||||
tempdb.secdir,
|
||||
password_file=tempdb.pwd_file)
|
||||
|
||||
# TODO: obtain KRA host & port from IPA service list or point to KRA load balancer
|
||||
# https://fedorahosted.org/freeipa/ticket/4557
|
||||
@@ -2021,9 +2032,16 @@ class kra(Backend):
|
||||
str(self.kra_port),
|
||||
'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()
|
||||
|
||||
@@ -35,20 +35,22 @@ from ipalib import errors
|
||||
import os
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
|
||||
class rabase(Backend):
|
||||
"""
|
||||
Request Authority backend plugin.
|
||||
"""
|
||||
def __init__(self, api):
|
||||
self.ca_cert = api.env.tls_ca_cert
|
||||
if api.env.in_tree:
|
||||
self.sec_dir = api.env.dot_ipa + os.sep + 'alias'
|
||||
self.pwd_file = self.sec_dir + os.sep + '.pwd'
|
||||
self.client_certfile = os.path.join(
|
||||
api.env.dot_ipa, 'ra-agent.pem')
|
||||
self.client_keyfile = os.path.join(api.env.dot_ipa, 'ra-agent.key')
|
||||
else:
|
||||
self.sec_dir = paths.IPA_RADB_DIR
|
||||
self.pwd_file = os.path.join(paths.IPA_RADB_DIR, 'pwdfile.txt')
|
||||
self.client_certfile = paths.RA_AGENT_PEM
|
||||
self.client_keyfile = paths.RA_AGENT_KEY
|
||||
super(rabase, self).__init__(api)
|
||||
|
||||
|
||||
def check_request_status(self, request_id):
|
||||
"""
|
||||
Check status of a certificate signing request.
|
||||
|
||||
@@ -816,23 +816,22 @@ class vault_del(LDAPDelete):
|
||||
def post_callback(self, ldap, dn, *args, **options):
|
||||
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)
|
||||
kra_account.login()
|
||||
client_key_id = self.obj.get_key_id(dn)
|
||||
|
||||
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
|
||||
response = kra_client.keys.list_keys(
|
||||
client_key_id, pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
||||
for key_info in response.key_infos:
|
||||
kra_client.keys.modify_key_status(
|
||||
key_info.get_key_id(),
|
||||
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
||||
|
||||
for key_info in response.key_infos:
|
||||
kra_client.keys.modify_key_status(
|
||||
key_info.get_key_id(),
|
||||
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
||||
|
||||
kra_account.logout()
|
||||
kra_account.logout()
|
||||
|
||||
return True
|
||||
|
||||
@@ -987,12 +986,12 @@ class vaultconfig_show(Retrieve):
|
||||
raise errors.InvocationError(
|
||||
format=_('KRA service is not enabled'))
|
||||
|
||||
kra_client = self.api.Backend.kra.get_client()
|
||||
transport_cert = kra_client.system_certs.get_transport_cert()
|
||||
config = {'transport_cert': transport_cert.binary}
|
||||
config.update(
|
||||
self.api.Backend.serverroles.config_retrieve("KRA server")
|
||||
)
|
||||
with self.api.Backend.kra.get_client() as kra_client:
|
||||
transport_cert = kra_client.system_certs.get_transport_cert()
|
||||
config = {'transport_cert': transport_cert.binary}
|
||||
config.update(
|
||||
self.api.Backend.serverroles.config_retrieve("KRA server")
|
||||
)
|
||||
|
||||
return {
|
||||
'result': config,
|
||||
@@ -1038,34 +1037,33 @@ class vault_archive_internal(PKQuery):
|
||||
vault = self.api.Command.vault_show(*args, **options)['result']
|
||||
|
||||
# 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)
|
||||
kra_account.login()
|
||||
client_key_id = self.obj.get_key_id(vault['dn'])
|
||||
|
||||
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
|
||||
response = kra_client.keys.list_keys(
|
||||
client_key_id,
|
||||
pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
||||
for key_info in response.key_infos:
|
||||
kra_client.keys.modify_key_status(
|
||||
key_info.get_key_id(),
|
||||
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
||||
|
||||
for key_info in response.key_infos:
|
||||
kra_client.keys.modify_key_status(
|
||||
key_info.get_key_id(),
|
||||
pki.key.KeyClient.KEY_STATUS_INACTIVE)
|
||||
# forward wrapped data to KRA
|
||||
kra_client.keys.archive_encrypted_data(
|
||||
client_key_id,
|
||||
pki.key.KeyClient.PASS_PHRASE_TYPE,
|
||||
wrapped_vault_data,
|
||||
wrapped_session_key,
|
||||
None,
|
||||
nonce,
|
||||
)
|
||||
|
||||
# forward wrapped data to KRA
|
||||
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()
|
||||
kra_account.logout()
|
||||
|
||||
response = {
|
||||
'value': args[-1],
|
||||
@@ -1105,29 +1103,28 @@ class vault_retrieve_internal(PKQuery):
|
||||
vault = self.api.Command.vault_show(*args, **options)['result']
|
||||
|
||||
# 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)
|
||||
kra_account.login()
|
||||
client_key_id = self.obj.get_key_id(vault['dn'])
|
||||
|
||||
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
|
||||
response = kra_client.keys.list_keys(
|
||||
client_key_id,
|
||||
pki.key.KeyClient.KEY_STATUS_ACTIVE)
|
||||
if not len(response.key_infos):
|
||||
raise errors.NotFound(reason=_('No archived data.'))
|
||||
|
||||
if not len(response.key_infos):
|
||||
raise errors.NotFound(reason=_('No archived data.'))
|
||||
key_info = response.key_infos[0]
|
||||
|
||||
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
|
||||
key = kra_client.keys.retrieve_key(
|
||||
key_info.get_key_id(),
|
||||
wrapped_session_key)
|
||||
|
||||
kra_account.logout()
|
||||
kra_account.logout()
|
||||
|
||||
response = {
|
||||
'value': args[-1],
|
||||
|
||||
@@ -45,12 +45,6 @@ def PKI_TOMCAT_password_callback():
|
||||
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):
|
||||
'''
|
||||
Store that extracts private keys from an NSSDB, wrapped with the
|
||||
@@ -193,11 +187,11 @@ class DMLDAP(DBMAPHandler):
|
||||
|
||||
class PEMFileHandler(DBMAPHandler):
|
||||
def __init__(self, config, dbmap, nickname=None):
|
||||
if 'type' not in dbmap or dbmap['type'] != 'OPENSSL':
|
||||
raise ValueError('Invalid type "{t}", expected OPENSSL'
|
||||
if 'type' not in dbmap or dbmap['type'] != 'PEM':
|
||||
raise ValueError('Invalid type "{t}", expected PEM'
|
||||
.format(t=dbmap['type']))
|
||||
self.certfile = dbmap['certfile']
|
||||
self.keyfile = dbmap.get(['keyfile'])
|
||||
self.keyfile = dbmap.get('keyfile')
|
||||
|
||||
def export_key(self):
|
||||
_fd, tmpfile = tempfile.mkstemp(dir=paths.TMP)
|
||||
@@ -266,10 +260,10 @@ NAME_DB_MAP = {
|
||||
'wrap_nick': 'caSigningCert cert-pki-ca',
|
||||
},
|
||||
'ra': {
|
||||
'type': 'NSSDB',
|
||||
'path': paths.IPA_RADB_DIR,
|
||||
'handler': NSSCertDB,
|
||||
'pwcallback': HTTPD_password_callback,
|
||||
'type': 'PEM',
|
||||
'handler': PEMFileHandler,
|
||||
'certfile': paths.RA_AGENT_PEM,
|
||||
'keyfile': paths.RA_AGENT_KEY,
|
||||
},
|
||||
'dm': {
|
||||
'type': 'DMLDAP',
|
||||
|
||||
@@ -79,7 +79,7 @@ def makecert(reqdir, subject, principal):
|
||||
"""
|
||||
|
||||
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'):
|
||||
raise AssertionError('The self-signed CA is not configured, '
|
||||
'see ipatests/test_xmlrpc/test_cert.py')
|
||||
|
||||
Reference in New Issue
Block a user