Commit 611b54ea authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added support for TLS negotiation as a client. JM-395

git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@2858 b35dd754-fafc-0310-a699-88a17e54d16e
parent 60a3afc3
...@@ -26,7 +26,6 @@ import java.io.Writer; ...@@ -26,7 +26,6 @@ import java.io.Writer;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
/** /**
...@@ -43,7 +42,7 @@ public class SocketConnection implements Connection { ...@@ -43,7 +42,7 @@ public class SocketConnection implements Connection {
*/ */
public static final String CHARSET = "UTF-8"; public static final String CHARSET = "UTF-8";
private Map listeners = new HashMap(); private Map<ConnectionCloseListener, Object> listeners = new HashMap<ConnectionCloseListener, Object>();
private Socket socket; private Socket socket;
...@@ -96,12 +95,13 @@ public class SocketConnection implements Connection { ...@@ -96,12 +95,13 @@ public class SocketConnection implements Connection {
/** /**
* Secures the plain connection by negotiating TLS with the client. * Secures the plain connection by negotiating TLS with the client.
* *
* @param clientMode boolean indicating if this entity is a client or a server.
* @throws IOException if an error occured while securing the connection. * @throws IOException if an error occured while securing the connection.
*/ */
public void startTLS() throws IOException { public void startTLS(boolean clientMode) throws IOException {
if (!secure) { if (!secure) {
secure = true; secure = true;
tlsStreamHandler = new TLSStreamHandler(socket); tlsStreamHandler = new TLSStreamHandler(socket, clientMode);
writer = new BufferedWriter(new OutputStreamWriter(tlsStreamHandler.getOutputStream(), CHARSET)); writer = new BufferedWriter(new OutputStreamWriter(tlsStreamHandler.getOutputStream(), CHARSET));
xmlSerializer = new XMLSocketWriter(writer, socket); xmlSerializer = new XMLSocketWriter(writer, socket);
} }
...@@ -336,9 +336,7 @@ public class SocketConnection implements Connection { ...@@ -336,9 +336,7 @@ public class SocketConnection implements Connection {
*/ */
private void notifyCloseListeners() { private void notifyCloseListeners() {
synchronized (listeners) { synchronized (listeners) {
Iterator itr = listeners.keySet().iterator(); for (ConnectionCloseListener listener : listeners.keySet()) {
while (itr.hasNext()) {
ConnectionCloseListener listener = (ConnectionCloseListener)itr.next();
listener.onConnectionClose(listeners.get(listener)); listener.onConnectionClose(listeners.get(listener));
} }
} }
......
...@@ -77,11 +77,12 @@ public class TLSStreamHandler { ...@@ -77,11 +77,12 @@ public class TLSStreamHandler {
/** /**
* Creates a new TLSStreamHandler and secures the plain socket connection. * Creates a new TLSStreamHandler and secures the plain socket connection.
* *
* @param clientMode boolean indicating if this entity is a client or a server.
* @param socket the plain socket connection to secure * @param socket the plain socket connection to secure
* @throws IOException * @throws IOException
*/ */
public TLSStreamHandler(Socket socket) throws IOException { public TLSStreamHandler(Socket socket, boolean clientMode) throws IOException {
wrapper = new TLSWrapper(); wrapper = new TLSWrapper(clientMode);
tlsEngine = wrapper.getTlsEngine(); tlsEngine = wrapper.getTlsEngine();
reader = new TLSStreamReader(wrapper, socket); reader = new TLSStreamReader(wrapper, socket);
writer = new TLSStreamWriter(wrapper, socket); writer = new TLSStreamWriter(wrapper, socket);
...@@ -101,8 +102,12 @@ public class TLSStreamHandler { ...@@ -101,8 +102,12 @@ public class TLSStreamHandler {
appBB = ByteBuffer.allocate(appBBSize); appBB = ByteBuffer.allocate(appBBSize);
//socket.setSoTimeout(0); if (clientMode) {
//socket.setKeepAlive(true); socket.setSoTimeout(0);
socket.setKeepAlive(true);
initialHSStatus = HandshakeStatus.NEED_WRAP;
tlsEngine.beginHandshake();
}
while (!initialHSComplete) { while (!initialHSComplete) {
initialHSComplete = doHandshake(null); initialHSComplete = doHandshake(null);
......
...@@ -11,23 +11,18 @@ ...@@ -11,23 +11,18 @@
package org.jivesoftware.messenger.net; package org.jivesoftware.messenger.net;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log;
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
import org.jivesoftware.util.Log;
/** /**
* Creates and initializes the SSLContext instance to use to secure the plain connection. This * Creates and initializes the SSLContext instance to use to secure the plain connection. This
...@@ -62,7 +57,7 @@ public class TLSWrapper { ...@@ -62,7 +57,7 @@ public class TLSWrapper {
private int netBuffSize; private int netBuffSize;
private int appBuffSize; private int appBuffSize;
public TLSWrapper() { public TLSWrapper(boolean clientMode) {
if (debug) { if (debug) {
System.setProperty("javax.net.debug", "all"); System.setProperty("javax.net.debug", "all");
...@@ -82,6 +77,26 @@ public class TLSWrapper { ...@@ -82,6 +77,26 @@ public class TLSWrapper {
// TrustManager's decide whether to allow connections. // TrustManager's decide whether to allow connections.
TrustManager[] tm = SSLJiveTrustManagerFactory.getTrustManagers(ksTrust, trustpass); TrustManager[] tm = SSLJiveTrustManagerFactory.getTrustManagers(ksTrust, trustpass);
boolean verify = JiveGlobals.getBooleanProperty("xmpp.server.certificate.verify", true);
if (clientMode && !verify) {
// Trust any certificate presented by the server. Disabling certificate validation
// is not recommended for production environments.
tm = new TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] x509Certificates,
String string) {
}
public void checkServerTrusted(X509Certificate[] x509Certificates,
String string) {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
}
SSLContext tlsContext = SSLContext.getInstance(PROTOCOL); SSLContext tlsContext = SSLContext.getInstance(PROTOCOL);
...@@ -94,7 +109,7 @@ public class TLSWrapper { ...@@ -94,7 +109,7 @@ public class TLSWrapper {
* The first call for a server is a NEED_UNWRAP. * The first call for a server is a NEED_UNWRAP.
*/ */
tlsEngine = tlsContext.createSSLEngine(); tlsEngine = tlsContext.createSSLEngine();
tlsEngine.setUseClientMode(false); tlsEngine.setUseClientMode(clientMode);
SSLSession session = tlsEngine.getSession(); SSLSession session = tlsEngine.getSession();
netBuffSize = session.getPacketBufferSize(); netBuffSize = session.getPacketBufferSize();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment