summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--freeipa.spec.in4
-rw-r--r--install/conf/ipa-pki-proxy.conf2
-rw-r--r--ipaplatform/base/paths.py4
-rw-r--r--ipaserver/install/cainstance.py4
-rw-r--r--ipaserver/install/ipa_backup.py3
-rw-r--r--ipaserver/install/krainstance.py83
-rw-r--r--ipaserver/plugins/dogtag.py122
7 files changed, 101 insertions, 121 deletions
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 52c96757e..1302d850d 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -130,8 +130,8 @@ Requires(post): systemd-units
Requires: selinux-policy >= %{selinux_policy_version}
Requires(post): selinux-policy-base
Requires: slapi-nis >= 0.54-1
-Requires: pki-ca >= 10.2.0-3
-Requires: pki-kra >= 10.2.0
+Requires: pki-ca >= 10.2.1-0.1
+Requires: pki-kra >= 10.2.1-0.1
%if 0%{?rhel}
Requires: subscription-manager
%endif
diff --git a/install/conf/ipa-pki-proxy.conf b/install/conf/ipa-pki-proxy.conf
index 2370b4d7a..5d2115684 100644
--- a/install/conf/ipa-pki-proxy.conf
+++ b/install/conf/ipa-pki-proxy.conf
@@ -19,7 +19,7 @@ ProxyRequests Off
</LocationMatch>
# matches for agent port and eeca port
-<LocationMatch "^/ca/agent/ca/displayBySerial|^/ca/agent/ca/doRevoke|^/ca/agent/ca/doUnrevoke|^/ca/agent/ca/updateDomainXML|^/ca/eeca/ca/profileSubmitSSLClient|^/kra/agent/kra/connector|^/kra/rest/agent/keyrequests|^/kra/rest/agent/keys|^/ca/rest/admin/kraconnector/remove">
+<LocationMatch "^/ca/agent/ca/displayBySerial|^/ca/agent/ca/doRevoke|^/ca/agent/ca/doUnrevoke|^/ca/agent/ca/updateDomainXML|^/ca/eeca/ca/profileSubmitSSLClient|^/kra/agent/kra/connector|^/kra/rest/account|^/kra/rest/agent/keyrequests|^/kra/rest/agent/keys|^/ca/rest/admin/kraconnector/remove">
NSSOptions +StdEnvVars +ExportCertData +StrictRequire +OptRenegotiate
NSSVerifyClient require
ProxyPassMatch ajp://localhost:$DOGTAG_PORT
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index bbe6eed76..01505594a 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -138,8 +138,8 @@ class BasePathNamespace(object):
HOME_DIR = "/home"
ROOT_IPA_CACHE = "/root/.ipa_cache"
ROOT_PKI = "/root/.pki"
- DOGTAG_AGENT_P12 = "/root/ca-agent.p12"
- DOGTAG_AGENT_PEM = "/etc/httpd/alias/agent.pem"
+ DOGTAG_ADMIN_P12 = "/root/ca-agent.p12"
+ KRA_AGENT_PEM = "/etc/httpd/alias/kra-agent.pem"
CACERT_P12 = "/root/cacert.p12"
ROOT_IPA_CSR = "/root/ipa.csr"
ROOT_TMP_CA_P12 = "/root/tmp-ca.p12"
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 1ae39639a..fe9520151 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -514,7 +514,7 @@ class CAInstance(DogtagInstance):
config.set("CA", "pki_admin_nickname", "ipa-ca-agent")
config.set("CA", "pki_admin_subject_dn",
str(DN(('cn', 'ipa-ca-agent'), self.subject_base)))
- config.set("CA", "pki_client_admin_cert_p12", paths.DOGTAG_AGENT_P12)
+ config.set("CA", "pki_client_admin_cert_p12", paths.DOGTAG_ADMIN_P12)
# Directory server
config.set("CA", "pki_ds_ldap_port", str(self.ds_port))
@@ -979,7 +979,7 @@ class CAInstance(DogtagInstance):
try:
ipautil.run([paths.PK12UTIL,
"-n", "ipa-ca-agent",
- "-o", paths.DOGTAG_AGENT_P12,
+ "-o", paths.DOGTAG_ADMIN_P12,
"-d", self.agent_db,
"-k", pwd_name,
"-w", pwd_name])
diff --git a/ipaserver/install/ipa_backup.py b/ipaserver/install/ipa_backup.py
index 4bee5d51f..34be5383d 100644
--- a/ipaserver/install/ipa_backup.py
+++ b/ipaserver/install/ipa_backup.py
@@ -157,7 +157,8 @@ class Backup(admintool.AdminTool):
paths.NTP_CONF,
paths.SMB_CONF,
paths.SAMBA_KEYTAB,
- paths.DOGTAG_AGENT_P12,
+ paths.DOGTAG_ADMIN_P12,
+ paths.KRA_AGENT_PEM,
paths.CACERT_P12,
paths.KRB5KDC_KDC_CONF,
paths.SYSTEMD_IPA_SERVICE,
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
index 1af1c0f72..7c1bded41 100644
--- a/ipaserver/install/krainstance.py
+++ b/ipaserver/install/krainstance.py
@@ -169,7 +169,7 @@ class KRAInstance(DogtagInstance):
str(DN(('cn', 'ipa-ca-agent'), self.subject_base)))
config.set("KRA", "pki_import_admin_cert", "True")
config.set("KRA", "pki_admin_cert_file", paths.ADMIN_CERT_PATH)
- config.set("KRA", "pki_client_admin_cert_p12", paths.DOGTAG_AGENT_P12)
+ config.set("KRA", "pki_client_admin_cert_p12", paths.DOGTAG_ADMIN_P12)
# Directory server
config.set("KRA", "pki_ds_ldap_port", str(self.ds_port))
@@ -259,16 +259,81 @@ class KRAInstance(DogtagInstance):
"""
Add RA agent created for CA to KRA agent group.
"""
- conn = ipaldap.IPAdmin(self.fqdn, self.ds_port)
- conn.do_simple_bind(DN(('cn', 'Directory Manager')), self.dm_password)
- entry_dn = DN(('uid', "ipara"), ('ou', 'People'), ('o', 'ipaca'))
- dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
- self.basedn)
- modlist = [(0, 'uniqueMember', '%s' % entry_dn)]
- conn.modify_s(dn, modlist)
+ # import CA certificate into temporary security database
+ args = ["/usr/bin/pki",
+ "-d", self.agent_db,
+ "-c", self.admin_password,
+ "client-cert-import",
+ "--pkcs12", paths.KRACERT_P12,
+ "--pkcs12-password", self.admin_password]
+ ipautil.run(args)
+
+ # trust CA certificate
+ args = ["/usr/bin/pki",
+ "-d", self.agent_db,
+ "-c", self.admin_password,
+ "client-cert-mod", "Certificate Authority - %s" % api.env.realm,
+ "--trust", "CT,c,"]
+ ipautil.run(args)
+
+ # import Dogtag admin certificate into temporary security database
+ args = ["/usr/bin/pki",
+ "-d", self.agent_db,
+ "-c", self.admin_password,
+ "client-cert-import",
+ "--pkcs12", paths.DOGTAG_ADMIN_P12,
+ "--pkcs12-password", self.admin_password]
+ ipautil.run(args)
+
+ # as Dogtag admin, create ipakra user in KRA
+ args = ["/usr/bin/pki",
+ "-d", self.agent_db,
+ "-c", self.admin_password,
+ "-n", "ipa-ca-agent",
+ "kra-user-add", "ipakra",
+ "--fullName", "IPA KRA User"]
+ ipautil.run(args)
+
+ # as Dogtag admin, add ipakra into KRA agents group
+ args = ["/usr/bin/pki",
+ "-d", self.agent_db,
+ "-c", self.admin_password,
+ "-n", "ipa-ca-agent",
+ "kra-user-membership-add", "ipakra", "Data Recovery Manager Agents"]
+ ipautil.run(args)
+
+ # assign ipaCert to ipakra
+ (file, filename) = tempfile.mkstemp()
+ os.close(file)
+ try:
+ # export ipaCert without private key
+ args = ["/usr/bin/pki",
+ "-d", paths.HTTPD_ALIAS_DIR,
+ "-C", paths.ALIAS_PWDFILE_TXT,
+ "client-cert-show", "ipaCert",
+ "--cert", filename]
+ ipautil.run(args)
+
+ # as Dogtag admin, upload and assign ipaCert to ipakra
+ args = ["/usr/bin/pki",
+ "-d", self.agent_db,
+ "-c", self.admin_password,
+ "-n", "ipa-ca-agent",
+ "kra-user-cert-add", "ipakra",
+ "--input", filename]
+ ipautil.run(args)
- conn.unbind()
+ finally:
+ os.remove(filename)
+
+ # export ipaCert with private key for client authentication
+ args = ["/usr/bin/pki",
+ "-d", paths.HTTPD_ALIAS_DIR,
+ "-C", paths.ALIAS_PWDFILE_TXT,
+ "client-cert-show", "ipaCert",
+ "--client-cert", paths.KRA_AGENT_PEM]
+ ipautil.run(args)
@staticmethod
def update_cert_config(nickname, cert, dogtag_constants=None):
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
index 0e141a45c..cd1c05cd5 100644
--- a/ipaserver/plugins/dogtag.py
+++ b/ipaserver/plugins/dogtag.py
@@ -1890,122 +1890,36 @@ class kra(Backend):
"""
def __init__(self, kra_port=443):
- if api.env.in_tree:
- self.sec_dir = os.path.join(api.env.dot_ipa, 'alias')
- pwd_file = os.path.join(self.sec_dir, '.pwd')
- self.pem_file = os.path.join(self.sec_dir, ".pemfile")
- else:
- self.sec_dir = paths.HTTPD_ALIAS_DIR
- pwd_file = paths.ALIAS_PWDFILE_TXT
- self.pem_file = paths.DOGTAG_AGENT_PEM
self.kra_port = kra_port
- self.transport_nick = "IPA KRA Transport Cert"
- self.password = ""
- with open(pwd_file, "r") as f:
- self.password = f.readline().strip()
- self.keyclient = None
super(kra, self).__init__()
- def _create_pem_file(self):
- """ Create PEM file used by KRA plugin for authentication.
-
- This function reads the IPA HTTPD database and extracts the
- Dogtag agent certificate and keys into a PKCS#12 temporary file.
- The PKCS#12 file is then converted into PEM format so that it
- can be used by python-requests to authenticate to the KRA.
-
- :return: None
+ def get_client(self):
"""
- (p12_pwd_fd, p12_pwd_fname) = tempfile.mkstemp()
- (p12_fd, p12_fname) = tempfile.mkstemp()
+ Returns an authenticated KRA client to access KRA services.
- try:
- os.write(p12_pwd_fd, self.password)
- os.close(p12_pwd_fd)
- os.close(p12_fd)
-
- certdb = CertDB(api.env.realm)
- certdb.export_pkcs12(p12_fname, p12_pwd_fname, "ipaCert")
-
- certdb.install_pem_from_p12(p12_fname, self.password, self.pem_file)
- except:
- self.debug("Error when creating PEM file for KRA operations")
- raise
- finally:
- os.remove(p12_fname)
- os.remove(p12_pwd_fname)
-
- def _transport_cert_present(self):
- """ Check if the client certDB contains the KRA transport certificate
- :return: True/False
- """
- # certutil -L -d db_dir -n cert_nick
- certdb = CertDB(api.env.realm)
- return certdb.has_nickname(self.transport_nick)
-
- def _setup(self):
- """ Do initial setup and crypto initialization of the KRA client
-
- Creates a PEM file containing the KRA agent cert/keys to be used for
- authentication to the KRA (if it does not already exist), Sets up a
- connection to the KRA and initializes an NSS certificate database to
- store the transport certificate, Retrieves the transport certificate
- if it is not already present.
+ Raises a generic exception if KRA is not enabled.
"""
- #set up pem file if not present
- if not os.path.exists(self.pem_file):
- self._create_pem_file()
-
- # set up connection
- connection = PKIConnection('https',
- self.kra_host,
- str(self.kra_port),
- 'kra')
- connection.set_authentication_cert(self.pem_file)
- crypto = cryptoutil.NSSCryptoProvider(self.sec_dir, self.password)
+ if not api.env.enable_kra:
+ # TODO: replace this with a more specific exception
+ raise RuntimeError('KRA service is not enabled')
- #create kraclient
- kraclient = KRAClient(connection, crypto)
+ crypto = cryptoutil.NSSCryptoProvider(
+ paths.HTTPD_ALIAS_DIR,
+ password_file=paths.ALIAS_PWDFILE_TXT)
- # get transport cert if needed
- if not self._transport_cert_present():
- transport_cert = kraclient.system_certs.get_transport_cert()
- crypto.import_cert(self.transport_nick, transport_cert, "u,u,u")
+ # TODO: obtain KRA host & port from IPA service list or point to KRA load balancer
+ # https://fedorahosted.org/freeipa/ticket/4557
+ connection = PKIConnection(
+ 'https',
+ api.env.kra_host,
+ str(self.kra_port),
+ 'kra')
- crypto.initialize()
+ connection.set_authentication_cert(paths.KRA_AGENT_PEM)
- self.keyclient = kraclient.keys
- self.keyclient.set_transport_cert(self.transport_nick)
-
- @cachedproperty
- def kra_host(self):
- """
- :return: host
- as str
-
- Select our KRA host.
- """
- ldap2 = self.api.Backend.ldap2
- if host_has_service(api.env.kra_host, ldap2, "kra"):
- return api.env.kra_host
- if api.env.host != api.env.kra_host:
- if host_has_service(api.env.host, ldap2, "kra"):
- return api.env.host
- host = select_any_master(ldap2, "kra")
- if host:
- return host
- else:
- return api.env.kra_host
-
- def get_keyclient(self):
- """Return a keyclient to perform key archival and retrieval.
- :return: pki.key.keyclient
- """
- if self.keyclient is None:
- self._setup()
- return self.keyclient
+ return KRAClient(connection, crypto)
api.register(kra)