dims 02/05/30 05:14:08 Modified: java/src/org/apache/axis/utils axisNLS.properties java/src/org/apache/axis/transport/http HTTPSender.java Added: java/src/org/apache/axis/transport/http FakeTrustSocketFactory.java Log: "PATCH: Allow connection to unsigned SSL servers" from <[EMAIL PROTECTED]> Revision Changes Path 1.2 +6 -0 xml-axis/java/src/org/apache/axis/utils/axisNLS.properties Index: axisNLS.properties =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/utils/axisNLS.properties,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- axisNLS.properties 22 May 2002 18:07:24 -0000 1.1 +++ axisNLS.properties 30 May 2002 12:14:08 -0000 1.2 @@ -843,4 +843,10 @@ dispatchIAE00=Tried to invoke method {0} with arguments {1}. The arguments do not match the signature. +ftsf00=Creating trusting socket factory +ftsf01=Exception creating factory +ftsf02=SSL setup failed +ftsf03=isClientTrusted: yes +ftsf04=isServerTrusted: yes +ftsf05=getAcceptedIssuers: none 1.63 +51 -26 xml-axis/java/src/org/apache/axis/transport/http/HTTPSender.java Index: HTTPSender.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/transport/http/HTTPSender.java,v retrieving revision 1.62 retrieving revision 1.63 diff -u -r1.62 -r1.63 --- HTTPSender.java 29 May 2002 14:30:01 -0000 1.62 +++ HTTPSender.java 30 May 2002 12:14:08 -0000 1.63 @@ -90,11 +90,25 @@ protected static Log log = LogFactory.getLog(HTTPSender.class.getName()); + /** Hook for creating a different SSL socket factory + * XXX The whole thing can be refactored to use something like tomcat.util, which + * is cleaner and support PureTLS. + */ + public static interface SocketFactoryFactory { + + /** Returns an instance of SSLSocketFactory, possibly with + * different parameters ( like different trust policies ) + */ + public Object createFactory() throws Exception; + } + + /** * Utility Class BooleanHolder */ static class BooleanHolder { public boolean value; + public BooleanHolder(boolean value) { this.value = value; } @@ -108,8 +122,7 @@ * * @throws AxisFault */ - public void invoke(MessageContext msgContext) throws AxisFault - { + public void invoke(MessageContext msgContext) throws AxisFault { if (log.isDebugEnabled()) { log.debug(JavaUtils.getMessage("enter00", "HTTPSender::invoke")); @@ -122,7 +135,7 @@ String host = tmpURL.getHost(); Socket sock = null; - try{ + try { // create socket based on the url protocol type if (tmpURL.getProtocol().equalsIgnoreCase("https")) { @@ -139,11 +152,11 @@ // Send the SOAP request to the server writeToSocket(sock, msgContext, tmpURL, otherHeaders, host, useFullURL); - }finally{ - // FIXME (DIMS): IS THIS REALLY NEEDED? SalesRankNPrice fails - // for a direct (non-proxy) connection if this is enabled. - //if(null != sock) sock.shutdownOutput(); //need to change for http 1.1 - } + } finally { + // FIXME (DIMS): IS THIS REALLY NEEDED? SalesRankNPrice fails + // for a direct (non-proxy) connection if this is enabled. + //if(null != sock) sock.shutdownOutput(); //need to change for http 1.1 + } // Read the response back from the server readFromSocket(sock, msgContext); @@ -167,8 +180,7 @@ * * @throws Exception */ - private Socket getSecureSocket(String host, URL tmpURL) throws Exception - { + private Socket getSecureSocket(String host, URL tmpURL) throws Exception { int port = 0; Socket sock = null; @@ -200,7 +212,26 @@ SSLSocketFactoryClass.getMethod("getDefault", new Class[]{}); Method startHandshakeMethod = SSLSocketClass.getMethod("startHandshake", new Class[]{}); - Object factory = getDefaultMethod.invoke(null,new Object[]{}); + + Object factory = null; + + // Hook in a different SSL socket factory + String socketFactoryClass = System.getProperty("axis.socketFactory"); + if (socketFactoryClass != null) { + try { + Class c1 = Class.forName(socketFactoryClass); + SocketFactoryFactory sff = (SocketFactoryFactory) c1.newInstance(); + factory = sff.createFactory(); + if (log.isDebugEnabled()) { + log.debug("Created socket factory " + sff.getClass().getName()); + } + } catch (Exception ex) { + } + } + + + if (factory == null) + factory = getDefaultMethod.invoke(null, new Object[]{}); Object sslSocket = null; if ((tunnelHost == null) || tunnelHost.equals("")) { @@ -233,8 +264,8 @@ (OutputStream) SSLSocketClass.getMethod("getOutputStream", new Class[]{}).invoke(tunnel, new Object[]{}); PrintWriter out = new PrintWriter( - new BufferedWriter( - new OutputStreamWriter(tunnelOutputStream))); + new BufferedWriter( + new OutputStreamWriter(tunnelOutputStream))); String tunnelUser = System.getProperty("https.proxyUser"); String tunnelPassword = System.getProperty("https.proxyPassword"); @@ -363,8 +394,7 @@ */ private Socket getSocket( String host, URL tmpURL, StringBuffer otherHeaders, BooleanHolder useFullURL) - throws IOException - { + throws IOException { int port = 0; Socket sock = null; @@ -421,8 +451,7 @@ */ private void writeToSocket( Socket sock, MessageContext msgContext, URL tmpURL, StringBuffer otherHeaders, String host, BooleanHolder useFullURL) - throws IOException - { + throws IOException { OutputStream out = new BufferedOutputStream(sock.getOutputStream(), 8 * 1024); @@ -531,7 +560,7 @@ .getBytes(HTTPConstants.HEADER_DEFAULT_CHAR_ENCODING)); try { reqMessage.writeTo(out); - } catch (SOAPException e){ + } catch (SOAPException e) { log.error(JavaUtils.getMessage("exception00"), e); } out.flush(); @@ -551,8 +580,7 @@ * @throws IOException */ private void readFromSocket(Socket sock, MessageContext msgContext) - throws IOException - { + throws IOException { Message outMsg = null; byte b; int len = 0; @@ -723,8 +751,7 @@ * @param msgContext */ public void handleCookie(String cookieName, String setCookieName, - Hashtable headers, MessageContext msgContext) - { + Hashtable headers, MessageContext msgContext) { if (headers.containsKey(setCookieName.toLowerCase())) { String cookie = (String) headers.get(setCookieName.toLowerCase()); @@ -748,8 +775,7 @@ * * @return true/false */ - private boolean isHostInNonProxyList(String host, String nonProxyHosts) - { + private boolean isHostInNonProxyList(String host, String nonProxyHosts) { if ((nonProxyHosts == null) || (host == null)) { return false; } @@ -785,8 +811,7 @@ * <code>false</code> otherwise. */ private static boolean match(String pattern, String str, - boolean isCaseSensitive) - { + boolean isCaseSensitive) { char[] patArr = pattern.toCharArray(); char[] strArr = str.toCharArray(); int patIdxStart = 0; 1.1 xml-axis/java/src/org/apache/axis/transport/http/FakeTrustSocketFactory.java Index: FakeTrustSocketFactory.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2001 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Axis" 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 name, without prior written * permission of the Apache Software Foundation. * * 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/>. */ package org.apache.axis.transport.http; import com.sun.net.ssl.SSLContext; import com.sun.net.ssl.TrustManager; import com.sun.net.ssl.X509TrustManager; import org.apache.axis.utils.JavaUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.io.IOException; /** Hook for Axis sender, allowing unsigned server certs */ public class FakeTrustSocketFactory implements HTTPSender.SocketFactoryFactory { protected static Log log = LogFactory.getLog(FakeTrustSocketFactory.class.getName()); public Object createFactory() throws IOException { try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init( null, // we don't need no stinkin KeyManager new TrustManager[]{new FakeX509TrustManager()}, new java.security.SecureRandom() ); if (log.isDebugEnabled()) { log.debug(JavaUtils.getMessage("ftsf00")); } return sc.getSocketFactory(); } catch (Exception exc) { log.error(JavaUtils.getMessage("ftsf01"), exc); throw new IOException(JavaUtils.getMessage("ftsf02")); } } public static class FakeX509TrustManager implements X509TrustManager { protected static Log log = LogFactory.getLog(FakeX509TrustManager.class.getName()); public boolean isClientTrusted(java.security.cert.X509Certificate[] chain) { if (log.isDebugEnabled()) { log.debug(JavaUtils.getMessage("ftsf03")); } return true; } public boolean isServerTrusted(java.security.cert.X509Certificate[] chain) { if (log.isDebugEnabled()) { log.debug(JavaUtils.getMessage("ftsf04")); } return true; } public java.security.cert.X509Certificate[] getAcceptedIssuers() { if (log.isDebugEnabled()) { log.debug(JavaUtils.getMessage("ftsf05")); } return null; } } }