Permalink
Browse files

added a proxy servlet based on the code from http://edwardstx.net/wik…

…i/Wiki.jsp?page=HttpProxyServlet. Optimized and modified the original for allowing unsigned SSL certificates (based on the EasySSLProtocolSocket factory, an HTTPClient contributed code, included in source). The trust manager mentioned above SHOULD NOT be used for productive systems due to security reasons, unless it is a conscious decision and you are perfectly aware of security implications of accepting self-signed certificates!
  • Loading branch information...
florin.patrascu@gmail.com
florin.patrascu@gmail.com committed Nov 2, 2010
1 parent bd9246c commit 2f67051dde2c0e90008774c1a1cf6fda52bb0ab1
View
@@ -0,0 +1,34 @@
#
# Copyright (c) 2010, Florin T.PATRASCU
#
# 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.
#
name=proxy
Name=proxy
version=1.0
root.dir=.
src.dir=java/src
docs.dir=doc
lib.dir=lib
dist.dir=dist
build.dir=build
build.classes=${build.dir}/classes
build.dist=${root.dir}/dist
build.docs=${build.dir}/doc
build.lib=${build.dir}/lib
build.javadocs=${build.docs}/api
View
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2010, Florin T.PATRASCU
~
~ 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.
-->
<project name="proxy" default="jar">
<property environment="env"/>
<property file="build.properties"/>
<property name="skip.tests" value="true"/>
<!-- Compiler options -->
<property name="compiler.debug" value="on"/>
<property name="compiler.optimize" value="on"/>
<property name="compiler.generate.no.warnings" value="off"/>
<property name="compiler.args" value=""/>
<!-- Compiler resources -->
<patternset id="compiler.resources">
<include name="**/?*.properties"/>
</patternset>
<!-- Global Libraries -->
<path id="build.classpath">
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
</path>
<!-- ==================================================== -->
<!-- Initialize Ant -->
<!-- ==================================================== -->
<target name="init">
<tstamp/>
</target>
<!-- ====================================================================== -->
<!-- Compile the source code. -->
<!-- ====================================================================== -->
<target name="compile" depends="init">
<mkdir dir="${build.dir}"/>
<mkdir dir="${build.classes}"/>
<javac srcdir="${src.dir}"
destdir="${build.classes}"
debug="${compiler.debug}"
deprecation="${compiler.generate.no.warnings}"
encoding="utf8"
classpathref="build.classpath"
optimize="${compiler.optimize}">
<include name="**/*.java"/>
</javac>
<copy todir="${build.classes}">
<fileset dir="${src.dir}">
<patternset refid="compiler.resources"/>
<type type="file"/>
</fileset>
</copy>
</target>
<!-- ====================================================================== -->
<!-- Create the JAR archive. -->
<!-- ====================================================================== -->
<target name="jar" depends="compile">
<mkdir dir="${build.dist}"/>
<jar jarfile="${build.dist}/${name}-${version}.jar"
basedir="${build.classes}"/>
</target>
<!-- ====================================================================== -->
<!-- Create the distribution -->
<!-- ====================================================================== -->
<target name="dist" depends="clean, jar">
<echo message="Building the proxy library ..."/>
<copy todir="${dist.dir}/${name}/WEB-INF/lib">
<fileset dir="${lib.dir}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${dist.dir}">
<include name="**/*.jar"/>
<include name="**/*.txt"/>
</fileset>
</copy>
</target>
<!-- ====================================================================== -->
<!-- Clean up generated stuff -->
<!-- ====================================================================== -->
<target name="clean">
<delete dir="${dist.dir}"/>
<delete dir="${build.dir}"/>
<delete dir="${docs.dir}/api"/>
</target>
</project>
@@ -0,0 +1,217 @@
/*
* Copyright 2002-2004 The Apache Software Foundation
*
* 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.
* =================================================================
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
*/
package proxy;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.io.IOException;
import java.net.*;
/**
* <p>
* EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s
* that accept self-signed certificates.
* </p>
* <p>
* This socket factory SHOULD NOT be used for productive systems
* due to security reasons, unless it is a concious decision and
* you are perfectly aware of security implications of accepting
* self-signed certificates
* </p>
* <p/>
* <p>
* Example of using custom protocol socket factory for a specific host:
* <pre>
* Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
* <p/>
* URI uri = new URI("https://localhost/", true);
* // use relative url only
* GetMethod httpget = new GetMethod(uri.getPathQuery());
* HostConfiguration hc = new HostConfiguration();
* hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
* HttpClient client = new HttpClient();
* client.executeMethod(hc, httpget);
* </pre>
* </p>
* <p>
* Example of using custom protocol socket factory per default instead of the standard one:
* <pre>
* Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
* Protocol.registerProtocol("https", easyhttps);
* <p/>
* HttpClient client = new HttpClient();
* GetMethod httpget = new GetMethod("https://localhost/");
* client.executeMethod(httpget);
* </pre>
* </p>
*
* @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
* <p/>
* <p>
* DISCLAIMER: HttpClient developers DO NOT actively support this component.
* The component is provided as a reference material, which may be inappropriate
* for use without additional customization.
* </p>
*/
public class EasySSLProtocolSocketFactory implements SecureProtocolSocketFactory {
/**
* Log object for this class.
*/
private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class);
private SSLContext sslcontext = null;
/**
* Constructor for EasySSLProtocolSocketFactory.
*/
public EasySSLProtocolSocketFactory() {
super();
}
private static SSLContext createEasySSLContext() {
try {
SSLContext context = SSLContext.getInstance("SSL");
context.init(
null,
new TrustManager[]{new EasyX509TrustManager(null)},
null);
return context;
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new HttpClientError(e.toString());
}
}
private SSLContext getSSLContext() {
if (this.sslcontext == null) {
this.sslcontext = createEasySSLContext();
}
return this.sslcontext;
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
*/
public Socket createSocket(
String host,
int port,
InetAddress clientHost,
int clientPort)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
host,
port,
clientHost,
clientPort
);
}
/**
* Attempts to get a new socket connection to the given host within the given time limit.
* <p>
* To circumvent the limitations of older JREs that do not support connect timeout a
* controller thread is executed. The controller thread attempts to create a new socket
* within the given limit of time. If socket constructor does not return until the
* timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
* </p>
*
* @param host the host name/IP
* @param port the port on the host
* @param clientHost the local host name/IP to bind the socket to
* @param clientPort the port on the local machine
* @param params {@link HttpConnectionParams Http connection parameters}
* @return Socket a new socket
* @throws IOException if an I/O error occurs while creating the socket
* @throws UnknownHostException if the IP address of the host cannot be
* determined
*/
public Socket createSocket(
final String host,
final int port,
final InetAddress localAddress,
final int localPort,
final HttpConnectionParams params
) throws IOException, UnknownHostException, ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = getSSLContext().getSocketFactory();
if (timeout == 0) {
return socketfactory.createSocket(host, port, localAddress, localPort);
} else {
Socket socket = socketfactory.createSocket();
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
socket.bind(localaddr);
socket.connect(remoteaddr, timeout);
return socket;
}
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
*/
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
host,
port
);
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
*/
public Socket createSocket(
Socket socket,
String host,
int port,
boolean autoClose)
throws IOException, UnknownHostException {
return getSSLContext().getSocketFactory().createSocket(
socket,
host,
port,
autoClose
);
}
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(EasySSLProtocolSocketFactory.class));
}
public int hashCode() {
return EasySSLProtocolSocketFactory.class.hashCode();
}
}
Oops, something went wrong.

0 comments on commit 2f67051

Please sign in to comment.