Commit 759f904b authored by Dave Cridland's avatar Dave Cridland

Merge pull request #418 from surevine/dwd/OF-985

OF-984 / OF-985 Dialback fixes for to attribute and TLS
parents 22c7eabd c7c4d7c2
......@@ -172,7 +172,7 @@ public class TLSStreamHandler {
return writer.getOutputStream();
}
void start() throws IOException {
public void start() throws IOException {
while (!initialHSComplete) {
initialHSComplete = doHandshake(null);
}
......
......@@ -27,6 +27,7 @@ import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
......@@ -43,16 +44,14 @@ import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.StreamID;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.AuthFactory;
import org.jivesoftware.openfire.net.DNSUtil;
import org.jivesoftware.openfire.net.MXParser;
import org.jivesoftware.openfire.net.SASLAuthentication;
import org.jivesoftware.openfire.net.ServerTrafficCounter;
import org.jivesoftware.openfire.net.SocketConnection;
import org.jivesoftware.openfire.net.*;
import org.jivesoftware.openfire.session.ConnectionSettings;
import org.jivesoftware.openfire.session.IncomingServerSession;
import org.jivesoftware.openfire.session.LocalIncomingServerSession;
import org.jivesoftware.openfire.session.LocalOutgoingServerSession;
import org.jivesoftware.openfire.spi.BasicStreamIDFactory;
import org.jivesoftware.openfire.spi.ConnectionManagerImpl;
import org.jivesoftware.openfire.spi.ConnectionType;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.cache.Cache;
......@@ -638,33 +637,21 @@ public class ServerDialback {
return host_unknown;
}
/**
* Verifies the key with the Authoritative Server.
*/
private VerifyResult verifyKey(String key, String streamID, String recipient, String hostname,
Socket socket) throws IOException, XmlPullParserException,
RemoteConnectionFailedException {
XMPPPacketReader reader;
Writer writer = null;
// Set a read timeout
socket.setSoTimeout(RemoteServerManager.getSocketTimeout());
private VerifyResult sendVerifyKey(String key, String streamID, String recipient, String hostname, Writer writer, XMPPPacketReader reader, Socket socket) throws IOException, XmlPullParserException, RemoteConnectionFailedException {
VerifyResult result = VerifyResult.error;
try {
reader = new XMPPPacketReader();
reader.setXPPFactory(FACTORY);
reader.getXPPParser().setInput(new InputStreamReader(socket.getInputStream(),
CHARSET));
// Get a writer for sending the open stream tag
writer =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),
CHARSET));
TLSStreamHandler tlsStreamHandler;
// Send the Authoritative Server a stream header
StringBuilder stream = new StringBuilder();
stream.append("<stream:stream");
stream.append(" xmlns:stream=\"http://etherx.jabber.org/streams\"");
stream.append(" xmlns=\"jabber:server\"");
stream.append(" xmlns:db=\"jabber:server:dialback\"");
stream.append(" to=\"");
stream.append(hostname);
stream.append("\"");
stream.append(" from=\"");
stream.append(recipient);
stream.append("\"");
stream.append(" version=\"1.0\">");
writer.write(stream.toString());
writer.flush();
......@@ -680,16 +667,36 @@ public class ServerDialback {
try {
doc = reader.parseDocument();
} catch (DocumentException e) {
// TODO Auto-generated catch block
Log.warn("XML Error!", e);
return VerifyResult.error;
}
Element features = doc.getRootElement();
Element starttls = features.element("starttls");
if (starttls != null) {
if (starttls.element("required") != null) {
Log.error("TLS required for db:verify but cannot yet do this.");
writer.write("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
writer.flush();
try {
doc = reader.parseDocument();
} catch (DocumentException e) {
Log.warn("XML Error!", e);
return VerifyResult.error;
}
if (!doc.getRootElement().getName().equals("proceed")) {
Log.warn("Got {} instead of proceed for starttls", doc.getRootElement().getName());
Log.debug("Like this: {}", doc.asXML());
return VerifyResult.error;
}
// Ugly hacks, apparently, copied from SocketConnection.
final ConnectionManagerImpl connectionManager = ((ConnectionManagerImpl) XMPPServer.getInstance().getConnectionManager());
tlsStreamHandler = new TLSStreamHandler(socket, connectionManager.getListener( ConnectionType.SOCKET_S2S, false ).generateConnectionConfiguration(), true);
// Start handshake
tlsStreamHandler.start();
// Use new wrapped writers
writer = new BufferedWriter(new OutputStreamWriter(tlsStreamHandler.getOutputStream(), StandardCharsets.UTF_8));
reader.getXPPParser().setInput(new InputStreamReader(tlsStreamHandler.getInputStream(),
StandardCharsets.UTF_8));
/// Recurses!
return sendVerifyKey(key, streamID, recipient, hostname, writer, reader, socket);
}
}
if ("jabber:server:dialback".equals(xpp.getNamespace("db"))) {
......@@ -767,6 +774,31 @@ public class ServerDialback {
// sent to the Originating Server
throw new RemoteConnectionFailedException("Invalid namespace");
}
return result;
}
/**
* Verifies the key with the Authoritative Server.
*/
private VerifyResult verifyKey(String key, String streamID, String recipient, String hostname,
Socket socket) throws IOException, XmlPullParserException,
RemoteConnectionFailedException {
XMPPPacketReader reader;
Writer writer = null;
// Set a read timeout
socket.setSoTimeout(RemoteServerManager.getSocketTimeout());
VerifyResult result = VerifyResult.error;
try {
reader = new XMPPPacketReader();
reader.setXPPFactory(FACTORY);
reader.getXPPParser().setInput(new InputStreamReader(socket.getInputStream(),
CHARSET));
// Get a writer for sending the open stream tag
writer =
new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),
CHARSET));
result = sendVerifyKey(key, streamID, recipient, hostname, writer, reader, socket);
}
finally {
try {
......
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