summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java')
-rw-r--r--pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java2235
1 files changed, 2235 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java b/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
new file mode 100644
index 000000000..e4008ab8d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/servlet/base/CMSServlet.java
@@ -0,0 +1,2235 @@
+// --- 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) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cms.servlet.base;
+
+import com.netscape.cms.servlet.common.*;
+import com.netscape.cms.servlet.common.AuthCredentials;
+import com.netscape.cmsutil.xml.*;
+import com.netscape.certsrv.base.SessionContext;
+import java.io.*;
+import java.util.*;
+import java.util.Locale;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Date;
+import java.math.BigInteger;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletException;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.AlgorithmId;
+import netscape.security.x509.RevokedCertImpl;
+import netscape.security.x509.RevocationReason;
+import netscape.security.x509.CRLReasonExtension;
+import netscape.security.x509.CRLExtensions;
+import netscape.security.pkcs.PKCS7;
+import netscape.security.pkcs.ContentInfo;
+import netscape.security.pkcs.SignerInfo;
+import netscape.security.util.DerValue;
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.ObjectIdentifier;
+
+import org.mozilla.jss.ssl.SSLSocket;
+import org.mozilla.jss.ssl.SSLSecurityStatus;
+import org.w3c.dom.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.usrgrp.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.kra.*;
+import com.netscape.certsrv.ocsp.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authorization.*;
+
+import com.netscape.certsrv.authentication.*;
+
+import com.netscape.certsrv.dbs.certdb.*;
+
+import com.netscape.certsrv.logging.ILogger;
+
+import com.netscape.certsrv.request.IRequestQueue;
+import com.netscape.certsrv.request.IRequest;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
+import java.net.SocketException;
+
+
+/**
+ * This is the base class of all CS servlet.
+ *
+ * @version $Revision$, $Date$
+ */
+public abstract class CMSServlet extends HttpServlet {
+ // servlet init params
+ // xxxx todo:Should enforce init param value checking!
+ public final static String SUCCESS = "0";
+ public final static String FAILURE = "1";
+ public final static String AUTH_FAILURE = "2";
+
+ public final static String PROP_ID = "ID";
+ public final static String PROP_AUTHORITY = "authority";
+ public final static String PROP_AUTHMGR = "AuthMgr";
+ public final static String PROP_CLIENTAUTH = "GetClientCert";
+ public final static String PROP_RESOURCEID = "resourceID";
+
+ public final static String AUTHZ_SRC_LDAP = "ldap";
+ public final static String AUTHZ_SRC_TYPE = "sourceType";
+ public final static String AUTHZ_CONFIG_STORE = "authz";
+ public final static String AUTHZ_SRC_XML = "web.xml";
+ public final static String PROP_AUTHZ_MGR = "AuthzMgr";
+ public final static String PROP_ACL = "ACLinfo";
+ public final static String AUTHZ_MGR_BASIC = "BasicAclAuthz";
+ public final static String AUTHZ_MGR_LDAP = "DirAclAuthz";
+ private final static String FAILED = "1";
+ private final static String HDR_LANG = "accept-language";
+
+ // final error message - if error and exception templates don't work
+ // send out this text string directly to output.
+
+ public final static String PROP_FINAL_ERROR_MSG = "finalErrorMsg";
+ public final static String ERROR_MSG_TOKEN = "$ERROR_MSG";
+ public final static String FINAL_ERROR_MSG =
+ "<HTML>\n" +
+ "<BODY BGCOLOR=white>\n" +
+ "<P>\n" +
+ "The Certificate System has encountered " +
+ "an unrecoverable error.\n" +
+ "<P>\n" +
+ "Error Message:<BR>\n" +
+ "<I>$ERROR_MSG</I>\n" +
+ "<P>\n" +
+ "Please contact your local administrator for assistance.\n" +
+ "</BODY>\n" +
+ "</HTML>\n";
+
+ // properties from configuration.
+
+ protected final static String
+ PROP_UNAUTHORIZED_TEMPLATE = "unauthorizedTemplate";
+ protected final static String
+ UNAUTHORIZED_TEMPLATE = "/GenUnauthorized.template";
+ protected final static String
+ PROP_SUCCESS_TEMPLATE = "successTemplate";
+ protected final static String
+ SUCCESS_TEMPLATE = "/GenSuccess.template";
+ protected final static String
+ PROP_PENDING_TEMPLATE = "pendingTemplate";
+ protected final static String
+ PENDING_TEMPLATE = "/GenPending.template";
+ protected final static String
+ PROP_SVC_PENDING_TEMPLATE = "svcpendingTemplate";
+ protected final static String
+ SVC_PENDING_TEMPLATE = "/GenSvcPending.template";
+ protected final static String
+ PROP_REJECTED_TEMPLATE = "rejectedTemplate";
+ protected final static String
+ REJECTED_TEMPLATE = "/GenRejected.template";
+ protected final static String
+ PROP_ERROR_TEMPLATE = "errorTemplate";
+ protected final static String
+ ERROR_TEMPLATE = "/GenError.template";
+ protected final static String
+ PROP_EXCEPTION_TEMPLATE = "unexpectedErrorTemplate";
+ protected final static String
+ EXCEPTION_TEMPLATE = "/GenUnexpectedError.template";
+
+ private final static String
+ PROP_UNAUTHOR_TEMPLATE_FILLER = "unauthorizedTemplateFiller";
+ protected final static String
+ PROP_SUCCESS_TEMPLATE_FILLER = "successTemplateFiller";
+ private final static String
+ PROP_ERROR_TEMPLATE_FILLER = "errorTemplateFiller";
+ private final static String
+ PROP_PENDING_TEMPLATE_FILLER = "pendingTemplateFiller";
+ private final static String
+ PROP_SVC_PENDING_TEMPLATE_FILLER = "svcpendingTemplateFiller";
+ private final static String
+ PROP_REJECTED_TEMPLATE_FILLER = "rejectedTemplateFiller";
+ private final static String
+ PROP_EXCEPTION_TEMPLATE_FILLER = "exceptionTemplateFiller";
+
+ protected final static String RA_AGENT_GROUP = "Registration Manager Agents";
+ protected final static String CA_AGENT_GROUP = "Certificate Manager Agents";
+ protected final static String KRA_AGENT_GROUP = "Data Recovery Manager Agents";
+ protected final static String OCSP_AGENT_GROUP = "Online Certificate Status Manager Agents";
+ protected final static String TRUSTED_RA_GROUP = "Trusted Managers";
+ protected final static String ADMIN_GROUP = "Administrators";
+
+ // default http params NOT to save in request.(config values added to list )
+ private static final String
+ PROP_DONT_SAVE_HTTP_PARAMS = "dontSaveHttpParams";
+ private static final String[]
+ DONT_SAVE_HTTP_PARAMS = { "pwd", "password", "passwd",
+ "challengePassword", "confirmChallengePassword" };
+
+ // default http headers to save in request. (config values added to list)
+ private static final String
+ PROP_SAVE_HTTP_HEADERS = "saveHttpHeaders";
+ private static final String[]
+ SAVE_HTTP_HEADERS = { "accept-language", "user-agent", };
+
+ // request prefixes to distinguish from other request attributes.
+ public static final String
+ PFX_HTTP_HEADER = "HTTP_HEADER";
+ public static final String
+ PFX_HTTP_PARAM = "HTTP_PARAM";
+ public static final String
+ PFX_AUTH_TOKEN = "AUTH_TOKEN";
+
+ /* input http params */
+ protected final static String AUTHMGR_PARAM = "authenticator";
+
+ /* fixed credential passed to auth managers */
+ protected final static String CERT_AUTH_CRED = "sslClientCert";
+
+ public static final String CERT_ATTR =
+ "javax.servlet.request.X509Certificate";
+
+ // members.
+
+ protected boolean mRenderResult = true;
+ protected String mFinalErrorMsg = FINAL_ERROR_MSG;
+ protected Hashtable mTemplates = new Hashtable();
+
+ protected ServletConfig mServletConfig = null;
+ protected ServletContext mServletContext = null;
+ private CMSFileLoader mFileLoader = null;
+
+ protected Vector mDontSaveHttpParams = new Vector();
+ protected Vector mSaveHttpHeaders = new Vector();
+
+ protected String mId = null;
+ protected IConfigStore mConfig = null;
+
+ // the authority, RA, CA, KRA this servlet is serving.
+ protected IAuthority mAuthority = null;
+ protected IRequestQueue mRequestQueue = null;
+
+ // system logger.
+ protected ILogger mLogger = CMS.getLogger();
+ protected int mLogCategory = ILogger.S_OTHER;
+ private MessageDigest mSHADigest = null;
+
+ protected String mGetClientCert = "false";
+ protected String mAuthMgr = null;
+ protected IAuthzSubsystem mAuthz = null;
+
+ protected String mAclMethod = null;
+ protected String mAuthzResourceName = null;
+
+ protected ILogger mSignedAuditLogger = CMS.getSignedAuditLogger();
+ protected String mOutputTemplatePath = null;
+ private IUGSubsystem mUG = (IUGSubsystem)
+ CMS.getSubsystem(CMS.SUBSYSTEM_UG);
+
+ 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 CMSServlet() {
+ }
+
+ public static Hashtable toHashtable(HttpServletRequest req) {
+ Hashtable httpReqHash = new Hashtable();
+ Enumeration names = req.getParameterNames();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+
+ httpReqHash.put(name, req.getParameter(name));
+ }
+ return httpReqHash;
+ }
+
+ public void init(ServletConfig sc) throws ServletException {
+ super.init(sc);
+ mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+ mId = sc.getInitParameter(PROP_ID);
+
+ try {
+ mAclMethod = Utils.initializeAuthz(sc, mAuthz, mId);
+ } catch (ServletException e) {
+ log(ILogger.LL_FAILURE, e.toString());
+ throw e;
+ }
+
+ mConfig = CMS.getConfigStore().getSubStore(CMSGateway.PROP_CMSGATEWAY);
+ mServletConfig = sc;
+ mServletContext = sc.getServletContext();
+ mFileLoader = new CMSFileLoader();
+
+ mGetClientCert = sc.getInitParameter(PROP_CLIENTAUTH);
+ mAuthMgr = sc.getInitParameter(PROP_AUTHMGR);
+ mAuthzResourceName = sc.getInitParameter(PROP_RESOURCEID);
+ mOutputTemplatePath = sc.getInitParameter("templatePath");
+
+ String authority = sc.getInitParameter(PROP_AUTHORITY);
+
+ if (authority != null)
+ mAuthority = (IAuthority)
+ CMS.getSubsystem(authority);
+ if (mAuthority != null)
+ mRequestQueue = mAuthority.getRequestQueue();
+
+ // set default templates.
+ setDefaultTemplates(sc);
+
+ // for logging to the right authority category.
+ if (mAuthority == null) {
+ mLogCategory = ILogger.S_OTHER;
+ } else {
+ if (mAuthority instanceof ICertificateAuthority)
+ mLogCategory = ILogger.S_CA;
+ else if (mAuthority instanceof IRegistrationAuthority)
+ mLogCategory = ILogger.S_RA;
+ else if (mAuthority instanceof IKeyRecoveryAuthority)
+ mLogCategory = ILogger.S_KRA;
+ else
+ mLogCategory = ILogger.S_OTHER;
+ }
+
+ try {
+ // get final error message.
+ // used when templates can't even be loaded.
+ String eMsg =
+ sc.getInitParameter(PROP_FINAL_ERROR_MSG);
+
+ if (eMsg != null)
+ mFinalErrorMsg = eMsg;
+
+ // get any configured templates.
+ Enumeration templs = mTemplates.elements();
+
+ while (templs.hasMoreElements()) {
+ CMSLoadTemplate templ = (CMSLoadTemplate) templs.nextElement();
+
+ if (templ == null || templ.mPropName == null) {
+ continue;
+ }
+ String tName =
+ sc.getInitParameter(templ.mPropName);
+
+ if (tName != null)
+ templ.mTemplateName = tName;
+ String fillerName =
+ sc.getInitParameter(templ.mFillerPropName);
+
+ if (fillerName != null) {
+ ICMSTemplateFiller filler = newFillerObject(fillerName);
+
+ if (filler != null)
+ templ.mFiller = filler;
+ }
+ }
+
+ // get http params NOT to store in a IRequest and
+ // get http headers TO store in a IRequest.
+ getDontSaveHttpParams(sc);
+ getSaveHttpHeaders(sc);
+ } catch (Exception e) {
+ // should never occur since we provide defaults above.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_CONF_TEMP_PARAMS",
+ e.toString()));
+ throw new ServletException(e.toString());
+ }
+
+ try {
+ mSHADigest = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_CONF_TEMP_PARAMS",
+ e.toString()));
+ throw new ServletException(e.toString());
+ }
+ }
+
+ public String getId() {
+ return mId;
+ }
+
+ public String getAuthMgr() {
+ return mAuthMgr;
+ }
+
+ public boolean isClientCertRequired() {
+ if (mGetClientCert != null && mGetClientCert.equals("true"))
+ return true;
+ else
+ return false;
+ }
+
+ public void outputHttpParameters(HttpServletRequest httpReq)
+ {
+ CMS.debug("CMSServlet:service() uri = " + httpReq.getRequestURI());
+ Enumeration paramNames = httpReq.getParameterNames();
+ while (paramNames.hasMoreElements()) {
+ String pn = (String)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( pn.startsWith("__") ||
+ pn.endsWith("password") ||
+ pn.endsWith("passwd") ||
+ pn.endsWith("pwd") ||
+ pn.equalsIgnoreCase("admin_password_again") ||
+ pn.equalsIgnoreCase("directoryManagerPwd") ||
+ pn.equalsIgnoreCase("bindpassword") ||
+ pn.equalsIgnoreCase("bindpwd") ||
+ pn.equalsIgnoreCase("passwd") ||
+ pn.equalsIgnoreCase("password") ||
+ pn.equalsIgnoreCase("pin") ||
+ pn.equalsIgnoreCase("pwd") ||
+ pn.equalsIgnoreCase("pwdagain") ||
+ pn.equalsIgnoreCase("uPasswd") ) {
+ CMS.debug("CMSServlet::service() param name='" + pn +
+ "' value='(sensitive)'" );
+ } else {
+ CMS.debug("CMSServlet::service() param name='" + pn +
+ "' value='" + httpReq.getParameter(pn) + "'" );
+ }
+ }
+ }
+
+ public void service(HttpServletRequest httpReq,
+ HttpServletResponse httpResp)
+ throws ServletException, IOException {
+
+ boolean running_state = CMS.isInRunningState();
+
+ if (!running_state)
+ throw new IOException(
+ "CS server is not ready to serve.");
+
+ try {
+ if (CMS.getConfigStore().getBoolean("useThreadNaming", false)) {
+ String currentName = Thread.currentThread().getName();
+
+ Thread.currentThread().setName(currentName + "-" + httpReq.getServletPath());
+ }
+ } catch (Exception e) {
+ }
+
+ httpReq.setCharacterEncoding("UTF-8");
+
+ if (CMS.debugOn()) {
+ outputHttpParameters(httpReq);
+ }
+ CMS.debug("CMSServlet: " + mId + " start to service.");
+ String className = this.getClass().getName();
+
+ // get a cms request
+ CMSRequest cmsRequest = newCMSRequest();
+
+ // set argblock
+ cmsRequest.setHttpParams(CMS.createArgBlock("http-request-params",toHashtable(httpReq)));
+
+ // set http request
+ cmsRequest.setHttpReq(httpReq);
+
+ // set http response
+ cmsRequest.setHttpResp(httpResp);
+
+ // set servlet config.
+ cmsRequest.setServletConfig(mServletConfig);
+
+ // set servlet context.
+ cmsRequest.setServletContext(mServletContext);
+
+ IArgBlock httpArgs = cmsRequest.getHttpParams();
+
+ // authenticator value from http overrides the value in web.xml.
+ String authMgr_http = httpArgs.getValueAsString(AUTHMGR_PARAM, null);
+
+ if (authMgr_http != null) {
+ mAuthMgr = authMgr_http;
+ } else {
+ mAuthMgr = mServletConfig.getInitParameter(PROP_AUTHMGR);
+ }
+
+ // process request.
+ ICommandQueue iCommandQueue = CMS.getCommandQueue();
+
+ try {
+ if (iCommandQueue.registerProcess((Object) cmsRequest, (Object) this) == false) {
+ cmsRequest.setStatus(CMSRequest.ERROR);
+ renderResult(cmsRequest);
+ SessionContext.releaseContext();
+ return;
+ }
+ long startTime = CMS.getCurrentDate().getTime();
+ process(cmsRequest);
+ renderResult(cmsRequest);
+ Date endDate = CMS.getCurrentDate();
+ long endTime = endDate.getTime();
+ if (CMS.debugOn()) {
+ CMS.debug(CMS.DEBUG_INFORM, "CMSServlet: curDate=" + endDate + " id=" + mId + " time=" + (endTime - startTime));
+ }
+ iCommandQueue.unRegisterProccess((Object) cmsRequest, (Object) this);
+ } catch (EBaseException e) {
+ iCommandQueue.unRegisterProccess((Object) cmsRequest, (Object) this);
+ // ByteArrayOutputStream os = new ByteArrayOutputStream(); for debugging only
+ // PrintStream ps = new PrintStream(os);
+ //e.printStackTrace(ps);
+ log(e.toString());
+ renderException(cmsRequest, e);
+ } catch (Exception ex) {
+ iCommandQueue.unRegisterProccess((Object) cmsRequest, (Object) this);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(os);
+
+ ex.printStackTrace(ps);
+ log(os.toString());
+ renderFinalError(cmsRequest, ex);
+ }
+
+ // destroy SessionContext
+ SessionContext.releaseContext();
+
+ return;
+ }
+
+ /**
+ * Create a new CMSRequest object. This should be overriden by servlets
+ * implementing different types of request
+ * @return a new CMSRequest object
+ */
+ protected CMSRequest newCMSRequest() {
+ return new CMSRequest();
+ }
+
+ /**
+ * process an HTTP request. Servlets must override this with their
+ * own implementation
+ * @throws EBaseException if the servlet was unable to satisfactorily
+ * process the request
+ */
+ protected void process(CMSRequest cmsRequest)
+ throws EBaseException
+ {
+ }
+
+
+ /**
+ * Output a template.
+ * If an error occurs while outputing the template the exception template
+ * is used to display the error.
+ *
+ * @param cmsReq the CS request
+ */
+ protected void renderResult(CMSRequest cmsReq)
+ throws IOException {
+
+ if (!mRenderResult)
+ return;
+ Integer status = cmsReq.getStatus();
+
+ CMSLoadTemplate ltempl = (CMSLoadTemplate) mTemplates.get(status);
+
+ if (ltempl == null || ltempl.mTemplateName == null) {
+ // result is previously outputed.
+ return;
+ }
+ ICMSTemplateFiller filler = ltempl.mFiller;
+
+ renderTemplate(cmsReq, ltempl.mTemplateName, filler);
+ }
+
+ private static final String PRESERVED = "preserved";
+ public static final String TEMPLATE_NAME = "templateName";
+
+ protected void outputArgBlockAsXML(XMLObject xmlObj, Node parent,
+ String argBlockName, IArgBlock argBlock)
+ {
+ Node argBlockContainer = xmlObj.createContainer(parent, argBlockName);
+
+ if (argBlock != null) {
+ Enumeration names = argBlock.getElements();
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ String val = argBlock.get(name).toString();
+ val = val.trim();
+ xmlObj.addItemToContainer(argBlockContainer, name, val);
+ }
+ }
+ }
+
+ protected void outputXML(HttpServletResponse httpResp, CMSTemplateParams params)
+ {
+ XMLObject xmlObj = null;
+ try {
+ xmlObj = new XMLObject();
+
+ Node root = xmlObj.createRoot("xml");
+ outputArgBlockAsXML(xmlObj, root, "header", params.getHeader());
+ outputArgBlockAsXML(xmlObj, root, "fixed", params.getFixed());
+
+ Enumeration records = params.queryRecords();
+ Node recordsNode = xmlObj.createContainer(root, "records");
+ if (records != null) {
+ while (records.hasMoreElements()) {
+ IArgBlock record = (IArgBlock) records.nextElement();
+ outputArgBlockAsXML(xmlObj, recordsNode, "record", record);
+ }
+ }
+
+ byte[] cb = xmlObj.toByteArray();
+ OutputStream os = httpResp.getOutputStream();
+ httpResp.setContentType("application/xml");
+ httpResp.setContentLength(cb.length);
+ os.write(cb);
+ os.flush();
+ } catch (Exception e) {
+ CMS.debug("failed in outputing XML " + e);
+ }
+ }
+
+ protected void renderTemplate(
+ CMSRequest cmsReq, String templateName, ICMSTemplateFiller filler)
+ throws IOException {
+ try {
+ IArgBlock httpParams = cmsReq.getHttpParams();
+
+ Locale[] locale = new Locale[1];
+ CMSTemplate template =
+ getTemplate(templateName, cmsReq.getHttpReq(), locale);
+ CMSTemplateParams templateParams = null;
+
+ if (filler != null) {
+ templateParams = filler.getTemplateParams(
+ cmsReq, mAuthority, locale[0], null);
+ }
+
+ // just output arg blocks as XML
+ CMS.debug("CMSServlet.java: renderTemplate");
+ String xmlOutput = cmsReq.getHttpReq().getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ CMS.debug("CMSServlet.java: xml parameter detected, returning xml");
+ outputXML(cmsReq.getHttpResp(), templateParams);
+ return;
+ }
+
+ if (httpParams != null) {
+ String httpTemplateName =
+ httpParams.getValueAsString(
+ TEMPLATE_NAME, null);
+
+ if (httpTemplateName != null) {
+ templateName = httpTemplateName;
+ }
+ }
+
+ if (templateParams == null)
+ templateParams = new CMSTemplateParams(null, null);
+
+ // #359630
+ // inject preserved http parameter into the template
+ if (httpParams != null) {
+ String preserved = httpParams.getValueAsString(
+ PRESERVED, null);
+
+ if (preserved != null) {
+ IArgBlock fixed = templateParams.getFixed();
+
+ if (fixed != null) {
+ fixed.set(PRESERVED, preserved);
+ }
+ }
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ template.renderOutput(bos, templateParams);
+ cmsReq.getHttpResp().setContentType("text/html");
+ cmsReq.getHttpResp().setContentLength(bos.size());
+ bos.writeTo(cmsReq.getHttpResp().getOutputStream());
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_OUT_TEMPLATE", templateName, e.toString()));
+ renderException(cmsReq,
+ new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE")));
+ return;
+ }
+ }
+
+ /**
+ * Output exception (unexpected error) template
+ * This is different from other templates in that if an exception occurs
+ * while rendering the exception a message is printed out directly.
+ * If the message gets an error an IOException is thrown.
+ * In others if an exception occurs while rendering the template the
+ * exception template (this) is called.
+ * <p>
+ * @param cmsReq the CS request to pass to template filler if any.
+ * @param e the unexpected exception
+ */
+ protected void renderException(CMSRequest cmsReq, EBaseException e)
+ throws IOException {
+ try {
+ Locale[] locale = new Locale[1];
+ CMSLoadTemplate loadTempl =
+ (CMSLoadTemplate) mTemplates.get(CMSRequest.EXCEPTION);
+ CMSTemplate template = getTemplate(loadTempl.mTemplateName,
+ cmsReq.getHttpReq(), locale);
+ ICMSTemplateFiller filler = loadTempl.mFiller;
+ CMSTemplateParams templateParams = null;
+
+ // When an exception occurs the exit is non-local which probably
+ // will leave the requestStatus value set to something other
+ // than CMSRequest.EXCEPTION, so force the requestStatus to
+ // EXCEPTION since it must be that if we're here.
+ cmsReq.setStatus(CMSRequest.EXCEPTION);
+
+ if (filler != null) {
+ templateParams = filler.getTemplateParams(
+ cmsReq, mAuthority, locale[0], e);
+ }
+ if (templateParams == null) {
+ templateParams = new CMSTemplateParams(null, CMS.createArgBlock());
+ }
+ if (e != null) {
+ templateParams.getFixed().set(
+ ICMSTemplateFiller.EXCEPTION, e.toString(locale[0]));
+ }
+
+ // just output arg blocks as XML
+ CMS.debug("CMSServlet.java: renderTemplate");
+ String xmlOutput = cmsReq.getHttpReq().getParameter("xml");
+ if (xmlOutput != null && xmlOutput.equals("true")) {
+ CMS.debug("CMSServlet.java: xml parameter detected, returning xml");
+ outputXML(cmsReq.getHttpResp(), templateParams);
+ return;
+ }
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ template.renderOutput(bos, templateParams);
+ cmsReq.getHttpResp().setContentType("text/html");
+ cmsReq.getHttpResp().setContentLength(bos.size());
+ bos.writeTo(cmsReq.getHttpResp().getOutputStream());
+ } catch (Exception ex) {
+ renderFinalError(cmsReq, ex);
+ }
+ }
+
+ public void renderFinalError(CMSRequest cmsReq, Exception ex)
+ throws IOException {
+ // this template is the last resort for all other unexpected
+ // errors in other templates so we can only output text.
+ HttpServletResponse httpResp = cmsReq.getHttpResp();
+
+ httpResp.setContentType("text/html");
+ ServletOutputStream out = httpResp.getOutputStream();
+
+ // replace $ERRORMSG with exception message if included.
+ String finalErrMsg = mFinalErrorMsg;
+ int tokenIdx = mFinalErrorMsg.indexOf(ERROR_MSG_TOKEN);
+
+ if (tokenIdx != -1) {
+ finalErrMsg =
+ mFinalErrorMsg.substring(0, tokenIdx) +
+ ex.toString() +
+ mFinalErrorMsg.substring(
+ tokenIdx + ERROR_MSG_TOKEN.length());
+ }
+ out.println(finalErrMsg);
+ return;
+ }
+
+ /**
+ * Invalidates a SSL Session. So client auth will happen again.
+ */
+ protected static void invalidateSSLSession(HttpServletRequest httpReq) {
+ SSLSocket s = null;
+
+ /*
+ try {
+ s = (SSLSocket) ((HTTPRequest) httpReq).getConnection().getSocket();
+ } catch (ClassCastException e) {
+ CMS.getLogger().log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_SSL_NO_INVALIDATE"));
+ // ignore.
+ return;
+ }
+ try {
+ s.invalidateSession();
+ s.resetHandshake();
+ }catch (SocketException se) {
+ }
+ */
+ return;
+ }
+
+ /**
+ * construct a authentication credentials to pass into authentication
+ * manager.
+ */
+ public static AuthCredentials getAuthCreds(
+ IAuthManager authMgr, IArgBlock argBlock, X509Certificate clientCert)
+ throws EBaseException {
+ // get credentials from http parameters.
+ String[] reqCreds = authMgr.getRequiredCreds();
+ AuthCredentials creds = new AuthCredentials();
+
+ for (int i = 0; i < reqCreds.length; i++) {
+ String reqCred = reqCreds[i];
+
+ if (reqCred.equals(IAuthManager.CRED_SSL_CLIENT_CERT)) {
+ // cert could be null;
+ creds.set(reqCred, new X509Certificate[] { clientCert}
+ );
+ } else {
+ String value = argBlock.getValueAsString(reqCred);
+
+ creds.set(reqCred, value); // value could be null;
+ }
+ }
+ // Inserted by bskim
+ creds.setArgBlock(argBlock);
+ // Insert end
+ return creds;
+ }
+
+ /**
+ * get ssl client authenticated certificate
+ */
+ protected X509Certificate
+ getSSLClientCertificate(HttpServletRequest httpReq)
+ throws EBaseException {
+
+ X509Certificate cert = null;
+
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_INFO,
+ CMS.getLogMessage("CMSGW_GETTING_SSL_CLIENT_CERT"));
+
+ // iws60 support Java Servlet Spec V2.2, attribute
+ // javax.servlet.request.X509Certificate now contains array
+ // of X509Certificates instead of one X509Certificate object
+ X509Certificate[] allCerts = (X509Certificate[]) httpReq.getAttribute(CERT_ATTR);
+
+ if (allCerts == null || allCerts.length == 0) {
+ throw new EBaseException("You did not provide a valid certificate for this operation");
+ }
+
+ cert = allCerts[0];
+
+ if (cert == null) {
+ // just don't have a cert.
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL"));
+ return null;
+ }
+
+ // convert to sun's x509 cert interface.
+ try {
+ byte[] certEncoded = cert.getEncoded();
+
+ cert = new X509CertImpl(certEncoded);
+ } catch (CertificateEncodingException e) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_ENCODE", e.getMessage()));
+ return null;
+ } catch (CertificateException e) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_DECODE", e.getMessage()));
+ return null;
+ }
+ return cert;
+ }
+
+ /**
+ * get a template based on result status.
+ */
+ protected CMSTemplate getTemplate(
+ String templateName, HttpServletRequest httpReq, Locale[] locale)
+ throws EBaseException, IOException {
+ // this converts to system dependent file seperator char.
+ if (mServletConfig == null) {
+ CMS.debug( "CMSServlet:getTemplate() - mServletConfig is null!" );
+ return null;
+ }
+ if (mServletConfig.getServletContext() == null) {
+ }
+ if (templateName == null) {
+ }
+ String realpath =
+ mServletConfig.getServletContext().getRealPath("/" + templateName);
+
+ if (realpath == null) {
+ mLogger.log(
+ ILogger.EV_SYSTEM, ILogger.S_OTHER, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_FIND_TEMPLATE", templateName));
+ throw new ECMSGWException(CMS.getLogMessage("CMSGW_ERROR_DISPLAY_TEMPLATE"));
+ }
+
+ File realpathFile = new File(realpath);
+ File templateFile =
+ getLangFile(httpReq, realpathFile, locale);
+ String charSet = httpReq.getCharacterEncoding();
+
+ if (charSet == null) {
+ charSet = "UTF8";
+ }
+ CMSTemplate template =
+ (CMSTemplate) mFileLoader.getCMSFile(templateFile, charSet);
+
+ return template;
+ }
+
+ /**
+ * log according to authority category.
+ */
+ protected void log(int event, int level, String msg) {
+ mLogger.log(event, mLogCategory, level,
+ "Servlet " + mId + ": " + msg);
+ }
+
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, mLogCategory, level,
+ "Servlet " + mId + ": " + msg);
+ }
+
+ /**
+ * get http parameters not to save from configuration.
+ */
+ protected void getDontSaveHttpParams(ServletConfig sc) {
+ String dontSaveParams = null;
+
+ try {
+ for (int i = 0; i < DONT_SAVE_HTTP_PARAMS.length; i++) {
+ mDontSaveHttpParams.addElement(DONT_SAVE_HTTP_PARAMS[i]);
+ }
+ dontSaveParams = sc.getInitParameter(
+ PROP_DONT_SAVE_HTTP_PARAMS);
+ if (dontSaveParams != null) {
+ StringTokenizer params =
+ new StringTokenizer(dontSaveParams, ",");
+
+ while (params.hasMoreTokens()) {
+ String param = params.nextToken();
+
+ mDontSaveHttpParams.addElement(param);
+ }
+ }
+ } catch (Exception e) {
+ // should never happen
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_NO_CONFIG_VALUE", PROP_DONT_SAVE_HTTP_PARAMS, e.toString()));
+ // default just in case.
+ for (int i = 0; i < DONT_SAVE_HTTP_PARAMS.length; i++) {
+ mDontSaveHttpParams.addElement(DONT_SAVE_HTTP_PARAMS[i]);
+ }
+ return;
+ }
+ }
+
+ /**
+ * get http headers to save from configuration.
+ */
+ protected void getSaveHttpHeaders(ServletConfig sc) {
+ try {
+ // init save http headers. default will always be saved.
+ for (int i = 0; i < SAVE_HTTP_HEADERS.length; i++) {
+ mSaveHttpHeaders.addElement(SAVE_HTTP_HEADERS[i]);
+ }
+
+ // now get from config file if there's more.
+ String saveHeaders =
+ sc.getInitParameter(PROP_SAVE_HTTP_HEADERS);
+
+ if (saveHeaders != null) {
+ StringTokenizer headers =
+ new StringTokenizer(saveHeaders, ",");
+
+ while (headers.hasMoreTokens()) {
+ String hdr = headers.nextToken();
+
+ mSaveHttpHeaders.addElement(hdr);
+ }
+ }
+ } catch (Exception e) {
+ // should never happen
+ log(ILogger.LL_WARN, CMS.getLogMessage("CMSGW_NO_CONFIG_VALUE", PROP_SAVE_HTTP_HEADERS, e.toString()));
+ return;
+ }
+ }
+
+ /**
+ * save http headers in a IRequest.
+ */
+ protected void saveHttpHeaders(
+ HttpServletRequest httpReq, IRequest req)
+ throws EBaseException {
+ Hashtable headers = new Hashtable();
+ Enumeration hdrs = mSaveHttpHeaders.elements();
+
+ while (hdrs.hasMoreElements()) {
+ String hdr = (String) hdrs.nextElement();
+ String val = httpReq.getHeader(hdr);
+
+ if (val != null) {
+ headers.put(hdr, val);
+ }
+ }
+ req.setExtData(IRequest.HTTP_HEADERS, headers);
+ }
+
+ /**
+ * save http headers in a IRequest.
+ */
+ protected void saveHttpParams(
+ IArgBlock httpParams, IRequest req) {
+ Hashtable saveParams = new Hashtable();
+
+ Enumeration names = httpParams.elements();
+
+ while (names.hasMoreElements()) {
+ String name = (String) names.nextElement();
+ Enumeration params = mDontSaveHttpParams.elements();
+ boolean dosave = true;
+
+ while (params.hasMoreElements()) {
+ String param = (String) params.nextElement();
+
+ if (name.equalsIgnoreCase(param)) {
+ dosave = false;
+ break;
+ }
+ }
+ if (dosave) {
+ // kmccarth
+ // fear not - service() calls toHashtable() which only
+ // retrieves string values.
+ // TODO - when we can use JDK5 features we should typecast
+ // the params until they get here
+ saveParams.put(name, httpParams.get(name));
+ }
+ }
+ req.setExtData(IRequest.HTTP_PARAMS, saveParams);
+ }
+
+ /**
+ * handy routine for getting a cert record given a serial number.
+ */
+ protected ICertRecord getCertRecord(BigInteger serialNo) {
+ if (mAuthority == null ||
+ !(mAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_NON_CERT_AUTH"));
+ return null;
+ }
+ ICertificateRepository certdb =
+ (ICertificateRepository) ((ICertificateAuthority) mAuthority).getCertificateRepository();
+
+ if (certdb == null) {
+ log(ILogger.LL_WARN, CMS.getLogMessage("CMSGW_CERT_DB_NULL", mAuthority.toString()));
+ return null;
+ }
+ ICertRecord certRecord = null;
+
+ try {
+ certRecord = certdb.readCertificateRecord(serialNo);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CERT_REC", serialNo.toString(16), e.toString()));
+ return null;
+ }
+ return certRecord;
+ }
+
+ /**
+ * handy routine for validating if a cert is from this CA.
+ * mAuthority must be a CA.
+ */
+ protected boolean isCertFromCA(X509Certificate cert) {
+ BigInteger serialno = cert.getSerialNumber();
+ X509CertImpl certInDB = (X509CertImpl) getX509Certificate(serialno);
+
+ if (certInDB == null || !certInDB.equals(cert))
+ return false;
+ return true;
+ }
+
+ /**
+ * handy routine for checking if a list of certs is from this CA.
+ * mAuthortiy must be a CA.
+ */
+ protected boolean areCertsFromCA(X509Certificate[] certs) {
+ for (int i = certs.length - 1; i >= 0; i--) {
+ if (!isCertFromCA(certs[i]))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * handy routine for getting a certificate from the certificate
+ * repository. mAuthority must be a CA.
+ */
+ protected X509Certificate getX509Certificate(BigInteger serialNo) {
+ if (mAuthority == null ||
+ !(mAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NOT_CERT_AUTH"));
+ return null;
+ }
+ ICertificateRepository certdb =
+ (ICertificateRepository) ((ICertificateAuthority) mAuthority).getCertificateRepository();
+
+ if (certdb == null) {
+ log(ILogger.LL_WARN, CMS.getLogMessage("CMSGW_CERT_DB_NULL", mAuthority.toString()));
+ return null;
+ }
+ X509Certificate cert = null;
+
+ try {
+ cert = certdb.getX509Certificate(serialNo);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_CERT_REC", serialNo.toString(16), e.toString()));
+ return null;
+ }
+ return cert;
+ }
+
+ /**
+ * instantiate a new filler from a class name,
+ * @return null if can't be instantiated, new instance otherwise.
+ */
+ protected ICMSTemplateFiller newFillerObject(String fillerClass) {
+ ICMSTemplateFiller filler = null;
+
+ try {
+ filler = (ICMSTemplateFiller)
+ Class.forName(fillerClass).newInstance();
+ } catch (Exception e) {
+ if ((e instanceof RuntimeException)) {
+ throw (RuntimeException) e;
+ } else {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("CMSGW_CANT_LOAD_FILLER", fillerClass, e.toString()));
+ return null;
+ }
+ }
+ return filler;
+ }
+
+ /**
+ * set default templates.
+ * subclasses can override, and should override at least the success
+ * template
+ */
+ protected void setDefaultTemplates(ServletConfig sc) {
+ // Subclasses should override these for diff templates and params in
+ // their constructors.
+ // Set a template name to null to not use these standard ones.
+ // When template name is set to null nothing will be displayed.
+ // Servlet is assumed to have rendered its own output.
+ // The only exception is the unexpected error template where the
+ // default one will always be used if template name is null.
+ String successTemplate = null;
+ String errorTemplate = null;
+ String unauthorizedTemplate = null;
+ String pendingTemplate = null;
+ String svcpendingTemplate = null;
+ String rejectedTemplate = null;
+ String unexpectedErrorTemplate = null;
+
+ String gateway = sc.getInitParameter("interface");
+ String authority = sc.getInitParameter(PROP_AUTHORITY);
+ if (authority == null) {
+ authority = sc.getInitParameter("authorityId");
+ }
+
+ try {
+ successTemplate = sc.getInitParameter(
+ PROP_SUCCESS_TEMPLATE);
+ if (successTemplate == null) {
+ successTemplate = SUCCESS_TEMPLATE;
+ if (gateway != null)
+ //successTemplate = "/"+gateway+successTemplate;
+ successTemplate = "/"+gateway+successTemplate;
+ }
+
+ errorTemplate = sc.getInitParameter(
+ PROP_ERROR_TEMPLATE);
+ if (errorTemplate == null) {
+ errorTemplate = ERROR_TEMPLATE;
+ if (gateway != null)
+ //errorTemplate = "/"+gateway+errorTemplate;
+ errorTemplate = "/"+gateway+errorTemplate;
+ }
+
+ unauthorizedTemplate = sc.getInitParameter(
+ PROP_UNAUTHORIZED_TEMPLATE);
+ if (unauthorizedTemplate == null) {
+ unauthorizedTemplate = UNAUTHORIZED_TEMPLATE;
+ if (gateway != null)
+ //unauthorizedTemplate = "/"+gateway+unauthorizedTemplate;
+ unauthorizedTemplate = "/"+gateway+unauthorizedTemplate;
+ }
+
+ pendingTemplate = sc.getInitParameter(
+ PROP_PENDING_TEMPLATE);
+ if (pendingTemplate == null) {
+ pendingTemplate = PENDING_TEMPLATE;
+ if (gateway != null)
+ //pendingTemplate = "/"+gateway+pendingTemplate;
+ pendingTemplate = "/"+gateway+pendingTemplate;
+ }
+
+ svcpendingTemplate = sc.getInitParameter(
+ PROP_SVC_PENDING_TEMPLATE);
+ if (svcpendingTemplate == null) {
+ svcpendingTemplate = SVC_PENDING_TEMPLATE;
+ if (gateway != null)
+ //svcpendingTemplate = "/"+gateway+svcpendingTemplate;
+ svcpendingTemplate = "/"+gateway+svcpendingTemplate;
+ }
+
+ rejectedTemplate = sc.getInitParameter(
+ PROP_REJECTED_TEMPLATE);
+ if (rejectedTemplate == null) {
+ rejectedTemplate = REJECTED_TEMPLATE;
+ if (gateway != null)
+ //rejectedTemplate = "/"+gateway+rejectedTemplate;
+ rejectedTemplate = "/"+gateway+rejectedTemplate;
+ }
+
+ unexpectedErrorTemplate = sc.getInitParameter(
+ PROP_EXCEPTION_TEMPLATE);
+ if (unexpectedErrorTemplate == null) {
+ unexpectedErrorTemplate = EXCEPTION_TEMPLATE;
+ if (gateway != null)
+ //unexpectedErrorTemplate = "/"+gateway+unexpectedErrorTemplate;
+ unexpectedErrorTemplate = "/"+gateway+unexpectedErrorTemplate;
+ }
+ } catch (Exception e) {
+ // this should never happen.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_IMP_INIT_SERV_ERR", e.toString(),
+ mId));
+ }
+
+ mTemplates.put(
+ CMSRequest.UNAUTHORIZED,
+ new CMSLoadTemplate(
+ PROP_UNAUTHORIZED_TEMPLATE, PROP_UNAUTHOR_TEMPLATE_FILLER,
+ unauthorizedTemplate, null));
+ mTemplates.put(
+ CMSRequest.SUCCESS,
+ new CMSLoadTemplate(
+ PROP_SUCCESS_TEMPLATE, PROP_SUCCESS_TEMPLATE_FILLER,
+ successTemplate, new GenSuccessTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.PENDING,
+ new CMSLoadTemplate(
+ PROP_PENDING_TEMPLATE, PROP_PENDING_TEMPLATE_FILLER,
+ pendingTemplate, new GenPendingTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.SVC_PENDING,
+ new CMSLoadTemplate(
+ PROP_SVC_PENDING_TEMPLATE, PROP_SVC_PENDING_TEMPLATE_FILLER,
+ svcpendingTemplate, new GenSvcPendingTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.REJECTED,
+ new CMSLoadTemplate(
+ PROP_REJECTED_TEMPLATE, PROP_REJECTED_TEMPLATE_FILLER,
+ rejectedTemplate, new GenRejectedTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.ERROR,
+ new CMSLoadTemplate(
+ PROP_ERROR_TEMPLATE, PROP_ERROR_TEMPLATE_FILLER,
+ errorTemplate, new GenErrorTemplateFiller()));
+ mTemplates.put(
+ CMSRequest.EXCEPTION,
+ new CMSLoadTemplate(
+ PROP_EXCEPTION_TEMPLATE, PROP_EXCEPTION_TEMPLATE_FILLER,
+ unexpectedErrorTemplate, new GenUnexpectedErrorTemplateFiller()));
+ }
+
+ /**
+ * handy routine to check if client is navigator based on user-agent.
+ */
+ public static boolean clientIsNav(HttpServletRequest httpReq) {
+ String useragent = httpReq.getHeader("user-agent");
+
+ if (useragent.startsWith("Mozilla") &&
+ useragent.indexOf("MSIE") == -1)
+ return true;
+ return false;
+ }
+
+ /**
+ * handy routine to check if client is msie based on user-agent.
+ */
+ public static boolean clientIsMSIE(HttpServletRequest httpReq) {
+ String useragent = httpReq.getHeader("user-agent");
+
+ if (useragent != null && useragent.indexOf("MSIE") != -1)
+ return true;
+ return false;
+ }
+
+ /**
+ * handy routine to check if client is cartman based on hidden http input
+ * set using cartman JS. (no other way to tell)
+ */
+ private static String CMMF_RESPONSE = "cmmfResponse";
+ public static boolean doCMMFResponse(IArgBlock httpParams) {
+ if (httpParams.getValueAsBoolean(CMMF_RESPONSE, false))
+ return true;
+ else
+ return false;
+ }
+
+ private static final String IMPORT_CERT = "importCert";
+ private static final String IMPORT_CHAIN = "importCAChain";
+ private static final String IMPORT_CERT_MIME_TYPE = "importCertMimeType";
+ // default mime type
+ private static final String
+ NS_X509_USER_CERT = "application/x-x509-user-cert";
+ private static final String
+ NS_X509_EMAIL_CERT = "application/x-x509-email-cert";
+
+ // CMC mime types
+ public static final String
+ SIMPLE_ENROLLMENT_REQUEST = "application/pkcs10";
+ public static final String
+ SIMPLE_ENROLLMENT_RESPONSE = "application/pkcs7-mime";
+ public static final String
+ FULL_ENROLLMENT_REQUEST = "application/pkcs7-mime";
+ public static final String
+ FULL_ENROLLMENT_RESPONSE = "application/pkcs7-mime";
+
+ /**
+ * handy routine to check if client want full enrollment response
+ */
+ public static String FULL_RESPONSE = "fullResponse";
+ public static boolean doFullResponse(IArgBlock httpParams) {
+ if (httpParams.getValueAsBoolean(FULL_RESPONSE, false))
+ return true;
+ else
+ return false;
+ }
+
+ /**
+ * @return false if import cert directly set to false.
+ * @return true if import cert directly is true and import cert.
+ */
+ protected boolean checkImportCertToNav(
+ HttpServletResponse httpResp, IArgBlock httpParams, X509CertImpl cert)
+ throws EBaseException {
+ if (!httpParams.getValueAsBoolean(IMPORT_CERT, false)) {
+ return false;
+ }
+ boolean importCAChain =
+ httpParams.getValueAsBoolean(IMPORT_CHAIN, true);
+ // XXX Temporary workaround because of problem with passing Mime type
+ boolean emailCert =
+ httpParams.getValueAsBoolean("emailCert", false);
+ String importMimeType = (emailCert) ?
+ httpParams.getValueAsString(IMPORT_CERT_MIME_TYPE, NS_X509_EMAIL_CERT) :
+ httpParams.getValueAsString(IMPORT_CERT_MIME_TYPE, NS_X509_USER_CERT);
+
+ // String importMimeType =
+ // httpParams.getValueAsString(
+ // IMPORT_CERT_MIME_TYPE, NS_X509_USER_CERT);
+ importCertToNav(httpResp, cert, importMimeType, importCAChain);
+ return true;
+ }
+
+ /**
+ * handy routine to import cert to old navigator in nav mime type.
+ */
+ public void importCertToNav(
+ HttpServletResponse httpResp, X509CertImpl cert,
+ String contentType, boolean importCAChain)
+ throws EBaseException {
+ ServletOutputStream out = null;
+ byte[] encoding = null;
+
+ CMS.debug("CMSServlet: importCertToNav " +
+ "contentType=" + contentType + " " +
+ "importCAChain=" + importCAChain);
+ try {
+ out = httpResp.getOutputStream();
+ // CA chain.
+ if (importCAChain) {
+ CertificateChain caChain = null;
+ X509Certificate[] caCerts = null;
+ PKCS7 p7 = null;
+
+ caChain = ((ICertAuthority) mAuthority).getCACertChain();
+ caCerts = caChain.getChain();
+
+ // set user + CA cert chain in pkcs7
+ X509CertImpl[] userChain =
+ new X509CertImpl[caCerts.length + 1];
+
+ userChain[0] = cert;
+ int m = 1, n = 0;
+
+ for (; n < caCerts.length; m++, n++) {
+ userChain[m] = (X509CertImpl) caCerts[n];
+
+ /*
+ System.out.println(
+ m+"th Cert "+userChain[m].toString());
+ */
+ }
+ p7 = new PKCS7(new AlgorithmId[0],
+ new ContentInfo(new byte[0]),
+ userChain,
+ new SignerInfo[0]);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ p7.encodeSignedData(bos, false);
+ encoding = bos.toByteArray();
+ CMS.debug("CMServlet: return P7 " + CMS.BtoA(encoding));
+ } else {
+ encoding = cert.getEncoded();
+ CMS.debug("CMServlet: return Certificate " + CMS.BtoA(encoding));
+ }
+ httpResp.setContentType(contentType);
+ out.write(encoding);
+ } catch (IOException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_RET_CERT_IMPORT_ERR", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_RETURNING_CERT"));
+ } catch (CertificateEncodingException e) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER,
+ ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_NO_ENCODED_IMP_CERT", e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_ENCODING_ISSUED_CERT"));
+ }
+ }
+
+ protected static void saveAuthToken(IAuthToken token, IRequest req) {
+ if (token != null && req != null)
+ req.setExtData(IRequest.AUTH_TOKEN, token);
+
+ // # 56230 - expose auth token parameters to the policy predicate
+ if (token != null && req != null) {
+ Enumeration e = token.getElements();
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+ String[] x1 = token.getInStringArray(n);
+ if (x1 != null) {
+ for (int i = 0; i < x1.length; i++) {
+ CMS.debug("Setting " + IRequest.AUTH_TOKEN + "-" + n +
+ "(" + i + ")=" + x1[i]);
+ req.setExtData(IRequest.AUTH_TOKEN + "-" + n + "(" + i + ")",
+ x1[i]);
+ }
+ } else {
+ String x = token.getInString(n);
+ if (x != null) {
+ CMS.debug("Setting " + IRequest.AUTH_TOKEN + "-" + n + "=" + x);
+ req.setExtData(IRequest.AUTH_TOKEN + "-" + n, x);
+ }
+ }
+ } // while
+ } // if
+ }
+
+ protected IAuthToken getAuthToken(IRequest req) {
+ return req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+ }
+
+ protected static boolean connectionIsSSL(HttpServletRequest httpReq) {
+ return httpReq.isSecure();
+ }
+
+ /**
+ * handy routine for getting agent's relative path
+ */
+ protected String getRelPath(IAuthority authority) {
+ if (authority instanceof ICertificateAuthority)
+ return "ca/";
+ else if (authority instanceof IRegistrationAuthority)
+ return "ra/";
+ else if (authority instanceof IKeyRecoveryAuthority)
+ return "kra/";
+ else
+ return "/";
+ }
+
+ /**
+ * A system certificate such as the CA signing certificate
+ * should not be allowed to delete.
+ * The main purpose is to avoid revoking the self signed
+ * CA certificate accidentially.
+ */
+ protected boolean isSystemCertificate(BigInteger serialNo) {
+ if (!(mAuthority instanceof ICertificateAuthority)) {
+ return false;
+ }
+ X509Certificate caCert =
+ ((ICertificateAuthority)mAuthority).getCACert();
+ if (caCert != null) {
+ /* only check this if we are self-signed */
+ if (caCert.getSubjectDN().equals(caCert.getIssuerDN())) {
+ if (caCert.getSerialNumber().equals(serialNo)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * make a CRL entry from a serial number and revocation reason.
+ * @return a RevokedCertImpl that can be entered in a CRL.
+ */
+ protected RevokedCertImpl formCRLEntry(
+ BigInteger serialNo, RevocationReason reason)
+ throws EBaseException {
+ CRLReasonExtension reasonExt = new CRLReasonExtension(reason);
+ CRLExtensions crlentryexts = new CRLExtensions();
+
+ try {
+ crlentryexts.set(CRLReasonExtension.NAME, reasonExt);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_CRL_REASON", reason.toString(), e.toString()));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_ERROR_SETTING_CRLREASON"));
+ }
+ RevokedCertImpl crlentry =
+ new RevokedCertImpl(serialNo, CMS.getCurrentDate(), crlentryexts);
+
+ return crlentry;
+ }
+
+ /**
+ * check if a certificate (serial number) is revoked on a CA.
+ * @return true if cert is marked revoked in the CA's database.
+ * @return false if cert is not marked revoked.
+ */
+ protected boolean certIsRevoked(BigInteger serialNum)
+ throws EBaseException {
+ ICertRecord certRecord = getCertRecord(serialNum);
+
+ if (certRecord == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_BAD_CERT_SER_NUM", String.valueOf(serialNum)));
+ throw new ECMSGWException(
+ CMS.getLogMessage("CMSGW_INVALID_CERT"));
+ }
+ if (certRecord.getStatus().equals(ICertRecord.STATUS_REVOKED))
+ return true;
+ return false;
+ }
+
+ public static String generateSalt() {
+ Random rnd = new Random();
+ String salt = new Integer( rnd.nextInt() ).toString();
+ return salt;
+ }
+
+ protected String hashPassword(String pwd) {
+ String salt = generateSalt();
+ byte[] pwdDigest = mSHADigest.digest((salt + pwd).getBytes());
+ String b64E = com.netscape.osutil.OSUtil.BtoA(pwdDigest);
+
+ return "{SHA}" + salt + ";" + b64E;
+ }
+
+ /**
+ * @param req http servlet request
+ * @param realpathFile the file to get.
+ * @param locale array of at least one to be filled with locale found.
+ */
+ public static File getLangFile(
+ HttpServletRequest req, File realpathFile, Locale[] locale)
+ throws IOException {
+ File file = null;
+ String acceptLang = req.getHeader("accept-language");
+
+ if (acceptLang != null && !acceptLang.equals("")) {
+ StringTokenizer tokenizer = new StringTokenizer(acceptLang, ",");
+ int numLangs = tokenizer.countTokens();
+
+ if (numLangs > 0) {
+ // languages are searched in order.
+ String parent = realpathFile.getParent();
+
+ if (parent == null) {
+ parent = "." + File.separatorChar;
+ }
+ String name = realpathFile.getName();
+
+ if (name == null) { // filename should never be null.
+ throw new IOException("file has no name");
+ }
+ int i;
+
+ for (i = 0; i < numLangs; i++) {
+ String lang = null;
+ String token = tokenizer.nextToken();
+
+ int semicolon = token.indexOf(';');
+
+ if (semicolon == -1) {
+ lang = token.trim();
+ } else {
+ if (semicolon < 2)
+ continue; // protocol error.
+ lang = token.substring(0, semicolon).trim();
+ }
+ // if browser locale is the same as default locale,
+ // use the default form. (is this the right thing to do ?)
+ Locale l = getLocale(lang);
+
+ if (Locale.getDefault().equals(l)) {
+ locale[0] = l;
+ file = realpathFile;
+ break;
+ }
+
+ String langfilepath =
+ parent + File.separatorChar +
+ lang + File.separatorChar + name;
+
+ file = new File(langfilepath);
+ if (file.exists()) {
+ locale[0] = getLocale(lang);
+ break;
+ }
+ }
+ // if no file for lang was found use default
+ if (i == numLangs) {
+ file = realpathFile;
+ locale[0] = Locale.getDefault();
+ }
+ }
+ } else {
+ // use default if accept-language is not availabe
+ file = realpathFile;
+ locale[0] = Locale.getDefault();
+ }
+ return file;
+ }
+
+ public static Locale getLocale(String lang) {
+ int dash = lang.indexOf('-');
+
+ if (dash == -1)
+ return new Locale(lang, "");
+ else
+ return new Locale(lang.substring(0, dash), lang.substring(dash + 1));
+ }
+
+ public IAuthToken authenticate(CMSRequest req)
+ throws EBaseException {
+ return authenticate(req, mAuthMgr);
+ }
+
+ public IAuthToken authenticate(HttpServletRequest httpReq)
+ throws EBaseException {
+ return authenticate(httpReq, mAuthMgr);
+ }
+
+ public IAuthToken authenticate(CMSRequest req, String authMgrName)
+ throws EBaseException {
+ IAuthToken authToken = authenticate(req.getHttpReq(),
+ authMgrName);
+
+ saveAuthToken(authToken, req.getIRequest());
+ return authToken;
+ }
+
+ /**
+ * Authentication
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTH_FAIL used when authentication
+ * fails (in case of SSL-client auth, only webserver env can pick up the
+ * SSL violation; CS authMgr can pick up cert mis-match, so this event
+ * is used)
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTH_SUCCESS used when authentication
+ * succeeded
+ * </ul>
+ * @exception EBaseException an error has occurred
+ */
+ public IAuthToken authenticate(HttpServletRequest httpReq, String authMgrName)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = ILogger.UNIDENTIFIED;
+ String auditAuthMgrID = ILogger.UNIDENTIFIED;
+ String auditUID = ILogger.UNIDENTIFIED;
+
+ // ensure that any low-level exceptions are reported
+ // to the signed audit log and stored as failures
+ try {
+ String getClientCert = mGetClientCert;
+
+ IArgBlock httpArgs = CMS.createArgBlock(toHashtable(httpReq));
+ SessionContext ctx = SessionContext.getContext();
+ String ip = httpReq.getRemoteAddr();
+ CMS.debug("IP: " + ip);
+
+ if (ip != null) {
+ ctx.put(SessionContext.IPADDRESS, ip);
+ }
+ if (authMgrName != null) {
+ CMS.debug("AuthMgrName: " + authMgrName);
+ ctx.put(SessionContext.AUTH_MANAGER_ID, authMgrName);
+ }
+ // put locale into session context
+ ctx.put(SessionContext.LOCALE, getLocale(httpReq));
+
+ //
+ // check ssl client authentication if specified.
+ //
+ X509Certificate clientCert = null;
+
+ if (getClientCert != null && getClientCert.equals("true")) {
+ CMS.debug("CMSServlet: retrieving SSL certificate");
+ clientCert = getSSLClientCertificate(httpReq);
+ }
+
+ //
+ // check authentication by auth manager if any.
+ //
+ if (authMgrName == null) {
+
+ // Fixed Blackflag Bug #613900: Since this code block does
+ // NOT actually constitute an authentication failure, but
+ // rather the case in which a given servlet has been correctly
+ // configured to NOT require an authentication manager, the
+ // audit message called LOGGING_SIGNED_AUDIT_AUTH_FAIL has
+ // been removed.
+
+ CMS.debug("CMSServlet: no authMgrName");
+ return null;
+ } else {
+ // save the "Subject DN" of this certificate in case it
+ // must be audited as an authentication failure
+ if (clientCert == null) {
+ CMS.debug("CMSServlet: no client certificate found");
+ } else {
+ String certUID = clientCert.getSubjectDN().getName();
+ CMS.debug("CMSServlet: certUID=" + certUID);
+
+ if (certUID != null) {
+ certUID = certUID.trim();
+
+ if (!(certUID.equals(""))) {
+ // reset the "auditUID"
+ auditUID = certUID;
+ }
+ }
+ }
+
+ // reset the "auditAuthMgrID"
+ auditAuthMgrID = authMgrName;
+ }
+ AuthToken authToken = CMSGateway.checkAuthManager(httpReq,
+ httpArgs,
+ clientCert,
+ authMgrName);
+ if (authToken == null) {
+ return null;
+ }
+ String userid = authToken.getInString(IAuthToken.USER_ID);
+
+ CMS.debug("CMSServlet: userid=" + userid);
+
+ if (userid != null) {
+ ctx.put(SessionContext.USER_ID, userid);
+ }
+
+ // reset the "auditSubjectID"
+ auditSubjectID = auditSubjectID();
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_SUCCESS,
+ auditSubjectID,
+ ILogger.SUCCESS,
+ auditAuthMgrID);
+
+ audit(auditMessage);
+
+ return authToken;
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTH_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditAuthMgrID,
+ auditUID);
+ audit(auditMessage);
+
+ // rethrow the specific exception to be handled later
+ throw eAudit1;
+ }
+ }
+
+ public AuthzToken authorize(String authzMgrName, IAuthToken authToken,
+ String exp) throws EBaseException {
+ AuthzToken authzToken = mAuthz.authorize(authzMgrName, authToken,
+ exp);
+ return authzToken;
+ }
+
+ /**
+ * Authorize must occur after Authenticate
+ * <P>
+ *
+ * <ul>
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_FAIL used when authorization
+ * has failed
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS used when authorization
+ * is successful
+ * <li>signed.audit LOGGING_SIGNED_AUDIT_ROLE_ASSUME used when user assumes a
+ * role (in current CS that's when one accesses a role port)
+ * </ul>
+ * @param authzMgrName string representing the name of the authorization
+ * manager
+ * @param authToken the authentication token
+ * @param resource a string representing the ACL resource id as defined in
+ * the ACL resource list
+ * @param operation a string representing one of the operations as defined
+ * within the ACL statement (e. g. - "read" for an ACL statement containing
+ * "(read,write)")
+ * @exception EBaseException an error has occurred
+ * @return the authorization token
+ */
+ public AuthzToken authorize(String authzMgrName, IAuthToken authToken,
+ String resource, String operation)
+ throws EBaseException {
+ String auditMessage = null;
+ String auditSubjectID = auditSubjectID();
+ String auditGroupID = auditGroupID();
+ String auditID = auditSubjectID;
+ String auditACLResource = resource;
+ String auditOperation = operation;
+
+
+ SessionContext auditContext = SessionContext.getExistingContext();
+ String authManagerId = null;
+
+ if(auditContext != null) {
+ authManagerId = (String) auditContext.get(SessionContext.AUTH_MANAGER_ID);
+
+ if(authManagerId != null && authManagerId.equals("TokenAuth")) {
+ if (auditSubjectID.equals(ILogger.NONROLEUSER) ||
+ auditSubjectID.equals(ILogger.UNIDENTIFIED)) {
+ CMS.debug("CMSServlet: in authorize... TokenAuth auditSubjectID unavailable, changing to auditGroupID");
+ auditID = auditGroupID;
+ }
+ }
+ }
+
+ // "normalize" the "auditACLResource" value
+ if (auditACLResource != null) {
+ auditACLResource = auditACLResource.trim();
+ }
+
+ // "normalize" the "auditOperation" value
+ if (auditOperation != null) {
+ auditOperation = auditOperation.trim();
+ }
+
+ if (authzMgrName == null) {
+ // Fixed Blackflag Bug #613900: Since this code block does
+ // NOT actually constitute an authorization failure, but
+ // rather the case in which a given servlet has been correctly
+ // configured to NOT require an authorization manager, the
+ // audit message called LOGGING_SIGNED_AUDIT_AUTHZ_FAIL and
+ // the audit message called LOGGING_SIGNED_AUDIT_ROLE_ASSUME
+ // (marked as a failure) have been removed.
+
+ return null;
+ }
+
+ try {
+ AuthzToken authzTok = mAuthz.authorize(authzMgrName,
+ authToken,
+ resource,
+ operation);
+
+ if (authzTok != null) {
+ // store a message in the signed audit log file
+ 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,
+ auditID,
+ ILogger.SUCCESS,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+ } else {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+ }
+
+ return authzTok;
+ } catch (EBaseException eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return null;
+ } catch (Exception eAudit1) {
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_AUTHZ_FAIL,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditACLResource,
+ auditOperation);
+
+ audit(auditMessage);
+
+ // store a message in the signed audit log file
+ auditMessage = CMS.getLogMessage(
+ LOGGING_SIGNED_AUDIT_ROLE_ASSUME,
+ auditSubjectID,
+ ILogger.FAILURE,
+ auditGroups(auditSubjectID));
+
+ audit(auditMessage);
+
+ return null;
+ }
+ }
+
+ /**
+ * Signed Audit Log
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to store messages to the signed audit log.
+ * <P>
+ *
+ * @param msg signed audit log message
+ */
+ protected void audit(String msg) {
+ // in this case, do NOT strip preceding/trailing whitespace
+ // from passed-in String parameters
+
+ if (mSignedAuditLogger == null) {
+ return;
+ }
+
+ mSignedAuditLogger.log(ILogger.EV_SIGNED_AUDIT,
+ null,
+ ILogger.S_SIGNED_AUDIT,
+ ILogger.LL_SECURITY,
+ msg);
+ }
+
+ /**
+ * Signed Audit Log Subject ID
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to obtain the "SubjectID" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditSubjectID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == 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;
+ }
+
+ /**
+ * Signed Audit Log Group ID
+ *
+ * This method is inherited by all extended "CMSServlet"s,
+ * and is called to obtain the "gid" for
+ * a signed audit log message.
+ * <P>
+ *
+ * @return id string containing the signed audit log message SubjectID
+ */
+ protected String auditGroupID() {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == 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;
+ }
+
+ /**
+ * Signed Audit Groups
+ *
+ * This method is called to extract all "groups" associated
+ * with the "auditSubjectID()".
+ * <P>
+ *
+ * @param id string containing the signed audit log message SubjectID
+ * @return a delimited string of groups associated
+ * with the "auditSubjectID()"
+ */
+ private String auditGroups(String SubjectID) {
+ // if no signed audit object exists, bail
+ if (mSignedAuditLogger == null) {
+ return null;
+ }
+
+ if ((SubjectID == null) ||
+ (SubjectID.equals(ILogger.UNIDENTIFIED))) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ Enumeration groups = null;
+
+ try {
+ groups = mUG.findGroups("*");
+ } catch (Exception e) {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+
+ StringBuffer membersString = new StringBuffer();
+
+ while (groups.hasMoreElements()) {
+ IGroup group = (IGroup) groups.nextElement();
+
+ if (group.isMember(SubjectID) == true) {
+ if (membersString.length()!= 0) {
+ membersString.append(", ");
+ }
+
+ membersString.append(group.getGroupID());
+ }
+ }
+
+ if (membersString.length()!=0) {
+ return membersString.toString();
+ } else {
+ return ILogger.SIGNED_AUDIT_EMPTY_VALUE;
+ }
+ }
+
+ /**
+ * Retrieves locale based on the request.
+ */
+ 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 void outputResult(HttpServletResponse httpResp,
+ String contentType, byte[] content) {
+ try {
+ OutputStream os = httpResp.getOutputStream();
+
+ httpResp.setContentType(contentType);
+ httpResp.setContentLength(content.length);
+ os.write(content);
+ os.flush();
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", e.toString()));
+ return;
+ }
+ }
+
+ protected void outputError(HttpServletResponse httpResp, String errorString) {
+ outputError(httpResp, FAILURE, errorString, null);
+ }
+
+ protected void outputError(HttpServletResponse httpResp, String errorString, String requestId) {
+ outputError(httpResp, FAILURE, errorString, null);
+ }
+
+ protected void outputError(HttpServletResponse httpResp, String status, String errorString, String requestId) {
+ XMLObject xmlObj = null;
+ try {
+ xmlObj = new XMLObject();
+ Node root = xmlObj.createRoot("XMLResponse");
+ xmlObj.addItemToContainer(root, "Status", status);
+ xmlObj.addItemToContainer(root, "Error", errorString);
+ if (requestId != null) {
+ xmlObj.addItemToContainer(root, "RequestId", requestId);
+ }
+ byte[] cb = xmlObj.toByteArray();
+
+ OutputStream os = httpResp.getOutputStream();
+ httpResp.setContentType("application/xml");
+ httpResp.setContentLength(cb.length);
+ os.write(cb);
+ os.flush();
+ return;
+ } catch (Exception ee) {
+ CMS.debug("Failed to send XML output to the server.");
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSGW_ERR_BAD_SERV_OUT_STREAM", "", ee.toString()));
+ }
+ }
+
+ 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 == '"') {
+ 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;
+ }
+
+}
+