Commit 549c6511 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Modified to close the outgoing session if a </stream> element is received from the remote server.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@1525 b35dd754-fafc-0310-a699-88a17e54d16e
parent 6ac3ba54
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
package org.jivesoftware.messenger.server; package org.jivesoftware.messenger.server;
import org.dom4j.io.XPPPacketReader;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.net.SocketAcceptThread; import org.jivesoftware.messenger.net.SocketAcceptThread;
...@@ -56,7 +55,7 @@ public class OutgoingServerSession extends Session { ...@@ -56,7 +55,7 @@ public class OutgoingServerSession extends Session {
private Collection<String> authenticatedDomains = new ArrayList<String>(); private Collection<String> authenticatedDomains = new ArrayList<String>();
private Collection<String> hostnames = new ArrayList<String>(); private Collection<String> hostnames = new ArrayList<String>();
private XPPPacketReader reader; private OutgoingServerSocketReader socketReader;
/** /**
* Creates a new outgoing connection to the specified hostname if no one exists. The port of * Creates a new outgoing connection to the specified hostname if no one exists. The port of
...@@ -176,7 +175,7 @@ public class OutgoingServerSession extends Session { ...@@ -176,7 +175,7 @@ public class OutgoingServerSession extends Session {
} }
// A session already exists so authenticate the domain using that session // A session already exists so authenticate the domain using that session
ServerDialback method = new ServerDialback(session.getConnection(), domain); ServerDialback method = new ServerDialback(session.getConnection(), domain);
if (method.authenticateDomain(session.reader, domain, hostname, if (method.authenticateDomain(session.socketReader, domain, hostname,
session.getStreamID().getID())) { session.getStreamID().getID())) {
// Add the validated domain as an authenticated domain // Add the validated domain as an authenticated domain
session.addAuthenticatedDomain(domain); session.addAuthenticatedDomain(domain);
...@@ -189,10 +188,11 @@ public class OutgoingServerSession extends Session { ...@@ -189,10 +188,11 @@ public class OutgoingServerSession extends Session {
return false; return false;
} }
OutgoingServerSession(String serverName, Connection connection, XPPPacketReader reader, OutgoingServerSession(String serverName, Connection connection,
StreamID streamID) { OutgoingServerSocketReader socketReader, StreamID streamID) {
super(serverName, connection, streamID); super(serverName, connection, streamID);
this.reader = reader; this.socketReader = socketReader;
socketReader.setSession(this);
} }
public void process(Packet packet) throws UnauthorizedException, PacketException { public void process(Packet packet) throws UnauthorizedException, PacketException {
......
...@@ -19,9 +19,9 @@ import org.jivesoftware.messenger.auth.AuthFactory; ...@@ -19,9 +19,9 @@ import org.jivesoftware.messenger.auth.AuthFactory;
import org.jivesoftware.messenger.net.DNSUtil; import org.jivesoftware.messenger.net.DNSUtil;
import org.jivesoftware.messenger.net.SocketConnection; import org.jivesoftware.messenger.net.SocketConnection;
import org.jivesoftware.messenger.spi.BasicStreamIDFactory; import org.jivesoftware.messenger.spi.BasicStreamIDFactory;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.JiveGlobals;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParserFactory;
...@@ -31,7 +31,7 @@ import org.xmpp.packet.StreamError; ...@@ -31,7 +31,7 @@ import org.xmpp.packet.StreamError;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import java.io.*; import java.io.*;
import java.net.Socket; import java.net.Socket;
import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit;
/** /**
* Implementation of the Server Dialback method as defined by the RFC3920. * Implementation of the Server Dialback method as defined by the RFC3920.
...@@ -87,7 +87,7 @@ class ServerDialback { ...@@ -87,7 +87,7 @@ class ServerDialback {
* session used for receiving packets from the remote server. Use * session used for receiving packets from the remote server. Use
* {@link #validateRemoteDomain(org.dom4j.Element, org.jivesoftware.messenger.StreamID)} for * {@link #validateRemoteDomain(org.dom4j.Element, org.jivesoftware.messenger.StreamID)} for
* validating subsequent domains and use * validating subsequent domains and use
* {@link #authenticateDomain(org.dom4j.io.XPPPacketReader, String, String, String)} for * {@link #authenticateDomain(OutgoingServerSocketReader, String, String, String)} for
* registering new domains that are allowed to send packets to the remote server.<p> * registering new domains that are allowed to send packets to the remote server.<p>
* *
* For validating domains a new TCP connection will be established to the Authoritative Server. * For validating domains a new TCP connection will be established to the Authoritative Server.
...@@ -128,8 +128,6 @@ class ServerDialback { ...@@ -128,8 +128,6 @@ class ServerDialback {
DNSUtil.HostAddress address = DNSUtil.resolveXMPPServerDomain(hostname); DNSUtil.HostAddress address = DNSUtil.resolveXMPPServerDomain(hostname);
realHostname = address.getHost(); realHostname = address.getHost();
Socket socket = SocketFactory.getDefault().createSocket(realHostname, port); Socket socket = SocketFactory.getDefault().createSocket(realHostname, port);
// Set a read timeout of 60 seconds during the dialback operation. Then reset to 0.
socket.setSoTimeout(JiveGlobals.getIntProperty("xmpp.server.read.timeout", 60000));
Log.debug("OS - Connection to " + hostname + ":" + port + " successfull"); Log.debug("OS - Connection to " + hostname + ":" + port + " successfull");
connection = connection =
new SocketConnection(XMPPServer.getInstance().getPacketDeliverer(), socket, new SocketConnection(XMPPServer.getInstance().getPacketDeliverer(), socket,
...@@ -155,13 +153,12 @@ class ServerDialback { ...@@ -155,13 +153,12 @@ class ServerDialback {
} }
if ("jabber:server:dialback".equals(xpp.getNamespace("db"))) { if ("jabber:server:dialback".equals(xpp.getNamespace("db"))) {
String id = xpp.getAttributeValue("", "id"); String id = xpp.getAttributeValue("", "id");
if (authenticateDomain(reader, domain, hostname, id)) { OutgoingServerSocketReader socketReader = new OutgoingServerSocketReader(reader);
// Reset the read timeout to infinite. if (authenticateDomain(socketReader, domain, hostname, id)) {
socket.setSoTimeout(0);
// Domain was validated so create a new OutgoingServerSession // Domain was validated so create a new OutgoingServerSession
StreamID streamID = new BasicStreamIDFactory().createStreamID(id); StreamID streamID = new BasicStreamIDFactory().createStreamID(id);
OutgoingServerSession session = new OutgoingServerSession(domain, connection, OutgoingServerSession session = new OutgoingServerSession(domain, connection,
reader, streamID); socketReader, streamID);
connection.init(session); connection.init(session);
// Set the hostname as the address of the session // Set the hostname as the address of the session
session.setAddress(new JID(null, hostname, null)); session.setAddress(new JID(null, hostname, null));
...@@ -204,25 +201,19 @@ class ServerDialback { ...@@ -204,25 +201,19 @@ class ServerDialback {
* The Receiving Server will connect to the Authoritative Server to verify the dialback key. * The Receiving Server will connect to the Authoritative Server to verify the dialback key.
* Most probably the Originating Server machine will be the Authoritative Server too. * Most probably the Originating Server machine will be the Authoritative Server too.
* *
* @param reader the reader to use for reading the answer from the Receiving Server. * @param socketReader the reader to use for reading the answer from the Receiving Server.
* @param domain the domain to authenticate. * @param domain the domain to authenticate.
* @param hostname the hostname of the remote server (i.e. Receiving Server). * @param hostname the hostname of the remote server (i.e. Receiving Server).
* @param id the stream id to be used for creating the dialback key. * @param id the stream id to be used for creating the dialback key.
* @return true if the Receiving Server authenticated the domain with the Authoritative Server. * @return true if the Receiving Server authenticated the domain with the Authoritative Server.
* @throws XmlPullParserException if a parsing error occured while reading the answer from
* the Receiving Server.
* @throws IOException if an input/output error occured while sending/receiving packets to/from
* the Receiving Server.
* @throws DocumentException if a parsing error occured while reading the answer from
* the Receiving Server.
*/ */
public boolean authenticateDomain(XPPPacketReader reader, String domain, String hostname, public boolean authenticateDomain(OutgoingServerSocketReader socketReader, String domain,
String id) throws XmlPullParserException, IOException, DocumentException { String hostname, String id) {
String key = AuthFactory.createDigest(id, secretKey); String key = AuthFactory.createDigest(id, secretKey);
Log.debug("OS - Sent dialback key to host: " + hostname + " id: " + id + " from domain: " + Log.debug("OS - Sent dialback key to host: " + hostname + " id: " + id + " from domain: " +
domain); domain);
synchronized (reader) { synchronized (socketReader) {
// Send a dialback key to the Receiving Server // Send a dialback key to the Receiving Server
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("<db:result"); sb.append("<db:result");
...@@ -235,8 +226,17 @@ class ServerDialback { ...@@ -235,8 +226,17 @@ class ServerDialback {
// Process the answer from the Receiving Server // Process the answer from the Receiving Server
try { try {
Element doc = reader.parseDocument().getRootElement(); Element doc = socketReader.getElement(JiveGlobals.getIntProperty("xmpp.server.read.timeout", 60000),
if ("db".equals(doc.getNamespacePrefix()) && "result".equals(doc.getName())) { TimeUnit.MILLISECONDS);
if (doc == null) {
Log.debug("OS - Time out waiting for answer in validation from: " + hostname +
" id: " +
id +
" for domain: " +
domain);
return false;
}
else if ("db".equals(doc.getNamespacePrefix()) && "result".equals(doc.getName())) {
boolean success = "valid".equals(doc.attributeValue("type")); boolean success = "valid".equals(doc.attributeValue("type"));
Log.debug("OS - Validation " + (success ? "GRANTED" : "FAILED") + " from: " + Log.debug("OS - Validation " + (success ? "GRANTED" : "FAILED") + " from: " +
hostname + hostname +
...@@ -256,12 +256,12 @@ class ServerDialback { ...@@ -256,12 +256,12 @@ class ServerDialback {
return false; return false;
} }
} }
catch (SocketTimeoutException e) { catch (InterruptedException e) {
Log.debug("OS - Time out waiting for answer in validation from: " + hostname + Log.debug("OS - Validation FAILED from: " + hostname +
" id: " + " id: " +
id + id +
" for domain: " + " for domain: " +
domain); domain, e);
return false; return false;
} }
} }
......
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