590d18
From 0ceb0c7b9730314cb8dfff7d2af9ef811a96aa13 Mon Sep 17 00:00:00 2001
590d18
From: "Endi S. Dewata" <edewata@redhat.com>
590d18
Date: Thu, 27 Aug 2015 06:44:29 +0200
590d18
Subject: [PATCH] Using LDAPI to setup CA and KRA agents.
590d18
590d18
The CA and KRA installation code has been modified to use LDAPI
590d18
to create the CA and KRA agents directly in the CA and KRA
590d18
database. This way it's no longer necessary to use the Directory
590d18
Manager password or CA and KRA admin certificate.
590d18
590d18
https://fedorahosted.org/freeipa/ticket/5257
590d18
590d18
Reviewed-By: Martin Basti <mbasti@redhat.com>
590d18
---
590d18
 ipaplatform/base/paths.py        |   2 -
590d18
 ipaserver/install/cainstance.py  |  49 ++++++++++-------
590d18
 ipaserver/install/krainstance.py | 113 +++++++++++++++------------------------
590d18
 3 files changed, 72 insertions(+), 92 deletions(-)
590d18
590d18
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
590d18
index a407c1273f01b3465bcb1985dd41f2f242346a62..ff75e0d7a5a0250ce71e67b0302bbaab64c5e935 100644
590d18
--- a/ipaplatform/base/paths.py
590d18
+++ b/ipaplatform/base/paths.py
590d18
@@ -344,8 +344,6 @@ class BasePathNamespace(object):
590d18
     SLAPD_INSTANCE_SOCKET_TEMPLATE = "/var/run/slapd-%s.socket"
590d18
     ALL_SLAPD_INSTANCE_SOCKETS = "/var/run/slapd-*.socket"
590d18
     ADMIN_CERT_PATH = '/root/.dogtag/pki-tomcat/ca_admin.cert'
590d18
-    KRA_NSSDB_PASSWORD_FILE = "/root/.dogtag/pki-tomcat/kra/password.conf"
590d18
-    KRA_PKCS12_PASSWORD_FILE = "/root/.dogtag/pki-tomcat/kra/pkcs12_password.conf"
590d18
     ENTROPY_AVAIL = '/proc/sys/kernel/random/entropy_avail'
590d18
     LDIF2DB = '/usr/sbin/ldif2db'
590d18
     DB2LDIF = '/usr/sbin/db2ldif'
590d18
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
590d18
index ecd9300036353426097d929918be974cbbb5c69d..a4504a35a42b8c8ea2a96738c82c546ebebf569f 100644
590d18
--- a/ipaserver/install/cainstance.py
590d18
+++ b/ipaserver/install/cainstance.py
590d18
@@ -464,7 +464,7 @@ class CAInstance(DogtagInstance):
590d18
                 self.step("restarting certificate server", self.restart_instance)
590d18
                 self.step("requesting RA certificate from CA", self.__request_ra_certificate)
590d18
                 self.step("issuing RA agent certificate", self.__issue_ra_cert)
590d18
-                self.step("adding RA agent as a trusted user", self.__configure_ra)
590d18
+                self.step("adding RA agent as a trusted user", self.__create_ca_agent)
590d18
                 self.step("authorizing RA to modify profiles", self.__configure_profiles_acl)
590d18
             self.step("configure certmonger for renewals", self.configure_certmonger_renewal)
590d18
             self.step("configure certificate renewals", self.configure_renewal)
590d18
@@ -903,18 +903,26 @@ class CAInstance(DogtagInstance):
590d18
 
590d18
         self.configure_agent_renewal()
590d18
 
590d18
-    def __configure_ra(self):
590d18
-        # Create an RA user in the CA LDAP server and add that user to
590d18
-        # the appropriate groups so it can issue certificates without
590d18
-        # manual intervention.
590d18
-        conn = ipaldap.IPAdmin(self.fqdn, self.ds_port)
590d18
-        conn.do_simple_bind(DN(('cn', 'Directory Manager')), self.dm_password)
590d18
+    def __create_ca_agent(self):
590d18
+        """
590d18
+        Create CA agent, assign a certificate, and add the user to
590d18
+        the appropriate groups for accessing CA services.
590d18
+        """
590d18
 
590d18
-        decoded = base64.b64decode(self.ra_cert)
590d18
+        # get ipaCert certificate
590d18
+        cert_data = base64.b64decode(self.ra_cert)
590d18
+        cert = x509.load_certificate(cert_data, x509.DER)
590d18
 
590d18
-        entry_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
590d18
+        # connect to CA database
590d18
+        server_id = installutils.realm_to_serverid(api.env.realm)
590d18
+        dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
590d18
+        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
590d18
+        conn.connect(autobind=True)
590d18
+
590d18
+        # create ipara user with ipaCert certificate
590d18
+        user_dn = DN(('uid', "ipara"), ('ou', 'People'), self.basedn)
590d18
         entry = conn.make_entry(
590d18
-            entry_dn,
590d18
+            user_dn,
590d18
             objectClass=['top', 'person', 'organizationalPerson',
590d18
                          'inetOrgPerson', 'cmsuser'],
590d18
             uid=["ipara"],
590d18
@@ -922,23 +930,24 @@ class CAInstance(DogtagInstance):
590d18
             cn=["ipara"],
590d18
             usertype=["agentType"],
590d18
             userstate=["1"],
590d18
-            userCertificate=[decoded],
590d18
+            userCertificate=[cert_data],
590d18
             description=['2;%s;%s;%s' % (
590d18
-                str(self.requestId),
590d18
+                cert.serial_number,
590d18
                 DN(('CN', 'Certificate Authority'), self.subject_base),
590d18
                 DN(('CN', 'IPA RA'), self.subject_base))])
590d18
-
590d18
         conn.add_entry(entry)
590d18
 
590d18
-        dn = DN(('cn', 'Certificate Manager Agents'), ('ou', 'groups'), self.basedn)
590d18
-        modlist = [(0, 'uniqueMember', '%s' % entry_dn)]
590d18
-        conn.modify_s(dn, modlist)
590d18
+        # add ipara user to Certificate Manager Agents group
590d18
+        group_dn = DN(('cn', 'Certificate Manager Agents'), ('ou', 'groups'),
590d18
+            self.basedn)
590d18
+        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')
590d18
 
590d18
-        dn = DN(('cn', 'Registration Manager Agents'), ('ou', 'groups'), self.basedn)
590d18
-        modlist = [(0, 'uniqueMember', '%s' % entry_dn)]
590d18
-        conn.modify_s(dn, modlist)
590d18
+        # add ipara user to Registration Manager Agents group
590d18
+        group_dn = DN(('cn', 'Registration Manager Agents'), ('ou', 'groups'),
590d18
+            self.basedn)
590d18
+        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')
590d18
 
590d18
-        conn.unbind()
590d18
+        conn.disconnect()
590d18
 
590d18
     def __configure_profiles_acl(self):
590d18
         """Allow the Certificate Manager Agents group to modify profiles."""
590d18
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
590d18
index e5cdbf5e7714603041e3f0156e87311994175b18..958fe6fb095e69f83342ce8299d1586b8bbacd47 100644
590d18
--- a/ipaserver/install/krainstance.py
590d18
+++ b/ipaserver/install/krainstance.py
590d18
@@ -25,17 +25,21 @@ import sys
590d18
 import tempfile
590d18
 
590d18
 from ipalib import api
590d18
+from ipalib import x509
590d18
 from ipaplatform import services
590d18
 from ipaplatform.paths import paths
590d18
+from ipapython import certdb
590d18
 from ipapython import dogtag
590d18
 from ipapython import ipautil
590d18
 from ipapython.dn import DN
590d18
 from ipaserver.install import certs
590d18
 from ipaserver.install import cainstance
590d18
+from ipaserver.install import installutils
590d18
 from ipaserver.install import ldapupdate
590d18
 from ipaserver.install import service
590d18
 from ipaserver.install.dogtaginstance import DogtagInstance
590d18
 from ipaserver.install.dogtaginstance import DEFAULT_DSPORT, PKI_USER
590d18
+from ipaserver.plugins import ldap2
590d18
 from ipapython.ipa_log_manager import log_mgr
590d18
 
590d18
 # When IPA is installed with DNS support, this CNAME should hold all IPA
590d18
@@ -111,8 +115,8 @@ class KRAInstance(DogtagInstance):
590d18
 
590d18
         self.step("configuring KRA instance", self.__spawn_instance)
590d18
         if not self.clone:
590d18
-            self.step("add RA user to KRA agent group",
590d18
-                      self.__add_ra_user_to_agent_group)
590d18
+            self.step("create KRA agent",
590d18
+                      self.__create_kra_agent)
590d18
         self.step("restarting KRA", self.restart_instance)
590d18
         self.step("configure certmonger for renewals",
590d18
                   self.configure_certmonger_renewal)
590d18
@@ -267,77 +271,46 @@ class KRAInstance(DogtagInstance):
590d18
 
590d18
         self.log.debug("completed creating KRA instance")
590d18
 
590d18
-    def __add_ra_user_to_agent_group(self):
590d18
+    def __create_kra_agent(self):
590d18
         """
590d18
-        Add RA agent created for CA to KRA agent group.
590d18
+        Create KRA agent, assign a certificate, and add the user to
590d18
+        the appropriate groups for accessing KRA services.
590d18
         """
590d18
 
590d18
-        # import CA certificate into temporary security database
590d18
-        args = ["/usr/bin/pki",
590d18
-            "-d", self.agent_db,
590d18
-            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
590d18
-            "client-cert-import",
590d18
-            "--pkcs12", paths.KRACERT_P12,
590d18
-            "--pkcs12-password-file", paths.KRA_PKCS12_PASSWORD_FILE]
590d18
-        ipautil.run(args)
590d18
-
590d18
-        # trust CA certificate
590d18
-        args = ["/usr/bin/pki",
590d18
-            "-d", self.agent_db,
590d18
-            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
590d18
-            "client-cert-mod", "Certificate Authority - %s" % api.env.realm,
590d18
-            "--trust", "CT,c,"]
590d18
-        ipautil.run(args)
590d18
-
590d18
-        # import Dogtag admin certificate into temporary security database
590d18
-        args = ["/usr/bin/pki",
590d18
-            "-d", self.agent_db,
590d18
-            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
590d18
-            "client-cert-import",
590d18
-            "--pkcs12", paths.DOGTAG_ADMIN_P12,
590d18
-            "--pkcs12-password-file", paths.KRA_PKCS12_PASSWORD_FILE]
590d18
-        ipautil.run(args)
590d18
-
590d18
-        # as Dogtag admin, create ipakra user in KRA
590d18
-        args = ["/usr/bin/pki",
590d18
-            "-d", self.agent_db,
590d18
-            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
590d18
-            "-n", "ipa-ca-agent",
590d18
-            "kra-user-add", "ipakra",
590d18
-            "--fullName", "IPA KRA User"]
590d18
-        ipautil.run(args)
590d18
-
590d18
-        # as Dogtag admin, add ipakra into KRA agents group
590d18
-        args = ["/usr/bin/pki",
590d18
-            "-d", self.agent_db,
590d18
-            "-C", paths.KRA_NSSDB_PASSWORD_FILE,
590d18
-            "-n", "ipa-ca-agent",
590d18
-            "kra-user-membership-add", "ipakra", "Data Recovery Manager Agents"]
590d18
-        ipautil.run(args)
590d18
-
590d18
-        # assign ipaCert to ipakra
590d18
-        (file, filename) = tempfile.mkstemp()
590d18
-        os.close(file)
590d18
-        try:
590d18
-            # export ipaCert without private key
590d18
-            args = ["/usr/bin/pki",
590d18
-                "-d", paths.HTTPD_ALIAS_DIR,
590d18
-                "-C", paths.ALIAS_PWDFILE_TXT,
590d18
-                "client-cert-show", "ipaCert",
590d18
-                "--cert", filename]
590d18
-            ipautil.run(args)
590d18
-
590d18
-            # as Dogtag admin, upload and assign ipaCert to ipakra
590d18
-            args = ["/usr/bin/pki",
590d18
-                "-d", self.agent_db,
590d18
-                "-C", paths.KRA_NSSDB_PASSWORD_FILE,
590d18
-                "-n", "ipa-ca-agent",
590d18
-                "kra-user-cert-add", "ipakra",
590d18
-                "--input", filename]
590d18
-            ipautil.run(args)
590d18
-
590d18
-        finally:
590d18
-            os.remove(filename)
590d18
+        # get ipaCert certificate
590d18
+        with certdb.NSSDatabase(paths.HTTPD_ALIAS_DIR) as ipa_nssdb:
590d18
+           cert_data = ipa_nssdb.get_cert("ipaCert")
590d18
+        cert = x509.load_certificate(cert_data, x509.DER)
590d18
+
590d18
+        # connect to KRA database
590d18
+        server_id = installutils.realm_to_serverid(api.env.realm)
590d18
+        dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
590d18
+        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
590d18
+        conn.connect(autobind=True)
590d18
+
590d18
+        # create ipakra user with ipaCert certificate
590d18
+        user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
590d18
+        entry = conn.make_entry(
590d18
+            user_dn,
590d18
+            objectClass=['top', 'person', 'organizationalPerson',
590d18
+                         'inetOrgPerson', 'cmsuser'],
590d18
+            uid=["ipakra"],
590d18
+            sn=["IPA KRA User"],
590d18
+            cn=["IPA KRA User"],
590d18
+            usertype=["undefined"],
590d18
+            userCertificate=[cert_data],
590d18
+            description=['2;%s;%s;%s' % (
590d18
+                cert.serial_number,
590d18
+                DN(('CN', 'Certificate Authority'), self.subject_base),
590d18
+                DN(('CN', 'IPA RA'), self.subject_base))])
590d18
+        conn.add_entry(entry)
590d18
+
590d18
+        # add ipakra user to Data Recovery Manager Agents group
590d18
+        group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
590d18
+                self.basedn)
590d18
+        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')
590d18
+
590d18
+        conn.disconnect()
590d18
 
590d18
     def __add_vault_container(self):
590d18
         sub_dict = {
590d18
-- 
590d18
2.5.1
590d18