aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/juick/xmpp/s2s/ConnectionIn.java')
-rw-r--r--src/main/java/com/juick/xmpp/s2s/ConnectionIn.java181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java b/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java
new file mode 100644
index 00000000..8150cc27
--- /dev/null
+++ b/src/main/java/com/juick/xmpp/s2s/ConnectionIn.java
@@ -0,0 +1,181 @@
+package com.juick.xmpp.s2s;
+
+import com.juick.xmpp.Iq;
+import com.juick.xmpp.JID;
+import com.juick.xmpp.Message;
+import com.juick.xmpp.Presence;
+import com.juick.xmpp.utils.XmlUtils;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.UUID;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ *
+ * @author ugnich
+ */
+public class ConnectionIn extends Connection implements Runnable {
+
+ final public ArrayList<String> from = new ArrayList<String>();
+ public long tsRemoteData = 0;
+ public long packetsRemote = 0;
+
+ public ConnectionIn(Socket socket) {
+ super();
+ this.socket = socket;
+ streamID = UUID.randomUUID().toString();
+ }
+
+ @Override
+ public void run() {
+ System.out.println("STREAM FROM ? " + streamID + " START");
+ try {
+ 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")) {
+// || !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);
+
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ updateTsRemoteData();
+ if (parser.getEventType() != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ if (XMPPComponent.LOGFILE != null) {
+ logParser();
+ }
+
+ packetsRemote++;
+
+ String tag = parser.getName();
+ if (tag.equals("db:result")) {
+ String dfrom = parser.getAttributeValue(null, "from");
+ String to = parser.getAttributeValue(null, "to");
+ System.out.println("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)) {
+ String dbKey = XmlUtils.getTagText(parser);
+ updateTsRemoteData();
+
+ ConnectionOut c = XMPPComponent.getConnectionOut(dfrom, false);
+ if (c != null) {
+ c.sendDialbackVerify(streamID, dbKey);
+ } else {
+ c = new ConnectionOut(dfrom, streamID, dbKey);
+ new Thread(c).start();
+ }
+ } else {
+ throw new Exception("STREAM FROM " + dfrom + " " + streamID + " DIALBACK RESULT FAIL");
+ }
+ } else if (tag.equals("db:verify")) {
+ String vfrom = parser.getAttributeValue(null, "from");
+ String vto = parser.getAttributeValue(null, "to");
+ String vid = parser.getAttributeValue(null, "id");
+ String vkey = XmlUtils.getTagText(parser);
+ updateTsRemoteData();
+ boolean valid = false;
+ if (vfrom != null && vto != null && vid != null && vkey != null) {
+ String vkey2 = generateDialbackKey(vfrom, vto, vid);
+ valid = vkey.equals(vkey2);
+ }
+ if (valid) {
+ sendStanza("<db:verify from='" + vto + "' to='" + vfrom + "' id='" + vid + "' type='valid'/>");
+ System.out.println("STREAM FROM " + vfrom + " " + streamID + " DIALBACK VERIFY VALID");
+ } else {
+ sendStanza("<db:verify from='" + vto + "' to='" + vfrom + "' id='" + vid + "' type='invalid'/>");
+ System.err.println("STREAM FROM " + vfrom + " " + streamID + " DIALBACK VERIFY INVALID");
+ }
+ } 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))) {
+ JuickBot.incomingPresence(p);
+ }
+ } else if (tag.equals("message") && checkFromTo(parser)) {
+ updateTsRemoteData();
+ Message msg = Message.parse(parser, XMPPComponent.childParsers);
+ if (msg != null && (msg.type == null || !msg.type.equals(Message.Type.error))) {
+ System.out.println("STREAM " + streamID + ": " + msg.toString());
+ if (!JuickBot.incomingMessage(msg)) {
+ XMPPComponent.connRouter.sendStanza(msg.toString());
+ }
+ }
+ } else if (tag.equals("iq") && checkFromTo(parser)) {
+ updateTsRemoteData();
+ String type = parser.getAttributeValue(null, "type");
+ String xml = XmlUtils.parseToString(parser, true);
+ if (type == null || !type.equals(Iq.Type.error)) {
+ System.out.println("STREAM " + streamID + ": " + xml);
+ XMPPComponent.connRouter.sendStanza(xml);
+ }
+ } else {
+ System.out.println("STREAM " + streamID + ": " + XmlUtils.parseToString(parser, true));
+ }
+ }
+ System.err.println("STREAM " + streamID + " FINISHED");
+ XMPPComponent.removeConnectionIn(this);
+ closeConnection();
+ } catch (Exception e) {
+ System.err.println("STREAM " + streamID + " ERROR:" + e.toString());
+ e.printStackTrace();
+ XMPPComponent.removeConnectionIn(this);
+ closeConnection();
+ }
+ }
+
+ void updateTsRemoteData() {
+ tsRemoteData = System.currentTimeMillis();
+ }
+
+ public void sendDialbackResult(String sfrom, String type) {
+ try {
+ sendStanza("<db:result from='" + XMPPComponent.HOSTNAME + "' to='" + sfrom + "' type='" + type + "'/>");
+ if (type.equals("valid")) {
+ from.add(sfrom);
+ System.out.println("STREAM FROM " + sfrom + " " + streamID + " READY");
+ }
+ } catch (IOException e) {
+ System.err.println("STREAM FROM " + sfrom + " " + streamID + " ERROR: " + e.toString());
+ }
+ }
+
+ boolean checkFromTo(XmlPullParser parser) throws Exception {
+ String cfrom = parser.getAttributeValue(null, "from");
+ String cto = parser.getAttributeValue(null, "to");
+ if (cfrom != null && cto != null && !cfrom.isEmpty() && !cto.isEmpty()) {
+ JID jidto = new JID(cto);
+ if (jidto.Host != null && jidto.Username != null && jidto.Host.equals(XMPPComponent.HOSTNAME) && jidto.Username.matches("^[a-zA-Z0-9\\-]{2,16}$")) {
+ JID jidfrom = new JID(cfrom);
+ int size = from.size();
+ for (int i = 0; i < size; i++) {
+ if (from.get(i).equals(jidfrom.Host)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}