protected void handleNotification(ProtocolTreeNode node) { if (!String.IsNullOrEmpty(node.GetAttribute("notify"))) { this.fireOnGetContactName(node.GetAttribute("from"), node.GetAttribute("notify")); } string type = node.GetAttribute("type"); switch (type) { case "picture": ProtocolTreeNode child = node.children.FirstOrDefault(); this.fireOnNotificationPicture(child.tag, child.GetAttribute("jid"), child.GetAttribute("id")); break; case "status": ProtocolTreeNode child2 = node.children.FirstOrDefault(); this.fireOnGetStatus(node.GetAttribute("from"), child2.tag, node.GetAttribute("notify"), System.Text.Encoding.UTF8.GetString(child2.GetData())); break; case "subject": //TODO break; case "contacts": //TODO break; default: throw new NotImplementedException(node.NodeString()); } this.SendNotificationAck(node); }
private void decodeInTree(byte[] data) { try { ProtocolTreeNode node = reader.nextTree(data, true); while (node != null) { File.AppendAllLines("xmpp.log", new string[] { node.NodeString("rx") }); //look for challengedata and forge key if (node.tag.Equals("challenge", StringComparison.InvariantCultureIgnoreCase) && !String.IsNullOrEmpty(this.password)) { this.AddListItem("ChallengeKey received, forging key..."); byte[] challengeData = node.GetData(); byte[] pass = Convert.FromBase64String(this.password); Rfc2898DeriveBytes r = new Rfc2898DeriveBytes(pass, challengeData, 16); byte[] key = r.GetBytes(20); reader.Encryptionkey = key; //reset static keys WhatsAppApi.Helper.Encryption.encryptionIncoming = null; WhatsAppApi.Helper.Encryption.encryptionOutgoing = null; } node = reader.nextTree(null, true); } } catch (IncompleteMessageException e) { } catch (Exception e) { this.AddListItem(String.Format("INDECODER ERROR: {0}", e.Message)); throw e; } }
public ProtocolTreeNode nextTree(byte[] pInput = null, bool useDecrypt = true) { if (pInput != null && pInput.Length > 0) { this.buffer = new List <byte>(); this.buffer.AddRange(pInput); int stanzaFlag = (this.peekInt8() & 0xF0) >> 4; int stanzaSize = this.peekInt16(1); int flags = stanzaFlag; int size = stanzaSize; this.readInt24(); bool isEncrypted = (stanzaFlag & 8) != 0; if (isEncrypted) { if (this.Key != null) { var realStanzaSize = stanzaSize - 4; var macOffset = stanzaSize - 4; var treeData = this.buffer.ToArray(); try { this.Key.DecodeMessage(treeData, macOffset, 0, realStanzaSize); } catch (Exception e) { Logger.Log.WriteLog(e.Message); } this.buffer.Clear(); this.buffer.AddRange(treeData); } else { throw new Exception("Received encrypted message, encryption key not set"); } } if (stanzaSize > 0) { ProtocolTreeNode node = this.nextTreeInternal(); if (node != null) { this.DebugPrint(node.NodeString("RECVD: ")); } return(node); } } return(null); }
public byte[] Write(ProtocolTreeNode node, bool encrypt = true) { if (node == null) { this.buffer.Add(0); } else { this.DebugPrint(node.NodeString("SENT: ")); this.writeInternal(node); } return(this.flushBuffer(encrypt)); }
private void decodeOutTree(byte[] data) { try { ProtocolTreeNode node = reader.nextTree(data, false); while (node != null) { File.AppendAllLines("xmpp.log", new string[] { node.NodeString("tx") }); node = reader.nextTree(null, false); } } catch (IncompleteMessageException e) { } catch (Exception e) { this.AddListItem(String.Format("OUTDECODER ERROR: {0}", e.Message)); throw e; } }
protected void handleMessage(ProtocolTreeNode node, bool autoReceipt) { if (!string.IsNullOrEmpty(node.GetAttribute("notify"))) { string name = node.GetAttribute("notify"); this.fireOnGetContactName(node.GetAttribute("from"), name); } if (node.GetAttribute("type") == "error") { throw new NotImplementedException(node.NodeString()); } if (node.GetChild("body") != null) { //text message this.fireOnGetMessage(node, node.GetAttribute("from"), node.GetAttribute("id"), node.GetAttribute("notify"), System.Text.Encoding.UTF8.GetString(node.GetChild("body").GetData()), autoReceipt); if (autoReceipt) { this.sendMessageReceived(node); } } if (node.GetChild("media") != null) { ProtocolTreeNode media = node.GetChild("media"); //media message //define variables in switch string file, url, from, id; int size; byte[] preview, dat; id = node.GetAttribute("id"); from = node.GetAttribute("from"); switch (media.GetAttribute("type")) { case "image": url = media.GetAttribute("url"); file = media.GetAttribute("file"); size = Int32.Parse(media.GetAttribute("size")); preview = media.GetData(); this.fireOnGetMessageImage(from, id, file, size, url, preview); break; case "audio": file = media.GetAttribute("file"); size = Int32.Parse(media.GetAttribute("size")); url = media.GetAttribute("url"); preview = media.GetData(); this.fireOnGetMessageAudio(from, id, file, size, url, preview); break; case "video": file = media.GetAttribute("file"); size = Int32.Parse(media.GetAttribute("size")); url = media.GetAttribute("url"); preview = media.GetData(); this.fireOnGetMessageVideo(from, id, file, size, url, preview); break; case "location": double lon = double.Parse(media.GetAttribute("longitude"), System.Globalization.CultureInfo.InvariantCulture); double lat = double.Parse(media.GetAttribute("latitude"), System.Globalization.CultureInfo.InvariantCulture); preview = media.GetData(); name = media.GetAttribute("name"); url = media.GetAttribute("url"); this.fireOnGetMessageLocation(from, id, lon, lat, url, name, preview); break; case "vcard": ProtocolTreeNode vcard = media.GetChild("vcard"); name = vcard.GetAttribute("name"); dat = vcard.GetData(); this.fireOnGetMessageVcard(from, id, name, dat); break; } this.sendMessageReceived(node); } }
protected bool processInboundData(byte[] msgdata, bool autoReceipt = true) { try { ProtocolTreeNode node = this.reader.nextTree(msgdata); if (node != null) { if (ProtocolTreeNode.TagEquals(node, "challenge")) { this.processChallenge(node); } else if (ProtocolTreeNode.TagEquals(node, "success")) { this.loginStatus = CONNECTION_STATUS.LOGGEDIN; this.accountinfo = new AccountInfo(node.GetAttribute("status"), node.GetAttribute("kind"), node.GetAttribute("creation"), node.GetAttribute("expiration")); this.fireOnLoginSuccess(this.phoneNumber, node.GetData()); } else if (ProtocolTreeNode.TagEquals(node, "failure")) { this.loginStatus = CONNECTION_STATUS.UNAUTHORIZED; this.fireOnLoginFailed(node.children.FirstOrDefault().tag); } if (ProtocolTreeNode.TagEquals(node, "receipt")) { string from = node.GetAttribute("from"); string id = node.GetAttribute("id"); string type = node.GetAttribute("type") ?? "delivery"; switch (type) { case "delivery": //delivered to target this.fireOnGetMessageReceivedClient(from, id); break; case "read": //read by target //todo break; case "played": //played by target //todo break; } //send ack SendNotificationAck(node, type); } if (ProtocolTreeNode.TagEquals(node, "message")) { this.handleMessage(node, autoReceipt); } if (ProtocolTreeNode.TagEquals(node, "iq")) { this.handleIq(node); } if (ProtocolTreeNode.TagEquals(node, "stream:error")) { var textNode = node.GetChild("text"); if (textNode != null) { string content = WhatsApp.SYSEncoding.GetString(textNode.GetData()); Console.WriteLine("Error : " + content); } this.Disconnect(); } if (ProtocolTreeNode.TagEquals(node, "presence")) { //presence node this.fireOnGetPresence(node.GetAttribute("from"), node.GetAttribute("type")); } if (node.tag == "ib") { foreach (ProtocolTreeNode child in node.children) { switch (child.tag) { case "dirty": this.SendClearDirty(child.GetAttribute("type")); break; case "offline": //this.SendQrSync(null); break; default: throw new NotImplementedException(node.NodeString()); } } } if (node.tag == "chatstate") { string state = node.children.FirstOrDefault().tag; switch (state) { case "composing": this.fireOnGetTyping(node.GetAttribute("from")); break; case "paused": this.fireOnGetPaused(node.GetAttribute("from")); break; default: throw new NotImplementedException(node.NodeString()); } } if (node.tag == "ack") { string cls = node.GetAttribute("class"); if (cls == "message") { //server receipt this.fireOnGetMessageReceivedServer(node.GetAttribute("from"), node.GetAttribute("id")); } } if (node.tag == "notification") { this.handleNotification(node); } return(true); } } catch (Exception e) { throw e; } return(false); }
/// <summary> /// Process inbound data /// </summary> /// <param name="data">Data to process</param> protected void processInboundData(byte[] data) { try { List <byte> foo = new List <byte>(); if (this._incompleteBytes.Count > 0) { foreach (IncompleteMessageException e in this._incompleteBytes) { foo.AddRange(e.getInput()); } this._incompleteBytes.Clear(); } if (data != null) { foo.AddRange(data); } ProtocolTreeNode node = this.reader.nextTree(foo.ToArray()); while (node != null) { //this.WhatsParser.ParseProtocolNode(node); if (node.tag == "iq" && node.GetAttribute("type") == "error") { this.AddMessage(node); } if (ProtocolTreeNode.TagEquals(node, "challenge")) { this.processChallenge(node); } else if (ProtocolTreeNode.TagEquals(node, "success")) { this.loginStatus = CONNECTION_STATUS.LOGGEDIN; this.accountinfo = new AccountInfo(node.GetAttribute("status"), node.GetAttribute("kind"), node.GetAttribute("creation"), node.GetAttribute("expiration")); } else if (ProtocolTreeNode.TagEquals(node, "failure")) { this.loginStatus = CONNECTION_STATUS.UNAUTHORIZED; } if (ProtocolTreeNode.TagEquals(node, "message")) { this.AddMessage(node); if (node.GetChild("request") != null) { this.sendMessageReceived(node); } else if (node.GetChild("received") != null) { this.sendMessageReceived(node, "ack"); } } if (ProtocolTreeNode.TagEquals(node, "stream:error")) { Console.Write(node.NodeString()); } if (ProtocolTreeNode.TagEquals(node, "iq") && node.GetAttribute("type").Equals("result", StringComparison.OrdinalIgnoreCase) && ProtocolTreeNode.TagEquals(node.children.First(), "query") ) { //last seen this.AddMessage(node); } if (ProtocolTreeNode.TagEquals(node, "iq") && node.GetAttribute("type").Equals("result", StringComparison.OrdinalIgnoreCase) && (ProtocolTreeNode.TagEquals(node.children.First(), "media") || ProtocolTreeNode.TagEquals(node.children.First(), "duplicate")) ) { //media upload this.uploadResponse = node; } if (ProtocolTreeNode.TagEquals(node, "iq") && node.GetAttribute("type").Equals("result", StringComparison.OrdinalIgnoreCase) && ProtocolTreeNode.TagEquals(node.children.First(), "picture") ) { //profile picture this.AddMessage(node); } if (ProtocolTreeNode.TagEquals(node, "iq") && node.GetAttribute("type").Equals("get", StringComparison.OrdinalIgnoreCase) && ProtocolTreeNode.TagEquals(node.children.First(), "ping")) { this.Pong(node.GetAttribute("id")); } if (ProtocolTreeNode.TagEquals(node, "stream:error")) { var textNode = node.GetChild("text"); if (textNode != null) { string content = WhatsApp.SYSEncoding.GetString(textNode.GetData()); Console.WriteLine("Error : " + content); if (content.Equals("Replaced by new connection", StringComparison.OrdinalIgnoreCase)) { this.Disconnect(); this.Connect(); this.Login(); } } } if (ProtocolTreeNode.TagEquals(node, "presence")) { //presence node this.AddMessage(node); } node = this.reader.nextTree(); } } catch (IncompleteMessageException ex) { this._incompleteBytes.Add(ex); } }