>From 0ba7a05b7247d763e26193141176b499996a6ed7 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Fri, 1 Feb 2013 14:20:15 -0500
Subject: [PATCH 116/117] Add updateDomainXML to admin interface

---
 base/ca/shared/conf/acl.ldif                       |  2 +-
 base/ca/shared/webapps/ca/WEB-INF/web.xml          | 24 ++++++
 .../cms/servlet/csadmin/ConfigurationUtils.java    | 99 +++++++++++++++++-----
 3 files changed, 102 insertions(+), 23 deletions(-)

diff --git a/base/ca/shared/conf/acl.ldif b/base/ca/shared/conf/acl.ldif
index 7321792167315ccc79fe5e56b9c3afb32c7f480e..d5385e8e2332a29c56943a87f565fd553fbc879c 100644
--- a/base/ca/shared/conf/acl.ldif
+++ b/base/ca/shared/conf/acl.ldif
@@ -6,7 +6,7 @@ resourceACLS: certServer.general.configuration:read,modify,delete:allow (read) g
 resourceACLS: certServer.policy.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents and auditors are allowed to read policy configuration but only administrators allowed to modify
 resourceACLS: certServer.acl.configuration:read,modify:allow (read) group="Administrators" || group="Certificate Manager Agents" || group="Registration Manager Agents" || group="Auditors";allow (modify) group="Administrators":Administrators, agents and auditors are allowed to read ACL configuration but only administrators allowed to modify
 resourceACLS: certServer.log.configuration:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";allow (modify) group="Administrators":Administrators, Agents, and auditors are allowed to read the log configuration but only administrators are allowed to modify
-resourceACLS: certServer.securitydomain.domainxml:read,modify:allow (read) user="anybody";allow (modify) group="Subsystem Group":Anybody is allowed to read domain.xml but only Subsystem group is allowed to modify the domain.xml
+resourceACLS: certServer.securitydomain.domainxml:read,modify:allow (read) user="anybody";allow (modify) group="Subsystem Group" || group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise RA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Anybody is allowed to read domain.xml but only Subsystem group and Enterprise Administrators are allowed to modify the domain.xml
 resourceACLS: certServer.log.configuration.fileName:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents" ;deny (modify) user=anybody:Nobody is allowed to modify a fileName parameter
 #resourceACLS: certServer.log.configuration.signedAudit.expirationTime:read,modify:allow (read) group="Administrators" || group="Auditors" || group="Certificate Manager Agents" || group="Registration Manager Agents";deny (modify) user=anybody:Nobody is allowed to modify an expirationTime parameter.
 resourceACLS: certServer.log.content.signedAudit:read:allow (read) group="Auditors":Only auditor is allowed to read the signed audit log
diff --git a/base/ca/shared/webapps/ca/WEB-INF/web.xml b/base/ca/shared/webapps/ca/WEB-INF/web.xml
index b922b3d9896ebbae3bb93a8dfb34a660111e452c..7528c310dc228a984343a52950cd8339030fefec 100644
--- a/base/ca/shared/webapps/ca/WEB-INF/web.xml
+++ b/base/ca/shared/webapps/ca/WEB-INF/web.xml
@@ -192,6 +192,25 @@
    </servlet>
 
    <servlet>
+      <servlet-name>  caUpdateDomainXML-admin  </servlet-name>
+      <servlet-class> com.netscape.cms.servlet.csadmin.UpdateDomainXML  </servlet-class>
+             <init-param><param-name>  GetClientCert  </param-name>
+                         <param-value> false       </param-value> </init-param>
+             <init-param><param-name>  authority   </param-name>
+                         <param-value> ca          </param-value> </init-param>
+             <init-param><param-name>  ID          </param-name>
+                         <param-value> caUpdateDomainXML </param-value> </init-param>
+             <init-param><param-name>  interface   </param-name>
+                         <param-value> admin          </param-value> </init-param>
+             <init-param><param-name>  AuthMgr     </param-name>
+                         <param-value> TokenAuth </param-value> </init-param>
+             <init-param><param-name>  AuthzMgr    </param-name>
+                         <param-value> BasicAclAuthz </param-value> </init-param>
+             <init-param><param-name>  resourceID  </param-name>
+                         <param-value> certServer.securitydomain.domainxml </param-value> </init-param>
+   </servlet>
+
+   <servlet>
       <servlet-name>  caUpdateNumberRange  </servlet-name>
       <servlet-class> com.netscape.cms.servlet.csadmin.UpdateNumberRange  </servlet-class>
              <init-param><param-name>  GetClientCert  </param-name>
@@ -1882,6 +1901,11 @@
       <url-pattern>   /agent/ca/updateDomainXML  </url-pattern>
    </servlet-mapping>
 
+   <servlet-mapping>
+      <servlet-name>  caUpdateDomainXML-admin </servlet-name>
+      <url-pattern>   /admin/ca/updateDomainXML  </url-pattern>
+   </servlet-mapping>
+
    <servlet-mapping>     
       <servlet-name>  caUpdateNumberRange </servlet-name>
       <url-pattern>   /admin/ca/updateNumberRange  </url-pattern>
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 782e0ec08af24b69a065f9a014c8cc955fe03313..917b6b52ba8ec2f27cb7be6de67aa7fee28a88c4 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -639,18 +639,23 @@ public class ConfigurationUtils {
         CMS.debug("updateNumberRange start host=" + hostname + " adminPort=" + adminPort + " eePort=" + eePort);
         IConfigStore cs = CMS.getConfigStore();
 
-        String cstype = "";
-        cstype = cs.getString("cs.type", "");
+        String cstype = cs.getString("cs.type", "");
         cstype = cstype.toLowerCase();
 
         String serverPath = "/" + cstype + "/admin/" + cstype + "/updateNumberRange";
         String c = null;
+        XMLObject parser = null;
         try {
             c = getHttpResponse(hostname, adminPort, https, serverPath, content, null, null);
             if (c == null || c.equals("")) {
                 CMS.debug("updateNumberRange: content is null.");
                 throw new IOException("The server you want to contact is not available");
             }
+
+            CMS.debug("content from admin interface ="+ c);
+            // when the admin servlet is unavailable, we return a badly formatted error page
+            // in that case, this will throw an exception and be passed into the catch block.
+            parser = new XMLObject(new ByteArrayInputStream(c.getBytes()));
         } catch (Exception e) {
             // for backward compatibility, try the old ee interface too
             CMS.debug("updateNumberRange: Failed to contact master using admin port" + e);
@@ -661,12 +666,10 @@ public class ConfigurationUtils {
                 CMS.debug("updateNumberRange: content is null.");
                 throw new IOException("The server you want to contact is not available");
             }
+            CMS.debug("content from ee interface =" + c);
+            parser = new XMLObject(new ByteArrayInputStream(c.getBytes()));
         }
 
-        CMS.debug("content=" + c);
-        ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
-        XMLObject parser = null;
-        parser = new XMLObject(bis);
         String status = parser.getValue("Status");
 
         CMS.debug("updateNumberRange(): status=" + status);
@@ -946,10 +949,18 @@ public class ConfigurationUtils {
         // delete all existing certificates first
         deleteExistingCerts();
 
+        ArrayList<String> masterList = getMasterCertKeyList();
+
         for (int i = 0; i < pkeyinfo_collection.size(); i++) {
             Vector<Object> pkeyinfo_v = pkeyinfo_collection.elementAt(i);
             PrivateKeyInfo pkeyinfo = (PrivateKeyInfo) pkeyinfo_v.elementAt(0);
             String nickname = (String) pkeyinfo_v.elementAt(1);
+            if (! masterList.contains(nickname)) {
+                // TODO - fix this to only import the keys that we need.
+                CMS.debug("Ignoring " + nickname);
+                // only import the master's system keys
+            //    continue;
+            }
             byte[] x509cert = getX509Cert(nickname, cert_collection);
             X509Certificate cert = cm.importCACertPackage(x509cert);
             ByteArrayOutputStream bos = new ByteArrayOutputStream();
@@ -986,6 +997,11 @@ public class ConfigurationUtils {
             byte[] cert = (byte[]) cert_v.elementAt(0);
             if (cert_v.size() > 1) {
                 String name = (String) cert_v.elementAt(1);
+                if (! masterList.contains(name)) {
+                    CMS.debug("Not importing " + name);
+                    // only import the master's system certs
+                    continue;
+                }
                 // we need to delete the trusted CA certificate if it is
                 // the same as the ca signing certificate
                 if (isCASigningCert(name)) {
@@ -1098,6 +1114,26 @@ public class ConfigurationUtils {
         }
     }
 
+    public static ArrayList<String> getMasterCertKeyList() throws EBaseException {
+        ArrayList<String> list = new ArrayList<String>();
+        IConfigStore cs = CMS.getConfigStore();
+        String certList = cs.getString("preop.cert.list", "");
+        StringTokenizer st = new StringTokenizer(certList, ",");
+        while (st.hasMoreTokens()) {
+            String s = st.nextToken();
+            if (s.equals("sslserver"))
+                    continue;
+            String name = "preop.master." + s + ".nickname";
+            String nickname = cs.getString(name);
+            list.add(nickname);
+
+            name = "preop.cert." + s + ".dn";
+            String dn = cs.getString(name);
+            list.add(dn);
+        }
+        return list;
+    }
+
     public static byte[] getX509Cert(String nickname, Vector<Vector<Object>> cert_collection)
             throws CertificateException {
         for (int i = 0; i < cert_collection.size(); i++) {
@@ -3249,9 +3285,8 @@ public class ConfigurationUtils {
         String eecaStr = (CMS.getEEClientAuthSSLPort() != null) ? "&eeclientauthsport=" + CMS.getEEClientAuthSSLPort()
                 : "";
 
-        updateDomainXML(sd_host, sd_agent_port, true,
-                "/ca/agent/ca/updateDomainXML",
-                "list=" + type + "List"
+        String url =  "/ca/admin/ca/updateDomainXML";
+        String content = "list=" + type + "List"
                 + "&type=" + type
                 + "&host=" + CMS.getEESSLHost()
                 + "&name=" + subsystemName
@@ -3261,7 +3296,19 @@ public class ConfigurationUtils {
                 + "&agentsport=" + CMS.getAgentPort()
                 + "&adminsport=" + CMS.getAdminPort()
                 + eecaStr
-                + "&httpport=" + CMS.getEENonSSLPort());
+                + "&httpport=" + CMS.getEENonSSLPort();
+
+        try {
+            String session_id = CMS.getConfigSDSessionId();
+            content += "&sessionID="+ session_id;
+            updateDomainXML(sd_host, sd_admin_port, true, url, content, false);
+        } catch (Exception e) {
+            CMS.debug("updateSecurityDomain: failed to update security domain using admin port "
+                      + sd_admin_port + ": " + e);
+            CMS.debug("updateSecurityDomain: now trying agent port with client auth");
+            url =  "/ca/agent/ca/updateDomainXML";
+            updateDomainXML(sd_host, sd_agent_port, true, url, content, true);
+        }
 
         // Fetch the "updated" security domain and display it
         CMS.debug("updateSecurityDomain(): Dump contents of updated Security Domain . . .");
@@ -3300,21 +3347,27 @@ public class ConfigurationUtils {
     }
 
     public static void updateDomainXML(String hostname, int port, boolean https,
-            String servlet, String uri) throws IOException, EBaseException, SAXException, ParserConfigurationException {
+            String servlet, String uri, boolean useClientAuth) throws IOException, EBaseException, SAXException,
+            ParserConfigurationException {
         CMS.debug("WizardPanelBase updateDomainXML start hostname=" + hostname + " port=" + port);
-        IConfigStore cs = CMS.getConfigStore();
-        String nickname = cs.getString("preop.cert.subsystem.nickname", "");
-        String tokenname = cs.getString("preop.module.token", "");
+        String c = null;
+        if (useClientAuth) {
+            IConfigStore cs = CMS.getConfigStore();
+            String nickname = cs.getString("preop.cert.subsystem.nickname", "");
+            String tokenname = cs.getString("preop.module.token", "");
 
-        if (!tokenname.equals("") &&
-                !tokenname.equals("Internal Key Storage Token") &&
-                !tokenname.equals("internal")) {
-            nickname = tokenname + ":" + nickname;
+            if (!tokenname.equals("") &&
+                    !tokenname.equals("Internal Key Storage Token") &&
+                    !tokenname.equals("internal")) {
+                nickname = tokenname + ":" + nickname;
+            }
+            CMS.debug("updateDomainXML() nickname=" + nickname);
+
+            c = getHttpResponse(hostname, port, https, servlet, uri, nickname, null);
+        } else {
+            c = getHttpResponse(hostname, port, https, servlet, uri, null, null);
         }
-        CMS.debug("updateDomainXML() nickname=" + nickname);
-
-        String c = getHttpResponse(hostname, port, https, servlet, uri, nickname, null);
-        if (c != null) {
+        if (c != null && !c.equals("")) {
             ByteArrayInputStream bis = new ByteArrayInputStream(c.getBytes());
             XMLObject obj = new XMLObject(bis);
             String status = obj.getValue("Status");
@@ -3326,6 +3379,8 @@ public class ConfigurationUtils {
                 String error = obj.getValue("Error");
                 throw new IOException(error);
             }
+        } else {
+            throw new IOException("Failed to get response when updating security domain");
         }
     }
 
-- 
1.7.11.7

