Commit 3c92837f authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added support for TLS and SASL. JM-395 and JM-396

git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@2866 b35dd754-fafc-0310-a699-88a17e54d16e
parent 3db455fc
...@@ -11,18 +11,20 @@ ...@@ -11,18 +11,20 @@
package org.jivesoftware.messenger.server; package org.jivesoftware.messenger.server;
import org.dom4j.Element;
import org.dom4j.io.XPPPacketReader;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.net.SocketConnection;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.xmpp.packet.Packet; import org.jivesoftware.messenger.net.SASLAuthentication;
import org.dom4j.io.XPPPacketReader; import org.jivesoftware.messenger.net.SocketConnection;
import org.dom4j.Element; import org.jivesoftware.util.Log;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmpp.packet.Packet;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
/** /**
...@@ -56,11 +58,11 @@ public class IncomingServerSession extends Session { ...@@ -56,11 +58,11 @@ public class IncomingServerSession extends Session {
private Collection<String> validatedDomains = new ArrayList<String>(); private Collection<String> validatedDomains = new ArrayList<String>();
/** /**
* List of domains or subdomains of this server that were used by the remote server * Domains or subdomain of this server that was used by the remote server
* when validating the new connection. For instance, when using ServerDialback the * when validating the new connection. This information is useful to prevent
* list will contain the different TO values used in the <tt>db:result</tt> packet. * many connections from the same remote server to the same local domain.
*/ */
private Collection<String> localDomains = new ArrayList<String>(); private String localDomain = null;
/** /**
* Creates a new session that will receive packets. The new session will be authenticated * Creates a new session that will receive packets. The new session will be authenticated
...@@ -88,14 +90,72 @@ public class IncomingServerSession extends Session { ...@@ -88,14 +90,72 @@ public class IncomingServerSession extends Session {
SocketConnection connection) throws XmlPullParserException, IOException { SocketConnection connection) throws XmlPullParserException, IOException {
XmlPullParser xpp = reader.getXPPParser(); XmlPullParser xpp = reader.getXPPParser();
if (xpp.getNamespace("db") != null) { if (xpp.getNamespace("db") != null) {
// Server is trying to establish connection and authenticate using server dialback
ServerDialback method = new ServerDialback(connection, serverName); ServerDialback method = new ServerDialback(connection, serverName);
return method.createIncomingSession(reader); return method.createIncomingSession(reader);
} }
// Close the connection since we only support server dialback for s2s communication String version = xpp.getAttributeValue("", "version");
int[] serverVersion = version != null ? decodeVersion(version) : new int[] {0,0};
if (serverVersion[0] >= 1) {
// Remote server is XMPP 1.0 compliant so offer TLS and SASL to establish the connection
try {
return createIncomingSession(connection, serverName);
}
catch (Exception e) {
Log.error("Error establishing connection from remote server", e);
}
}
// Close the connection since remote server is not XMPP 1.0 compliant and is not
// using server dialback to establish and authenticate the connection
connection.close(); connection.close();
return null; return null;
} }
/**
* Returns a new incoming server session pending to be authenticated. The remote server
* will be notified that TLS and SASL are available. The remote server will be able to
* send packets to this server only after SASL authentication has been finished.
*
* @param connection the new established connection with the remote server.
* @param serverName hostname of this server.
* @return a new incoming server session pending to be authenticated.
* @throws UnauthorizedException if this server is being shutdown.
*/
private static Session createIncomingSession(SocketConnection connection, String serverName)
throws UnauthorizedException {
// Get the stream ID for the new session
StreamID streamID = SessionManager.getInstance().nextStreamID();
// Create a server Session for the remote server
IncomingServerSession session = SessionManager.getInstance()
.createIncomingServerSession(connection, streamID);
// Send the stream header
StringBuilder openingStream = new StringBuilder();
openingStream.append("<stream:stream");
openingStream.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
openingStream.append(" xmlns=\"jabber:server\"");
openingStream.append(" from=\"").append(serverName).append("\"");
openingStream.append(" id=\"").append(streamID).append("\"");
openingStream.append(" version=\"1.0\">");
connection.deliverRawText(openingStream.toString());
StringBuilder sb = new StringBuilder();
sb.append("<stream:features>");
sb.append("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\">");
// TODO Consider that STARTTLS may be optional (add TLS options to the AC - disabled, optional, required)
// sb.append("<required/>");
sb.append("</starttls>");
// Include available SASL Mechanisms
sb.append(SASLAuthentication.getSASLMechanisms(session));
sb.append("</stream:features>");
connection.deliverRawText(sb.toString());
// Set the domain or subdomain of the local server targeted by the remote server
session.setLocalDomain(serverName);
return session;
}
public IncomingServerSession(String serverName, Connection connection, StreamID streamID) { public IncomingServerSession(String serverName, Connection connection, StreamID streamID) {
super(serverName, connection, streamID); super(serverName, connection, streamID);
} }
...@@ -186,28 +246,28 @@ public class IncomingServerSession extends Session { ...@@ -186,28 +246,28 @@ public class IncomingServerSession extends Session {
} }
/** /**
* Returns a collection with the domains and subdomains of the local server used by * Returns the domain or subdomain of the local server used by the remote server
* the remote server when validating the session. This information is only used to * when validating the session. This information is only used to prevent many
* prevent many connections from the same remote server to the same domain or * connections from the same remote server to the same domain or subdomain of
* subdomain of the local server. * the local server.
* *
* @return collection with the domains and subdomains of the local server used by * @return the domain or subdomain of the local server used by the remote server
* the remote server when validating the session. * when validating the session.
*/ */
public Collection<String> getLocalDomains() { public String getLocalDomain() {
return Collections.unmodifiableCollection(localDomains); return localDomain;
} }
/** /**
* Adds a new domain or subdomain of the local server used by the remote server when asking * Sets the domain or subdomain of the local server used by the remote server when asking
* to validate the session. This information is only used to prevent many connections from * to validate the session. This information is only used to prevent many connections from
* the same remote server to the same domain or subdomain of the local server. * the same remote server to the same domain or subdomain of the local server.
* *
* @param domain the domain or subdomain of the local server used when validating the * @param domain the domain or subdomain of the local server used when validating the
* session. * session.
*/ */
public void addLocalDomain(String domain) { public void setLocalDomain(String domain) {
localDomains.add(domain); localDomain = domain;
} }
/** /**
......
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