Blob Blame History Raw
commit eb44234b5fba6c0047577529d3bd6fdb7c338fe1
Author: Endi S. Dewata <edewata@redhat.com>
Date:   Mon Sep 28 22:37:02 2015 +0200

    Refactored certificate processors.
    
    The CertProcessor.setCredentialsIntoContext() and CAProcessor.
    authenticate() methods have been modified such that they can
    accept credentials provided via the AuthCredentials (for REST
    services) or via the HttpServletRequest (for legacy servlets).
    
    The CertEnrollmentRequest has been modified to inherit from
    ResourceMessage such that REST clients can provide the credentials
    via request attributes.
    
    https://fedorahosted.org/pki/ticket/1463
    (cherry picked from commit 6c5fc90ffedcd7be17a2d014915f8e908e2488d5)

diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
index 95f1f4c..3c1e50b 100644
--- a/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
+++ b/base/ca/src/org/dogtagpki/server/ca/rest/CertRequestService.java
@@ -138,6 +138,7 @@ public class CertRequestService extends PKIService implements CertRequestResourc
             CMS.debug("enrollCert: bad request data: " + e);
             throw new BadRequestException(e.toString());
         } catch (EBaseException e) {
+            CMS.debug(e);
             throw new PKIException(e);
         } catch (Exception e) {
             CMS.debug(e);
diff --git a/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java b/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java
index d55b5b4..2b914e8 100644
--- a/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java
+++ b/base/common/src/com/netscape/certsrv/cert/CertEnrollmentRequest.java
@@ -37,6 +37,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import com.netscape.certsrv.base.ResourceMessage;
 import com.netscape.certsrv.profile.ProfileAttribute;
 import com.netscape.certsrv.profile.ProfileInput;
 import com.netscape.certsrv.profile.ProfileOutput;
@@ -48,7 +49,7 @@ import com.netscape.certsrv.profile.ProfileOutput;
 
 @XmlRootElement(name = "CertEnrollmentRequest")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class CertEnrollmentRequest {
+public class CertEnrollmentRequest extends ResourceMessage {
 
     private static final String PROFILE_ID = "profileId";
     private static final String RENEWAL = "renewal";
@@ -286,7 +287,7 @@ public class CertEnrollmentRequest {
     @Override
     public int hashCode() {
         final int prime = 31;
-        int result = 1;
+        int result = super.hashCode();
         result = prime * result + ((inputs == null) ? 0 : inputs.hashCode());
         result = prime * result + ((outputs == null) ? 0 : outputs.hashCode());
         result = prime * result + ((profileId == null) ? 0 : profileId.hashCode());
@@ -301,7 +302,7 @@ public class CertEnrollmentRequest {
     public boolean equals(Object obj) {
         if (this == obj)
             return true;
-        if (obj == null)
+        if (!super.equals(obj))
             return false;
         if (getClass() != obj.getClass())
             return false;
@@ -346,8 +347,6 @@ public class CertEnrollmentRequest {
         before.setProfileId("caUserCert");
         before.setRenewal(false);
 
-        //Simulate a "caUserCert" Profile enrollment
-
         ProfileInput certReq = before.createInput("KeyGenInput");
         certReq.addAttribute(new ProfileAttribute("cert_request_type", "crmf", null));
         certReq.addAttribute(new ProfileAttribute(
@@ -371,6 +370,9 @@ public class CertEnrollmentRequest {
         submitter.addAttribute(new ProfileAttribute("requestor_email", "admin@redhat.com", null));
         submitter.addAttribute(new ProfileAttribute("requestor_phone", "650-555-5555", null));
 
+        before.setAttribute("uid", "testuser");
+        before.setAttribute("pwd", "password");
+
         String xml = before.toXML();
         System.out.println(xml);
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
index f1a147e..e5daf78 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertProcessor.java
@@ -42,6 +42,7 @@ import com.netscape.certsrv.profile.ProfileInput;
 import com.netscape.certsrv.request.INotify;
 import com.netscape.certsrv.request.IRequest;
 import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.common.AuthCredentials;
 import com.netscape.cms.servlet.processors.CAProcessor;
 import com.netscape.cmsutil.ldap.LDAPUtil;
 
@@ -51,26 +52,31 @@ public class CertProcessor extends CAProcessor {
         super(id, locale);
     }
 
-    protected void setCredentialsIntoContext(HttpServletRequest request, IProfileAuthenticator authenticator,
+    protected void setCredentialsIntoContext(
+            HttpServletRequest request,
+            AuthCredentials creds,
+            IProfileAuthenticator authenticator,
             IProfileContext ctx) {
-        Enumeration<String> authIds = authenticator.getValueNames();
-
-        if (authIds != null) {
-            CMS.debug("CertRequestSubmitter:setCredentialsIntoContext() authNames not null");
-            while (authIds.hasMoreElements()) {
-                String authName = authIds.nextElement();
-
-                CMS.debug("CertRequestSubmitter:setCredentialsIntoContext() authName:" +
-                        authName);
-                if (request.getParameter(authName) != null) {
-                    CMS.debug("CertRequestSubmitter:setCredentialsIntoContext() authName found in request");
-                    ctx.set(authName, request.getParameter(authName));
-                } else {
-                    CMS.debug("CertRequestSubmitter:setCredentialsIntoContext() authName not found in request");
-                }
+
+        Enumeration<String> names = authenticator.getValueNames();
+        if (names == null) {
+            CMS.debug("CertProcessor: No authenticator credentials required");
+            return;
+        }
+
+        CMS.debug("CertProcessor: Authentication credentials:");
+        while (names.hasMoreElements()) {
+            String name = names.nextElement();
+
+            Object value;
+            if (creds == null) {
+                value = request.getParameter(name);
+            } else {
+                value = creds.get(name);
             }
-        } else {
-            CMS.debug("CertRequestSubmitter:setCredentialsIntoContext() authIds` null");
+
+            if (value == null) continue;
+            ctx.set(name, value.toString());
         }
     }
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java
index c94ee14..be6d22c 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/CertRequestDAO.java
@@ -43,6 +43,7 @@ import com.netscape.certsrv.request.IRequest;
 import com.netscape.certsrv.request.IRequestQueue;
 import com.netscape.certsrv.request.RequestId;
 import com.netscape.certsrv.request.RequestNotFoundException;
+import com.netscape.cms.servlet.common.AuthCredentials;
 import com.netscape.cms.servlet.processors.CAProcessor;
 import com.netscape.cms.servlet.request.CMSRequestDAO;
 
@@ -169,13 +170,23 @@ public class CertRequestDAO extends CMSRequestDAO {
 
         CertRequestInfos ret = new CertRequestInfos();
 
+        AuthCredentials credentials = new AuthCredentials();
+        String uid = data.getAttribute("uid");
+        if (uid != null) {
+            credentials.set("uid", uid);
+        }
+        String password = data.getAttribute("pwd");
+        if (password != null) {
+            credentials.set("pwd", password);
+        }
+
         HashMap<String, Object> results = null;
         if (data.isRenewal()) {
             RenewalProcessor processor = new RenewalProcessor("caProfileSubmit", locale);
-            results = processor.processRenewal(data, request);
+            results = processor.processRenewal(data, request, credentials);
         } else {
             EnrollmentProcessor processor = new EnrollmentProcessor("caProfileSubmit", locale);
-            results = processor.processEnrollment(data, request);
+            results = processor.processEnrollment(data, request, credentials);
         }
 
         IRequest reqs[] = (IRequest[]) results.get(CAProcessor.ARG_REQUESTS);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
index ce57e1f..eac4359 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
@@ -37,6 +37,7 @@ import com.netscape.certsrv.profile.IProfileInput;
 import com.netscape.certsrv.profile.ProfileAttribute;
 import com.netscape.certsrv.profile.ProfileInput;
 import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.common.AuthCredentials;
 import com.netscape.cms.servlet.common.CMSTemplate;
 import com.netscape.cms.servlet.profile.SSLClientCertProvider;
 import com.netscape.cmsutil.ldap.LDAPUtil;
@@ -97,8 +98,11 @@ public class EnrollmentProcessor extends CertProcessor {
      * @param cmsReq the object holding the request and response information
      * @exception EBaseException an error has occurred
      */
-    public HashMap<String, Object> processEnrollment(CertEnrollmentRequest data, HttpServletRequest request)
-            throws EBaseException {
+    public HashMap<String, Object> processEnrollment(
+            CertEnrollmentRequest data,
+            HttpServletRequest request,
+            AuthCredentials credentials)
+        throws EBaseException {
 
         try {
             if (CMS.debugOn()) {
@@ -131,7 +135,7 @@ public class EnrollmentProcessor extends CertProcessor {
             IProfileAuthenticator authenticator = profile.getAuthenticator();
             if (authenticator != null) {
                 CMS.debug("EnrollmentProcessor: authenticator " + authenticator.getName() + " found");
-                setCredentialsIntoContext(request, authenticator, ctx);
+                setCredentialsIntoContext(request, credentials, authenticator, ctx);
             }
 
             // for ssl authentication; pass in servlet for retrieving ssl client certificates
@@ -142,7 +146,7 @@ public class EnrollmentProcessor extends CertProcessor {
             CMS.debug("EnrollmentProcessor: set sslClientCertProvider");
 
             // before creating the request, authenticate the request
-            IAuthToken authToken = authenticate(request, null, authenticator, context, false);
+            IAuthToken authToken = authenticate(request, null, authenticator, context, false, credentials);
 
             // authentication success, now authorize
             authorize(profileId, profile, authToken);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
index 5ebbbff..7e34e4d 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
@@ -42,6 +42,7 @@ import com.netscape.certsrv.profile.IProfileAuthenticator;
 import com.netscape.certsrv.profile.IProfileContext;
 import com.netscape.certsrv.profile.IProfileInput;
 import com.netscape.certsrv.request.IRequest;
+import com.netscape.cms.servlet.common.AuthCredentials;
 import com.netscape.cms.servlet.common.CMSTemplate;
 import com.netscape.cms.servlet.profile.SSLClientCertProvider;
 
@@ -63,7 +64,10 @@ public class RenewalProcessor extends CertProcessor {
      * Things to note:
      * * the renew request will contain the original profile instead of the new
      */
-    public HashMap<String, Object> processRenewal(CertEnrollmentRequest data, HttpServletRequest request)
+    public HashMap<String, Object> processRenewal(
+            CertEnrollmentRequest data,
+            HttpServletRequest request,
+            AuthCredentials credentials)
             throws EBaseException {
         try {
             if (CMS.debugOn()) {
@@ -170,14 +174,14 @@ public class RenewalProcessor extends CertProcessor {
 
             if (authenticator != null) {
                 CMS.debug("RenewalSubmitter: authenticator " + authenticator.getName() + " found");
-                setCredentialsIntoContext(request, authenticator, ctx);
+                setCredentialsIntoContext(request, credentials, authenticator, ctx);
             }
 
             // for renewal, this will override or add auth info to the profile context
             if (origAuthenticator != null) {
                 CMS.debug("RenewalSubmitter: for renewal, original authenticator " +
                         origAuthenticator.getName() + " found");
-                setCredentialsIntoContext(request, origAuthenticator, ctx);
+                setCredentialsIntoContext(request, credentials, origAuthenticator, ctx);
             }
 
             // for renewal, input needs to be retrieved from the orig req record
@@ -197,7 +201,7 @@ public class RenewalProcessor extends CertProcessor {
                 context.put("origSubjectDN", origSubjectDN);
 
             // before creating the request, authenticate the request
-            IAuthToken authToken = authenticate(request, origReq, authenticator, context, true);
+            IAuthToken authToken = authenticate(request, origReq, authenticator, context, true, credentials);
 
             // authentication success, now authorize
             authorize(profileId, renewProfile, authToken);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/common/AuthCredentials.java b/base/server/cms/src/com/netscape/cms/servlet/common/AuthCredentials.java
index 32ae0fc..b4d5fa9 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/common/AuthCredentials.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/common/AuthCredentials.java
@@ -54,7 +54,7 @@ public class AuthCredentials implements IAuthCredentials {
      */
     public void set(String name, Object cred) throws EAuthException {
         if (cred == null) {
-            throw new EAuthException("AuthCredentials.set()");
+            throw new EAuthException("Missing credential: " + name);
         }
 
         authCreds.put(name, cred);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java b/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java
index 5f6f45c..e3b3d34 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/processors/CAProcessor.java
@@ -36,6 +36,7 @@ import javax.servlet.http.HttpServletRequest;
 
 import com.netscape.certsrv.apps.CMS;
 import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.EAuthException;
 import com.netscape.certsrv.authentication.IAuthToken;
 import com.netscape.certsrv.authorization.AuthzToken;
 import com.netscape.certsrv.authorization.IAuthzSubsystem;
@@ -358,10 +359,14 @@ public class CAProcessor extends Processor {
      *   authenticate for renewal - more to add necessary params/values
      *   to the session context
      */
-    public IAuthToken authenticate(IProfileAuthenticator authenticator,
-            HttpServletRequest request, IRequest origReq, SessionContext context) throws EBaseException
+    public IAuthToken authenticate(
+            IProfileAuthenticator authenticator,
+            HttpServletRequest request,
+            IRequest origReq,
+            SessionContext context,
+            AuthCredentials credentials) throws EBaseException
     {
-        IAuthToken authToken = authenticate(authenticator, request);
+        IAuthToken authToken = authenticate(authenticator, request, credentials);
         // For renewal, fill in necessary params
         if (authToken != null) {
             String ouid = origReq.getExtDataInString("auth_token.uid");
@@ -417,18 +422,23 @@ public class CAProcessor extends Processor {
         return authToken;
     }
 
-    public IAuthToken authenticate(IProfileAuthenticator authenticator,
-            HttpServletRequest request) throws EBaseException {
-        AuthCredentials credentials = new AuthCredentials();
+    public IAuthToken authenticate(
+            IProfileAuthenticator authenticator,
+            HttpServletRequest request,
+            AuthCredentials credentials) throws EBaseException {
 
-        // build credential
-        Enumeration<String> authNames = authenticator.getValueNames();
+        if (credentials == null) {
+            credentials = new AuthCredentials();
 
-        if (authNames != null) {
-            while (authNames.hasMoreElements()) {
-                String authName = authNames.nextElement();
+            // build credential
+            Enumeration<String> authNames = authenticator.getValueNames();
 
-                credentials.set(authName, request.getParameter(authName));
+            if (authNames != null) {
+                while (authNames.hasMoreElements()) {
+                    String authName = authNames.nextElement();
+
+                    credentials.set(authName, request.getParameter(authName));
+                }
             }
         }
 
@@ -447,8 +457,13 @@ public class CAProcessor extends Processor {
         return authToken;
     }
 
-    public IAuthToken authenticate(HttpServletRequest request, IRequest origReq, IProfileAuthenticator authenticator,
-            SessionContext context, boolean isRenewal) throws EBaseException {
+    public IAuthToken authenticate(
+            HttpServletRequest request,
+            IRequest origReq,
+            IProfileAuthenticator authenticator,
+            SessionContext context,
+            boolean isRenewal,
+            AuthCredentials credentials) throws EBaseException {
         startTiming("profile_authentication");
 
         IAuthToken authToken = null;
@@ -475,12 +490,27 @@ public class CAProcessor extends Processor {
             String auditMessage = null;
             try {
                 if (isRenewal) {
-                    authToken = authenticate(authenticator, request, origReq, context);
+                    authToken = authenticate(authenticator, request, origReq, context, credentials);
                 } else {
-                    authToken = authenticate(authenticator, request);
+                    authToken = authenticate(authenticator, request, credentials);
                 }
+
+            } catch (EAuthException e) {
+                CMS.debug("CAProcessor: authentication error: " + e);
+
+                authSubjectID += " : " + uid_cred;
+                auditMessage = CMS.getLogMessage(
+                        LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+                        authSubjectID,
+                        ILogger.FAILURE,
+                        authMgrID,
+                        uid_attempted_cred);
+                audit(auditMessage);
+
+                throw e;
+
             } catch (EBaseException e) {
-                CMS.debug("CertProcessor: authentication error " + e.toString());
+                CMS.debug(e);
 
                 authSubjectID += " : " + uid_cred;
                 auditMessage = CMS.getLogMessage(
diff --git a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
index b64819e..69b9d9c 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/profile/ProfileSubmitServlet.java
@@ -221,7 +221,7 @@ public class ProfileSubmitServlet extends ProfileServlet {
         }
 
         CertEnrollmentRequest data = CertEnrollmentRequestFactory.create(cmsReq, profile, locale);
-        return processor.processEnrollment(data, request);
+        return processor.processEnrollment(data, request, null);
     }
 
     public HashMap<String, Object> processRenewal(CMSRequest cmsReq) throws EBaseException {
@@ -248,7 +248,7 @@ public class ProfileSubmitServlet extends ProfileServlet {
         //only used in renewal
         data.setSerialNum(request.getParameter("serial_num"));
 
-        return processor.processRenewal(data, request);
+        return processor.processRenewal(data, request, null);
     }
 
     private void setOutputIntoArgs(IProfile profile, ArgList outputlist, Locale locale, IRequest req) {
diff --git a/base/server/cmscore/src/com/netscape/cmscore/authentication/AuthSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/authentication/AuthSubsystem.java
index 137edb5..8e2c59c 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/authentication/AuthSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/authentication/AuthSubsystem.java
@@ -195,6 +195,8 @@ public class AuthSubsystem implements IAuthSubsystem {
 
             while (instances.hasMoreElements()) {
                 String insName = instances.nextElement();
+                CMS.debug("AuthSubsystem: initializing authentication manager " + insName);
+
                 String implName = c.getString(insName + "." + PROP_PLUGIN);
                 AuthMgrPlugin plugin =
                         mAuthMgrPlugins.get(implName);
@@ -233,6 +235,7 @@ public class AuthSubsystem implements IAuthSubsystem {
                     throw new EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className), e);
 
                 } catch (EBaseException e) {
+                    CMS.debug(e);
                     log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTH_INIT_ERROR", insName, e.toString()));
                     // Skip the authenticaiton instance if
                     // it is mis-configurated. This give
@@ -240,6 +243,7 @@ public class AuthSubsystem implements IAuthSubsystem {
                     // fix the problem via console
 
                 } catch (Throwable e) {
+                    CMS.debug(e);
                     log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTH_INIT_ERROR", insName, e.toString()));
                     // Skip the authenticaiton instance if
                     // it is mis-configurated. This give