From 32d3f9b0df7e376a8c86c37a77bde1658a33485f Mon Sep 17 00:00:00 2001
From: Jack Magne <jmagne@localhost.localdomain>
Date: Fri, 1 May 2015 10:12:06 -0700
Subject: [PATCH] OCSP and CA minor cloning fixes

Tickets #1294, #1058

The patch does the following:

1. Allows an OCSP clone to actually install and operate.
It also sets a param appropriate for an OCSP clone. Ticket #1058

The controversial part of this one is the fact that I have disabled
having OCSP clones register themselves to the CA as publishing target.
The master is already getting the updates and we rely upon replication
to keep the clones updated. The current downside is the master is on an
island with respect to updates and could be considered a single point of failure.

Thus my proposal for this simple patch is to get the OCSP clone working as in existing
functionality. Then we come back and propose a ticket to allow the installer OCSP clones
to set up the publishers in such a way that all clones and master are registered, but when
it is actually time to publish, the CRL publisher has the smarts to know that members of a
clone cluster are in a group and the first successfull publish should end the processing of
that group.

2. Allows the CA clone to set some params to disable certain things that a clone should not do.
This was listed as a set of misc post install tasks that we are trying to automate.

Code tested to work.

1. OCSP clones can be installed and the CRL were checked to be in sync when an update occured to the master.
2. The CA clone has been seen to have the required params and it looks to come up just fine.
---
 .../server/ca/rest/CAInstallerService.java         | 73 ++++++++++++++++------
 .../server/ocsp/rest/OCSPInstallerService.java     | 29 ++++++++-
 2 files changed, 82 insertions(+), 20 deletions(-)

diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java
index 883ab37..7789df2 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CAInstallerService.java
@@ -20,6 +20,8 @@ package org.dogtagpki.server.ca.rest;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.StringTokenizer;
 
 import netscape.ldap.LDAPAttribute;
@@ -39,7 +41,6 @@ import com.netscape.cms.servlet.csadmin.ConfigurationUtils;
 import com.netscape.cmscore.base.LDAPConfigStore;
 import com.netscape.cmscore.profile.LDAPProfileSubsystem;
 
-
 /**
  * @author alee
  *
@@ -55,9 +56,9 @@ public class CAInstallerService extends SystemConfigService {
         super.finalizeConfiguration(request);
 
         try {
-             if (!request.isClone()) {
-                 ConfigurationUtils.updateNextRanges();
-             }
+            if (!request.isClone()) {
+                ConfigurationUtils.updateNextRanges();
+            }
 
         } catch (Exception e) {
             CMS.debug(e);
@@ -75,6 +76,10 @@ public class CAInstallerService extends SystemConfigService {
                 cs.putString("securitydomain.select", "new");
             }
 
+            if (request.isClone()) {
+                disableCRLCachingAndGenerationForClone(request);
+            }
+
         } catch (Exception e) {
             CMS.debug(e);
             throw new PKIException("Errors in determining if security domain host is a master CA");
@@ -105,16 +110,16 @@ public class CAInstallerService extends SystemConfigService {
     /**
      * Import profiles from the filesystem into the database.
      *
-     * @param configRoot Where to look for the profile files.  For a
-     *                   fresh installation this should be
-     *                   "/usr/share/pki".  For existing installations it
-     *                   should be CMS.getConfigStore().getString("instanceRoot").
+     * @param configRoot Where to look for the profile files. For a
+     *            fresh installation this should be
+     *            "/usr/share/pki". For existing installations it
+     *            should be CMS.getConfigStore().getString("instanceRoot").
      *
      */
     public void importProfiles(String configRoot)
             throws EBaseException, ELdapException {
         IPluginRegistry registry = (IPluginRegistry)
-            CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+                CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
         IConfigStore profileCfg = cs.getSubStore("profile");
         String profileIds = profileCfg.getString("list", "");
         StringTokenizer st = new StringTokenizer(profileIds, ",");
@@ -146,10 +151,10 @@ public class CAInstallerService extends SystemConfigService {
     /**
      * Import one profile from the filesystem into the database.
      *
-     * @param dbFactory     LDAP connection factory.
-     * @param classId       The profile class of the profile to import.
-     * @param profileId     The ID of the profile to import.
-     * @param profilePath   Path to the on-disk profile configuration.
+     * @param dbFactory LDAP connection factory.
+     * @param classId The profile class of the profile to import.
+     * @param profileId The ID of the profile to import.
+     * @param profilePath Path to the on-disk profile configuration.
      */
     public void importProfile(
             ILdapConnFactory dbFactory, String classId,
@@ -160,15 +165,15 @@ public class CAInstallerService extends SystemConfigService {
 
         String dn = "cn=" + profileId + ",ou=certificateProfiles,ou=ca," + basedn;
 
-        String[] objectClasses = {"top", "certProfile"};
+        String[] objectClasses = { "top", "certProfile" };
         LDAPAttribute[] createAttrs = {
-            new LDAPAttribute("objectclass", objectClasses),
-            new LDAPAttribute("cn", profileId),
-            new LDAPAttribute("classId", classId)
+                new LDAPAttribute("objectclass", objectClasses),
+                new LDAPAttribute("cn", profileId),
+                new LDAPAttribute("classId", classId)
         };
 
         IConfigStore configStore = new LDAPConfigStore(
-            dbFactory, dn, createAttrs, "certProfileConfig");
+                dbFactory, dn, createAttrs, "certProfileConfig");
 
         try {
             FileInputStream input = new FileInputStream(profilePath);
@@ -181,4 +186,36 @@ public class CAInstallerService extends SystemConfigService {
 
         configStore.commit(false /* no backup */);
     }
+
+    private void disableCRLCachingAndGenerationForClone(ConfigurationRequest data) {
+
+        CMS.debug("CAInstallerService:disableCRLCachingAndGenerationForClone entering.");
+        if (data == null || !data.isClone())
+            return;
+
+        //Now add some well know entries that we need to disable CRL functionality.
+        //With well known values to disable and well known master CRL ID.
+
+        cs.putInteger("ca.certStatusUpdateInterval", 0);
+        cs.putBoolean("ca.listenToCloneModifications", false);
+        cs.putBoolean("ca.crl.MasterCRL.enableCRLCache", false);
+        cs.putBoolean("ca.crl.MasterCRL.enableCRLUpdates", false);
+
+        String cloneUri = data.getCloneUri();
+        URL url = null;
+        try {
+            url = new URL(cloneUri);
+        } catch (MalformedURLException e) {
+            // url pre validated before reaching here
+        }
+        String masterHost = url.getHost();
+        int masterPort = url.getPort();
+
+        CMS.debug("CAInstallerService:disableCRLCachingAndGenerationForClone: masterHost: " + masterHost
+                + " masterPort: " + masterPort);
+
+        cs.putString("master.ca.agent.host", masterHost);
+        cs.putInteger("master.ca.agent.port", masterPort);
+
+    }
 }
diff --git a/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPInstallerService.java b/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPInstallerService.java
index aaeeb34..afe1841 100644
--- a/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPInstallerService.java
+++ b/base/ocsp/src/org/dogtagpki/server/ocsp/rest/OCSPInstallerService.java
@@ -32,6 +32,8 @@ import com.netscape.cms.servlet.csadmin.ConfigurationUtils;
  */
 public class OCSPInstallerService extends SystemConfigService {
 
+    private static final int DEF_REFRESH_IN_SECS_FOR_CLONE = 1500;
+
     public OCSPInstallerService() throws EBaseException {
     }
 
@@ -47,17 +49,40 @@ public class OCSPInstallerService extends SystemConfigService {
             // configure the CRL Publishing to OCSP in CA
             if (!ca_host.equals("")) {
                 CMS.reinit(IOCSPAuthority.ID);
-                ConfigurationUtils.importCACertToOCSP();
+                if (!request.isClone())
+                    ConfigurationUtils.importCACertToOCSP();
+                else
+                    CMS.debug("OCSPInstallerService: Skipping importCACertToOCSP for clone.");
 
                 if (!request.getStandAlone()) {
-                    ConfigurationUtils.updateOCSPConfig();
+
+                    // For now don't register publishing with the CA for a clone.
+                    // Preserves existing functionality
+                    // Next we need to treat the publishing of clones as a group ,
+                    // and fail over amongst them.
+                    if (!request.isClone())
+                        ConfigurationUtils.updateOCSPConfig();
+
                     ConfigurationUtils.setupClientAuthUser();
                 }
             }
 
+            if (request.isClone()) {
+                configureCloneRefresh(request);
+            }
+
         } catch (Exception e) {
             CMS.debug(e);
             throw new PKIException("Errors in configuring CA publishing to OCSP: " + e);
         }
     }
+
+    private void configureCloneRefresh(ConfigurationRequest request) {
+        if (request == null || !request.isClone())
+            return;
+
+        //Set well know default value for OCSP clone
+        cs.putInteger("ocsp.store.defStore.refreshInSec", DEF_REFRESH_IN_SECS_FOR_CLONE);
+
+    }
 }
-- 
2.1.0

