summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2012-05-23 16:03:04 -0400
committerAde Lee <alee@redhat.com>2012-05-23 16:03:04 -0400
commit5ea434ff081455e6d2be77f316bacda292658a49 (patch)
treeea6fc8b3214832b6cfef515b0a5db601b171f48a
parent19242552d553f3ab05a126ca73143688fb540d64 (diff)
downloadpki-alee_profilesubmit_0525.tar.gz
pki-alee_profilesubmit_0525.tar.xz
pki-alee_profilesubmit_0525.zip
Second checkin - this adds ProfileProcessor and some logic to do cert enrollment through restalee_profilesubmit_0525
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java1602
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/model/ProfileData.java1
-rw-r--r--base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java1
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java32
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java13
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/model/ExtendableHttpRequest.java29
6 files changed, 1675 insertions, 3 deletions
diff --git a/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java
new file mode 100644
index 00000000..b92b31e9
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java
@@ -0,0 +1,1602 @@
+package com.netscape.cms.servlet.profile;
+
+import java.math.BigInteger;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+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.authority.IAuthority;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.MetaInfo;
+import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.dbs.certdb.ICertRecord;
+import com.netscape.certsrv.dbs.certdb.ICertificateRepository;
+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.IProfile;
+import com.netscape.certsrv.profile.IProfileAuthenticator;
+import com.netscape.certsrv.profile.IProfileContext;
+import com.netscape.certsrv.profile.IProfileInput;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.request.INotify;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.certsrv.request.RequestStatus;
+import com.netscape.certsrv.template.ArgSet;
+import com.netscape.certsrv.util.IStatsSubsystem;
+import com.netscape.cms.servlet.base.UserInfo;
+import com.netscape.cms.servlet.common.AuthCredentials;
+import com.netscape.cmsutil.util.Utils;
+
+public class ProfileProcessor {
+
+ /**
+ *
+ */
+ private static final String ARG_AUTH_TOKEN = "auth_token";
+ private static final String ARG_REQUEST_OWNER = "requestOwner";
+ private final static String HDR_LANG = "accept-language";
+ public final static String ARG_PROFILE = "profile";
+ public final static String ARG_REQUEST_NOTES = "requestNotes";
+ public final static String ARG_PROFILE_ID = "profileId";
+ public final static String ARG_RENEWAL_PROFILE_ID = "rprofileId";
+ public final static String ARG_PROFILE_IS_ENABLED = "profileIsEnable";
+ public final static String ARG_PROFILE_IS_VISIBLE = "profileIsVisible";
+ public final static String ARG_PROFILE_ENABLED_BY = "profileEnableBy";
+ public final static String ARG_PROFILE_APPROVED_BY = "profileApprovedBy";
+ public final static String ARG_PROFILE_NAME = "profileName";
+ public final static String ARG_PROFILE_DESC = "profileDesc";
+ public final static String ARG_PROFILE_REMOTE_HOST = "profileRemoteHost";
+ public final static String ARG_PROFILE_REMOTE_ADDR = "profileRemoteAddr";
+ public final static String ARG_PROFILE_SET_ID = "profileSetId";
+
+ private final static String SUCCESS = "0";
+ private final static String FAILED = "1";
+
+ private String profileID = null;
+ private String mProfileSubId = null;
+ private String authorityId = null;
+ private String aclMethod = null;
+ private Locale locale = null;
+
+ private IAuthority authority = null;
+ private IAuthzSubsystem authz = null;
+
+ //logging and stats
+ protected ILogger signedAuditLogger = CMS.getSignedAuditLogger();
+ protected LinkedHashSet<String> statEvents = null;
+
+ private final static String LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED =
+ "LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED_5";
+ private final static String LOGGING_SIGNED_AUDIT_AUTH_FAIL =
+ "LOGGING_SIGNED_AUDIT_AUTH_FAIL_4";
+ private final static String LOGGING_SIGNED_AUDIT_AUTH_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_AUTH_SUCCESS_3";
+ private final static String LOGGING_SIGNED_AUDIT_AUTHZ_FAIL =
+ "LOGGING_SIGNED_AUDIT_AUTHZ_FAIL_4";
+ private final static String LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS =
+ "LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS_4";
+ private final static String LOGGING_SIGNED_AUDIT_ROLE_ASSUME =
+ "LOGGING_SIGNED_AUDIT_ROLE_ASSUME_3";
+
+ public ProfileProcessor(String authorityId, String profileID, String aclMethod, Locale locale) {
+ this.authorityId = authorityId;
+ this.profileID = profileID;
+ this.aclMethod = aclMethod;
+ this.locale = locale;
+
+ if (authorityId != null)
+ authority = (IAuthority) CMS.getSubsystem(authorityId);
+
+ authz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+ }
+
+ private void setInputsIntoContext(HttpServletRequest request, IProfile profile, IProfileContext ctx) {
+ // 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();
+ if (request.getParameter(inputName) != null) {
+ // all subject name parameters start with sn_, no other input parameters do
+ if (inputName.matches("^sn_.*")) {
+ ctx.set(inputName, escapeValueRfc1779(request.getParameter(inputName), false).toString());
+ } else {
+ ctx.set(inputName, request.getParameter(inputName));
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ /*
+ * 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("ProfileProcessor: setInputsIntoContext() getting input name= " + inputName);
+ try {
+ inputValue = profileInput.getValue(inputName, locale, request);
+ } catch (Exception e) {
+ CMS.debug("ProfileProcessor: setInputsIntoContext() getvalue() failed: " + e.toString());
+ }
+
+ if (inputValue != null) {
+ CMS.debug("ProfileProcessor: setInputsIntoContext() setting value in ctx:" + inputValue);
+ ctx.set(inputName, inputValue);
+ } else {
+ CMS.debug("ProfileProcessor: setInputsIntoContext() value null");
+ }
+ }
+ }
+ }
+
+ }
+
+ private void setCredentialsIntoContext(HttpServletRequest request, IProfileAuthenticator authenticator,
+ IProfileContext ctx) {
+ Enumeration<String> authIds = authenticator.getValueNames();
+
+ if (authIds != null) {
+ CMS.debug("ProfileProcessor:setCredentialsIntoContext() authNames not null");
+ while (authIds.hasMoreElements()) {
+ String authName = authIds.nextElement();
+
+ CMS.debug("ProfileProcessor:setCredentialsIntoContext() authName:" +
+ authName);
+ if (request.getParameter(authName) != null) {
+ CMS.debug("ProfileProcessor:setCredentialsIntoContext() authName found in request");
+ ctx.set(authName, request.getParameter(authName));
+ } else {
+ CMS.debug("ProfileProcessor:setCredentialsIntoContext() authName not found in request");
+ }
+ }
+ } else {
+ CMS.debug("ProfileProcessor:setCredentialsIntoContext() authIds` null");
+ }
+ }
+
+ String getUidFromDN(String userdn) {
+ StringTokenizer st = new StringTokenizer(userdn, ",");
+ while (st.hasMoreTokens()) {
+ String t = st.nextToken();
+ int i = t.indexOf("=");
+
+ if (i == -1) {
+ continue;
+ }
+ String n = t.substring(0, i);
+ if (n.equalsIgnoreCase("uid")) {
+ String v = t.substring(i + 1);
+ CMS.debug("ProfileProcessor:: getUidFromDN(): uid found:" + v);
+ return v;
+ } else {
+ continue;
+ }
+ }
+ return null;
+ }
+
+ /*
+ * 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 {
+ IAuthToken authToken = authenticate(authenticator, request);
+ // For renewal, fill in necessary params
+ if (authToken != null) {
+ String ouid = origReq.getExtDataInString("auth_token.uid");
+ // if the orig cert was manually approved, then there was
+ // no auth token uid. Try to get the uid from the cert dn
+ // itself, if possible
+ if (ouid == null) {
+ String sdn = (String) context.get("origSubjectDN");
+ if (sdn != null) {
+ ouid = getUidFromDN(sdn);
+ if (ouid != null)
+ CMS.debug("ProfileProcessor: renewal: authToken original uid not found");
+ }
+ } else {
+ CMS.debug("ProfileProcessor: renewal: authToken original uid found in orig request auth_token");
+ }
+ String auid = authToken.getInString("uid");
+ if (auid != null) { // not through ssl client auth
+ CMS.debug("ProfileProcessor: renewal: authToken uid found:" + auid);
+ // authenticated with uid
+ // put "orig_req.auth_token.uid" so that authz with
+ // UserOrigReqAccessEvaluator will work
+ if (ouid != null) {
+ context.put("orig_req.auth_token.uid", ouid);
+ CMS.debug("ProfileProcessor: renewal: authToken original uid found:" + ouid);
+ } else {
+ CMS.debug("ProfileProcessor: renewal: authToken original uid not found");
+ }
+ } else { // through ssl client auth?
+ CMS.debug("ProfileProcessor: renewal: authToken uid not found:");
+ // put in orig_req's uid
+ if (ouid != null) {
+ CMS.debug("ProfileProcessor: renewal: origReq uid not null:" + ouid + ". Setting authtoken");
+ authToken.set("uid", ouid);
+ context.put(SessionContext.USER_ID, ouid);
+ } else {
+ CMS.debug("ProfileProcessor: renewal: origReq uid not found");
+ // throw new EBaseException("origReq uid not found");
+ }
+ }
+
+ String userdn = origReq.getExtDataInString("auth_token.userdn");
+ if (userdn != null) {
+ CMS.debug("ProfileProcessor: renewal: origReq userdn not null:" + userdn + ". Setting authtoken");
+ authToken.set("userdn", userdn);
+ } else {
+ CMS.debug("ProfileProcessor: renewal: origReq userdn not found");
+ // throw new EBaseException("origReq userdn not found");
+ }
+ } else {
+ CMS.debug("ProfileProcessor: renewal: authToken null");
+ }
+ return authToken;
+ }
+
+ public IAuthToken authenticate(IProfileAuthenticator authenticator,
+ HttpServletRequest request) throws EBaseException {
+ AuthCredentials credentials = new AuthCredentials();
+
+ // build credential
+ Enumeration<String> authNames = authenticator.getValueNames();
+
+ if (authNames != null) {
+ while (authNames.hasMoreElements()) {
+ String authName = authNames.nextElement();
+
+ credentials.set(authName, request.getParameter(authName));
+ }
+ }
+
+ credentials.set("clientHost", request.getRemoteHost());
+ IAuthToken authToken = authenticator.authenticate(credentials);
+
+ SessionContext sc = SessionContext.getContext();
+ if (sc != null) {
+ sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName());
+ String userid = authToken.getInString(IAuthToken.USER_ID);
+ if (userid != null) {
+ sc.put(SessionContext.USER_ID, userid);
+ }
+ }
+
+ return authToken;
+ }
+
+ private void setInputsIntoRequest(HttpServletRequest request, IProfile profile, IRequest req) {
+ 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 (request.getParameter(inputName) != null) {
+ // special characters in subject names parameters must be escaped
+ if (inputName.matches("^sn_.*")) {
+ req.setExtData(inputName, escapeValueRfc1779(request.getParameter(inputName), false)
+ .toString());
+ } else {
+ req.setExtData(inputName, request.getParameter(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("ProfileProcessor: setInputsIntoRequest() getting input name= " + inputName);
+ try {
+ inputValue = profileInput.getValue(inputName, locale, request);
+ } catch (Exception e) {
+ CMS.debug("ProfileProcessor: setInputsIntoRequest() getvalue() failed: " + e.toString());
+ }
+
+ if (inputValue != null) {
+ CMS.debug("ProfileProcessor: setInputsIntoRequest() setting value in ctx:" + inputValue);
+ req.setExtData(inputName, inputValue);
+ } else {
+ CMS.debug("ProfileProcessor: setInputsIntoRequest() value null");
+ }
+ }
+ }
+ }
+
+ }
+
+
+
+ private void errorExit(String message)
+ throws EBaseException {
+ CMS.debug(message);
+
+ for (String event : statEvents) {
+ endTiming(event);
+ }
+ throw new EBaseException(message);
+ }
+
+ /**
+ * 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 void processEnrollment(HttpServletRequest request) throws EBaseException {
+
+ if (CMS.debugOn()) {
+ printParameterValues(request);
+ }
+
+ CMS.debug("ProfileProcessor: isRenewal false");
+ startTiming("enrollment");
+
+ // if we did not configure profileId in xml file,
+ // then accept the user-provided one
+ String profileId = (this.profileID == null) ? request.getParameter("profileId") : this.profileID;
+ CMS.debug("ProfileProcessor: profileId " + profileId);
+
+ IProfile profile = getProfile(profileId);
+ if (profile == null) {
+ errorExit(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ }
+
+ IProfileContext ctx = profile.createContext();
+ IProfileAuthenticator authenticator = null;
+ try {
+ authenticator = profile.getAuthenticator();
+ if (authenticator != null) {
+ CMS.debug("ProfileProcessor: authenticator " + authenticator.getName() + " found");
+ setCredentialsIntoContext(request, authenticator, ctx);
+ }
+ } catch (EProfileException e) {
+ // authenticator not installed correctly
+ CMS.debug("ProfileProcessor: renewal: exception:" + e.toString());
+ errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+
+ CMS.debug("ProfileProcessor: set Inputs into profile Context");
+ setInputsIntoContext(request, profile, 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("ProfileProcessor: set sslClientCertProvider");
+
+ // before creating the request, authenticate the request
+ IAuthToken authToken = null;
+ try {
+ authToken = authenticate(request, null, authenticator, context, false);
+ } catch (EBaseException e) {
+ errorExit(CMS.getUserMessage(locale, "CMS_AUTHENTICATION_ERROR"));
+ }
+
+ // authentication success, now authorize
+ try {
+ authorize(profileId, profile, authToken);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ errorExit(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR"));
+ }
+
+ ///////////////////////////////////////////////
+ // create and populate request
+ ///////////////////////////////////////////////
+ startTiming("request_population");
+ IRequest reqs[] = null;
+ try {
+ reqs = profile.createRequests(ctx, locale);
+ } catch (Exception e) {
+ CMS.debug(e);
+ e.printStackTrace();
+ CMS.debug("ProfileProcessor: createRequests " + e.toString());
+ errorExit(e.toString());
+ }
+
+ try {
+ populateRequests(request, false, locale, null, null, null, profileId, profile,
+ ctx, authenticator, authToken, reqs);
+ } catch (EBaseException e) {
+ CMS.debug("Error in populating request: " + e);
+ errorExit(e.toString());
+ }
+ endTiming("request_population");
+
+ ///////////////////////////////////////////////
+ // submit request
+ ///////////////////////////////////////////////
+ ArgSet args = new ArgSet();
+ String errorCode = submitRequests(locale, profile, authToken, reqs);
+ String errorReason = codeToReason(locale, errorCode);
+
+ if (errorCode != null) {
+ /* error stuff */
+ /*if (xmlOutput) {
+ String requestIds = "";
+ for (IRequest req : reqs) {
+ requestIds += " " + req.getRequestId().toString();
+ }
+
+ outputError(response, errorCode, errorReason, requestIds);
+ } else {
+ ArgList requestlist = new ArgList();
+
+ for (IRequest req : reqs) {
+ ArgSet requestset = new ArgSet();
+ requestset.set(ARG_REQUEST_ID, req.getRequestId().toString());
+ requestlist.add(requestset);
+ }
+ args.set(ARG_REQUEST_LIST, requestlist);
+ args.set(ARG_ERROR_CODE, errorCode);
+ args.set(ARG_ERROR_REASON, errorReason);
+ outputTemplate(request, response, args);
+ }*/
+
+ endTiming("enrollment");
+ return;
+ }
+
+ ///////////////////////////////////////////////
+ // output output list
+ ///////////////////////////////////////////////
+
+ /* output stuff */
+ /*if (xmlOutput) {
+ xmlOutput(response, profile, locale, reqs);
+ } else {
+ ArgList outputlist = new ArgList();
+ for (int k = 0; k < reqs.length; k++) {
+
+ setOutputIntoArgs(profile, outputlist, locale, reqs[k]);
+ args.set(ARG_OUTPUT_LIST, outputlist);
+ }
+
+ CMS.debug("ProfileProcessor: done serving");
+
+ ArgList requestlist = new ArgList();
+
+ for (int k = 0; k < reqs.length; k++) {
+ ArgSet requestset = new ArgSet();
+
+ requestset.set(ARG_REQUEST_ID,
+ reqs[k].getRequestId().toString());
+ requestlist.add(requestset);
+ }
+ args.set(ARG_REQUEST_LIST, requestlist);
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ outputTemplate(request, response, args);
+ }*/
+
+ SessionContext.releaseContext();
+ endTiming("enrollment");
+ }
+
+ /*
+ * 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 void processRenewal(HttpServletRequest request) throws EBaseException {
+ if (CMS.debugOn()) {
+ printParameterValues(request);
+ }
+ CMS.debug("ProfileProcessor: 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) ? request.getParameter("profileId") : this.profileID;
+ CMS.debug("processRenewal: renewProfileId " + renewProfileId);
+
+ IProfile renewProfile = getProfile(renewProfileId);
+ if (renewProfile == null) {
+ errorExit(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", renewProfileId));
+ }
+
+ String serial = request.getParameter("serial_num");
+ 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("ProfileProcessor: 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("ProfileProcessor: renewal: serial_num not found, must do ssl client auth");
+ certSerial = getSerialNumberFromCert(request);
+ if (certSerial == null) {
+ errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+ }
+ CMS.debug("processRenewal: serial number of cert to renew:" + certSerial.toString());
+
+ ICertRecord rec = getCertRecord(certSerial);
+ if (rec == null) {
+ CMS.debug("processRenewal: cert record not found for serial number " + certSerial.toString());
+ errorExit(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());
+ errorExit(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());
+ errorExit(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");
+ errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+
+ String profileId = origReq.getExtDataInString("profileId");
+ CMS.debug("ProfileProcessor: renewal original profileId=" + profileId);
+
+ Integer origSeqNum = origReq.getExtDataInInteger(IEnrollProfile.REQUEST_SEQ_NUM);
+ IProfile profile = getProfile(profileId);
+ if (profile == null) {
+ errorExit(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId));
+ }
+
+ IProfileContext ctx = profile.createContext();
+
+ IProfileAuthenticator authenticator = null;
+ IProfileAuthenticator origAuthenticator = null;
+ try {
+ authenticator = renewProfile.getAuthenticator();
+ origAuthenticator = profile.getAuthenticator();
+
+ if (authenticator != null) {
+ CMS.debug("ProfileProcessor: 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("ProfileProcessor: for renewal, original authenticator " +
+ origAuthenticator.getName() + " found");
+ setCredentialsIntoContext(request, origAuthenticator, ctx);
+ }
+
+ } catch (EProfileException e) {
+ // authenticator not installed correctly
+ CMS.debug("processRenewal: exception:" + e.toString());
+ errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+
+ // 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("ProfileProcessor: set sslClientCertProvider");
+ if (origSubjectDN != null)
+ context.put("origSubjectDN", origSubjectDN);
+
+ // before creating the request, authenticate the request
+ IAuthToken authToken = null;
+ try {
+ authToken = authenticate(request, origReq, authenticator, context, true);
+ } catch (EBaseException e) {
+ errorExit(CMS.getUserMessage(locale, "CMS_AUTHENTICATION_ERROR"));
+ }
+
+ // authentication success, now authorize
+ try {
+ authorize(profileId, renewProfile, authToken);
+ } catch (EBaseException e) {
+ e.printStackTrace();
+ errorExit(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR"));
+ }
+
+ ///////////////////////////////////////////////
+ // create and populate requests
+ ///////////////////////////////////////////////
+ startTiming("request_population");
+ IRequest reqs[] = null;
+
+ try {
+ reqs = profile.createRequests(ctx, locale);
+ } catch (EProfileException e) {
+ CMS.debug(e);
+ CMS.debug("ProfileProcessor: createRequests " + e.toString());
+ errorExit(e.toString());
+ } catch (Throwable e) {
+ CMS.debug(e);
+ CMS.debug("ProfileProcessor: createRequests " + e.toString());
+ errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+
+ try {
+ populateRequests(request, true, locale, origNotAfter, origSubjectDN, origReq, profileId, profile,
+ ctx, authenticator, authToken, reqs);
+ } catch (EBaseException e) {
+ CMS.debug("Error in populating request: " + e);
+ errorExit(e.toString());
+ return;
+ }
+
+ endTiming("request_population");
+
+ ///////////////////////////////////////////////
+ // submit request
+ ///////////////////////////////////////////////
+ ArgSet args = new ArgSet();
+ String errorCode = submitRequests(locale, profile, authToken, reqs);
+ String errorReason = codeToReason(locale, errorCode);
+
+ if (errorCode != null) {
+ /* error output */
+ /*
+ if (xmlOutput) {
+ String requestIds = "";
+ for (IRequest req : reqs) {
+ requestIds += " " + req.getRequestId().toString();
+ }
+
+ outputError(response, errorCode, errorReason, requestIds);
+ } else {
+ ArgList requestlist = new ArgList();
+
+ for (IRequest req : reqs) {
+ ArgSet requestset = new ArgSet();
+ requestset.set(ARG_REQUEST_ID, req.getRequestId().toString());
+ requestlist.add(requestset);
+ }
+ args.set(ARG_REQUEST_LIST, requestlist);
+ args.set(ARG_ERROR_CODE, errorCode);
+ args.set(ARG_ERROR_REASON, errorReason);
+ outputTemplate(request, response, args);
+ }*/
+
+ endTiming("enrollment");
+ return;
+ }
+
+ ///////////////////////////////////////////////
+ // output output list
+ ///////////////////////////////////////////////
+ /* output stuff */
+ /*if (xmlOutput) {
+ xmlOutput(response, profile, locale, reqs);
+ } else {
+ ArgList outputlist = new ArgList();
+ for (int k = 0; k < reqs.length; k++) {
+
+ setOutputIntoArgs(profile, outputlist, locale, reqs[k]);
+ args.set(ARG_OUTPUT_LIST, outputlist);
+ }
+
+ CMS.debug("ProfileProcessor: done serving");
+
+ ArgList requestlist = new ArgList();
+
+ for (int k = 0; k < reqs.length; k++) {
+ ArgSet requestset = new ArgSet();
+
+ requestset.set(ARG_REQUEST_ID,
+ reqs[k].getRequestId().toString());
+ requestlist.add(requestset);
+ }
+ args.set(ARG_REQUEST_LIST, requestlist);
+ args.set(ARG_ERROR_CODE, "0");
+ args.set(ARG_ERROR_REASON, "");
+
+ outputTemplate(request, response, args);
+ }*/
+
+ SessionContext.releaseContext();
+ endTiming("enrollment");
+ }
+
+ private void authorize(String profileId, IProfile profile, IAuthToken authToken) throws EBaseException {
+ if (authToken != null) {
+ CMS.debug("ProfileProcessor authToken not null");
+
+ String acl = profile.getAuthzAcl();
+ CMS.debug("ProfileProcessor: authz using acl: " + acl);
+ if (acl != null && acl.length() > 0) {
+ String resource = profileId + ".authz.acl";
+ authorize(aclMethod, resource, authToken, acl);
+ }
+ }
+ }
+
+ private IProfile getProfile(String profileId) {
+ if (mProfileSubId == null || mProfileSubId.equals("")) {
+ mProfileSubId = IProfileSubsystem.ID;
+ }
+ CMS.debug("ProfileProcessor: SubId=" + mProfileSubId);
+
+ IProfileSubsystem ps = (IProfileSubsystem) CMS.getSubsystem(mProfileSubId);
+ if (ps == null) {
+ CMS.debug("getProfile: Profile Subsystem not found");
+ return null;
+ }
+
+ IProfile profile = null;
+
+ try {
+ profile = ps.getProfile(profileId);
+ } catch (EProfileException e) {
+ if (profile == null) {
+ CMS.debug("ProfileProcessor: profile not found profileId " + profileId + " " + e.toString());
+ }
+ }
+ if (profile == null) {
+ CMS.debug("getProfile: Profile not found: " + profileId);
+ return null;
+ }
+
+ if (!ps.isProfileEnable(profileId)) {
+ CMS.debug("ProfileProcessor: Profile " + profileId + " not enabled");
+ return null;
+ }
+ return profile;
+ }
+
+ private String codeToReason(Locale locale, String errorCode) {
+ 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;
+ }
+
+ private 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("ProfileProcessor: 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("ProfileProcessor: 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("ProfileProcessor: 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("ProfileProcessor: 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("ProfileProcessor: updateRequest " + e.toString());
+ }
+ }
+ return errorCode;
+ }
+
+ private void populateRequests(HttpServletRequest request, 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(request, 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("ProfileProcessor: 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, request.getParameter("profileId"));
+ req.setExtData(ARG_PROFILE_APPROVED_BY, profile.getApprovedBy());
+ String setId = profile.getPolicySetId(req);
+
+ if (setId == null) {
+ // no profile set found
+ CMS.debug("ProfileProcessor: no profile policy set found");
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_PROFILE_NO_POLICY_SET_FOUND"));
+ }
+
+ CMS.debug("ProfileProcessor profileSetid=" + setId);
+ req.setExtData(ARG_PROFILE_SET_ID, setId);
+ req.setExtData(ARG_PROFILE_REMOTE_HOST, request.getRemoteHost());
+ req.setExtData(ARG_PROFILE_REMOTE_ADDR, request.getRemoteAddr());
+
+ CMS.debug("ProfileProcessor: request " + req.getRequestId().toString());
+
+ try {
+ CMS.debug("ProfileProcessor: 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);
+ } catch (EProfileException e) {
+ e.printStackTrace();
+ CMS.debug("ProfileProcessor: EProfileException for " + req.getRequestId().toString()
+ + ": " + e.toString());
+ throw new EBaseException(e.toString());
+ } catch (Throwable e) {
+ CMS.debug("ProfileProcessor: populate " + e.toString());
+ throw new EBaseException(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"));
+ }
+ }
+ }
+
+ private IAuthToken authenticate(HttpServletRequest request, IRequest origReq, IProfileAuthenticator authenticator,
+ SessionContext context, boolean isRenewal) throws EBaseException {
+ startTiming("profile_authentication");
+
+ IAuthToken authToken = null;
+ if (authenticator != null) {
+ CMS.debug("authenticate: authentication required.");
+ String uid_cred = "Unidentified";
+ String uid_attempted_cred = "Unidentified";
+ Enumeration<String> authIds = authenticator.getValueNames();
+ //Attempt to possibly fetch attempted uid, may not always be available.
+ if (authIds != null) {
+ while (authIds.hasMoreElements()) {
+ String authName = authIds.nextElement();
+ String value = request.getParameter(authName);
+ if (value != null) {
+ if (authName.equals("uid")) {
+ uid_attempted_cred = value;
+ }
+ }
+ }
+ }
+
+ String authSubjectID = auditSubjectID();
+ String authMgrID = authenticator.getName();
+ String auditMessage = null;
+ try {
+ if (isRenewal) {
+ authToken = authenticate(authenticator, request, origReq, context);
+ } else {
+ authToken = authenticate(authenticator, request);
+ }
+ } catch (EBaseException e) {
+ CMS.debug("ProfileProcessor: authentication error " + e.toString());
+
+ authSubjectID += " : " + uid_cred;
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ authSubjectID,
+ ILogger.FAILURE,
+ authMgrID,
+ uid_attempted_cred);
+ audit(auditMessage);
+
+ throw e;
+ }
+
+ //Log successful authentication
+ //Attempt to get uid from authToken, most tokens respond to the "uid" cred.
+ uid_cred = authToken.getInString("uid");
+
+ if (uid_cred == null || uid_cred.length() == 0) {
+ uid_cred = "Unidentified";
+ }
+
+ authSubjectID = authSubjectID + " : " + uid_cred;
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_SUCCESS,
+ authSubjectID,
+ ILogger.SUCCESS,
+ authMgrID);
+
+ audit(auditMessage);
+ }
+ endTiming("profile_authentication");
+ return authToken;
+ }
+
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (signedAuditLogger == null) {
+ return;
+ }
+
+ signedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ 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("ProfileProcessor: renewal: no ssl client cert chain");
+ return null;
+ } else { // has ssl client cert
+ CMS.debug("ProfileProcessor: 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("ProfileProcessor: renewal: found leaf cert");
+ break;
+ } else {
+ CMS.debug("ProfileProcessor: 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("ProfileProcessor: renewal: found CA cert in chain");
+ break;
+ } // else found a ca cert, continue
+ }
+ } catch (Exception e) {
+ CMS.debug("ProfileProcessor: renewal: exception:" + e.toString());
+ return null;
+ }
+ }
+ }
+ if (clientCert == null) {
+ CMS.debug("ProfileProcessor: 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("ProfileProcessor: renewal: exception:" + e.toString());
+ return null;
+ }
+
+ certSerial = clientCert.getSerialNumber();
+ }
+ return certSerial;
+ }
+
+ private IRequest getOriginalRequest(BigInteger certSerial, ICertRecord rec) throws EBaseException {
+ IAuthority authority = (IAuthority) CMS.getSubsystem(authorityId);
+ if (authority == null) {
+ CMS.debug("getOriginalRequest: Authority " + authorityId + " not found");
+ return null;
+ }
+ IRequestQueue queue = authority.getRequestQueue();
+
+ if (queue == null) {
+ CMS.debug("getOriginalRequest: Request Queue of " + authorityId + " not found");
+ return null;
+ }
+
+ MetaInfo metaInfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO);
+ if (metaInfo == null) {
+ CMS.debug("getOriginalRequest: cert record locating MetaInfo failed for serial number "
+ + certSerial.toString());
+ return null;
+ }
+
+ String rid = (String) metaInfo.get(ICertRecord.META_REQUEST_ID);
+ if (rid == null) {
+ CMS.debug("getOriginalRequest: cert record locating request id in MetaInfo failed " +
+ "for serial number " + certSerial.toString());
+ return null;
+ }
+
+ CMS.debug("getOriginalRequest: request id is " + rid);
+ IRequest origReq = queue.findRequest(new RequestId(rid));
+ return origReq;
+ }
+
+ private void printParameterValues(HttpServletRequest request) {
+ CMS.debug("Start of ProfileProcessor Input Parameters");
+ // @SuppressWarnings("unchecked")
+ Enumeration<String> paramNames = request.getParameterNames();
+
+ while (paramNames.hasMoreElements()) {
+ String paramName = paramNames.nextElement();
+ // added this facility so that password can be hidden,
+ // all sensitive parameters should be prefixed with
+ // __ (double underscores); however, in the event that
+ // a security parameter slips through, we perform multiple
+ // additional checks to insure that it is NOT displayed
+ if (paramName.startsWith("__") ||
+ paramName.endsWith("password") ||
+ paramName.endsWith("passwd") ||
+ paramName.endsWith("pwd") ||
+ paramName.equalsIgnoreCase("admin_password_again") ||
+ paramName.equalsIgnoreCase("directoryManagerPwd") ||
+ paramName.equalsIgnoreCase("bindpassword") ||
+ paramName.equalsIgnoreCase("bindpwd") ||
+ paramName.equalsIgnoreCase("passwd") ||
+ paramName.equalsIgnoreCase("password") ||
+ paramName.equalsIgnoreCase("pin") ||
+ paramName.equalsIgnoreCase("pwd") ||
+ paramName.equalsIgnoreCase("pwdagain") ||
+ paramName.equalsIgnoreCase("uPasswd")) {
+ CMS.debug("ProfileProcessor Input Parameter " +
+ paramName + "='(sensitive)'");
+ } else {
+ CMS.debug("ProfileProcessor Input Parameter " +
+ paramName + "='" +
+ request.getParameter(paramName) + "'");
+ }
+ }
+ CMS.debug("End of ProfileProcessor Input Parameters");
+ }
+
+ /**
+ * Signed Audit Log Requester ID
+ *
+ * This method is called to obtain the "RequesterID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @param request the actual request
+ * @return id string containing the signed audit log message RequesterID
+ */
+ private String auditRequesterID(IRequest request) {
+ // if no signed audit object exists, bail
+ if (signedAuditLogger == null) {
+ return null;
+ }
+
+ String requesterID = ILogger.UNIDENTIFIED;
+
+ if (request != null) {
+ // overwrite "requesterID" if and only if "id" != null
+ String id = request.getRequestId().toString();
+
+ if (id != null) {
+ requesterID = id.trim();
+ }
+ }
+
+ return requesterID;
+ }
+
+ /**
+ * Signed Audit Log Info Certificate Value
+ *
+ * This method is called to obtain the certificate from the passed in
+ * "X509CertImpl" for a signed audit log message.
+ * <P>
+ *
+ * @param request request containing an X509CertImpl
+ * @return cert string containing the certificate
+ */
+ private String auditInfoCertValue(IRequest request) {
+ // if no signed audit object exists, bail
+ if (signedAuditLogger == null) {
+ return null;
+ }
+
+ X509CertImpl x509cert = request.getExtDataInCert(
+ IEnrollProfile.REQUEST_ISSUED_CERT);
+
+ if (x509cert == null) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ byte rawData[] = null;
+
+ try {
+ rawData = x509cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ String cert = null;
+
+ // convert "rawData" into "base64Data"
+ if (rawData != null) {
+ String base64Data = null;
+
+ base64Data = Utils.base64encode(rawData).trim();
+
+ // extract all line separators from the "base64Data"
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < base64Data.length(); i++) {
+ if (!Character.isWhitespace(base64Data.charAt(i))) {
+ sb.append(base64Data.charAt(i));
+
+ }
+ }
+ cert = sb.toString();
+ }
+
+ if (cert != null) {
+ cert = cert.trim();
+
+ if (cert.equals("")) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ } else {
+ return cert;
+ }
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+
+ protected StringBuffer escapeValueRfc1779(String v, boolean doubleEscape) {
+ StringBuffer result = new StringBuffer();
+
+ // Do we need to escape any characters
+ for (int i = 0; i < v.length(); i++) {
+ int c = v.charAt(i);
+ if (c == ',' || c == '=' || c == '+' || c == '<' ||
+ c == '>' || c == '#' || c == ';' || c == '\r' ||
+ c == '\n' || c == '\\' || c == '"') {
+ if ((c == 0x5c) && ((i + 1) < v.length())) {
+ int nextC = v.charAt(i + 1);
+ if ((c == 0x5c) && (nextC == ',' || nextC == '=' || nextC == '+' ||
+ nextC == '<' || nextC == '>' || nextC == '#' ||
+ nextC == ';' || nextC == '\r' || nextC == '\n' ||
+ nextC == '\\' || nextC == '"')) {
+ if (doubleEscape)
+ result.append('\\');
+ } else {
+ result.append('\\');
+ if (doubleEscape)
+ result.append('\\');
+ }
+ } else {
+ result.append('\\');
+ if (doubleEscape)
+ result.append('\\');
+ }
+ }
+ if (c == '\r') {
+ result.append("0D");
+ } else if (c == '\n') {
+ result.append("0A");
+ } else {
+ result.append((char) c);
+ }
+ }
+ return result;
+ }
+
+ public void startTiming(String event) {
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.startTiming(event, true);
+ }
+ if (statEvents == null) {
+ statEvents = new LinkedHashSet<String>();
+ }
+ statEvents.add(event);
+ }
+
+ public void endTiming(String event) {
+ IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats");
+ if (statsSub != null) {
+ statsSub.endTiming(event);
+ }
+ if (statEvents != null) {
+ statEvents.remove(event);
+ }
+ }
+
+ protected Locale getLocale(HttpServletRequest req) {
+ Locale locale = null;
+ String lang = req.getHeader(HDR_LANG);
+
+ if (lang == null) {
+ // use server locale
+ locale = Locale.getDefault();
+ } else {
+ locale = new Locale(UserInfo.getUserLanguage(lang),
+ UserInfo.getUserCountry(lang));
+ }
+ return locale;
+ }
+
+ protected ICertRecord getCertRecord(BigInteger serialNo) {
+ if (authority == null ||
+ !(authority instanceof ICertificateAuthority)) {
+ CMS.debug(CMS.getLogMessage("CMSGW_NON_CERT_AUTH"));
+ return null;
+ }
+
+ ICertificateRepository certdb = ((ICertificateAuthority) authority).getCertificateRepository();
+ if (certdb == null) {
+ CMS.debug(CMS.getLogMessage("CMSGW_CERT_DB_NULL", authority.toString()));
+ return null;
+ }
+
+ ICertRecord certRecord = null;
+ try {
+ certRecord = certdb.readCertificateRecord(serialNo);
+ } catch (EBaseException e) {
+ CMS.debug(CMS.getLogMessage("CMSGW_NO_CERT_REC", serialNo.toString(16), e.toString()));
+ return null;
+ }
+ return certRecord;
+ }
+
+ protected String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (signedAuditLogger == null) {
+ return null;
+ }
+
+ CMS.debug("CMSServlet: in auditSubjectID");
+ String subjectID = null;
+
+ // Initialize subjectID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ CMS.debug("CMSServlet: auditSubjectID auditContext " + auditContext);
+ if (auditContext != null) {
+ subjectID = (String)
+ auditContext.get(SessionContext.USER_ID);
+
+ CMS.debug("CMSServlet auditSubjectID: subjectID: " + subjectID);
+ if (subjectID != null) {
+ subjectID = subjectID.trim();
+ } else {
+ subjectID = ILogger.NONROLEUSER;
+ }
+ } else {
+ subjectID = ILogger.UNIDENTIFIED;
+ }
+
+ return subjectID;
+ }
+
+
+ public AuthzToken authorize(String authzMgrName, String resource, IAuthToken authToken,
+ String exp) throws EBaseException {
+ AuthzToken authzToken = null;
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditGroupID = auditGroupID();
+ String auditACLResource = resource;
+ String auditOperation = "enroll";
+
+ try {
+ authzToken = authz.authorize(authzMgrName, authToken, exp);
+ if (authzToken != null) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditGroupID);
+
+ audit(auditMessage);
+ } else {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroupID);
+
+ audit(auditMessage);
+ }
+ return authzToken;
+ } catch (Exception e) {
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroupID);
+
+ audit(auditMessage);
+ throw new EBaseException(e.toString());
+ }
+ }
+
+ protected String auditGroupID() {
+ // if no signed audit object exists, bail
+ if (signedAuditLogger == null) {
+ return null;
+ }
+
+ CMS.debug("CMSServlet: in auditGroupID");
+ String groupID = null;
+
+ // Initialize groupID
+ SessionContext auditContext = SessionContext.getExistingContext();
+
+ CMS.debug("CMSServlet: auditGroupID auditContext " + auditContext);
+ if (auditContext != null) {
+ groupID = (String)
+ auditContext.get(SessionContext.GROUP_ID);
+
+ CMS.debug("CMSServlet auditGroupID: groupID: " + groupID);
+ if (groupID != null) {
+ groupID = groupID.trim();
+ } else {
+ groupID = ILogger.NONROLEUSER;
+ }
+ } else {
+ groupID = ILogger.UNIDENTIFIED;
+ }
+
+ return groupID;
+ }
+
+}
diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/ProfileData.java b/base/common/src/com/netscape/cms/servlet/profile/model/ProfileData.java
index 22a59c47..7f7f26b2 100644
--- a/base/common/src/com/netscape/cms/servlet/profile/model/ProfileData.java
+++ b/base/common/src/com/netscape/cms/servlet/profile/model/ProfileData.java
@@ -41,6 +41,7 @@ public class ProfileData {
@XmlElement
protected String id;
+
@XmlElement
protected String name;
diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java b/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java
index a0aea9fd..47cfdb73 100644
--- a/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java
+++ b/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java
@@ -36,6 +36,7 @@ public class ProfileInput {
}
private String inputId;
+
@XmlJavaTypeAdapter(InputAttrsAdapter.class)
public Map<String, String> InputAttrs = new LinkedHashMap<String, String>();
diff --git a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java
index 1d7f8aea..8fcd1d2e 100644
--- a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java
+++ b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java
@@ -21,7 +21,9 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Path;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
@@ -37,6 +39,8 @@ import com.netscape.certsrv.request.IRequestQueue;
import com.netscape.certsrv.request.RequestId;
import com.netscape.certsrv.request.RequestStatus;
import com.netscape.cms.servlet.cert.CertResource;
+import com.netscape.cms.servlet.profile.ProfileProcessor;
+import com.netscape.cms.servlet.profile.model.ProfileInput;
import com.netscape.cms.servlet.request.CertRequestResource;
/**
@@ -128,11 +132,33 @@ public class CertRequestDAO extends CMSRequestDAO {
* @return info for the request submitted.
* @throws EBaseException
*/
- public CertRequestInfo submitRequest(EnrollmentRequestData data, UriInfo uriInfo) throws EBaseException {
+ public CertRequestInfo submitRequest(EnrollmentRequestData data, HttpServletRequest request) throws EBaseException {
+ HttpServletRequest extReq = createServletRequest(request, data);
+ ProfileProcessor processor = new ProfileProcessor(authorityId, profileID, aclMethod, locale);
+ if (data.getIsRenewal()) {
+ processor.processRenewal(extReq);
+ } else {
+ processor.processEnrollment(extReq);
+ }
+ //TODO handle good data return.
+ }
+
+ private HttpServletRequest createServletRequest(HttpServletRequest request, EnrollmentRequestData data) {
+ ExtendableHttpRequest extReq = new ExtendableHttpRequest(request);
+ extReq.addParameter("profileId", data.getProfileId());
+ extReq.addParameter("serial_num", data.getSerialNum());
+
+ for (ProfileInput input: data.inputs) {
+ Map<String, String> attrs = input.getAttributes();
+ for (Map.Entry<String, String> entry: attrs.entrySet()) {
+ extReq.addParameter(entry.getKey(), entry.getValue());
+ }
+ }
- //TODO perform actual profile request.
+ // TODO - add authenticator entries
+ return extReq;
- throw new EBaseException("Not implemented.");
+ // TODO Auto-generated method stub
}
public void approveRequest(RequestId id) throws EBaseException {
diff --git a/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java b/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java
index f2979ebc..aa2f4a33 100644
--- a/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java
+++ b/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java
@@ -50,6 +50,7 @@ public class EnrollmentRequestData {
private static final String PROFILE_ID = "profileId";
private static final String RENEWAL = "renewal";
+ private static final String SERIAL_NUM = "serial_num";
@XmlElement
protected String profileId;
@@ -57,6 +58,9 @@ public class EnrollmentRequestData {
@XmlElement
protected boolean isRenewal;
+ @XmlElement
+ protected String serialNum; // used for one type of renewal
+
@XmlElement(name = "Input")
protected List<ProfileInput> inputs = new ArrayList<ProfileInput>();
@@ -66,6 +70,7 @@ public class EnrollmentRequestData {
public EnrollmentRequestData(MultivaluedMap<String, String> form) {
profileId = form.getFirst(PROFILE_ID);
String renewalStr = form.getFirst(RENEWAL);
+ serialNum = form.getFirst(SERIAL_NUM);
isRenewal = new Boolean(renewalStr);
@@ -199,4 +204,12 @@ public class EnrollmentRequestData {
}
}
+ public String getSerialNum() {
+ return serialNum;
+ }
+
+ public void setSerialNum(String serialNum) {
+ this.serialNum = serialNum;
+ }
+
}
diff --git a/base/common/src/com/netscape/cms/servlet/request/model/ExtendableHttpRequest.java b/base/common/src/com/netscape/cms/servlet/request/model/ExtendableHttpRequest.java
new file mode 100644
index 00000000..33c13bb1
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/request/model/ExtendableHttpRequest.java
@@ -0,0 +1,29 @@
+package com.netscape.cms.servlet.request.model;
+
+import java.util.HashMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+public class ExtendableHttpRequest extends HttpServletRequestWrapper {
+
+ private HashMap<String, String> params = new HashMap<String, String>();
+
+ public ExtendableHttpRequest(HttpServletRequest request) {
+ super(request);
+ }
+
+ public String getParameter(String name) {
+ // if we added one, return that one
+ if (params.get(name) != null) {
+ return params.get(name);
+ }
+ // otherwise return what's in the original request
+ HttpServletRequest req = (HttpServletRequest) super.getRequest();
+ return req.getParameter(name);
+ }
+
+ public void addParameter(String name, String value) {
+ if (value != null) params.put(name, value);
+ }
+}