public ProtocolNode CreateFeaturesNode() { ProtocolNode child = new ProtocolNode("receipt_acks", null, null, ""); List<ProtocolNode> children = new List<ProtocolNode>(); children.Add(child); ProtocolNode parent = new ProtocolNode("stream:features", null, children, ""); return parent; }
public ProtocolNode CreateAuthResponseNode(string m_realm, string m_username, string m_password, string m_nonce, string m_qop, string m_charset) { byte[] resp = GenerateResponse(m_realm, m_username, m_password, m_nonce, m_qop, m_charset); Dictionary<string, string> respHash = new Dictionary<string, string>(); respHash["xmlns"] = "urn:ietf:params:xml:ns:xmpp-sasl"; ProtocolNode node = new ProtocolNode("response", respHash, null, Convert.ToBase64String(resp)); return node; }
public ProtocolNode CreateAuthNode() { Dictionary<string, string> authHash = new Dictionary<string, string>(); authHash["xmlns"] = "urn:ietf:params:xml:ns:xmpp-sasl"; authHash["mechanism"] = "DIGEST-MD5-1"; ProtocolNode node = new ProtocolNode("auth", authHash, null, ""); return node; }
public List<byte> CreateHelloMessage() { List<byte> helloMessage = new List<byte>(); helloMessage.AddRange(ASCIIEncoding.ASCII.GetBytes("WA")); helloMessage.AddRange(new byte[] { 0x01, 0x01, 0x00, 0x19 }); Dictionary<string, string> attributes = new Dictionary<string, string>(); attributes["to"] = "s.whatsapp.net"; attributes["resource"] = "iPhone-2.8.2-5222"; ProtocolNode helloMessageNode = new ProtocolNode("stream:stream", attributes, null, ""); helloMessage.AddRange(helloMessageNode.WriteNode(helloMessageNode)); return helloMessage; }
static void worker_DoWork(object sender, DoWorkEventArgs e) { ProtocolNode resultNode = null; while (true) { resultNode = api.ReceiveNode(); switch (resultNode.tag) { case "presence": Console.WriteLine(resultNode.ToString()); break; case "message": if (resultNode.getAttribute("from") == "error.us") { throw new ApplicationException("error sending message"); } else if (resultNode.getChild("body") != null) { Console.WriteLine("{0} > {1}", resultNode.getAttribute("from"), resultNode.getChild("body").data); Dictionary<string, string> messageParameters = new Dictionary<string, string>(); messageParameters["to"] = resultNode.getAttribute("from"); messageParameters["type"] = "chat"; messageParameters["id"] = resultNode.getAttribute("id"); Dictionary<string, string> receivedHash = new Dictionary<string, string>(); receivedHash["xmlns"] = "urn:xmpp:receipts"; ProtocolNode receivedNode = new ProtocolNode("received", receivedHash, null, ""); List<ProtocolNode> childrenMessageReceivedNode = new List<ProtocolNode>(); childrenMessageReceivedNode.Add(receivedNode); ProtocolNode messageReceivedNode = new ProtocolNode("message", messageParameters, childrenMessageReceivedNode, ""); api.SendNode(messageReceivedNode); } else { Console.WriteLine(resultNode.ToString()); } break; case "stream:error": throw new ApplicationException(resultNode.data); break; default: Console.WriteLine(resultNode.ToString()); break; } } }
public ProtocolNode CreateTextMessage(string msgid, string to, string txt) { ProtocolNode bodyNode = new ProtocolNode("body", null, null, txt); ProtocolNode serverNode = new ProtocolNode("server", null, null, ""); Dictionary<string, string> xHash = new Dictionary<string, string>(); xHash["xmlns"] = "jabber:x:event"; List<ProtocolNode> listOfServerNode = new List<ProtocolNode>(); listOfServerNode.Add(serverNode); ProtocolNode xNode = new ProtocolNode("x", xHash, listOfServerNode, ""); Dictionary<string, string> messageHash = new Dictionary<string, string>(); messageHash["to"] = to + "@" + "s.whatsapp.net"; messageHash["type"] = "chat"; messageHash["id"] = msgid; List<ProtocolNode> listOfMessageNodeChildren = new List<ProtocolNode>(); listOfMessageNodeChildren.Add(xNode); listOfMessageNodeChildren.Add(bodyNode); return new ProtocolNode("message", messageHash, listOfMessageNodeChildren, ""); }
private List<byte> WriteNodeInternal(ProtocolNode node) { List<byte> tokenAsBytes = new List<byte>(); int len = 1; if (node.attributeHash != null) { len += node.attributeHash.Count * 2; } if (node.children != null && node.children.Count > 0) { len += 1; } if (node.data.Length > 0) { len += 1; } tokenAsBytes.AddRange(CreateListStart(len)); tokenAsBytes.AddRange(CreateString(node.tag)); if (node.attributeHash != null) { tokenAsBytes.AddRange(CreateAttributes(node.attributeHash)); } if (node.data.Length > 0) { tokenAsBytes.AddRange(WriteBytes(node.data)); } if (node.children != null) { tokenAsBytes.AddRange(CreateListStart(node.children.Count)); foreach (ProtocolNode child in node.children) { tokenAsBytes.AddRange(WriteNodeInternal(child)); } } return tokenAsBytes; }
public List<byte> WriteNode(ProtocolNode node) { List<byte> tokenAsBytes = new List<byte>(); if (node == null) { tokenAsBytes.Add(0); } else { tokenAsBytes.AddRange(WriteNodeInternal(node)); } return tokenAsBytes; }
public int Send(byte[] buffer) { if (buffer[0] == 'W' && buffer[1] == 'A') { //received hello, must wait for features protocolPhase = 1; } else { MessageParser parser = new MessageParser(); ProtocolNode node = parser.ParseNode(buffer); if (node.tag == "stream:features") { //received features, must wait for auth protocolPhase = 2; } else if (node.tag == "auth") { protocolPhase = 3; receiveBuffer = new List<byte>(); //<stream:stream from="s.whatsapp.net"></stream:stream> Dictionary<string, string> startNodeAttributes = new Dictionary<string, string>(); startNodeAttributes["from"] = "s.whatsapp.net"; ProtocolNode startNode = new ProtocolNode("stream:stream", startNodeAttributes, null, ""); receiveBuffer.AddRange(startNode.ToBytes()); // <stream:features> // <receipt_acks></receipt_acks> //</stream:features> ProtocolNode receiptAcksNode = new ProtocolNode("receipt_acks", null, null, ""); List<ProtocolNode> featuresNodeChildren = new List<ProtocolNode>(); featuresNodeChildren.Add(receiptAcksNode); ProtocolNode featuresNode = new ProtocolNode("stream:features", null, featuresNodeChildren, ""); receiveBuffer.AddRange(featuresNode.ToBytes()); // <challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">bm9uY2U9IjE0OTcxOTQ2MzkyMSIscW9wPSJhdXRoIixjaGFyc2V0PXV0Zi04LGFsZ29yaXRobT1tZDUtc2Vzcw==</challenge> Dictionary<string, string> attributes = new Dictionary<string, string>(); attributes["xmlns"] = "urn:ietf:params:xml:ns:xmpp-sasl"; ProtocolNode challenge = new ProtocolNode("challenge", attributes, null, "bm9uY2U9IjE0OTcxOTQ2MzkyMSIscW9wPSJhdXRoIixjaGFyc2V0PXV0Zi04LGFsZ29yaXRobT1tZDUtc2Vzcw=="); receiveBuffer.AddRange(challenge.ToBytes()); } else if (node.tag == "response") { //received //<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">dXNlcm5hbWU9IjU1NTE5ODc2NTQzMiIscmVhbG09InMud2hhdHNhcHAubmV0Iixub25jZT0iMTQ5NzE5NDYzOTIxIixjbm9uY2U9IjM2MzgzNTNhMzUzNTM1MzEzOTM4MzczNjM1MzQzMzMyM2EzODMxMzIzODYxMzQzMDM4MzMzNzMxMzE2MTM4NjU2MTYzMzk2MTMzNjM2MzY0MzYzODMwNjM2MzMzNjMzOTMyIixuYz0wMDAwMDAwMSxxb3A9YXV0aCxkaWdlc3QtdXJpPSJ4bXBwL3Mud2hhdHNhcHAubmV0IixyZXNwb25zZT1lM2Q5MjIxOTRlN2M3MTBlYmE3YjEyNjI4Mjc5MTgzMyxjaGFyc2V0PXV0Zi04</response> //must verify and send success MessageFactory factory = new MessageFactory(); Dictionary<string,string> encodedAttributes = factory.ProcessChallenge(node); if (encodedAttributes["username"] == "555198765432" && encodedAttributes["realm"] == "s.whatsapp.net" && encodedAttributes["nonce"] == "149719463921" && encodedAttributes["nc"] == "00000001" && encodedAttributes["qop"] == "auth" && encodedAttributes["digest-uri"] == "xmpp/s.whatsapp.net" && encodedAttributes["charset"] == "utf-8") { //&& encodedAttributes["cnonce"] == "aaaaa" //&& encodedAttributes["response"] == "e3d922194e7c710eba7b126282791833" //TODO: validate cnonce e response //send //<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl" status="active" kind="free" creation="1338065926" expiration="1369601926"></success> ProtocolNode success = new ProtocolNode("success", null, null, ""); receiveBuffer.AddRange(success.ToBytes()); } } } return buffer.Length; }
public Dictionary<string, string> ProcessChallenge(ProtocolNode node) { string challenge = Encoding.ASCII.GetString(Convert.FromBase64String(node.data)); string[] challengeStrs = challenge.Split(new char[] { ',' }); Dictionary<string, string> challengeArray = new Dictionary<string, string>(); foreach (string c in challengeStrs) { string[] d = c.Split(new char[] { '=' }); challengeArray[d[0]] = d[1].Replace("\"", ""); } return challengeArray; }