Commit 01eafc87 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Finished TLS for s2s. JM-395

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@3253 b35dd754-fafc-0310-a699-88a17e54d16e
parent 75bbf141
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
package org.jivesoftware.wildfire.net; package org.jivesoftware.wildfire.net;
import org.jivesoftware.wildfire.*; import org.jivesoftware.wildfire.*;
import org.jivesoftware.wildfire.server.IncomingServerSession;
import org.jivesoftware.wildfire.auth.UnauthorizedException; import org.jivesoftware.wildfire.auth.UnauthorizedException;
import org.jivesoftware.wildfire.interceptor.InterceptorManager; import org.jivesoftware.wildfire.interceptor.InterceptorManager;
import org.jivesoftware.wildfire.interceptor.PacketRejectedException; import org.jivesoftware.wildfire.interceptor.PacketRejectedException;
...@@ -20,6 +21,7 @@ import org.jivesoftware.util.LocaleUtils; ...@@ -20,6 +21,7 @@ import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import javax.net.ssl.SSLSession;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
...@@ -131,15 +133,20 @@ public class SocketConnection implements Connection { ...@@ -131,15 +133,20 @@ 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. When connecting
* to a remote server then <tt>clientMode</tt> will be <code>true</code> and
* <tt>remoteServer</tt> is the server name of the remote server. Otherwise <tt>clientMode</tt>
* will be <code>false</code> and <tt>remoteServer</tt> null.
* *
* @param clientMode boolean indicating if this entity is a client or a server. * @param clientMode boolean indicating if this entity is a client or a server.
* @param remoteServer server name of the remote server we are connecting to or <tt>null</tt>
* when not in client mode.
* @throws IOException if an error occured while securing the connection. * @throws IOException if an error occured while securing the connection.
*/ */
public void startTLS(boolean clientMode) throws IOException { public void startTLS(boolean clientMode, String remoteServer) throws IOException {
if (!secure) { if (!secure) {
secure = true; secure = true;
tlsStreamHandler = new TLSStreamHandler(socket, clientMode); tlsStreamHandler = new TLSStreamHandler(socket, clientMode, remoteServer, session instanceof IncomingServerSession);
writer = new BufferedWriter(new OutputStreamWriter(tlsStreamHandler.getOutputStream(), CHARSET)); writer = new BufferedWriter(new OutputStreamWriter(tlsStreamHandler.getOutputStream(), CHARSET));
xmlSerializer = new XMLSocketWriter(writer, this); xmlSerializer = new XMLSocketWriter(writer, this);
} }
...@@ -304,6 +311,13 @@ public class SocketConnection implements Connection { ...@@ -304,6 +311,13 @@ public class SocketConnection implements Connection {
this.flashClient = flashClient; this.flashClient = flashClient;
} }
public SSLSession getSSLSession() {
if (tlsStreamHandler != null) {
return tlsStreamHandler.getSSLSession();
}
return null;
}
public void close() { public void close() {
boolean wasClosed = false; boolean wasClosed = false;
synchronized (this) { synchronized (this) {
......
...@@ -670,9 +670,10 @@ public abstract class SocketReader implements Runnable { ...@@ -670,9 +670,10 @@ public abstract class SocketReader implements Runnable {
connection.deliverRawText("<proceed xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"); connection.deliverRawText("<proceed xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>");
// Negotiate TLS. // Negotiate TLS.
try { try {
connection.startTLS(false); connection.startTLS(false, null);
} }
catch (IOException e) { catch (IOException e) {
Log.error("Error while negotiating TLS", e);
connection.deliverRawText("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">"); connection.deliverRawText("<failure xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">");
connection.close(); connection.close();
return false; return false;
......
...@@ -14,6 +14,7 @@ package org.jivesoftware.wildfire.net; ...@@ -14,6 +14,7 @@ package org.jivesoftware.wildfire.net;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLSession;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
...@@ -74,14 +75,23 @@ public class TLSStreamHandler { ...@@ -74,14 +75,23 @@ public class TLSStreamHandler {
private static ByteBuffer hsBB = ByteBuffer.allocate(0); private static ByteBuffer hsBB = ByteBuffer.allocate(0);
/** /**
* Creates a new TLSStreamHandler and secures the plain socket connection. * Creates a new TLSStreamHandler and secures the plain socket connection. When connecting
* to a remote server then <tt>clientMode</tt> will be <code>true</code> and
* <tt>remoteServer</tt> is the server name of the remote server. Otherwise <tt>clientMode</tt>
* will be <code>false</code> and <tt>remoteServer</tt> null.
* *
* @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 * @param clientMode boolean indicating if this entity is a client or a server.
* @param remoteServer server name of the remote server we are connecting to or <tt>null</tt>
* when not in client mode.
* @param needClientAuth boolean that indicates if client should authenticate during the TLS
* negotiation. This option is only required when the client is a server since
* EXTERNAL SASL is going to be used.
* @throws java.io.IOException
*/ */
public TLSStreamHandler(Socket socket, boolean clientMode) throws IOException { public TLSStreamHandler(Socket socket, boolean clientMode, String remoteServer,
wrapper = new TLSWrapper(clientMode); boolean needClientAuth) throws IOException {
wrapper = new TLSWrapper(clientMode, needClientAuth, remoteServer);
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);
...@@ -107,6 +117,9 @@ public class TLSStreamHandler { ...@@ -107,6 +117,9 @@ public class TLSStreamHandler {
initialHSStatus = HandshakeStatus.NEED_WRAP; initialHSStatus = HandshakeStatus.NEED_WRAP;
tlsEngine.beginHandshake(); tlsEngine.beginHandshake();
} }
else if (needClientAuth) {
tlsEngine.setNeedClientAuth(true);
}
while (!initialHSComplete) { while (!initialHSComplete) {
initialHSComplete = doHandshake(null); initialHSComplete = doHandshake(null);
...@@ -290,4 +303,15 @@ public class TLSStreamHandler { ...@@ -290,4 +303,15 @@ public class TLSStreamHandler {
wbc.close(); wbc.close();
rbc.close(); rbc.close();
} }
/**
* Returns the SSLSession in use. The session specifies a particular cipher suite which
* is being actively used by all connections in that session, as well as the identities
* of the session's client and server.
*
* @return the SSLSession in use.
*/
public SSLSession getSSLSession() {
return tlsEngine.getSession();
}
} }
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
package org.jivesoftware.wildfire.net; package org.jivesoftware.wildfire.net;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import javax.net.ssl.*; import javax.net.ssl.*;
...@@ -22,7 +21,6 @@ import java.nio.ByteBuffer; ...@@ -22,7 +21,6 @@ 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;
/** /**
* 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
...@@ -57,7 +55,7 @@ public class TLSWrapper { ...@@ -57,7 +55,7 @@ public class TLSWrapper {
private int netBuffSize; private int netBuffSize;
private int appBuffSize; private int appBuffSize;
public TLSWrapper(boolean clientMode) { public TLSWrapper(boolean clientMode, boolean needClientAuth, String remoteServer) {
if (debug) { if (debug) {
System.setProperty("javax.net.debug", "all"); System.setProperty("javax.net.debug", "all");
...@@ -77,27 +75,11 @@ public class TLSWrapper { ...@@ -77,27 +75,11 @@ 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 || needClientAuth) {
if (clientMode && !verify) { // Check if we can trust certificates presented by the server
// Trust any certificate presented by the server. Disabling certificate validation tm = new TrustManager[]{new ServerTrustManager(remoteServer, ksTrust)};
// 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);
tlsContext.init(km, tm, null); tlsContext.init(km, tm, null);
......
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