/* * Copyright 2003 Federal Chancellery Austria * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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.HostnameVerifier; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.servlet.http.HttpServletRequest; import HTTPClient.HTTPConnection; import HTTPClient.HttpURLConnection; 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; /** * 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 conn 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 */ // JSSE Abhängigkeit private class HostnameNonVerifier implements HostnameVerifier { public boolean verify(String hostname, SSLSession session) { return true; } /** * @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