/* Copyright (2006-2012) Schibsted ASA
* This file is part of Possom.
*
* Possom is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Possom 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Possom. If not, see <http://www.gnu.org/licenses/>.
*/
package no.sesat.search.http.filters;
import no.sesat.search.datamodel.DataModel;
import no.sesat.search.security.MD5Generator;
import no.sesat.search.site.config.SiteConfiguration;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.log4j.Logger;
/** Generalised way to protect parameter values through md5 signings.
* A skin must define the properties (in configuration.properties):
* md5.secret and md5.protectedParameters
* Any secret can be chosen. Any parameter matches those listed in md5.protectedParameters (separated by commas)
* are expected to have a paired parameter (called <parameterName>_x) that represents the signing of the
* original parameter value. If this second parameter does not exist or it's not an accurate signing of the original
* parameter then the request immediately returns with a 404 response error.
*
*
* @version <tt>$Id$</tt>
*/
public final class MD5ProtectedParametersFilter implements Filter {
private static final Logger LOG = Logger.getLogger(MD5ProtectedParametersFilter.class);
public void init(final FilterConfig filterConfig) throws ServletException {
}
public void doFilter(
final ServletRequest servletRequest,
final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
final Enumeration e = servletRequest.getParameterNames();
if(servletRequest instanceof HttpServletRequest) {
final HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
final DataModel datamodel = (DataModel)httpServletRequest.getSession().getAttribute(DataModel.KEY);
final SiteConfiguration siteConf = datamodel.getSite().getSiteConfiguration();
if(null != siteConf.getProperty("md5.secret") && null != siteConf.getProperty("md5.protectedParameters")){
final MD5Generator generator = new MD5Generator(siteConf.getProperty("md5.secret"));
final Map<String, Boolean> protectedParameters = new HashMap<String, Boolean>();
final String[] p = siteConf.getProperty("md5.protectedParameters").split(",");
for (final String parameter : p) {
LOG.info("Adding " + parameter + " as protected parameter");
protectedParameters.put(parameter, Boolean.TRUE);
}
while (e.hasMoreElements()) {
final String paramName = (String) e.nextElement();
LOG.trace("Checking to see if " + paramName + " is protected");
if (protectedParameters.containsKey(paramName)) {
LOG.trace(paramName + " is protected");
final String md5Param = servletRequest.getParameter(paramName + "_x");
if (md5Param == null || !generator.validate(servletRequest.getParameter(paramName), md5Param)){
final HttpServletResponse response = (HttpServletResponse) servletResponse;
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
}
}
servletRequest.setAttribute("hashGenerator", generator);
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
}
}