diff options
Diffstat (limited to 'base/common/src/com/netscape/cms/servlet/cert')
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); + } + } +} |