summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Laznicka <slaznick@redhat.com>2017-01-13 09:08:42 +0100
committerJan Cholasta <jcholast@redhat.com>2017-03-01 09:43:41 +0000
commit5ab85b365ae886558b1f077b0d039a0d24bebfa7 (patch)
tree270e8328af5b0d7934e55b81928a2417daa95985
parent24b134c633390343ba76e4091fa612650976280a (diff)
downloadfreeipa-5ab85b365ae886558b1f077b0d039a0d24bebfa7.tar.gz
freeipa-5ab85b365ae886558b1f077b0d039a0d24bebfa7.tar.xz
freeipa-5ab85b365ae886558b1f077b0d039a0d24bebfa7.zip
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>
-rwxr-xr-xinstall/certmonger/dogtag-ipa-ca-renew-agent-submit10
-rw-r--r--install/restart_scripts/renew_ra_cert30
-rw-r--r--ipaclient/install/ipa_certupdate.py1
-rw-r--r--ipaplatform/base/paths.py3
-rw-r--r--ipapython/dogtag.py6
-rw-r--r--ipaserver/install/ca.py38
-rw-r--r--ipaserver/install/cainstance.py130
-rw-r--r--ipaserver/install/certs.py4
-rw-r--r--ipaserver/install/custodiainstance.py4
-rw-r--r--ipaserver/install/dogtaginstance.py25
-rw-r--r--ipaserver/install/dsinstance.py15
-rw-r--r--ipaserver/install/httpinstance.py15
-rw-r--r--ipaserver/install/ipa_backup.py2
-rw-r--r--ipaserver/install/ipa_replica_prepare.py22
-rw-r--r--ipaserver/install/krainstance.py11
-rw-r--r--ipaserver/install/plugins/ca_renewal_master.py11
-rw-r--r--ipaserver/install/plugins/update_ra_cert_store.py80
-rw-r--r--ipaserver/install/server/install.py21
-rw-r--r--ipaserver/install/server/upgrade.py161
-rw-r--r--ipaserver/plugins/dogtag.py30
-rw-r--r--ipaserver/plugins/rabase.py12
-rw-r--r--ipaserver/plugins/vault.py125
-rw-r--r--ipaserver/secrets/store.py20
-rw-r--r--ipatests/test_xmlrpc/testcert.py2
24 files changed, 347 insertions, 431 deletions
diff --git a/install/certmonger/dogtag-ipa-ca-renew-agent-submit b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
index 2e67c7e5a..cc690b8fa 100755
--- a/install/certmonger/dogtag-ipa-ca-renew-agent-submit
+++ b/install/certmonger/dogtag-ipa-ca-renew-agent-submit
@@ -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,
diff --git a/install/restart_scripts/renew_ra_cert b/install/restart_scripts/renew_ra_cert
index 4dc6c2e4f..5c71d5791 100644
--- a/install/restart_scripts/renew_ra_cert
+++ b/install/restart_scripts/renew_ra_cert
@@ -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, "Can't open '{certpath}': {err}"
+ .format(certpath=ra_certpath, err=e)
+ )
+ sys.exit(1)
+ except (TypeError, ValueError):
syslog.syslog(
- syslog.LOG_ERR, "No certificate %s found." % nickname)
+ 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()
diff --git a/ipaclient/install/ipa_certupdate.py b/ipaclient/install/ipa_certupdate.py
index ec22594f8..75c5d97df 100644
--- a/ipaclient/install/ipa_certupdate.py
+++ b/ipaclient/install/ipa_certupdate.py
@@ -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()
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index d89f1a7f1..e4d4f2edc 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -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"
diff --git a/ipapython/dogtag.py b/ipapython/dogtag.py
index 4aeb897fd..ff7dc4464 100644
--- a/ipapython/dogtag.py
+++ b/ipapython/dogtag.py
@@ -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)
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index e346a2b92..649c15293 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -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()
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index a4f470cf7..0991883ab 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -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()
-
- import_pkcs12(
- rafile, agent_file.name, self.ra_agent_db, self.ra_agent_pwd)
+ # get the private key from the file
+ ipautil.run([paths.OPENSSL,
+ "pkcs12",
+ "-in", rafile,
+ "-nocerts", "-nodes",
+ "-out", paths.RA_AGENT_KEY,
+ "-passin", "pass:"])
+
+ # 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)
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index c55f3c599..4f978012f 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -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:
diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
index 1be53994a..6a6139231 100644
--- a/ipaserver/install/custodiainstance.py
+++ b/ipaserver/install/custodiainstance.py
@@ -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):
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
index 9fa61761a..9cbd34942 100644
--- a/ipaserver/install/dogtaginstance.py
+++ b/ipaserver/install/dogtaginstance.py
@@ -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
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index bf80ae089..99e61903d 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -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:
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 7979ca116..0c2216eb3 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -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)
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
index 9f35bf6ac..d722e48e1 100644
--- a/ipaserver/install/ipa_backup.py
+++ b/ipaserver/install/ipa_backup.py
@@ -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,
diff --git a/ipaserver/install/ipa_replica_prepare.py b/ipaserver/install/ipa_replica_prepare.py
index 6fa4b4a42..5f6b6e957 100644
--- a/ipaserver/install/ipa_replica_prepare.py
+++ b/ipaserver/install/ipa_replica_prepare.py
@@ -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')
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
index 1fc69bd68..5ee08dc32 100644
--- a/ipaserver/install/krainstance.py
+++ b/ipaserver/install/krainstance.py
@@ -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,
diff --git a/ipaserver/install/plugins/ca_renewal_master.py b/ipaserver/install/plugins/ca_renewal_master.py
index 2447a3406..99503adfe 100644
--- a/ipaserver/install/plugins/ca_renewal_master.py
+++ b/ipaserver/install/plugins/ca_renewal_master.py
@@ -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', '=')
diff --git a/ipaserver/install/plugins/update_ra_cert_store.py b/ipaserver/install/plugins/update_ra_cert_store.py
index e4c0ac528..937f9c59f 100644
--- a/ipaserver/install/plugins/update_ra_cert_store.py
+++ b/ipaserver/install/plugins/update_ra_cert_store.py
@@ -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, []
-
- 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)
-
- # 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)))
-
- # 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)
-
- certmonger.stop_tracking(secdir=olddb.secdir,
- nickname='ipaCert')
- certmonger.start_tracking(certpath=newdb.secdir,
- nickname='ipaCert',
- pinfile=newdb.pwd_file)
-
- olddb.delete_cert('ipaCert')
+ 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))
+
+ _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='')
+
+ # 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)
+
+ # get the private key and certificate from the file and start
+ # tracking it in certmonger
+ ca = cainstance.CAInstance()
+ ca.import_ra_cert(p12file)
+
+ os.remove(p12file)
return False, []
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 813329372..be398bce7 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -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)
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index c7965c7c3..eef675577 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -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()
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
index 4ae10b9fe..ca25352eb 100644
--- a/ipaserver/plugins/dogtag.py
+++ b/ipaserver/plugins/dogtag.py
@@ -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()
diff --git a/ipaserver/plugins/rabase.py b/ipaserver/plugins/rabase.py
index 8f2c8c388..49a3f8baf 100644
--- a/ipaserver/plugins/rabase.py
+++ b/ipaserver/plugins/rabase.py
@@ -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.
diff --git a/ipaserver/plugins/vault.py b/ipaserver/plugins/vault.py
index 5c4c09685..57e1ed780 100644
--- a/ipaserver/plugins/vault.py
+++ b/ipaserver/plugins/vault.py
@@ -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()
-
- kra_account = pki.account.AccountClient(kra_client.connection)
- 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)
-
- 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,
- )
-
- kra_account.logout()
+ with self.api.Backend.kra.get_client() as kra_client:
+ kra_account = pki.account.AccountClient(kra_client.connection)
+ 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)
+
+ 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,
+ )
+
+ 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()
-
- kra_account = pki.account.AccountClient(kra_client.connection)
- kra_account.login()
+ with self.api.Backend.kra.get_client() as kra_client:
+ 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],
diff --git a/ipaserver/secrets/store.py b/ipaserver/secrets/store.py
index a499aef13..6a448a348 100644
--- a/ipaserver/secrets/store.py
+++ b/ipaserver/secrets/store.py
@@ -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',
diff --git a/ipatests/test_xmlrpc/testcert.py b/ipatests/test_xmlrpc/testcert.py
index def820f16..c27ea95b0 100644
--- a/ipatests/test_xmlrpc/testcert.py
+++ b/ipatests/test_xmlrpc/testcert.py
@@ -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')