dims 2002/10/08 05:12:47
Modified: java build.xml
java/xmls targets.xml
Added: java/src/org/apache/axis/components/net
IBMJSSESocketFactory.java
Log:
Adding IBMJSSESocketFactory for
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13393
Revision Changes Path
1.203 +1 -0 xml-axis/java/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/xml-axis/java/build.xml,v
retrieving revision 1.202
retrieving revision 1.203
diff -u -r1.202 -r1.203
--- build.xml 30 Sep 2002 18:33:04 -0000 1.202
+++ build.xml 8 Oct 2002 12:12:46 -0000 1.203
@@ -80,6 +80,7 @@
<exclude name="**/old/**/*" />
<exclude name="**/bak/**"/>
<exclude name="**/org/apache/axis/components/net/JSSE*.java"
unless="jsse.present"/>
+ <exclude name="**/org/apache/axis/components/net/IBM*.java"
unless="ibmjsse.present"/>
<exclude name="**/org/apache/axis/components/net/Fake*.java"
unless="jsse.present"/>
<exclude name="**/org/apache/axis/components/image/JimiIO.java"
unless="jimi.present"/>
<exclude name="**/org/apache/axis/components/image/MerlinIO.java"
unless="merlinio.present"/>
1.1
xml-axis/java/src/org/apache/axis/components/net/IBMJSSESocketFactory.java
Index: IBMJSSESocketFactory.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.components.net;
import com.ibm.net.ssl.SSLContext;
import org.apache.axis.AxisProperties;
import org.apache.axis.utils.JavaUtils;
import org.apache.axis.utils.Messages;
import org.apache.axis.utils.XMLUtils;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.security.KeyStore;
import java.security.Security;
import java.util.Hashtable;
/**
* SSL socket factory. It _requires_ a valid RSA key and
* JSSE. (borrowed code from tomcat)
*
* @author Davanum Srinivas ([EMAIL PROTECTED])
*/
public class IBMJSSESocketFactory extends DefaultSocketFactory {
/** Field keystoreType */
private String keystoreType;
/** Field defaultKeystoreType */
static String defaultKeystoreType = "JKS";
/** Field defaultProtocol */
static String defaultProtocol = "TLS";
/** Field defaultAlgorithm */
static String defaultAlgorithm = "IbmX509";
/** Field defaultClientAuth */
static boolean defaultClientAuth = false;
/** Field clientAuth */
private boolean clientAuth = false;
/** Field sslFactory */
private SSLSocketFactory sslFactory = null;
/** Field defaultKeystoreFile */
static String defaultKeystoreFile =
System.getProperty("user.home") + "/.keystore";
/** Field defaultKeyPass */
static String defaultKeyPass = "changeit";
/**
* Constructor IBMJSSESocketFactory
*
* @param attributes
*/
public IBMJSSESocketFactory(Hashtable attributes) {
super(attributes);
}
/**
* creates a secure socket
*
* @param host
* @param port
* @param otherHeaders
* @param useFullURL
*
* @return Socket
* @throws Exception
*/
public Socket create(
String host, int port, StringBuffer otherHeaders, BooleanHolder
useFullURL)
throws Exception {
Socket sslSocket = null;
if (sslFactory == null) {
initFactory();
}
if (port == -1) {
port = 443;
}
TransportClientProperties tcp =
TransportClientPropertiesFactory.create("https");
boolean hostInNonProxyList = isHostInNonProxyList(host,
tcp.getNonProxyHosts());
if (tcp.getProxyHost().length() == 0 || hostInNonProxyList) {
// direct SSL connection
sslSocket = sslFactory.createSocket(host, port);
} else {
// Default proxy port is 80, even for https
int tunnelPort = (tcp.getProxyPort().length() != 0)
? Integer.parseInt(tcp.getProxyPort())
: 80;
if (tunnelPort < 0)
tunnelPort = 80;
// Create the regular socket connection to the proxy
Socket tunnel = new Socket(tcp.getProxyHost(), tunnelPort);
// The tunnel handshake method (condensed and made reflexive)
OutputStream tunnelOutputStream = tunnel.getOutputStream();
PrintWriter out = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(tunnelOutputStream)));
// More secure version... engage later?
// PasswordAuthentication pa =
// Authenticator.requestPasswordAuthentication(
// InetAddress.getByName(tunnelHost),
// tunnelPort, "SOCK", "Proxy","HTTP");
// if(pa == null){
// printDebug("No Authenticator set.");
// }else{
// printDebug("Using Authenticator.");
// tunnelUser = pa.getUserName();
// tunnelPassword = new String(pa.getPassword());
// }
out.print("CONNECT " + host + ":" + port + " HTTP/1.0\r\n"
+ "User-Agent: AxisClient");
if (tcp.getProxyUser().length() != 0 &&
tcp.getProxyPassword().length() != 0) {
// add basic authentication header for the proxy
String encodedPassword = XMLUtils.base64encode((tcp.getProxyUser()
+ ":"
+ tcp.getProxyPassword()).getBytes());
out.print("\nProxy-Authorization: Basic " + encodedPassword);
}
out.print("\nContent-Length: 0");
out.print("\nPragma: no-cache");
out.print("\r\n\r\n");
out.flush();
InputStream tunnelInputStream = tunnel.getInputStream();
if (log.isDebugEnabled()) {
log.debug(Messages.getMessage("isNull00", "tunnelInputStream",
"" + (tunnelInputStream
== null)));
}
String replyStr = "";
// Make sure to read all the response from the proxy to prevent SSL
negotiation failure
// Response message terminated by two sequential newlines
int newlinesSeen = 0;
boolean headerDone = false; /* Done on first newline */
while (newlinesSeen < 2) {
int i = tunnelInputStream.read();
if (i < 0) {
throw new IOException("Unexpected EOF from proxy");
}
if (i == '\n') {
headerDone = true;
++newlinesSeen;
} else if (i != '\r') {
newlinesSeen = 0;
if (!headerDone) {
replyStr += String.valueOf((char) i);
}
}
}
if (!replyStr.startsWith("HTTP/1.0 200")
&& !replyStr.startsWith("HTTP/1.1 200")) {
throw new IOException(Messages.getMessage("cantTunnel00",
new String[]{
tcp.getProxyHost(),
"" + tunnelPort,
replyStr}));
}
// End of condensed reflective tunnel handshake method
sslSocket = sslFactory.createSocket(tunnel, host, port, true);
if (log.isDebugEnabled()) {
log.debug(Messages.getMessage("setupTunnel00",
tcp.getProxyHost(),
"" + tunnelPort));
}
}
((SSLSocket) sslSocket).startHandshake();
if (log.isDebugEnabled()) {
log.debug(Messages.getMessage("createdSSL00"));
}
return sslSocket;
}
/**
* Read the keystore, init the SSL socket factory
*
* @throws IOException
*/
protected void initFactory() throws IOException {
try {
Security.addProvider(new com.ibm.jsse.JSSEProvider());
Security.addProvider(new com.ibm.crypto.provider.IBMJCA());
if(attributes == null) {
//No configuration specified. Get the default.
sslFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
} else {
//Configuration specified in wsdd.
SSLContext context = getContext();
sslFactory = context.getSocketFactory();
}
} catch (Exception e) {
if (e instanceof IOException) {
throw (IOException) e;
}
throw new IOException(e.getMessage());
}
}
/**
* gets a SSL Context
*
* @return SSLContext
* @throws Exception
*/
protected com.ibm.net.ssl.SSLContext getContext() throws Exception {
// Please don't change the name of the attribute - other
// software may depend on it ( j2ee for sure )
String keystoreFile = (String) attributes.get("keystore");
if (keystoreFile == null) {
keystoreFile = defaultKeystoreFile;
}
keystoreType = (String) attributes.get("keystoreType");
if (keystoreType == null) {
keystoreType = defaultKeystoreType;
}
// determine whether we want client authentication
// the presence of the attribute enables client auth
clientAuth = null != (String) attributes.get("clientauth");
String keyPass = (String) attributes.get("keypass");
if (keyPass == null) {
keyPass = defaultKeyPass;
}
String keystorePass = (String) attributes.get("keystorePass");
if (keystorePass == null) {
keystorePass = keyPass;
}
// protocol for the SSL ie - TLS, SSL v3 etc.
String protocol = (String) attributes.get("protocol");
if (protocol == null) {
protocol = defaultProtocol;
}
// Algorithm used to encode the certificate ie - SunX509
String algorithm = (String) attributes.get("algorithm");
if (algorithm == null) {
algorithm = defaultAlgorithm;
}
// You can't use ssl without a server certificate.
// Create a KeyStore ( to get server certs )
KeyStore kstore = initKeyStore(keystoreFile, keystorePass);
// Key manager will extract the server key
com.ibm.net.ssl.KeyManagerFactory kmf =
com.ibm.net.ssl.KeyManagerFactory.getInstance(algorithm);
kmf.init(kstore, keyPass.toCharArray());
// If client authentication is needed, set up TrustManager
com.ibm.net.ssl.TrustManager[] tm = null;
if (clientAuth) {
com.ibm.net.ssl.TrustManagerFactory tmf =
com.ibm.net.ssl.TrustManagerFactory.getInstance("SunX509");
tmf.init(kstore);
tm = tmf.getTrustManagers();
}
// Create a SSLContext ( to create the ssl factory )
// This is the only way to use server sockets with JSSE 1.0.1
com.ibm.net.ssl.SSLContext context =
com.ibm.net.ssl.SSLContext.getInstance(protocol); // SSL
// init context with the key managers
context.init(kmf.getKeyManagers(), tm,
new java.security.SecureRandom());
return context;
}
/**
* intializes a keystore.
*
* @param keystoreFile
* @param keyPass
*
* @return keystore
* @throws IOException
*/
private KeyStore initKeyStore(String keystoreFile, String keyPass)
throws IOException {
try {
KeyStore kstore = KeyStore.getInstance(keystoreType);
InputStream istream = new FileInputStream(keystoreFile);
kstore.load(istream, keyPass.toCharArray());
return kstore;
} catch (FileNotFoundException fnfe) {
throw fnfe;
} catch (IOException ioe) {
throw ioe;
} catch (Exception ex) {
ex.printStackTrace();
throw new IOException("Exception trying to load keystore "
+ keystoreFile + ": " + ex.getMessage());
}
}
}
1.39 +9 -0 xml-axis/java/xmls/targets.xml
Index: targets.xml
===================================================================
RCS file: /home/cvs/xml-axis/java/xmls/targets.xml,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- targets.xml 30 Sep 2002 14:44:54 -0000 1.38
+++ targets.xml 8 Oct 2002 12:12:47 -0000 1.39
@@ -124,6 +124,15 @@
</and>
</condition>
+ <condition property="ibmjsse.present" >
+ <and>
+ <available classname="com.ibm.net.ssl.X509TrustManager"
classpathref="classpath" />
+ <available classname="javax.net.SocketFactory" classpathref="classpath" />
+ <available classname="com.ibm.net.ssl.SSLContext" classpathref="classpath"
/>
+ <available classname="javax.net.ssl.SSLSocketFactory"
classpathref="classpath" />
+ </and>
+ </condition>
+
<condition property="attachments.present" >
<and>
<available classname="javax.activation.DataHandler"
classpathref="classpath" />