package at.gv.egovernment.moa.id.proxy;
import java.io.IOException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.util.Iterator;
import java.util.Vector;
import javax.net.ssl.SSLSocketFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import at.gv.egovernment.moa.id.config.ConfigurationException;
import at.gv.egovernment.moa.id.config.proxy.ProxyConfigurationProvider;
import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.BoolUtils;
import com.sun.net.ssl.HostnameVerifier;
import HTTPClient.HttpURLConnection;
import HTTPClient.HTTPConnection;
/**
* Outlook Web Access (OWA) Implementierung von ConnectionBuilder
.
* uses the HTTP(s)Client from Ronald Tschalär.
* origin version (without https support) is available at http://www.innovation.ch/java/HTTPClient/
*
* @author pdanner
*/
public class EnhancedConnectionBuilder implements ConnectionBuilder {
/** a boolean to disable the HostnameVerification (default = false)*/
private static boolean cbDisableHostnameVerification = false;
/** Name of the Parameter for the Target */
private static final String PARAM_TARGET = "Target";
/** Name of the Parameter for the SAMLArtifact */
private static final String PARAM_SAMLARTIFACT = "SAMLArtifact";
/** Name of the Attribute for marking the session as authenticated*/
private static final String ATT_AUTHDATAFETCHED = "AuthDataFetched";
static {
HTTPConnection.setDefaultTimeout(0);
try {
HTTPConnection.removeDefaultModule(Class.forName("HTTPClient.AuthorizationModule"));
HTTPConnection.removeDefaultModule(Class.forName("HTTPClient.RedirectionModule"));
HTTPConnection.removeDefaultModule(Class.forName("HTTPClient.CookieModule"));
//HTTPConnection.removeDefaultModule(Class.forName("HTTPClient.RetryModule"));
} catch (ClassNotFoundException e) {
}
}
/**
* Constructor for OWAConnectionBuilder.
* @throws ConfigurationException on any config error
*/
public EnhancedConnectionBuilder() throws ConfigurationException {
cbDisableHostnameVerification = BoolUtils.valueOf(
ProxyConfigurationProvider.getInstance().getGenericConfigurationParameter(
"ProxyComponent.DisableHostnameVerification"));
//TODO MOA-ID BRZ undocumented feature
if (cbDisableHostnameVerification)
Logger.warn("ProxyComponent.DisableHostnameVerification: " + cbDisableHostnameVerification);
}
/**
* @see at.gv.egovernment.moa.id.proxy.ConnectionBuilder#buildConnection
*/
public java.net.HttpURLConnection buildConnection(HttpServletRequest req, String publicURLPrefix, String realURLPrefix, SSLSocketFactory sslSocketFactory, Vector parameters) throws IOException {
String requestedURL = req.getRequestURL().toString();
// check whether requested URL starts with publicURLPrefix
if (! requestedURL.startsWith(publicURLPrefix.substring(0,5)))
throw new IOException(MOAIDMessageProvider.getInstance().getMessage(
"proxy.01", new Object[] {requestedURL, publicURLPrefix}));
String query = req.getQueryString();
if (req.getSession().getAttribute(ATT_AUTHDATAFETCHED)!=null) {
query = removeParameter(query, PARAM_SAMLARTIFACT);
query = removeParameter(query, PARAM_TARGET);
req.getSession().removeAttribute(ATT_AUTHDATAFETCHED);
}
if (null != query && 0 != query.length() ) {
requestedURL = requestedURL + "?" + query;
String parameter[] = new String[2];
for (Iterator iter = parameters.iterator(); iter.hasNext();) {
parameter = (String[]) iter.next();
if(query.indexOf(parameter[0]) >= 0) iter.remove();
}
}
// build real URL in online application
String realURLString = realURLPrefix + requestedURL.substring(publicURLPrefix.length());
// build real URL in online application
URLStreamHandler urlStreamHandler = null;
//URL url = new URL(realURLString);
if (realURLString.startsWith("https")) {
urlStreamHandler = new HTTPClient.https.Handler();
} else{
urlStreamHandler = new HTTPClient.http.Handler();
}
URL url = new URL(null, realURLString, urlStreamHandler);
Logger.debug("OA Request: " + req.getMethod() + " " + url.toString());
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod(req.getMethod());
conn.setDoInput(true);
conn.setDoOutput(true);
//conn.setUseCaches(false);
//conn.setAllowUserInteraction(true);
conn.setInstanceFollowRedirects(false);
if (realURLString.startsWith("https") && sslSocketFactory != null) {
conn.setSSLSocketFactory(sslSocketFactory);
//Not available in HTTPClient
//if (cbDisableHostnameVerification)
// conn.setHostnameVerifier(new HostnameNonVerifier());
}
return conn;
}
/**
* Disconnects the HttpURLConnection if necessary.
* The implementation of the Connectionbuilder decides wether
* if this should be happen or not.
*
* @param con the HttpURLConnection which is normaly to be closed
*/
public void disconnect(java.net.HttpURLConnection conn) {
// In HTTPClient there must not be an diconnect!
// conn.disconnect();
}
/**
* @author Stefan Knirsch
* @version $Id$
* A private class to change the standard HostName verifier to disable the
* Hostname Verification Check
*/
private class HostnameNonVerifier implements HostnameVerifier {
/**
* @see com.sun.net.ssl.HostnameVerifier#verify(String, String)
*/
public boolean verify(String arg0, String arg1) {
return true;
}
}
/**
* Removes parameters from the query-URL recursively
*
* @param query the query from which the parameter is to be removed
* @param parameter the parameter to be removed
* @return the parameterclean query
*/
private String removeParameter(String query, String parameter) {
return removeParameter(query, parameter, true);
}
/**
* Removes one parameter from the query-URL recursively
*
* @param query the query from which the parameter is to be removed
* @param parameter the parameter to be removed
* @param remove. Boolean value wether a parameter was removed in last call or not. In initial call set to true to check for new occurrences
* @return the parameterclean query
*/
private String removeParameter(String query, String parameter, boolean remove) {
String result = query;
if (remove && query!=null && !query.equals("") && parameter!=null && !parameter.equals("")) {
String param = parameter;
int capEnd=0;
if (!param.endsWith("=")) param=param+"=";
if (query.startsWith(param)) {
//remove leading
result="";
} else {
if (!param.startsWith("&")) param="&"+param;
capEnd = query.indexOf(param);
if (capEnd!=-1) {
//leading part
result=query.substring(0, capEnd);
}
}
if (capEnd!=-1) {
//trailing part
capEnd += param.length();
int capBegin = -1;
if (capEnd