summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2014-10-01 14:59:46 -0400
committerPetr Viktorin <pviktori@dhcp-31-13.brq.redhat.com>2014-11-04 16:33:16 +0100
commit0b08043c37210d0f86cb0c66d659acafda0fb529 (patch)
tree1695b9b4b416a0b0ed14f63d1f5758b07dd170af
parente7edac30a10c0da40d7cfd625e19bd4237b9e1f6 (diff)
downloadfreeipa-0b08043c37210d0f86cb0c66d659acafda0fb529.tar.gz
freeipa-0b08043c37210d0f86cb0c66d659acafda0fb529.tar.xz
freeipa-0b08043c37210d0f86cb0c66d659acafda0fb529.zip
Fixed KRA backend.
The KRA backend has been simplified since most of the tasks have been moved somewhere else. The transport certificate will be installed on the client, and it is not needed by KRA backend. The KRA agent's PEM certificate is now generated during installation due to permission issue. The kra_host() for now is removed since the current ldap_enable() cannot register the KRA service, so it is using the kra_host environment variable. The KRA installer has been modified to use Dogtag's CLI to create KRA agent and setup the client authentication. The proxy settings have been updated to include KRA's URLs. Some constants have been renamed for clarity. The DOGTAG_AGENT_P12 has been renamed to DOGTAG_ADMIN_P12 since file actually contains the Dogtag admin's certificate and private key and it can be used to access both CA and KRA. The DOGTAG_AGENT_PEM has been renamed to KRA_AGENT_PEM since it can only be used for KRA. The Dogtag dependency has been updated to 10.2.1-0.1. https://fedorahosted.org/freeipa/ticket/4503 Reviewed-By: Petr Viktorin <pviktori@redhat.com>
-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)