summaryrefslogtreecommitdiffstats
path: root/base/common/src/com/netscape/cms/servlet/cert
diff options
context:
space:
mode:
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet/cert')
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/CertProcessor.java351
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java205
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/RenewalProcessor.java345
-rw-r--r--base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java475
4 files changed, 1376 insertions, 0 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/cert/CertProcessor.java b/base/common/src/com/netscape/cms/servlet/cert/CertProcessor.java
new file mode 100644
index 000000000..13b0072b4
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/CertProcessor.java
@@ -0,0 +1,351 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.cert;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EDeferException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.servlet.processors.Processor;
+import com.netscape.cms.servlet.profile.model.ProfileInput;
+import com.netscape.cms.servlet.request.model.EnrollmentRequestData;
+
+public class CertProcessor extends Processor {
+
+ public CertProcessor(String id, Locale locale) throws EPropertyNotFound, EBaseException {
+ super(id, locale);
+ }
+
+ protected void setCredentialsIntoContext(HttpServletRequest request, 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");
+ }
+ }
+ } else {
+ CMS.debug("CertRequestSubmitter:setCredentialsIntoContext() authIds` null");
+ }
+ }
+
+ private void setInputsIntoRequest(EnrollmentRequestData data, IProfile profile, IRequest req) {
+ // put profile inputs into a local map
+ HashMap<String, String> dataInputs = new HashMap<String, String>();
+ for (ProfileInput input : data.getInputs()) {
+ Map<String, String> attrs = input.getAttributes();
+ for (Map.Entry<String, String> entry : attrs.entrySet()) {
+ dataInputs.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ // iterate over inputs in profile
+ Enumeration<String> inputIds = profile.getProfileInputIds();
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> inputNames = profileInput.getValueNames();
+
+ if (inputNames != null) {
+ while (inputNames.hasMoreElements()) {
+ String inputName = inputNames.nextElement();
+ if (dataInputs.containsKey(inputName)) {
+ // special characters in subject names parameters must be escaped
+ if (inputName.matches("^sn_.*")) {
+ req.setExtData(inputName,
+ escapeValueRfc1779(dataInputs.get(inputName), false)
+ .toString());
+ } else {
+ req.setExtData(inputName, dataInputs.get(inputName));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * fill input info from orig request to the renew request.
+ * This is expected to be used by renewal where the request
+ * is retrieved from request record
+ */
+ private void setInputsIntoRequest(IRequest request, IProfile profile, IRequest req, Locale locale) {
+ // passing inputs into request
+ Enumeration<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> inputNames = profileInput.getValueNames();
+
+ while (inputNames.hasMoreElements()) {
+ String inputName = inputNames.nextElement();
+ String inputValue = "";
+ CMS.debug("CertRequestSubmitter: setInputsIntoRequest() getting input name= " + inputName);
+ try {
+ inputValue = profileInput.getValue(inputName, locale, request);
+ } catch (Exception e) {
+ CMS.debug("CertRequestSubmitter: setInputsIntoRequest() getvalue() failed: " + e.toString());
+ }
+
+ if (inputValue != null) {
+ CMS.debug("CertRequestSubmitter: setInputsIntoRequest() setting value in ctx:" + inputValue);
+ req.setExtData(inputName, inputValue);
+ } else {
+ CMS.debug("CertRequestSubmitter: setInputsIntoRequest() value null");
+ }
+ }
+ }
+ }
+
+ }
+
+ protected String codeToReason(Locale locale, String errorCode) {
+ if (errorCode == null) return null;
+ if (errorCode.equals("1")) {
+ return CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR");
+ } else if (errorCode.equals("2")) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_DEFERRED");
+ } else if (errorCode.equals("3")) {
+ return CMS.getUserMessage(locale, "CMS_PROFILE_REJECTED");
+ }
+ return null;
+ }
+
+ protected String submitRequests(Locale locale, IProfile profile, IAuthToken authToken, IRequest[] reqs) {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = ILogger.UNIDENTIFIED;
+ String auditInfoCertValue = ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ String errorCode = null;
+ String errorReason = null;
+
+ for (IRequest req : reqs) {
+ try {
+ // reset the "auditRequesterID"
+ auditRequesterID = auditRequesterID(req);
+
+ // print request debug
+ if (req != null) {
+ Enumeration<String> reqKeys = req.getExtDataKeys();
+ while (reqKeys.hasMoreElements()) {
+ String reqKey = reqKeys.nextElement();
+ String reqVal = req.getExtDataInString(reqKey);
+ if (reqVal != null) {
+ CMS.debug("CertRequestSubmitter: key=$request." + reqKey + "$ value=" + reqVal);
+ }
+ }
+ }
+
+ profile.submit(authToken, req);
+ req.setRequestStatus(RequestStatus.COMPLETE);
+
+ // reset the "auditInfoCertValue"
+ auditInfoCertValue = auditInfoCertValue(req);
+
+ if (auditInfoCertValue != null) {
+ if (!(auditInfoCertValue.equals(
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE))) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue);
+
+ audit(auditMessage);
+ }
+ }
+ } catch (EDeferException e) {
+ // return defer message to the user
+ req.setRequestStatus(RequestStatus.PENDING);
+ // need to notify
+ INotify notify = profile.getRequestQueue().getPendingNotify();
+ if (notify != null) {
+ notify.notify(req);
+ }
+
+ CMS.debug("CertRequestSubmitter: submit " + e.toString());
+ errorCode = "2";
+ errorReason = CMS.getUserMessage(locale, "CMS_PROFILE_DEFERRED", e.toString());
+
+ // do NOT store a message in the signed audit log file
+ // as this errorCode indicates that a process has been
+ // deferred for manual acceptance/cancellation/rejection
+ } catch (ERejectException e) {
+ // return error to the user
+ req.setRequestStatus(RequestStatus.REJECTED);
+ CMS.debug("CertRequestSubmitter: submit " + e.toString());
+ errorCode = "3";
+ errorReason = CMS.getUserMessage(locale, "CMS_PROFILE_REJECTED", e.toString());
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ errorReason);
+
+ audit(auditMessage);
+ } catch (Throwable e) {
+ // return error to the user
+ e.printStackTrace();
+ CMS.debug("CertRequestSubmitter: submit " + e.toString());
+ errorCode = "1";
+ errorReason = CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR");
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ errorReason);
+
+ audit(auditMessage);
+ }
+
+ try {
+ if (errorCode == null) {
+ profile.getRequestQueue().markAsServiced(req);
+ } else {
+ profile.getRequestQueue().updateRequest(req);
+ }
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ CMS.debug("CertRequestSubmitter: updateRequest " + e.toString());
+ }
+ }
+ return errorCode;
+ }
+
+ protected void populateRequests(EnrollmentRequestData data, boolean isRenewal,
+ Locale locale, Date origNotAfter, String origSubjectDN, IRequest origReq, String profileId,
+ IProfile profile, IProfileContext ctx, IProfileAuthenticator authenticator, IAuthToken authToken,
+ IRequest[] reqs) throws EBaseException {
+ for (IRequest req : reqs) {
+ boolean fromRA = false;
+ String uid = "";
+
+ // adding parameters to request
+ if (isRenewal) {
+ setInputsIntoRequest(origReq, profile, req, locale);
+ req.setExtData("origNotAfter", BigInteger.valueOf(origNotAfter.getTime()));
+ req.setExtData(IProfileAuthenticator.AUTHENTICATED_NAME, origSubjectDN);
+ req.setRequestType("renewal");
+ } else {
+ setInputsIntoRequest(data, profile, req);
+ }
+
+ // serial auth token into request
+ if (authToken != null) {
+ Enumeration<String> tokenNames = authToken.getElements();
+ while (tokenNames.hasMoreElements()) {
+ String tokenName = tokenNames.nextElement();
+ String[] tokenVals = authToken.getInStringArray(tokenName);
+ if (tokenVals != null) {
+ for (int i = 0; i < tokenVals.length; i++) {
+ req.setExtData(ARG_AUTH_TOKEN + "." + tokenName + "[" + i + "]", tokenVals[i]);
+ }
+ } else {
+ String tokenVal = authToken.getInString(tokenName);
+ if (tokenVal != null) {
+ req.setExtData(ARG_AUTH_TOKEN + "." + tokenName, tokenVal);
+ // if RA agent, auto assign the request
+ if (tokenName.equals("uid"))
+ uid = tokenVal;
+ if (tokenName.equals("group") && tokenVal.equals("Registration Manager Agents")) {
+ fromRA = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (fromRA) {
+ CMS.debug("CertRequestSubmitter: request from RA: " + uid);
+ req.setExtData(ARG_REQUEST_OWNER, uid);
+ }
+
+ // put profile framework parameters into the request
+ req.setExtData(ARG_PROFILE, "true");
+ req.setExtData(ARG_PROFILE_ID, profileId);
+ if (isRenewal)
+ req.setExtData(ARG_RENEWAL_PROFILE_ID, data.getProfileId());
+ req.setExtData(ARG_PROFILE_APPROVED_BY, profile.getApprovedBy());
+ String setId = profile.getPolicySetId(req);
+
+ if (setId == null) {
+ // no profile set found
+ CMS.debug("CertRequestSubmitter: no profile policy set found");
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_PROFILE_NO_POLICY_SET_FOUND"));
+ }
+
+ CMS.debug("CertRequestSubmitter profileSetid=" + setId);
+ req.setExtData(ARG_PROFILE_SET_ID, setId);
+ req.setExtData(ARG_PROFILE_REMOTE_HOST, data.getRemoteHost());
+ req.setExtData(ARG_PROFILE_REMOTE_ADDR, data.getRemoteAddr());
+
+ CMS.debug("CertRequestSubmitter: request " + req.getRequestId().toString());
+
+ CMS.debug("CertRequestSubmitter: populating request inputs");
+ // give authenticator a chance to populate the request
+ if (authenticator != null) {
+ authenticator.populate(authToken, req);
+ }
+ profile.populateInput(ctx, req);
+ profile.populate(req);
+ }
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java b/base/common/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
new file mode 100644
index 000000000..8b48f0d73
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/EnrollmentProcessor.java
@@ -0,0 +1,205 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.cert;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.BadRequestDataException;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.profile.IProfile;
+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.CMSRequest;
+import com.netscape.cms.servlet.profile.SSLClientCertProvider;
+import com.netscape.cms.servlet.profile.model.ProfileInput;
+import com.netscape.cms.servlet.request.model.EnrollmentRequestData;
+import com.netscape.cms.servlet.request.model.EnrollmentRequestDataFactory;
+
+public class EnrollmentProcessor extends CertProcessor {
+
+ public EnrollmentProcessor(String id, Locale locale) throws EPropertyNotFound, EBaseException {
+ super(id, locale);
+ }
+
+ private void setInputsIntoContext(EnrollmentRequestData data, IProfile profile, IProfileContext ctx) {
+ // put profile inputs into a local map
+ HashMap<String, String> dataInputs = new HashMap<String, String>();
+ for (ProfileInput input : data.getInputs()) {
+ Map<String, String> attrs = input.getAttributes();
+ for (Map.Entry<String, String> entry : attrs.entrySet()) {
+ dataInputs.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ // iterate through inputs in profile and put those in context
+ Enumeration<String> inputIds = profile.getProfileInputIds();
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> inputNames = profileInput.getValueNames();
+
+ while (inputNames.hasMoreElements()) {
+ String inputName = inputNames.nextElement();
+ if (dataInputs.containsKey(inputName)) {
+ // all subject name parameters start with sn_, no other input parameters do
+ if (inputName.matches("^sn_.*")) {
+ ctx.set(inputName, escapeValueRfc1779(dataInputs.get(inputName), false).toString());
+ } else {
+ ctx.set(inputName, dataInputs.get(inputName));
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Called by the legacy servlets to access the Processor function
+ * @param request
+ * @return
+ * @throws EBaseException
+ */
+ public HashMap<String, Object> processEnrollment(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ String profileId = (this.profileID == null) ? req.getParameter("profileId") : this.profileID;
+ IProfile profile = ps.getProfile(profileId);
+
+ if (profile == null) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ }
+
+ EnrollmentRequestData data = EnrollmentRequestDataFactory.create(cmsReq, profile, locale);
+ return processEnrollment(data, cmsReq.getHttpReq());
+ }
+
+ /**
+ * Process the HTTP request
+ * <P>
+ *
+ * (Certificate Request Processed - either an automated "EE" profile based cert acceptance, or an automated "EE"
+ * profile based cert rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>http.param profileId ID of profile to use to process request
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been
+ * through the approval process
+ * </ul>
+ *
+ * @param cmsReq the object holding the request and response information
+ * @exception EBaseException an error has occurred
+ */
+ public HashMap<String, Object> processEnrollment(EnrollmentRequestData data, HttpServletRequest request)
+ throws EBaseException {
+
+ try {
+ if (CMS.debugOn()) {
+ HashMap<String,String> params = data.toParams();
+ printParameterValues(params);
+ }
+
+ CMS.debug("EnrollmentSubmitter: isRenewal false");
+ startTiming("enrollment");
+
+ // if we did not configure profileId in xml file,
+ // then accept the user-provided one
+ String profileId = (this.profileID == null) ? data.getProfileId() : this.profileID;
+ CMS.debug("EnrollmentSubmitter: profileId " + profileId);
+
+ IProfile profile = ps.getProfile(profileId);
+ if (profile == null) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ }
+ if (!ps.isProfileEnable(profileId)) {
+ CMS.debug("EnrollmentSubmitter: Profile " + profileId + " not enabled");
+ throw new BadRequestDataException("Profile " + profileId + " not enabled");
+ }
+
+ IProfileContext ctx = profile.createContext();
+ CMS.debug("EnrollmentSubmitter: set Inputs into profile Context");
+ setInputsIntoContext(data, profile, ctx);
+
+ IProfileAuthenticator authenticator = profile.getAuthenticator();
+ if (authenticator != null) {
+ CMS.debug("EnrollmentSubmitter: authenticator " + authenticator.getName() + " found");
+ setCredentialsIntoContext(request, authenticator, ctx);
+ }
+
+ // for ssl authentication; pass in servlet for retrieving ssl client certificates
+ // insert profile context so that input parameter can be retrieved
+ SessionContext context = SessionContext.getContext();
+ context.put("profileContext", ctx);
+ context.put("sslClientCertProvider", new SSLClientCertProvider(request));
+ CMS.debug("EnrollmentSubmitter: set sslClientCertProvider");
+
+ // before creating the request, authenticate the request
+ IAuthToken authToken = authenticate(request, null, authenticator, context, false);
+
+ // authentication success, now authorize
+ authorize(profileId, profile, authToken);
+
+ ///////////////////////////////////////////////
+ // create and populate request
+ ///////////////////////////////////////////////
+ startTiming("request_population");
+ IRequest[] reqs = profile.createRequests(ctx, locale);
+ populateRequests(data, false, locale, null, null, null, profileId, profile,
+ ctx, authenticator, authToken, reqs);
+ endTiming("request_population");
+
+ ///////////////////////////////////////////////
+ // submit request
+ ///////////////////////////////////////////////
+ String errorCode = submitRequests(locale, profile, authToken, reqs);
+ String errorReason = codeToReason(locale, errorCode);
+
+ HashMap<String, Object> ret = new HashMap<String, Object>();
+ ret.put(ARG_REQUESTS, reqs);
+ ret.put(ARG_ERROR_CODE, errorCode);
+ ret.put(ARG_ERROR_REASON, errorReason);
+ ret.put(ARG_PROFILE, profile);
+
+ CMS.debug("EnrollmentSubmitter: done serving");
+ endTiming("enrollment");
+
+ return ret;
+ } finally {
+ SessionContext.releaseContext();
+ endAllEvents();
+ }
+ }
+
+
+
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/RenewalProcessor.java b/base/common/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
new file mode 100644
index 000000000..cc4dd12ae
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
@@ -0,0 +1,345 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.cert;
+
+import java.math.BigInteger;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.x509.BasicConstraintsExtension;
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.base.BadRequestDataException;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IProfile;
+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.CMSRequest;
+import com.netscape.cms.servlet.profile.SSLClientCertProvider;
+import com.netscape.cms.servlet.request.model.EnrollmentRequestData;
+import com.netscape.cms.servlet.request.model.EnrollmentRequestDataFactory;
+
+public class RenewalProcessor extends CertProcessor {
+
+ public RenewalProcessor(String id, Locale locale) throws EPropertyNotFound, EBaseException {
+ super(id, locale);
+ }
+
+ public HashMap<String, Object> processRenewal(CMSRequest cmsReq) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ String profileId = (this.profileID == null) ? req.getParameter("profileId") : this.profileID;
+ IProfile profile = ps.getProfile(profileId);
+ if (profile == null) {
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ }
+
+ EnrollmentRequestData data = EnrollmentRequestDataFactory.create(cmsReq, profile, locale);
+
+ //only used in renewal
+ data.setSerialNum(req.getParameter("serial_num"));
+
+ return processRenewal(data, req);
+ }
+
+ /*
+ * Renewal - Renewal is retrofitted into the Profile Enrollment
+ * Framework. The authentication and authorization are taken from
+ * the renewal profile, while the input (with requests) and grace
+ * period constraint are taken from the original cert's request record.
+ *
+ * Things to note:
+ * * the renew request will contain the original profile instead of the new
+ */
+ public HashMap<String, Object> processRenewal(EnrollmentRequestData data, HttpServletRequest request)
+ throws EBaseException {
+ try {
+ if (CMS.debugOn()) {
+ HashMap<String,String> params = data.toParams();
+ printParameterValues(params);
+ }
+ CMS.debug("RenewalSubmitter: isRenewal true");
+
+ startTiming("enrollment");
+ request.setAttribute("reqType", "renewal");
+
+ // in case of renew, "profile" is the orig profile
+ // while "renewProfile" is the current profile used for renewal
+ String renewProfileId = (this.profileID == null) ? data.getProfileId() : this.profileID;
+ CMS.debug("processRenewal: renewProfileId " + renewProfileId);
+
+ IProfile renewProfile = ps.getProfile(renewProfileId);
+ if (renewProfile == null) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", renewProfileId));
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", renewProfileId));
+ }
+ if (!ps.isProfileEnable(renewProfileId)) {
+ CMS.debug("RenewalSubmitter: Profile " + renewProfileId + " not enabled");
+ throw new BadRequestDataException("Profile " + renewProfileId + " not enabled");
+ }
+
+ String serial = data.getSerialNum();
+ BigInteger certSerial = null;
+
+ if (serial != null) {
+ // if serial number is sent with request, then the authentication
+ // method is not ssl client auth. In this case, an alternative
+ // authentication method is used (default: ldap based)
+ // usr_origreq evaluator should be used to authorize ownership
+ // of the cert
+ CMS.debug("RenewalSubmitter: renewal: found serial_num");
+ certSerial = new BigInteger(serial);
+ } else {
+ // ssl client auth is to be used
+ // this is not authentication. Just use the cert to search
+ // for orig request and find the right profile
+ CMS.debug("RenewalSubmitter: renewal: serial_num not found, must do ssl client auth");
+ certSerial = getSerialNumberFromCert(request);
+ if (certSerial == null) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+ }
+ CMS.debug("processRenewal: serial number of cert to renew:" + certSerial.toString());
+ ICertRecord rec = certdb.readCertificateRecord(certSerial);
+ if (rec == null) {
+ CMS.debug("processRenewal: cert record not found for serial number " + certSerial.toString());
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+
+ // check to see if the cert is revoked or revoked_expired
+ if ((rec.getStatus().equals(ICertRecord.STATUS_REVOKED))
+ || (rec.getStatus().equals(ICertRecord.STATUS_REVOKED_EXPIRED))) {
+ CMS.debug("processRenewal: cert found to be revoked. Serial number = "
+ + certSerial.toString());
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_CA_CANNOT_RENEW_REVOKED_CERT"));
+ }
+
+ X509CertImpl origCert = rec.getCertificate();
+ if (origCert == null) {
+ CMS.debug("processRenewal: original cert not found in cert record for serial number "
+ + certSerial.toString());
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+
+ Date origNotAfter = origCert.getNotAfter();
+ CMS.debug("processRenewal: origNotAfter =" + origNotAfter.toString());
+
+ String origSubjectDN = origCert.getSubjectDN().getName();
+ CMS.debug("processRenewal: orig subj dn =" + origSubjectDN);
+
+ IRequest origReq = getOriginalRequest(certSerial, rec);
+ if (origReq == null) {
+ CMS.debug("processRenewal: original request not found");
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+
+ String profileId = origReq.getExtDataInString("profileId");
+ CMS.debug("RenewalSubmitter: renewal original profileId=" + profileId);
+
+ Integer origSeqNum = origReq.getExtDataInInteger(IEnrollProfile.REQUEST_SEQ_NUM);
+ IProfile profile = ps.getProfile(profileId);
+ if (profile == null) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ }
+ if (!ps.isProfileEnable(profileId)) {
+ CMS.debug("RenewalSubmitter: Profile " + profileId + " not enabled");
+ throw new BadRequestDataException("Profile " + profileId + " not enabled");
+ }
+
+ IProfileContext ctx = profile.createContext();
+ IProfileAuthenticator authenticator = renewProfile.getAuthenticator();
+ IProfileAuthenticator origAuthenticator = profile.getAuthenticator();
+
+ if (authenticator != null) {
+ CMS.debug("RenewalSubmitter: authenticator " + authenticator.getName() + " found");
+ setCredentialsIntoContext(request, 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);
+ }
+
+ // for renewal, input needs to be retrieved from the orig req record
+ CMS.debug("processRenewal: set original Inputs into profile Context");
+ setInputsIntoContext(origReq, profile, ctx, locale);
+ ctx.set(IEnrollProfile.CTX_RENEWAL, "true");
+ ctx.set("renewProfileId", renewProfileId);
+ ctx.set(IEnrollProfile.CTX_RENEWAL_SEQ_NUM, origSeqNum.toString());
+
+ // for ssl authentication; pass in servlet for retrieving
+ // ssl client certificates
+ SessionContext context = SessionContext.getContext();
+ context.put("profileContext", ctx);
+ context.put("sslClientCertProvider", new SSLClientCertProvider(request));
+ CMS.debug("RenewalSubmitter: set sslClientCertProvider");
+ if (origSubjectDN != null)
+ context.put("origSubjectDN", origSubjectDN);
+
+ // before creating the request, authenticate the request
+ IAuthToken authToken = authenticate(request, origReq, authenticator, context, true);
+
+ // authentication success, now authorize
+ authorize(profileId, renewProfile, authToken);
+
+ ///////////////////////////////////////////////
+ // create and populate requests
+ ///////////////////////////////////////////////
+ startTiming("request_population");
+ IRequest[] reqs = profile.createRequests(ctx, locale);
+ populateRequests(data, true, locale, origNotAfter, origSubjectDN, origReq, profileId,
+ profile, ctx, authenticator, authToken, reqs);
+ endTiming("request_population");
+
+ ///////////////////////////////////////////////
+ // submit request
+ ///////////////////////////////////////////////
+ String errorCode = submitRequests(locale, profile, authToken, reqs);
+ String errorReason = codeToReason(locale, errorCode);
+
+ HashMap<String, Object> ret = new HashMap<String, Object>();
+ ret.put(ARG_REQUESTS, reqs);
+ ret.put(ARG_ERROR_CODE, errorCode);
+ ret.put(ARG_ERROR_REASON, errorReason);
+ ret.put(ARG_PROFILE, profile);
+
+ CMS.debug("RenewalSubmitter: done serving");
+ endTiming("enrollment");
+
+ return ret;
+ } finally {
+ SessionContext.releaseContext();
+ endAllEvents();
+ }
+ }
+
+ private BigInteger getSerialNumberFromCert(HttpServletRequest request) throws EBaseException {
+ BigInteger certSerial;
+ SSLClientCertProvider sslCCP = new SSLClientCertProvider(request);
+ X509Certificate[] certs = sslCCP.getClientCertificateChain();
+ certSerial = null;
+ if (certs == null || certs.length == 0) {
+ CMS.debug("RenewalSubmitter: renewal: no ssl client cert chain");
+ return null;
+ } else { // has ssl client cert
+ CMS.debug("RenewalSubmitter: renewal: has ssl client cert chain");
+ // shouldn't expect leaf cert to be always at the
+ // same location
+ X509Certificate clientCert = null;
+ for (int i = 0; i < certs.length; i++) {
+ clientCert = certs[i];
+ byte[] extBytes = clientCert.getExtensionValue("2.5.29.19");
+ // try to see if this is a leaf cert
+ // look for BasicConstraint extension
+ if (extBytes == null) {
+ // found leaf cert
+ CMS.debug("RenewalSubmitter: renewal: found leaf cert");
+ break;
+ } else {
+ CMS.debug("RenewalSubmitter: renewal: found cert having BasicConstraints ext");
+ // it's got BasicConstraints extension
+ // so it's not likely to be a leaf cert,
+ // however, check the isCA field regardless
+ try {
+ BasicConstraintsExtension bce =
+ new BasicConstraintsExtension(true, extBytes);
+ if (bce != null) {
+ if (!(Boolean) bce.get("is_ca")) {
+ CMS.debug("RenewalSubmitter: renewal: found CA cert in chain");
+ break;
+ } // else found a ca cert, continue
+ }
+ } catch (Exception e) {
+ CMS.debug("RenewalSubmitter: renewal: exception:" + e.toString());
+ return null;
+ }
+ }
+ }
+ if (clientCert == null) {
+ CMS.debug("RenewalSubmitter: renewal: no client cert in chain");
+ return null;
+ }
+ // convert to java X509 cert interface
+ try {
+ byte[] certEncoded = clientCert.getEncoded();
+ clientCert = new X509CertImpl(certEncoded);
+ } catch (Exception e) {
+ e.printStackTrace();
+ CMS.debug("RenewalSubmitter: renewal: exception:" + e.toString());
+ return null;
+ }
+
+ certSerial = clientCert.getSerialNumber();
+ }
+ return certSerial;
+ }
+
+ /*
+ * fill input info from "request" to context.
+ * This is expected to be used by renewal where the request
+ * is retrieved from request record
+ */
+ private void setInputsIntoContext(IRequest request, IProfile profile, IProfileContext ctx, Locale locale) {
+ // passing inputs into context
+ Enumeration<String> inputIds = profile.getProfileInputIds();
+
+ if (inputIds != null) {
+ while (inputIds.hasMoreElements()) {
+ String inputId = inputIds.nextElement();
+ IProfileInput profileInput = profile.getProfileInput(inputId);
+ Enumeration<String> inputNames = profileInput.getValueNames();
+
+ while (inputNames.hasMoreElements()) {
+ String inputName = inputNames.nextElement();
+ String inputValue = "";
+ CMS.debug("RenewalSubmitter: setInputsIntoContext() getting input name= " + inputName);
+ try {
+ inputValue = profileInput.getValue(inputName, locale, request);
+ } catch (Exception e) {
+ CMS.debug("RenewalSubmitter: setInputsIntoContext() getvalue() failed: " + e.toString());
+ }
+
+ if (inputValue != null) {
+ CMS.debug("RenewalSubmitter: setInputsIntoContext() setting value in ctx:" + inputValue);
+ ctx.set(inputName, inputValue);
+ } else {
+ CMS.debug("RenewalSubmitter: setInputsIntoContext() value null");
+ }
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java b/base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java
new file mode 100644
index 000000000..9bb0c4b64
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/cert/RequestProcessor.java
@@ -0,0 +1,475 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.cert;
+
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+import javax.servlet.http.HttpServletRequest;
+
+import netscape.security.x509.X509CertImpl;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzException;
+import com.netscape.certsrv.base.BadRequestDataException;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.EPropertyNotFound;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.EDeferException;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.ERejectException;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.profile.IPolicyConstraint;
+import com.netscape.certsrv.profile.IPolicyDefault;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileOutput;
+import com.netscape.certsrv.profile.IProfilePolicy;
+import com.netscape.certsrv.property.EPropertyException;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.cms.profile.common.ProfilePolicy;
+import com.netscape.cms.servlet.common.CMSRequest;
+import com.netscape.cms.servlet.profile.model.PolicyDefault;
+import com.netscape.cms.servlet.profile.model.ProfileAttribute;
+import com.netscape.cms.servlet.profile.model.ProfileOutput;
+import com.netscape.cms.servlet.profile.model.ProfileOutputFactory;
+import com.netscape.cms.servlet.profile.model.ProfilePolicySet;
+import com.netscape.cms.servlet.request.model.AgentEnrollmentRequestData;
+import com.netscape.cms.servlet.request.model.AgentEnrollmentRequestDataFactory;
+
+public class RequestProcessor extends CertProcessor {
+
+ public RequestProcessor(String id, Locale locale) throws EPropertyNotFound, EBaseException {
+ super(id, locale);
+ }
+
+ public AgentEnrollmentRequestData processRequest(CMSRequest cmsReq, IRequest request, String op) throws EBaseException {
+ HttpServletRequest req = cmsReq.getHttpReq();
+ IRequest ireq = cmsReq.getIRequest();
+
+ String profileId = ireq.getExtDataInString("profileId");
+ IProfile profile = ps.getProfile(profileId);
+ AgentEnrollmentRequestData data = AgentEnrollmentRequestDataFactory.create(cmsReq, profile, nonces, locale);
+
+ processRequest(req, data, request, op);
+ return data;
+ }
+
+ public void processRequest(HttpServletRequest request, AgentEnrollmentRequestData data, IRequest req, String op)
+ throws EBaseException {
+ try {
+
+ startTiming("approval");
+
+ IAuthToken authToken = null;
+
+ if (CMS.debugOn()) {
+ HashMap<String, String> params = data.toParams();
+ printParameterValues(params);
+ CMS.debug("processRequest op is " + op);
+ }
+
+ if (authMgr != null) {
+ authToken = authenticate(request);
+ }
+
+ AuthzToken authzToken = authorize(aclMethod, authToken, authzResourceName, "approve");
+ if (authzToken == null) {
+ throw new EAuthzException(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR"));
+ }
+
+ if (nonces != null) {
+ String requestNonce = data.getNonce();
+ boolean nonceVerified = false;
+ if (requestNonce != null) {
+ long nonce = Long.parseLong(requestNonce.trim());
+ X509Certificate cert1 = nonces.getCertificate(nonce);
+ X509Certificate cert2 = getSSLClientCertificate(request);
+ if (cert1 == null) {
+ CMS.debug("CertRequestExecutor: Unknown nonce");
+ } else if (cert1 != null && cert2 != null && cert1.equals(cert2)) {
+ nonceVerified = true;
+ nonces.removeNonce(nonce);
+ }
+ } else {
+ CMS.debug("CertRequestExecutor: Missing nonce");
+ }
+ CMS.debug("CertRequestExecutor: nonceVerified=" + nonceVerified);
+ if (!nonceVerified) {
+ CMS.debug("nonce not verified");
+ throw new EAuthzException(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR"));
+ }
+ }
+
+ CMS.debug("CertRequestExecutor: processRequest: start serving");
+
+ RequestId requestId = data.getRequestId();
+ if (requestId == null || requestId.equals("")) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_REQUEST_ID_NOT_FOUND"));
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_REQUEST_ID_NOT_FOUND"));
+ }
+ CMS.debug("CertRequestExecutor: requestId=" + requestId);
+
+ // check if the request is in one of the terminal states
+ if (!req.getRequestStatus().equals(RequestStatus.PENDING)) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_REQUEST_NOT_PENDING", requestId.toString()));
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_REQUEST_NOT_PENDING",
+ requestId.toString()));
+ }
+
+ // save auth token in request
+ saveAuthToken(authToken, req);
+
+ String profileId = req.getExtDataInString("profileId");
+ if (profileId == null || profileId.equals("")) {
+ CMS.debug("CertRequestExecutor: Profile Id not found in request");
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_PROFILE_ID_NOT_FOUND"));
+ }
+ CMS.debug("CertRequestExecutor: profileId=" + profileId);
+
+ IProfile profile = ps.getProfile(profileId);
+ if (profile == null) {
+ CMS.debug(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ throw new BadRequestDataException(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ }
+ if (!ps.isProfileEnable(profileId)) {
+ CMS.debug("CertRequestExecutor: Profile " + profileId + " not enabled");
+ throw new BadRequestDataException("Profile " + profileId + " not enabled");
+ }
+
+ if (op.equals("assign")) {
+ String owner = req.getRequestOwner();
+
+ // assigned owner
+ if (owner != null && owner.length() > 0) {
+ if (!grantPermission(req, authToken)) {
+ CMS.debug("CertRequestExecutor: Permission not granted to assign request.");
+ throw new EAuthzException(CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION"));
+ }
+ }
+ String id = auditSubjectID();
+ req.setRequestOwner(id);
+ } else {
+ if (grantPermission(req, authToken)) {
+ if (op.equals("approve")) {
+ checkProfileVersion(profile, req);
+ updateValues(data, req, profile, locale);
+ updateNotes(data, req);
+ approveRequest(req, data, profile, locale);
+ } else if (op.equals("reject")) {
+ updateNotes(data, req);
+ rejectRequest(req);
+ } else if (op.equals("cancel")) {
+ updateNotes(data, req);
+ cancelRequest(req);
+ } else if (op.equals("update")) {
+ checkProfileVersion(profile, req);
+ updateValues(data, req, profile, locale);
+ updateNotes(data, req);
+ } else if (op.equals("validate")) {
+ updateValues(data, req, profile, locale);
+ } else if (op.equals("unassign")) {
+ req.setRequestOwner("");
+ }
+ } else {
+ CMS.debug("CertRequestExecutor: Permission not granted to approve/reject/cancel/update/validate/unassign request.");
+ throw new EAuthzException(CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION"));
+ }
+ }
+
+ // commit request to the storage
+ if (!op.equals("validate")) {
+ if (op.equals("approve")) {
+ queue.markAsServiced(req);
+ } else {
+ queue.updateRequest(req);
+ }
+ }
+ endTiming("approval");
+ } finally {
+ endAllEvents();
+ }
+ }
+
+ private boolean grantPermission(IRequest req, IAuthToken token) {
+ boolean enable = false;
+ try {
+ enable = CMS.getConfigStore().getBoolean("request.assignee.enable", false);
+ } catch (EBaseException e) {
+ }
+
+ if (!enable)
+ return true;
+ String owner = req.getRequestOwner();
+
+ // unassigned owner
+ if (owner == null || owner.length() == 0)
+ return true;
+ String uid = token.getInString(IAuthToken.USER_ID);
+ if (uid.equals(owner))
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Check if the request creation time is older than the profile
+ * lastModified attribute.
+ */
+ private void checkProfileVersion(IProfile profile, IRequest req) throws EProfileException {
+ IConfigStore profileConfig = profile.getConfigStore();
+ if (profileConfig != null) {
+ String lastModified = null;
+
+ try {
+ lastModified = profileConfig.getString("lastModified", "");
+ } catch (EBaseException e) {
+ }
+
+ if (!lastModified.equals("")) {
+ Date profileModifiedAt = new Date(Long.parseLong(lastModified));
+ CMS.debug("CertRequestExecutor: Profile Last Modified=" +
+ profileModifiedAt);
+ Date reqCreatedAt = req.getCreationTime();
+ CMS.debug("CertRequestExecutor: Request Created At=" +
+ reqCreatedAt);
+ if (profileModifiedAt.after(reqCreatedAt)) {
+ CMS.debug("Profile Newer Than Request");
+ throw new ERejectException("Profile Newer Than Request");
+ }
+ }
+ }
+ }
+
+ /**
+ * Cancel request
+ * <P>
+ *
+ * (Certificate Request Processed - a manual "agent" profile based cert cancellation)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been
+ * through the approval process
+ * </ul>
+ *
+ *
+ * @param req the certificate request
+ * @exception EProfileException an error related to this profile has
+ * occurred
+ */
+ private void cancelRequest(IRequest req) throws EProfileException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditInfoValue = auditInfoValue(req);
+
+ req.setRequestStatus(RequestStatus.CANCELED);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_CANCELLATION,
+ auditInfoValue);
+
+ audit(auditMessage);
+ }
+
+ /**
+ * Reject request
+ * <P>
+ *
+ * (Certificate Request Processed - a manual "agent" profile based cert rejection)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been
+ * through the approval process
+ * </ul>
+ *
+ * @param req the certificate request
+ * @exception EProfileException an error related to this profile has
+ * occurred
+ */
+ private void rejectRequest(IRequest req) throws EProfileException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+ String auditInfoValue = auditInfoValue(req);
+
+ req.setRequestStatus(RequestStatus.REJECTED);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_REJECTION,
+ auditInfoValue);
+
+ audit(auditMessage);
+ }
+
+ /**
+ * Approve request
+ * <P>
+ *
+ * (Certificate Request Processed - a manual "agent" profile based cert acceptance)
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been
+ * through the approval process
+ * </ul>
+ *
+ * @param request the servlet request
+ * @param req the certificate request
+ * @param profile this profile
+ * @param locale the system locale
+ * @exception EProfileException an error related to this profile has
+ * occurred
+ */
+ private void approveRequest(IRequest req, AgentEnrollmentRequestData data, IProfile profile, Locale locale)
+ throws EProfileException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditRequesterID = auditRequesterID(req);
+
+ try {
+ profile.execute(req);
+ req.setRequestStatus(RequestStatus.COMPLETE);
+
+ Enumeration<String> outputIds = profile.getProfileOutputIds();
+ while (outputIds.hasMoreElements()) {
+ IProfileOutput output = profile.getProfileOutput(outputIds.nextElement());
+ ProfileOutput addOutput = ProfileOutputFactory.create(output, req, locale);
+ data.addOutput(addOutput);
+ }
+
+ // retrieve the certificate
+ X509CertImpl theCert = req.getExtDataInCert(
+ IEnrollProfile.REQUEST_ISSUED_CERT);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ auditInfoCertValue(theCert));
+
+ audit(auditMessage);
+
+ } catch (EProfileException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditRequesterID,
+ ILogger.SIGNED_AUDIT_ACCEPTANCE,
+ ILogger.SIGNED_AUDIT_EMPTY_VALUE);
+
+ audit(auditMessage);
+
+ CMS.debug("CertRequestExecutor: about to throw EProfileException because of bad profile execute.");
+ throw eAudit1;
+ }
+ }
+
+ private void updateValues(AgentEnrollmentRequestData data, IRequest req,
+ IProfile profile, Locale locale)
+ throws ERejectException, EDeferException, EPropertyException {
+
+ // put request policy defaults in a local hash
+ HashMap<String, String> policyData = new HashMap<String,String>();
+ for (ProfilePolicySet policySet: data.getPolicySets()) {
+ for (com.netscape.cms.servlet.profile.model.ProfilePolicy policy: policySet.getPolicies()) {
+ PolicyDefault def = policy.getDef();
+ List<ProfileAttribute> attrs = def.getAttributes();
+ for (ProfileAttribute attr: attrs) {
+ policyData.put(attr.getName(), attr.getValue());
+ }
+ }
+ }
+
+ String profileSetId = req.getExtDataInString("profileSetId");
+
+ Enumeration<ProfilePolicy> policies = profile.getProfilePolicies(profileSetId);
+ int count = 0;
+
+ while (policies.hasMoreElements()) {
+ ProfilePolicy policy = policies.nextElement();
+
+ setValue(locale, count, policy, req, policyData);
+ count++;
+ }
+
+ policies = profile.getProfilePolicies(profileSetId);
+ count = 0;
+ while (policies.hasMoreElements()) {
+ ProfilePolicy policy = policies.nextElement();
+
+ validate(count, policy, req);
+ count++;
+ }
+
+ }
+
+ private void updateNotes(AgentEnrollmentRequestData data, IRequest req) {
+ String notes = data.getRequestNotes();
+
+ if (notes != null) {
+ req.setExtData("requestNotes", notes);
+ }
+ }
+
+ private void validate(int count, IProfilePolicy policy, IRequest req)
+ throws ERejectException, EDeferException {
+ IPolicyConstraint con = policy.getConstraint();
+
+ con.validate(req);
+ }
+
+ private void setValue(Locale locale, int count, IProfilePolicy policy, IRequest req,
+ HashMap<String, String> data) throws EPropertyException {
+ // handle default policy
+ IPolicyDefault def = policy.getDefault();
+ Enumeration<String> defNames = def.getValueNames();
+
+ while (defNames.hasMoreElements()) {
+ String defName = defNames.nextElement();
+ String defValue = data.get(defName);
+
+ def.setValue(defName, locale, req, defValue);
+ }
+ }
+}