From 58ac4567a402d383c3edb0749b9f2fb88b8422d6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 25 Jan 2015 19:54:43 +0000 Subject: less pointers, less memory problems git-svn-id: http://svn.miranda-ng.org/main/trunk@11906 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/WhatsApp/src/WASocketConnection.cpp | 4 +- .../WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp | 73 +++++++--------------- .../WhatsApp/src/WhatsAPI++/BinTreeNodeReader.h | 8 +-- .../WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp | 26 ++++---- .../WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h | 7 ++- protocols/WhatsApp/src/WhatsAPI++/KeyStream.cpp | 19 +++--- protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp | 64 +++++++++++-------- protocols/WhatsApp/src/WhatsAPI++/WAConnection.h | 25 +++++--- protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp | 40 ++++-------- protocols/WhatsApp/src/WhatsAPI++/WALogin.h | 14 ++--- protocols/WhatsApp/src/connection.cpp | 28 ++++----- 11 files changed, 135 insertions(+), 173 deletions(-) (limited to 'protocols/WhatsApp') diff --git a/protocols/WhatsApp/src/WASocketConnection.cpp b/protocols/WhatsApp/src/WASocketConnection.cpp index 41d0b78663..c688492e4e 100644 --- a/protocols/WhatsApp/src/WASocketConnection.cpp +++ b/protocols/WhatsApp/src/WASocketConnection.cpp @@ -20,9 +20,8 @@ WASocketConnection::WASocketConnection(const std::string& dir, int port) throw ( noc.flags = NLOCF_V2; // | NLOCF_SSL; this->hConn = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, reinterpret_cast(this->hNetlibUser), reinterpret_cast(&noc)); - if (this->hConn == NULL) { + if (this->hConn == NULL) throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_OPEN); - } this->connected = true; } @@ -45,7 +44,6 @@ void WASocketConnection::write(int i) void WASocketConnection::makeNonBlock() { - //if (fcntl(socket->channel, F_SETFL, O_NONBLOCK) == -1) // #TODO !? throw WAException("Error setting socket nonblocking!", WAException::SOCKET_EX, WAException::SOCKET_EX_OPEN); } diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp index 16e9238a4f..492dde1027 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp @@ -12,45 +12,17 @@ #include "ProtocolTreeNode.h" #include "utilities.h" -static const char *secondary_dict[] = { - "mpeg4", "wmv", "audio/3gpp", "audio/aac", "audio/amr", "audio/mp4", "audio/mpeg", "audio/ogg", "audio/qcelp", "audio/wav", - "audio/webm", "audio/x-caf", "audio/x-ms-wma", "image/gif", "image/jpeg", "image/png", "video/3gpp", "video/avi", "video/mp4", - "video/mpeg", "video/quicktime", "video/x-flv", "video/x-ms-asf", "302", "400", "401", "402", "403", "404", "405", "406", "407", - "409", "410", "500", "501", "503", "504", "abitrate", "acodec", "app_uptime", "asampfmt", "asampfreq", "audio", "clear", "conflict", - "conn_no_nna", "cost", "currency", "duration", "extend", "file", "fps", "g_notify", "g_sound", "gcm", "gone", "google_play", "hash", - "height", "invalid", "jid-malformed", "latitude", "lc", "lg", "live", "location", "log", "longitude", "max_groups", "max_participants", - "max_subject", "mimetype", "mode", "napi_version", "normalize", "orighash", "origin", "passive", "password", "played", - "policy-violation", "pop_mean_time", "pop_plus_minus", "price", "pricing", "redeem", "Replaced by new connection", "resume", - "signature", "size", "sound", "source", "system-shutdown", "username", "vbitrate", "vcard", "vcodec", "video", "width", - "xml-not-well-formed", "checkmarks", "image_max_edge", "image_max_kbytes", "image_quality", "ka", "ka_grow", "ka_shrink", "newmedia", - "library", "caption", "forward", "c0", "c1", "c2", "c3", "clock_skew", "cts", "k0", "k1", "login_rtt", "m_id", "nna_msg_rtt", - "nna_no_off_count", "nna_offline_ratio", "nna_push_rtt", "no_nna_con_count", "off_msg_rtt", "on_msg_rtt", "stat_name", "sts", - "suspect_conn", "lists", "self", "qr", "web", "w:b", "recipient", "w:stats", "forbidden", "aurora.m4r", "bamboo.m4r", "chord.m4r", - "circles.m4r", "complete.m4r", "hello.m4r", "input.m4r", "keys.m4r", "note.m4r", "popcorn.m4r", "pulse.m4r", "synth.m4r", "filehash", - "max_list_recipients", "en-AU", "en-GB", "es-MX", "pt-PT", "zh-Hans", "zh-Hant", "relayelection", "relaylatency", "interruption", - "Apex.m4r", "Beacon.m4r", "Bulletin.m4r", "By The Seaside.m4r", "Chimes.m4r", "Circuit.m4r", "Constellation.m4r", "Cosmic.m4r", - "Crystals.m4r", "Hillside.m4r", "Illuminate.m4r", "Night Owl.m4r", "Opening.m4r", "Playtime.m4r", "Presto.m4r", "Radar.m4r", - "Radiate.m4r", "Ripples.m4r", "Sencha.m4r", "Signal.m4r", "Silk.m4r", "Slow Rise.m4r", "Stargaze.m4r", "Summit.m4r", "Twinkle.m4r", - "Uplift.m4r", "Waves.m4r", "voip", "eligible", "upgrade", "planned", "current", "future", "disable", "expire", "start", "stop", - "accuracy", "speed", "bearing", "recording", "encrypt", "key", "identity", "w:gp2", "admin", "locked", "unlocked", "new", "battery", - "archive", "adm", "plaintext_size", "compressed_size", "delivered", "msg", "pkmsg", "everyone", "v", "transport", "call-id" -}; - -BinTreeNodeReader::BinTreeNodeReader(WAConnection* conn, ISocketConnection* connection, const char** dictionary, const int dictionarysize) +BinTreeNodeReader::BinTreeNodeReader(WAConnection *conn, ISocketConnection *connection) : + buf(BUFFER_SIZE) { this->conn = conn; this->rawIn = connection; - this->tokenMap = dictionary; - this->tokenmapsize = dictionarysize; this->readSize = 1; this->in = NULL; - this->buf = new std::vector(BUFFER_SIZE); } BinTreeNodeReader::~BinTreeNodeReader() { - if (this->buf != NULL) - delete this->buf; if (this->in != NULL) delete this->in; } @@ -88,9 +60,7 @@ ProtocolTreeNode* BinTreeNodeReader::nextTreeInternal() data = new std::vector(s->begin(), s->end()); delete s; } - else { - data = (std::vector*) obj->data; - } + else data = (std::vector*) obj->data; ProtocolTreeNode* ret = new ProtocolTreeNode(*tag, data); ret->attributes = attribs; delete obj; @@ -105,20 +75,21 @@ bool BinTreeNodeReader::isListTag(int b) void BinTreeNodeReader::decodeStream(int flags, int offset, int length) { + unsigned char *pData = (unsigned char*)&buf[0]; + if ((flags & 8) != 0) { if (length < 4) throw WAException("invalid length" + length, WAException::CORRUPT_STREAM_EX, 0); length -= 4; - unsigned char *pData = (unsigned char*)&(*this->buf)[0]; - this->conn->inputKey->decodeMessage(pData, offset + length, 0, length); - this->rawIn->dump(pData + offset, length); + this->conn->inputKey.decodeMessage(pData, offset + length, 0, length); } + this->rawIn->dump(pData + offset, length); if (this->in != NULL) delete this->in; - this->in = new ByteArrayInputStream(this->buf, offset, length); + this->in = new ByteArrayInputStream(&this->buf, offset, length); } std::map* BinTreeNodeReader::readAttributes(int attribCount) @@ -172,17 +143,17 @@ ReadData* BinTreeNodeReader::readString(int token) throw WAException("-1 token in readString", WAException::CORRUPT_STREAM_EX, -1); int bSize; - ReadData* ret = new ReadData(); + ReadData *ret = new ReadData(); - if (token > 2 && token <= this->tokenmapsize) { - if (token != this->tokenmapsize) - ret->data = new std::string(this->tokenMap[token]); + if (token > 2 && token <= WAConnection::DICTIONARY_LEN) { + if (token != WAConnection::DICTIONARY_LEN) + ret->data = new std::string(WAConnection::dictionary[token]); else { token = readInt8(this->in); - if (token >= 0 && token < _countof(secondary_dict)) - ret->data = new std::string(secondary_dict[token]); - else + if (token >= WAConnection::EXTDICTIONARY_LEN) throw WAException("invalid token/length in getToken", WAException::CORRUPT_STREAM_EX, 0); + + ret->data = new std::string(WAConnection::extended_dict[token]); } ret->type = STRING; @@ -305,12 +276,11 @@ void BinTreeNodeReader::getTopLevelStream() int flags = (stanzaSize >> 20); stanzaSize &= 0x0FFFFF; - if (this->buf->size() < (size_t)stanzaSize) { - int newsize = max((int)(this->buf->size() * 3 / 2), stanzaSize); - delete this->buf; - this->buf = new std::vector(newsize); + if (this->buf.size() < (size_t)stanzaSize) { + int newsize = max((int)(this->buf.size() * 3 / 2), stanzaSize); + this->buf.resize(newsize); } - fillArray(*this->buf, stanzaSize, this->rawIn); + fillArray(this->buf, stanzaSize, this->rawIn); this->decodeStream(flags, 0, stanzaSize); } @@ -351,11 +321,10 @@ void BinTreeNodeReader::streamStart() int tag = this->in->read(); int size = readListSize(tag); tag = this->in->read(); - if (tag != 1) { + if (tag != 1) throw WAException("expecting STREAM_START in streamStart", WAException::CORRUPT_STREAM_EX, 0); - } - int attribCount = (size - 2 + size % 2) / 2; + int attribCount = (size - 2 + size % 2) / 2; std::map* attributes = readAttributes(attribCount); delete attributes; } diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.h b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.h index 4288c671f3..29fdf4ec0a 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.h +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.h @@ -32,13 +32,11 @@ public: class BinTreeNodeReader { private: - const char** tokenMap; - int tokenmapsize; ISocketConnection *rawIn; ByteArrayInputStream* in; - std::vector* buf; + std::vector buf; int readSize; - WAConnection* conn; + WAConnection *conn; ProtocolTreeNode* nextTreeInternal(); bool isListTag(int b); @@ -64,7 +62,7 @@ private: public: - BinTreeNodeReader(WAConnection* conn, ISocketConnection* connection, const char** dictionary, const int dictionarysize); + BinTreeNodeReader(WAConnection* conn, ISocketConnection* connection); virtual ~BinTreeNodeReader(); ProtocolTreeNode* nextTree(); void streamStart(); diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp index d4387278e1..a4f79baf17 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp @@ -10,15 +10,15 @@ #include "BinTreeNodeWriter.h" #include "utilities.h" -BinTreeNodeWriter::BinTreeNodeWriter(WAConnection* conn, ISocketConnection* connection, - const char** dictionary, const int dictionarysize, IMutex* mutex) +BinTreeNodeWriter::BinTreeNodeWriter(WAConnection* conn, ISocketConnection* connection, IMutex* mutex) { + this->bLoggedIn = false; this->mutex = mutex; this->conn = conn; this->out = new ByteArrayOutputStream(2048); this->realOut = connection; - for (int i = 0; i < dictionarysize; i++) { - std::string token(dictionary[i]); + for (int i = 0; i < WAConnection::DICTIONARY_LEN; i++) { + std::string token(WAConnection::dictionary[i]); if (token.compare("") != 0) this->tokenMap[token] = i; } @@ -34,26 +34,23 @@ void BinTreeNodeWriter::writeDummyHeader() this->out->setPosition(num2); } - void BinTreeNodeWriter::processBuffer() { - bool flag = this->conn->outputKey != NULL; unsigned int num = 0u; - if (flag) { + if (bLoggedIn) { long num2 = (long)this->out->getLength() + 4L; this->out->setLength(num2); this->out->setPosition(num2); num |= 1u; } long num3 = (long)this->out->getLength() - 3L - (long) this->dataBegin; - if (num3 >= 1048576L) { + if (num3 >= 1048576L) throw WAException("Buffer too large: " + num3, WAException::CORRUPT_STREAM_EX, 0); - } std::vector* buffer = this->out->getBuffer(); - if (flag) { + if (bLoggedIn) { int num4 = (int)num3 - 4; - this->conn->outputKey->encodeMessage(buffer->data(), this->dataBegin + 3 + num4, this->dataBegin + 3, num4); + this->conn->outputKey.encodeMessage(buffer->data(), this->dataBegin + 3 + num4, this->dataBegin + 3, num4); } (*buffer)[this->dataBegin] = (unsigned char)((unsigned long)((unsigned long)num << 4) | (unsigned long)((num3 & 16711680L) >> 16)); (*buffer)[this->dataBegin + 1] = (unsigned char)((num3 & 65280L) >> 8); @@ -156,12 +153,11 @@ void BinTreeNodeWriter::writeString(const std::string& tag) void BinTreeNodeWriter::writeJid(std::string* user, const std::string& server) { this->out->write(250); - if (user != NULL && !user->empty()) { + if (user != NULL && !user->empty()) writeString(*user); - } - else { + else writeToken(0); - } + writeString(server); } diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h index c87b58f32b..e4a771f231 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h @@ -40,6 +40,7 @@ private: ByteArrayOutputStream *out; IMutex* mutex; int dataBegin; + bool bLoggedIn; void writeListStart(int i); void writeInt8(int v); @@ -57,7 +58,9 @@ private: void processBuffer(); public: - BinTreeNodeWriter(WAConnection* conn, ISocketConnection* connection, const char** dictionary, const int dictionarysize, IMutex* mutex); + BinTreeNodeWriter(WAConnection* conn, ISocketConnection* connection, IMutex* mutex); + virtual ~BinTreeNodeWriter(); + void streamStart(std::string domain, std::string resource); void flushBuffer(bool flushNetwork); void flushBuffer(bool flushNetwork, int startingOffset); @@ -65,7 +68,7 @@ public: void write(const ProtocolTreeNode &node); void write(const ProtocolTreeNode &node, bool needsFlush); - virtual ~BinTreeNodeWriter(); + void setLoggedIn() { bLoggedIn = true; } }; #endif /* BINTREENODEWRITER_H_ */ diff --git a/protocols/WhatsApp/src/WhatsAPI++/KeyStream.cpp b/protocols/WhatsApp/src/WhatsAPI++/KeyStream.cpp index f4741729a7..d027cb9c86 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/KeyStream.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/KeyStream.cpp @@ -14,8 +14,18 @@ using namespace Utilities; -KeyStream::KeyStream(unsigned char* _key, unsigned char* _keyMac) : +KeyStream::KeyStream() : seq(0) +{ + HMAC_CTX_init(&hmac); +} + +KeyStream::~KeyStream() +{ + HMAC_CTX_cleanup(&hmac); +} + +void KeyStream::init(unsigned char* _key, unsigned char* _keyMac) { memcpy(key, _key, 20); memcpy(keyMac, _keyMac, 20); @@ -24,13 +34,6 @@ KeyStream::KeyStream(unsigned char* _key, unsigned char* _keyMac) : unsigned char drop[768]; RC4(&this->rc4, sizeof(drop), drop, drop); - - HMAC_CTX_init(&hmac); -} - -KeyStream::~KeyStream() -{ - HMAC_CTX_cleanup(&hmac); } void KeyStream::keyFromPasswordAndNonce(const std::string& pass, const std::vector& nonce, unsigned char *out) diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp index 83310b4ac2..48300ad530 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp @@ -36,6 +36,34 @@ const char* WAConnection::dictionary[] = { const int WAConnection::DICTIONARY_LEN = _countof(WAConnection::dictionary); +const char* WAConnection::extended_dict[] = { + "mpeg4", "wmv", "audio/3gpp", "audio/aac", "audio/amr", "audio/mp4", "audio/mpeg", "audio/ogg", "audio/qcelp", "audio/wav", + "audio/webm", "audio/x-caf", "audio/x-ms-wma", "image/gif", "image/jpeg", "image/png", "video/3gpp", "video/avi", "video/mp4", + "video/mpeg", "video/quicktime", "video/x-flv", "video/x-ms-asf", "302", "400", "401", "402", "403", "404", "405", "406", "407", + "409", "410", "500", "501", "503", "504", "abitrate", "acodec", "app_uptime", "asampfmt", "asampfreq", "audio", "clear", "conflict", + "conn_no_nna", "cost", "currency", "duration", "extend", "file", "fps", "g_notify", "g_sound", "gcm", "gone", "google_play", "hash", + "height", "invalid", "jid-malformed", "latitude", "lc", "lg", "live", "location", "log", "longitude", "max_groups", "max_participants", + "max_subject", "mimetype", "mode", "napi_version", "normalize", "orighash", "origin", "passive", "password", "played", + "policy-violation", "pop_mean_time", "pop_plus_minus", "price", "pricing", "redeem", "Replaced by new connection", "resume", + "signature", "size", "sound", "source", "system-shutdown", "username", "vbitrate", "vcard", "vcodec", "video", "width", + "xml-not-well-formed", "checkmarks", "image_max_edge", "image_max_kbytes", "image_quality", "ka", "ka_grow", "ka_shrink", "newmedia", + "library", "caption", "forward", "c0", "c1", "c2", "c3", "clock_skew", "cts", "k0", "k1", "login_rtt", "m_id", "nna_msg_rtt", + "nna_no_off_count", "nna_offline_ratio", "nna_push_rtt", "no_nna_con_count", "off_msg_rtt", "on_msg_rtt", "stat_name", "sts", + "suspect_conn", "lists", "self", "qr", "web", "w:b", "recipient", "w:stats", "forbidden", "aurora.m4r", "bamboo.m4r", "chord.m4r", + "circles.m4r", "complete.m4r", "hello.m4r", "input.m4r", "keys.m4r", "note.m4r", "popcorn.m4r", "pulse.m4r", "synth.m4r", "filehash", + "max_list_recipients", "en-AU", "en-GB", "es-MX", "pt-PT", "zh-Hans", "zh-Hant", "relayelection", "relaylatency", "interruption", + "Apex.m4r", "Beacon.m4r", "Bulletin.m4r", "By The Seaside.m4r", "Chimes.m4r", "Circuit.m4r", "Constellation.m4r", "Cosmic.m4r", + "Crystals.m4r", "Hillside.m4r", "Illuminate.m4r", "Night Owl.m4r", "Opening.m4r", "Playtime.m4r", "Presto.m4r", "Radar.m4r", + "Radiate.m4r", "Ripples.m4r", "Sencha.m4r", "Signal.m4r", "Silk.m4r", "Slow Rise.m4r", "Stargaze.m4r", "Summit.m4r", "Twinkle.m4r", + "Uplift.m4r", "Waves.m4r", "voip", "eligible", "upgrade", "planned", "current", "future", "disable", "expire", "start", "stop", + "accuracy", "speed", "bearing", "recording", "encrypt", "key", "identity", "w:gp2", "admin", "locked", "unlocked", "new", "battery", + "archive", "adm", "plaintext_size", "compressed_size", "delivered", "msg", "pkmsg", "everyone", "v", "transport", "call-id" +}; + +const int WAConnection::EXTDICTIONARY_LEN = _countof(WAConnection::extended_dict); + +///////////////////////////////////////////////////////////////////////////////////////// + WAConnection::WAConnection(IMutex* mutex, WAListener* event_handler, WAGroupListener* group_event_handler) { this->init(event_handler, group_event_handler, mutex); @@ -43,8 +71,6 @@ WAConnection::WAConnection(IMutex* mutex, WAListener* event_handler, WAGroupList WAConnection::~WAConnection() { - delete this->inputKey; - delete this->outputKey; delete this->in; delete this->out; std::map::iterator it; @@ -54,18 +80,15 @@ WAConnection::~WAConnection() void WAConnection::init(WAListener* event_handler, WAGroupListener* group_event_handler, IMutex* mutex) { - this->login = NULL; this->event_handler = event_handler; this->group_event_handler = group_event_handler; - this->inputKey = NULL; - this->outputKey = NULL; this->in = NULL; this->out = NULL; this->msg_id = 0; - this->state = 0; // 0 disconnected 1 connecting 2 connected this->retry = true; + this->supports_receipt_acks = false; this->iqid = 0; this->verbose = true; this->lastTreeRead = 0; @@ -76,27 +99,18 @@ void WAConnection::init(WAListener* event_handler, WAGroupListener* group_event_ void WAConnection::setLogin(WALogin* login) { - this->login = login; - - if (login->expire_date != 0L) { + if (login->expire_date != 0L) this->expire_date = login->expire_date; - } - if (login->account_kind != -1) { + + if (login->account_kind != -1) this->account_kind = login->account_kind; - } - this->jid = this->login->user + "@" + this->login->domain; - this->fromm = this->login->user + "@" + this->login->domain + "/" + this->login->resource; + this->jid = user + "@" + domain; this->in = login->getTreeNodeReader(); this->out = login->getTreeNodeWriter(); } -WALogin* WAConnection::getLogin() -{ - return this->login; -} - void WAConnection::sendMessageWithMedia(FMessage* message) throw (WAException) { _LOGDATA("Send message with media %s %d", message->media_name.c_str(), message->media_size); @@ -177,7 +191,7 @@ void WAConnection::setVerboseId(bool b) void WAConnection::sendAvailableForChat() throw(WAException) { - this->out->write(ProtocolTreeNode("presence") << XATTR("name", this->login->push_name)); + this->out->write(ProtocolTreeNode("presence") << XATTR("name", this->nick)); } bool WAConnection::read() throw(WAException) @@ -213,7 +227,7 @@ bool WAConnection::read() throw(WAException) delete it->second; this->pending_server_requests.erase(id); } - else if (id.compare(0, this->login->user.size(), this->login->user) == 0) { + else if (id.compare(0, this->user.size(), this->user) == 0) { ProtocolTreeNode* accountNode = node->getChild(0); ProtocolTreeNode::require(accountNode, "account"); const string &kind = accountNode->getAttributeValue("kind"); @@ -328,7 +342,7 @@ void WAConnection::sendPing() throw(WAException) void WAConnection::sendPong(const std::string& id) throw(WAException) { this->out->write(ProtocolTreeNode("iq") - << XATTR("type", "result") << XATTR("to", this->login->domain) << XATTR("id", id)); + << XATTR("type", "result") << XATTR("to", this->domain) << XATTR("id", id)); } void WAConnection::sendComposing(const std::string& to) throw(WAException) @@ -400,7 +414,7 @@ void WAConnection::sendClientConfig(const std::string& sound, const std::string& this->pending_server_requests[id] = new IqSendClientConfigHandler(this); this->out->write(ProtocolTreeNode("iq", configNode) - << XATTR("id", id) << XATTR("type", "set") << XATTR("to", this->login->domain)); + << XATTR("id", id) << XATTR("type", "set") << XATTR("to", this->domain)); } void WAConnection::sendClientConfig(const std::string& pushID, bool preview, const std::string& platform, bool defaultSettings, bool groupSettings, const std::vector& groups) throw(WAException) @@ -411,7 +425,7 @@ void WAConnection::sendClientConfig(const std::string& pushID, bool preview, con << XATTR("default", defaultSettings ? "1" : "0") << XATTR("groups", groupSettings ? "1" : "0"); std::string id = makeId("config_"); - this->out->write(ProtocolTreeNode("iq", configNode) << XATTR("id", id) << XATTR("type", "set") << XATTR("to", this->login->domain)); + this->out->write(ProtocolTreeNode("iq", configNode) << XATTR("id", id) << XATTR("type", "set") << XATTR("to", this->domain)); } std::vector* WAConnection::processGroupSettings(const std::vector& groups) @@ -658,7 +672,7 @@ void WAConnection::parseMessageInitialTagAlreadyChecked(ProtocolTreeNode* messag bool WAConnection::supportsReceiptAcks() { - return (this->login != NULL) && (this->login->supports_receipt_acks); + return supports_receipt_acks; } void WAConnection::sendNotificationReceived(const std::string& jid, const std::string& id) throw(WAException) diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h index 0271e8dc66..983cb4e4bc 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h @@ -352,8 +352,7 @@ class WAConnection { }; - private: - WALogin* login; +private: BinTreeNodeReader* in; BinTreeNodeWriter* out; WAListener* event_handler; @@ -363,8 +362,6 @@ class WAConnection { std::map pending_server_requests; IMutex* mutex; - // std:: message_store; - void init(WAListener* event_handler, WAGroupListener* group_event_handler, IMutex* mutex); void sendMessageWithMedia(FMessage* message) throw(WAException); void sendMessageWithBody(FMessage* message) throw(WAException); @@ -381,26 +378,34 @@ class WAConnection { static ProtocolTreeNode getMessageNode(FMessage* message, ProtocolTreeNode* node); std::vector* processGroupSettings(const std::vector& gruops); - public: +public: WAConnection(IMutex* mutex, WAListener* event_handler = NULL, WAGroupListener* group_event_handler = NULL); virtual ~WAConnection(); + + std::string user; + std::string domain; + std::string resource; std::string jid; - std::string fromm; + std::string nick; + int msg_id; - int state; bool retry; + bool supports_receipt_acks; time_t expire_date; int account_kind; time_t lastTreeRead; + static const int DICTIONARY_LEN; static const char* dictionary[]; + + static const int EXTDICTIONARY_LEN; + static const char* extended_dict[]; + static MessageStore* message_store; - KeyStream* inputKey; - KeyStream* outputKey; + KeyStream inputKey, outputKey; static std::string removeResourceFromJid(const std::string& jid); - WALogin* getLogin(); void setLogin(WALogin* login); void setVerboseId(bool b); void sendMessage(FMessage* message) throw(WAException); diff --git a/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp b/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp index 0e0ebc22d7..c833d30ffe 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp @@ -20,25 +20,19 @@ using namespace Utilities; const std::string WALogin::NONCE_KEY = "nonce=\""; -WALogin::WALogin(WAConnection* connection, BinTreeNodeReader *reader, BinTreeNodeWriter *writer, const std::string& domain, const std::string& user, const std::string& resource, const std::string& password, const std::string& push_name) +WALogin::WALogin(WAConnection* connection, BinTreeNodeReader *reader, BinTreeNodeWriter *writer, const std::string& password) { this->connection = connection; + this->password = password; this->inn = reader; this->out = writer; - this->domain = domain; - this->user = user; - this->resource = resource; - this->password = password; - this->push_name = push_name; - this->supports_receipt_acks = false; this->account_kind = -1; this->expire_date = 0L; - this->outputKey = NULL; } std::vector* WALogin::login(const std::vector& authBlob) { - this->out->streamStart(this->domain, this->resource); + this->out->streamStart(connection->domain, connection->resource); _LOGDATA("sent stream start"); @@ -92,7 +86,7 @@ void WALogin::sendAuth(const std::vector& existingChallenge) data = this->getAuthBlob(existingChallenge); this->out->write(ProtocolTreeNode("auth", data) << - XATTR("mechanism", "WAUTH-2") << XATTR("user", this->user), true); + XATTR("mechanism", "WAUTH-2") << XATTR("user", connection->user), true); } std::vector* WALogin::getAuthBlob(const std::vector& nonce) @@ -100,31 +94,25 @@ std::vector* WALogin::getAuthBlob(const std::vectorpassword, nonce, out); - if (this->connection->inputKey != NULL) - delete this->connection->inputKey; - this->connection->inputKey = new KeyStream(out + 40, out + 60); - - if (this->outputKey != NULL) - delete this->outputKey; - this->outputKey = new KeyStream(out, out + 20); + this->connection->inputKey.init(out + 40, out + 60); + this->connection->outputKey.init(out, out + 20); std::vector* list = new std::vector(0); for (int i = 0; i < 4; i++) list->push_back(0); - list->insert(list->end(), this->user.begin(), this->user.end()); + list->insert(list->end(), connection->user.begin(), connection->user.end()); list->insert(list->end(), nonce.begin(), nonce.end()); - this->outputKey->encodeMessage(&((*list)[0]), 0, 4, (int)list->size() - 4); + this->connection->outputKey.encodeMessage(&((*list)[0]), 0, 4, (int)list->size() - 4); return list; } std::vector* WALogin::readFeaturesUntilChallengeOrSuccess() { - ProtocolTreeNode* root; - while ((root = this->inn->nextTree()) != NULL) { + while (ProtocolTreeNode *root = this->inn->nextTree()) { if (ProtocolTreeNode::tagEquals(root, "stream:features")) { - this->supports_receipt_acks = root->getChild("receipt_acks") != NULL; + connection->supports_receipt_acks = root->getChild("receipt_acks") != NULL; delete root; continue; } @@ -166,15 +154,11 @@ void WALogin::parseSuccessNode(ProtocolTreeNode* node) this->account_kind = 0; else this->account_kind = -1; - - if (this->connection->outputKey != NULL) - delete this->connection->outputKey; - this->connection->outputKey = this->outputKey; } std::vector WALogin::readSuccess() { - ProtocolTreeNode* node = this->inn->nextTree(); + ProtocolTreeNode *node = this->inn->nextTree(); if (ProtocolTreeNode::tagEquals(node, "failure")) { delete node; @@ -197,6 +181,8 @@ std::vector WALogin::readSuccess() } else this->account_kind = -1; + this->out->setLoggedIn(); + std::vector data = *node->data; delete node; return data; diff --git a/protocols/WhatsApp/src/WhatsAPI++/WALogin.h b/protocols/WhatsApp/src/WhatsAPI++/WALogin.h index 3e08bdbe8e..ab1e13472b 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WALogin.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WALogin.h @@ -30,9 +30,11 @@ private: void hmacsha1(unsigned char* text, int textLength, unsigned char *out); public: - KeyStream(unsigned char* _key, unsigned char* _keyMac); + KeyStream(); ~KeyStream(); + void init(unsigned char *_key, unsigned char *_keyMac); + static void keyFromPasswordAndNonce(const std::string& pass, const std::vector& nonce, unsigned char *out); void decodeMessage(unsigned char* buffer, int macOffset, int offset, const int length); void encodeMessage(unsigned char* buffer, int macOffset, int offset, const int length); @@ -42,7 +44,6 @@ public: class WALogin { private: static const std::string NONCE_KEY; - KeyStream* outputKey; WAConnection* connection; BinTreeNodeReader* inn; BinTreeNodeWriter* out; @@ -56,16 +57,11 @@ private: std::vector readSuccess(); public: - std::string user; - std::string domain; - std::string password; - std::string resource; - std::string push_name; - bool supports_receipt_acks; time_t expire_date; int account_kind; + std::string password; - WALogin(WAConnection* connection, BinTreeNodeReader *reader, BinTreeNodeWriter *writer, const std::string& domain, const std::string& user, const std::string& resource, const std::string& password, const std::string& push_name); + WALogin(WAConnection* connection, BinTreeNodeReader *reader, BinTreeNodeWriter *writer, const std::string& password); ~WALogin(); std::vector* login(const std::vector& blobLength); diff --git a/protocols/WhatsApp/src/connection.cpp b/protocols/WhatsApp/src/connection.cpp index b970db7d96..ee4609fc75 100644 --- a/protocols/WhatsApp/src/connection.cpp +++ b/protocols/WhatsApp/src/connection.cpp @@ -77,7 +77,6 @@ void WhatsAppProto::stayConnectedLoop(void*) // ----------------------------- Mutex writerMutex; - WALogin* login = NULL; int desiredStatus; bool error = false; @@ -85,10 +84,6 @@ void WhatsAppProto::stayConnectedLoop(void*) while (true) { if (connection != NULL) { - if (connection->getLogin() == NULL && login != NULL) { - delete login; - login = NULL; - } delete connection; connection = NULL; } @@ -123,20 +118,19 @@ void WhatsAppProto::stayConnectedLoop(void*) portNumber = 5222, resource += "-5222"; this->conn = new WASocketConnection("c.whatsapp.net", portNumber); - - connection = new WAConnection(&this->connMutex, this, this); - login = new WALogin(connection, new BinTreeNodeReader(connection, conn, WAConnection::dictionary, WAConnection::DICTIONARY_LEN), - new BinTreeNodeWriter(connection, conn, WAConnection::dictionary, WAConnection::DICTIONARY_LEN, &writerMutex), - "s.whatsapp.net", this->phoneNumber, resource, password, nick); - - std::vector* nextChallenge = login->login(*this->challenge); - delete this->challenge; - this->challenge = nextChallenge; - connection->setLogin(login); + this->connection = new WAConnection(&this->connMutex, this, this); + { + WALogin login(connection, new BinTreeNodeReader(connection, conn), new BinTreeNodeWriter(connection, conn, &writerMutex), password); + + std::vector* nextChallenge = login.login(*this->challenge); + delete this->challenge; + this->challenge = nextChallenge; + connection->setLogin(&login); + } + connection->nick = this->nick; connection->setVerboseId(true); // ? - if (desiredStatus != ID_STATUS_INVISIBLE) { + if (desiredStatus != ID_STATUS_INVISIBLE) connection->sendAvailableForChat(); - } debugLogA("Set status to online"); this->m_iStatus = desiredStatus; -- cgit v1.2.3