diff options
Diffstat (limited to 'src/main/java/com/juick/xmpp/s2s/ConnectionIn.java')
-rw-r--r-- | src/main/java/com/juick/xmpp/s2s/ConnectionIn.java | 181 |
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; + } +} |