olegk 2003/03/16 04:39:34 Added: httpclient/src/contrib/org/apache/commons/httpclient/contrib/ssl EasySSLProtocolSocketFactory.java EasyX509TrustManager.java httpclient/src/contrib/org/apache/commons/httpclient/contrib/utils HttpMethodCloner.java Log: Changelog: - HttpClient Contribution package established - HttpMethodCloner contributed by Thomas Mathis. This utility can be used to create exact copies of objects that implement HttpMethod interface - EasySSLProtocolSocketFactory & EasyX509TrustManager contributed by Adrian Sutton & Oleg Kalnichevski. EasySSLProtocolSocketFactory can be used to create SSL sockets that accept self-signed certificates when communicating with HTTP servers over SSL Reviews by Oleg Kalnichevski Revision Changes Path 1.1 jakarta-commons/httpclient/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java Index: EasySSLProtocolSocketFactory.java =================================================================== /* * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2002-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * 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 * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.commons.httpclient.contrib.ssl; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import com.sun.net.ssl.SSLContext; import com.sun.net.ssl.TrustManager; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * <p> * EasySSLProtocolSocketFactory can be used to creats SSL [EMAIL PROTECTED] 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> * * @author <a href="mailto:[EMAIL PROTECTED]">Oleg Kalnichevski</a> * * DISCLAIMER: HttpClient developers DO NOT actively support this component. * The component is provided as a reference material, which may be inappropriate * to be used without additional customization. */ public class EasySSLProtocolSocketFactory implements SecureProtocolSocketFactory { /** Log object for this class. */ private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class); /** * Constructor for EasySSLProtocolSocketFactory. * * Code sample: * * <blockquote> * Protocol easyhttps = new Protocol( * "https", new EasySSLProtocolSocketFactory(), 443); * * HttpClient client = new HttpClient(); * client.getHostConfiguration().setHost("localhost", 443, easyhttps); * </blockquote> */ public EasySSLProtocolSocketFactory() { super(); } private static SSLSocketFactory getEasySSLSocketFactory() { SSLContext context = null; try { context = SSLContext.getInstance("SSL"); context.init( null, new TrustManager[] {new EasyX509TrustManager(null)}, null); } catch (Exception e) { LOG.error(e.getMessage(), e); throw new RuntimeException(e.toString()); } return context.getSocketFactory(); } /** * @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 { Socket socket = getEasySSLSocketFactory().createSocket( host, port, clientHost, clientPort ); return socket; } /** * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) */ public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return getEasySSLSocketFactory().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 getEasySSLSocketFactory().createSocket( socket, host, port, autoClose ); } } 1.1 jakarta-commons/httpclient/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasyX509TrustManager.java Index: EasyX509TrustManager.java =================================================================== /* * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2002-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * 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 * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.commons.httpclient.contrib.ssl; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import com.sun.net.ssl.TrustManagerFactory; import com.sun.net.ssl.TrustManager; import com.sun.net.ssl.X509TrustManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * <p> * EasyX509TrustManager unlike default [EMAIL PROTECTED] X509TrustManager} accepts * self-signed certificates. * </p> * <p> * This trust manager 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> * * @author <a href="mailto:[EMAIL PROTECTED]">Adrian Sutton</a> * @author <a href="mailto:[EMAIL PROTECTED]">Oleg Kalnichevski</a> * * DISCLAIMER: HttpClient developers DO NOT actively support this component. * The component is provided as a reference material, which may be inappropriate * to be used without additional customization. */ public class EasyX509TrustManager implements X509TrustManager { private X509TrustManager standardTrustManager = null; /** Log object for this class. */ private static final Log LOG = LogFactory.getLog(EasyX509TrustManager.class); /** * Constructor for EasyX509TrustManager. */ public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException { super(); TrustManagerFactory factory = TrustManagerFactory.getInstance("SunX509"); factory.init(keystore); TrustManager[] trustmanagers = factory.getTrustManagers(); if (trustmanagers.length == 0) { throw new NoSuchAlgorithmException("SunX509 trust manager not supported"); } this.standardTrustManager = (X509TrustManager)trustmanagers[0]; } /** * @see com.sun.net.ssl.X509TrustManager#isClientTrusted(X509Certificate[]) */ public boolean isClientTrusted(X509Certificate[] certificates) { return this.standardTrustManager.isClientTrusted(certificates); } /** * @see com.sun.net.ssl.X509TrustManager#isServerTrusted(X509Certificate[]) */ public boolean isServerTrusted(X509Certificate[] certificates) { if ((certificates != null) && LOG.isDebugEnabled()) { LOG.debug("Number of server certificates: " + certificates.length); for (int i = 0; i < certificates.length; i++) { LOG.debug(certificates[i].toString()); } } if ((certificates != null) && (certificates.length == 1)) { X509Certificate certificate = certificates[0]; try { certificate.checkValidity(); } catch (CertificateException e) { LOG.error(e.toString()); return false; } return true; } else { return this.standardTrustManager.isServerTrusted(certificates); } } /** * @see com.sun.net.ssl.X509TrustManager#getAcceptedIssuers() */ public X509Certificate[] getAcceptedIssuers() { return this.standardTrustManager.getAcceptedIssuers(); } } 1.1 jakarta-commons/httpclient/src/contrib/org/apache/commons/httpclient/contrib/utils/HttpMethodCloner.java Index: HttpMethodCloner.java =================================================================== /* * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2002-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * 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 * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.commons.httpclient.contrib.utils; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethodBase; import org.apache.commons.httpclient.methods.EntityEnclosingMethod; import org.apache.commons.httpclient.URI; import org.apache.commons.httpclient.URIException; /** * In this class are only methods to copy a HttpMethod: * PUT, GET, POST,DELETE, TRACE, ... * * @author <a href="mailto:[EMAIL PROTECTED]">Thomas Mathis</a> * * DISCLAIMER: HttpClient developers DO NOT actively support this component. * The component is provided as a reference material, which may be inappropriate * to be used without additional customization. */ public class HttpMethodCloner { private static void copyEntityEnclosingMethod( EntityEnclosingMethod m, EntityEnclosingMethod copy ) throws java.io.IOException { copy.setRequestBody(m.getRequestBodyAsString()); copy.setUseExpectHeader(m.getUseExpectHeader()); } private static void copyHttpMethodBase( HttpMethodBase m, HttpMethodBase copy) { if (m.getHostConfiguration() != null) { copy.setHostConfiguration( new HostConfiguration(m.getHostConfiguration())); } copy.setHttp11(m.isHttp11()); copy.setStrictMode(m.isStrictMode()); } /** * Clones a HttpMethod. <br> * <b>Attention:</b> You have to clone a method before it has * been executed, because the URI can change if followRedirects * is set to true. * * @param m the HttpMethod to clone * * @return the cloned HttpMethod, null if the HttpMethod could * not be instantiated * * @throws java.io.IOException if the request body couldn't be read */ public static HttpMethod clone(HttpMethod m) throws java.io.IOException { HttpMethod copy = null; // copy the HttpMethod try { copy = (HttpMethod) m.getClass().newInstance(); } catch (InstantiationException iEx) { } catch (IllegalAccessException iaEx) { } if ( copy == null ) { return null; } copy.setDoAuthentication(m.getDoAuthentication()); copy.setFollowRedirects(m.getFollowRedirects()); copy.setPath( m.getPath() ); copy.setQueryString(m.getQueryString()); // clone the headers Header[] h = m.getRequestHeaders(); int size = (h == null) ? 0 : h.length; for (int i = 0; i < size; i++) { copy.setRequestHeader( new Header(h[i].getName(), h[i].getValue())); } copy.setStrictMode(m.isStrictMode()); if (m instanceof HttpMethodBase) { copyHttpMethodBase( (HttpMethodBase)m, (HttpMethodBase)copy); } if (m instanceof EntityEnclosingMethod) { copyEntityEnclosingMethod( (EntityEnclosingMethod)m, (EntityEnclosingMethod)copy); } return copy; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]