Sie sind auf Seite 1von 13

/*

* CNSControlServlet.java
*
* Created on May 16, 2002, 10:20 AM
*/
package com.bottomline.cns.control;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.bottomline.cns.CNSBusLogic.CNSLogicFactory;
import com.bottomline.cns.CNSBusLogic.interfaces.ICNSUserLogic;
import com.bottomline.cns.utils.CNSConsts;
import com.bottomline.cns.utils.CNSUtil;
import com.bottomline.cns.utils.LoaderUtility;
import com.bottomline.utils.CNSXSRFBean;
import com.bottomline.utils.TokenProcessor;
import com.bottomline.utils.logger.Logger;
import com.bottomline.webseries.control.ActionBase;
import com.bottomline.webseries.control.ControlServletNT;
import com.bottomline.webseries.control.RequestForm;
import com.bottomline.webseries.control.RequestForward;
import com.bottomline.webseries.control.RequestMapping;
import com.bottomline.webseries.logic.LogicFactoryNT;
import com.bottomline.webseries.logic.StateManagerLogic;
import com.bottomline.webseries.model.UserAuthType;
import com.bottomline.webseries.model.UserModel;
/**
*
* @author mryan
* @version
*/
//changed parent from ControlServlet to ControlServletNT
public class CNSControlServlet extends ControlServletNT
{
/** Parameter constants for CNS-specific parameters
*/
protected static final String kInitParam_PasswordExpireDaysMaximum = "passwo
rdExpireDaysMaximum";
protected static final String kInitParam_AccountDisableDaysMaximum = "accoun
tDisableDaysMaximum";
// 504-RFS00023
protected static final String kInitParam_UserSessionTimeout = "userSessionTi
meout";
protected static int m_passwordExpireDaysMaximum = 90;
protected static int m_accountDisableDaysMaximum = 90;
// 504-RFS00023
public static int m_userSessionTimeout = -1;
private static HashSet hs = new HashSet();
/** Creates new CNSControlServlet */
public CNSControlServlet ()
{
}
public void log( String message )
{
this.initLogging();
Logger.debug(this, message );
}
public void log(String message, int level)
{
log( message );
}
/**
* Ask the specified Action instance to handle this request. Return
* the <code>RequestForward</code> instance (if any) returned by
* the called <code>Action</code>.
*
* <p>Overriden for three reasons:
*
* <ol>
* <li>As an optimization, if we are calling this method immediately after a
successful
* logon, there is no reason to call stateManager.saveState</li>
* <li>It is possible (though rare) for action.perform to return null. This
* can happen when a submit doesn't want to generate page refresh. This tend
s
* to happen only in highly frame intensive apps (like CNS), and even then,
* not very often. In any case, a check is made allow for <code>forward</cod
e>
* to be null.</li>
* <li>A change is also made to use the new {@link StateManagerLogic} logic
* to save the user state, if neccessary. (Note that in the core default
* state management, this call will do nothing, because the state is already
* saved in the page. It is needed for other state management systems,
* however.)</li>
* @param action The Action to process this request
* @param mapping The RequestMapping we are processing
* @param formInstance The RequestForm we are processing
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet exception occurs
*/
protected RequestForward innerProcessActionPerform(ActionBase action,
RequestMapping mapping,
RequestForm formInstance,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// LLW - Note, we can't just call super.processActionPerform here due
// to the location of the (forward != null) check. So, if the parent
// class changes, we'll need to make those same changes here. Not the
// best solution, but the only one we have at the moment.
// initialize the action
action.init(request);
// perform the requested action
RequestForward forward = action.perform(mapping, formInstance, request,
response);
// find out if we need to reset the help page
String helpPage = null;
if (forward != null)
helpPage = forward.getHelpPage();
if(helpPage == null)
helpPage = mapping.getHelpPage();
if(helpPage != null)
action.setStateValue(action.HELP_PAGE_KEY, helpPage, request);
// save any state values required
action.saveStateValues(request, response);
//if we have just logged on, we do not need to save state since it has j
ust been created
// String path = forward.getPath();
if ( forward == null || !forward.getPath().equals("/logdir.jsp") && !for
ward.getPath().equals("/CNSLoadTandC.do") && !forward.getPath().equals("/TermsAn
dConditions.jsp") )
{
// Some state management implementations need to be called here to
// record the state produced by the action.
StateManagerLogic stateManager = LogicFactoryNT.createStateManagment
Logic( this );
if ( stateManager != null )
{
try
{
stateManager.saveState( this,request,response );
Logger.debug( this, "***updating state table***");
}
catch(Exception ex)
{
Logger.error(this, ex);
}
}
}
return forward;
}
public int processCookie(HttpServletRequest request, HttpServletResponse res
ponse, boolean deadman)
{
UserAuthType ret = UserAuthType.NOTAUTHORIZED;
StateManagerLogic stateManager = LogicFactoryNT.createStateManagmentLogi
c( this );
if ( stateManager != null )
{
try
{
ret = stateManager.restoreState( this,request,response );
}
catch(Exception ex)
{
Logger.error( this, ex);
ret = UserAuthType.AUTHORIZED;
}
}
if ( ret == UserAuthType.TIMEOUT )
{
// Set errorMessage attribute with timeout message to be shown in lo
gin screen
// AEY-TODO: Eliminate hardcoded string
request.setAttribute("errorMessage", "Please log in again.");
// Delete all existing cookies
CNSUtil.deleteAllCookies(request, response, true);
}
return ret.toInt();
}
protected static boolean statInitLogging = false;
protected void initLogging()
{
if ( !statInitLogging )
{
// Now do new stuff
ServletConfig config = getServletConfig();
String sRealPath = this.getServletContext().getRealPath( "/WEB-INF/
");
sRealPath = sRealPath + "CNSLog.txt";
CNSUtil.setLogFileLoc( sRealPath );
statInitLogging = true;
}
}
/**
* Initialize the MessageResources bundle for this application, if any.
*
* @exception ServletException if we cannot initialize these resources
*/
protected void initApplication() throws ServletException
{
// Run the parent class' code
super.initApplication();
// 504-RFS00023
m_userSessionTimeout = CNSConsts.kUserTimeout ; // default value = 30
// check in properties file first. then check in web.xml.
// finally use default if not used in both these files.
Properties props = null;
try {
String sPropPath = this.getServletContext().getRealPath("/WEB-IN
F/cns-common.properties");
props = LoaderUtility.loadPropertiesByContext(sPropPath);
// DB version
CNSConsts.WEB_INF_PATH = this.getServletContext().getRealPath("/
WEB-INF/");
// DB version
} catch(Exception ex) {
props=null;
}
String tout = null;
if (props == null) {
// check in web.xml if not found in properties file.
ServletConfig cfg = getServletConfig();
/*
Enumeration enx = cfg.getInitParameterNames();
while (enx.hasMoreElements()) {
Object key = enx.nextElement();
Object val = cfg.getInitParameter(key.toString());
System.out.println("K: ("+key.toString()+") V: ("+val.toString()
+").");

}
*/
tout = cfg.getInitParameter(kInitParam_UserSessionTimeout);
if (tout != null) {
Logger.info("Using user session timeout from web.xml file.");
}
} else {
tout = props.getProperty(kInitParam_UserSessionTimeout);
if (tout != null) {
Logger.info("Using user session timeout from cns-common.properti
es file.");
}
}

if (tout != null) {
try {
m_userSessionTimeout = Integer.parseInt(tout);
} catch (Exception e) {
// use default
Logger.info("Warn: Using default user session timeout: ("+m_user
SessionTimeout+") instead of configured value: ("+tout+").");
m_userSessionTimeout = CNSConsts.kUserTimeout;
}
}
//set idle time timeout for user
//super.setUserTimeout( CNSConsts.kUserTimeout );
// 504-RFS00023
super.setUserTimeout( getUserSessionTimeout() );
initLogging();
/**
* Purpose: code to load the peoperty file.
* Helps to fix the 503-Ethical hack H1 (Cross Site Scripting INPV-003).
Post use is in the CNSUtil class.
* Argement to loadFilterProperties(arg) method id file mentioned is loc
ated relative to WEB-INF folder
* Date: 01/11/06
* Author: Amol
*/
try {
String sRealPath = this.getServletContext().getRealPath("/WEB-IN
F/filter.properties");
LoaderUtility.loadFilterPropertiesByContext(sRealPath);
} catch(Exception ex) {
Logger.error("Loading filter.properties failed: ",ex);
}
//End
// Now do new stuff
ServletConfig config = getServletConfig();
// Get CNS-specific parameters from iPlanet registry...
String param = config.getInitParameter(kInitParam_PasswordExpireDaysMaxi
mum);
if (param != null)
{
try
{
m_passwordExpireDaysMaximum = Integer.parseInt(param);
}
catch (NumberFormatException ex)
{
}
}
param = config.getInitParameter(kInitParam_AccountDisableDaysMaximum);
if (param != null)
{
try
{
m_accountDisableDaysMaximum = Integer.parseInt(param);
}
catch (NumberFormatException ex)
{
}
}
String sRealPath = this.getServletContext().getRealPath("/WEB-INF/https-
method.properties");
getNavMenuAction(sRealPath);
}
protected void initMapping() throws IOException, ServletException
{
//mjr - does this does do anything
//String sAppPath = getServletConfig().getInitParameter("appPath");
//CNSConsts.setAppPath( sAppPath );
super.initMapping();
}
protected RequestForward processActionPerform(ActionBase action,
RequestMapping mapping,
RequestForm formInstance,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
///RequestForward forward = super.processActionPerform(action, mapping,
formInstance, request, response);
RequestForward forward = innerProcessActionPerform(action, mapping, form
Instance, request, response);

//if the action is error or logoff it means an error occured, we want to
write the stack trace to the log
if( forward != null )
{
String sAction = forward.getName();
if (sAction.equals("error") || sAction.equals("logoff"))
{
String actionClass = mapping.getType();
//String sStackTrace = CNSUtil.getCurrentStackAsString();
//System.out.println( SBAlloc.freeAndGetString( SBAlloc.get(800)
.append( sAction ).append( " called. Stack is " ).append( sStackTrace ) ) );
//System.out.println("*** ERROR OR LOGOFF GETTING CALLED **** ac
tion: " + actionClass);
Logger.info( this, "*** ERROR OR LOGOFF GETTING CALLED **** acti
on: " + actionClass);
}
}


return forward;
}
protected void processRequestForward(RequestForward forward,
RequestMapping mapping,
RequestForm formInstance,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
HttpSession sess = request.getSession();
if( forward != null )
{
String path = forward.getPath();
super.processRequestForward( forward,
mapping,
formInstance,
request,
response);
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
//Modifying the code to accomodate only valid GET methods.
//If the user enters a POST action via GET, the application logs off.
Map mValues = request.getParameterMap();
String sPath = super.processPath(request);
if(null!= mValues && !mValues.isEmpty() && (sPath.equalsIgnoreCase("/l
ogon")) || (!hs.contains(sPath))){
Logger.error("* * * *Trying to access "+sPath+" through GET *
* * *");
RequestDispatcher view = this.getServletContext().getRequestDi
spatcher("logoff.do");
view.forward(request, response);
return;
}
//sets flag in request object indicating access was through the contro
lservlet
setAccessThruApp( request );
if ( CNSUtil.checkForMaliciousScript( request ) )
{
forwardError( request, response );
}
else
super.doGet(request, response);
}
protected void setAccessThruApp( HttpServletRequest req)
{
req.setAttribute("THRU_APP", "true");
}
protected void forwardError( HttpServletRequest request, HttpServletResponse
response ) {
try {
/**
* Purpose: As per FS when user provides any invalid data to sys
tem then system should log out,
* but when user hits the back button on the browser then page w
ith data is visible.
* so to avoid this issue need to kill all user level informatio
n.(This was missed out).
* This is a refractory and good to be done.
* Modified Date: 07/11/06
* Modified By: Amol
*/
//delete state record
ICNSUserLogic logic = CNSLogicFactory.getCNSUserLogic();
String sStateKey = CNSUtil.getCookieValue( (HttpServletReque
st)request, CNSConsts.kSessionCookieName );
logic.deleteSessionInfoByStateKeyID( sStateKey );
//update the user from logging off.
logic.updateUserInfoFromLogout( (int)CNSUtil.getUserID((Http
ServletRequest)request) );
//End
}
catch(Exception ex){
Logger.error("Update user info fails: ",ex);
}
finally{
try{
request.setAttribute("errorMessage", "Invalid characters.");
this.getServletContext().getRequestDispatcher("/logoff.jsp").for
ward(request, response);
}catch(Exception exc){
Logger.error("Fail to redirect: ",exc);
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse respons
e)
throws IOException, ServletException
{
//sets flag in request object indicating access was through the contro
lservlet
setAccessThruApp( request );
if ( CNSUtil.checkForMaliciousScript( request ) )
{
forwardError( request, response );
}
else
super.doPost( request, response);
/**
* Purpose: Code to fix the 503-Ethical hack H10 (Block Cache-Sensitiv
e info).
* helps to block the cache information.
* Date: 02/11/06
* Author: Amol
*/
if(!request.isSecure()){
response.setDateHeader("Expires", 0); // HTTP 1.0
response.setHeader("Pragma", "no-cache"); // HTTP 1.0
response.setHeader("Cache-Control", "no-store, no-cache, must-reva
lidate"); // HTTP 1.1
//Set IE extended HTTP/1.1 no-cache headers (use addHeader).
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
}
}
// Getters for CNS-specific parameters
public int getPasswordExpireDaysMaximum()
{
return m_passwordExpireDaysMaximum;
}
public int getAccountDisableDaysMaximum()
{
return m_accountDisableDaysMaximum;
}
//cns has its own security tag we add to each page we want to disable cachin
g - the core disables caching
//for all pages which creates a problem for downloading files
protected void processNoCache(HttpServletResponse response)
throws IOException, ServletException
{
}
/**
* Process an HTTP request.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet exception occurs
*/
//this is overridden to allow for the passwordLogon action in CNS
protected void process(HttpServletRequest request,HttpServletResponse response
)
throws IOException, ServletException
{
// Identify the path component we will use to select a mapping
String path = processPath(request);
if (path == null)
{
if (debug >= 1)
log(" No path available for request URI " +
request.getRequestURI());
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
internal.getMessage("processPath"));
return;
}
if (debug >= 1)
log("Processing a " + request.getMethod() + " for " + path);
// Set the content type and no-caching headers if requested
processContent(response);
processNoCache(response);
// General purpose preprocessing hook
if (!processPreprocess(request, response))
return;
// Check if Deadman, if yes, process deadman and return
if (path.equalsIgnoreCase(deadmanPath))
{
processDeadman(request, response);
return;
}
// Look up the corresponding mapping
RequestMapping mapping = processMapping(path, request);
if (mapping == null)
{
if (debug >= 1)
log(" No mapping available for path " + path);
response.sendError(HttpServletResponse.SC_BAD_REQUEST,
internal.getMessage("processInvalid", path));
return;
}
// Check for logged on user unless this is a logon request
if((!path.equalsIgnoreCase(logonPath)) && (!path.equalsIgnoreCas
e(logoffPath))&& (!path.equalsIgnoreCase("/passwordLogon")))
{
switch (processCookie(request, response, false))
{
case UserModel.AUTHORIZED:
break;
case UserModel.NOTAUTHORIZED:
RequestForward logoff = mapping.findFo
rward("logoff");
if(logoff == null)
logoff = new RequestFo
rward("/logoff.jsp",false,"Logoff");
processRequestForward(logoff, ma
pping, null,request, response);
return;
case UserModel.PASSWORDEXPIRED:
if ((!path.equalsIgnoreCase(head
erInitPath)) && (!path.equalsIgnoreCase(menuInitPath)) &&
(!path.equalsIgn
oreCase(changePasswordPath)) && (!path.equalsIgnoreCase(toolBarPath)) &&
(!path.equalsIgn
oreCase(messageCheckPath)))
{
RequestForward changePas
sword;
changePassword = new R
equestForward("/changePassword.jsp",false,"ChangePassword");
processRequestForward(ch
angePassword, mapping, null,request, response);
return;
}
break;
default:
// Error
break;
}
}
/**
* VA: Cross Site Request Forgery (CSRF)
* validatetoken is a attribute set in the webseries-config.xml file and
depend on the flag value validate
* the tokens.
*/
String validFlag = mapping.getValidatetoken();
if(validFlag!=null && validFlag.equalsIgnoreCase("true")) {
TokenProcessor token = TokenProcessor.getInstance();
if(!token.validateToken(request)) {
try{
Logger.error(this,token.PRINT_ERR_MESSAGE);
//request.setAttribute("errorMessage", "Don't ma
ke me fool");
this.getServletContext().getRequestDispatcher("/
logoff.jsp").forward(request, response);
return;
}catch(Exception exc){
Logger.error("Failed to validate: "+exc);
}
}
}
/**
* VA: End.
*/
// Process any RequestForm bean related to this request
RequestForm formInstance = processRequestForm(mapping, request);
processPopulate(formInstance, mapping, request);
if (!processValidate(mapping, formInstance, request, response))
return;
// Acquire the Action instance to process this request
ActionBase actionInstance = processActionCreate(mapping, request);
if (actionInstance == null)
{
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERRO
R,
internal.getMessage("actionCreate",mapping.getPath()));
return;
}
// Call the Action instance to perform task
RequestForward forward = processActionPerform(actionInstance, mappin
g, formInstance,request, response);
// Forward the request to the view
processRequestForward(forward, mapping, formInstance,request, respon
se);
}
// 504-RFS00023
public static int getUserSessionTimeout() {
if (m_userSessionTimeout <= 0) {
throw new RuntimeException("Invalid/Uninitialized User s
ession timeout value.");
}
return m_userSessionTimeout;
}
/**
* Method to populate all the valid GET actions in the HashSet
*/
private static void getNavMenuAction(String sRealPath) {
// TODO Auto-generated method stub
try {
LoaderUtility.loadFilterProperties(sRealPath);
String sVal = LoaderUtility.getProperty("REQUEST_GET_ACT
IONS");
if(null==sVal){
Logger.error("No entry for REQUEST_GET_ACTIONS i
n https-method.properties");
return;
}
String[] sValue = sVal.split(", ");
for(int i=0; i<sValue.length; i++)
hs.add(sValue[i]);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Das könnte Ihnen auch gefallen