diff options
author | Vitaly Takmazov | 2016-05-07 19:57:10 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2016-05-07 19:57:10 +0300 |
commit | b1d5d5801e90ef0d4e282a78543f1435b8b7d223 (patch) | |
tree | 70dcd3a4a67c4a15847b3c17357897709f2334ee /src/main/java/com/juick/xmpp/s2s/ConnectionIn.java | |
parent | f2a2660e753fa11478fd3edadfdff9c000b22cc9 (diff) |
STARTTLS
Diffstat (limited to 'src/main/java/com/juick/xmpp/s2s/ConnectionIn.java')
-rw-r--r-- | src/main/java/com/juick/xmpp/s2s/ConnectionIn.java | 67 |
1 files changed, 47 insertions, 20 deletions
diff --git a/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java b/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java index c215e375..950a2eaa 100644 --- a/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java +++ b/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java @@ -7,12 +7,13 @@ import com.juick.xmpp.Presence; import com.juick.xmpp.utils.XmlUtils; import org.xmlpull.v1.XmlPullParser; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSocket; import java.io.EOFException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; -import java.nio.channels.AsynchronousSocketChannel; -import java.nio.channels.Channels; +import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -31,7 +32,7 @@ public class ConnectionIn extends Connection { public long tsRemoteData = 0; public long packetsRemote = 0; - public ConnectionIn(AsynchronousSocketChannel socket) { + public ConnectionIn(Socket socket) throws Exception { super(); this.socket = socket; streamID = UUID.randomUUID().toString(); @@ -40,28 +41,21 @@ public class ConnectionIn extends Connection { public void parseStream() { LOGGER.info("STREAM FROM ? " + streamID + " START"); try { - parser.setInput(new InputStreamReader(Channels.newInputStream(socket))); - writer = new OutputStreamWriter(Channels.newOutputStream(socket)); + parser.setInput(new InputStreamReader(socket.getInputStream())); + writer = new OutputStreamWriter(socket.getOutputStream()); parser.next(); // stream:stream updateTsRemoteData(); - if (!parser.getName().equals("stream:stream") - || !parser.getAttributeValue(null, "xmlns").equals("jabber:server") - || !parser.getAttributeValue(null, "xmlns:stream").equals("http://etherx.jabber.org/streams") - || !parser.getAttributeValue(null, "xmlns:db").equals("jabber:server:dialback")) { + if (!parser.getName().equals("stream") + || !parser.getAttributeValue(null, "stream").equals(NS_STREAM) + || !parser.getAttributeValue(null, "db").equals(NS_DB)) { // || !parser.getAttributeValue(null, "version").equals("1.0") // || !parser.getAttributeValue(null, "to").equals(Main.HOSTNAME)) { throw new Exception("STREAM FROM ? " + streamID + " INVALID FIRST PACKET"); } boolean xmppversionnew = parser.getAttributeValue(null, "version") != null; - String openStream = "<?xml version='1.0'?><stream:stream xmlns='jabber:server' " + - "xmlns:stream='http://etherx.jabber.org/streams' xmlns:db='jabber:server:dialback' from='" + - XMPPComponent.HOSTNAME + "' id='" + streamID + "' version='1.0'>"; - if (xmppversionnew) { - openStream += "<stream:features></stream:features>"; - } - sendStanza(openStream); + sendOpenStream(xmppversionnew); while (parser.next() != XmlPullParser.END_DOCUMENT) { updateTsRemoteData(); @@ -73,14 +67,14 @@ public class ConnectionIn extends Connection { packetsRemote++; String tag = parser.getName(); - if (tag.equals("db:result")) { + if (tag.equals("result") && parser.getNamespace().equals(NS_DB)) { String dfrom = parser.getAttributeValue(null, "from"); String to = parser.getAttributeValue(null, "to"); LOGGER.info("STREAM FROM " + dfrom + " TO " + to + " " + streamID + " ASKING FOR DIALBACK"); if (dfrom.endsWith(XMPPComponent.HOSTNAME) && (dfrom.equals(XMPPComponent.HOSTNAME) || dfrom.endsWith("." + XMPPComponent.HOSTNAME))) { break; } - if (dfrom != null && to != null && to.equals(XMPPComponent.HOSTNAME)) { + if (to != null && to.equals(XMPPComponent.HOSTNAME)) { String dbKey = XmlUtils.getTagText(parser); updateTsRemoteData(); @@ -89,12 +83,12 @@ public class ConnectionIn extends Connection { c.sendDialbackVerify(streamID, dbKey); } else { c = new ConnectionOut(dfrom, streamID, dbKey); - c.parseStream(); + XMPPComponent.executorService.submit(c); } } else { throw new Exception("STREAM FROM " + dfrom + " " + streamID + " DIALBACK RESULT FAIL"); } - } else if (tag.equals("db:verify")) { + } else if (tag.equals("verify") && parser.getNamespace().equals(NS_DB)) { String vfrom = parser.getAttributeValue(null, "from"); String vto = parser.getAttributeValue(null, "to"); String vid = parser.getAttributeValue(null, "id"); @@ -112,6 +106,25 @@ public class ConnectionIn extends Connection { sendStanza("<db:verify from='" + vto + "' to='" + vfrom + "' id='" + vid + "' type='invalid'/>"); LOGGER.warning("STREAM FROM " + vfrom + " " + streamID + " DIALBACK VERIFY INVALID"); } + } else if (!isSecured() && tag.equals("starttls")) { + LOGGER.info("STREAM " + streamID + " SECURING"); + sendStanza("<proceed xmlns=\"" + NS_TLS + "\" />"); + try { + socket = sc.getSocketFactory().createSocket(socket, socket.getInetAddress().getHostAddress(), + socket.getPort(), true); + ((SSLSocket) socket).setUseClientMode(false); + ((SSLSocket) socket).startHandshake(); + setSecured(true); + LOGGER.info("STREAM " + streamID + " SECURED"); + restartParser(); + } catch (SSLException sex) { + LOGGER.warning("STREAM " + streamID + " SSL ERROR"); + sendStanza("<failed xmlns\"" + NS_TLS + "\" />"); + XMPPComponent.removeConnectionIn(this); + closeConnection(); + } + } else if (isSecured() && tag.equals("stream") && parser.getNamespace().equals(NS_STREAM)) { + sendOpenStream(true); } else if (tag.equals("presence") && checkFromTo(parser)) { Presence p = Presence.parse(parser, null); if (p != null && (p.type == null || !p.type.equals(Presence.Type.error))) { @@ -156,6 +169,20 @@ public class ConnectionIn extends Connection { tsRemoteData = System.currentTimeMillis(); } + void sendOpenStream(boolean xmppversionnew) throws IOException { + String openStream = "<?xml version='1.0'?><stream:stream xmlns='jabber:server' " + + "xmlns:stream='http://etherx.jabber.org/streams' xmlns:db='jabber:server:dialback' from='" + + XMPPComponent.HOSTNAME + "' id='" + streamID + "' version='1.0'>"; + if (xmppversionnew) { + openStream += "<stream:features>"; + if (!isSecured()) { + openStream += "<starttls xmlns=\"" + NS_TLS + "\"><optional/></starttls>"; + } + openStream += "</stream:features>"; + } + sendStanza(openStream); + } + public void sendDialbackResult(String sfrom, String type) { try { sendStanza("<db:result from='" + XMPPComponent.HOSTNAME + "' to='" + sfrom + "' type='" + type + "'/>"); |