diff options
| author | George Hazan <george.hazan@gmail.com> | 2015-01-25 22:07:28 +0000 | 
|---|---|---|
| committer | George Hazan <george.hazan@gmail.com> | 2015-01-25 22:07:28 +0000 | 
| commit | 97ba0b94c5da04f0d03945baa21c338c77c9dc20 (patch) | |
| tree | 55d1b4c131a616b8c660128c70418df95de99b90 /protocols/WhatsApp/src | |
| parent | 4b9da6b7ea643ac4917440880583d507b697cf9a (diff) | |
- correct writing of tokens, especially extended
- further code optimizations
git-svn-id: http://svn.miranda-ng.org/main/trunk@11911 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/WhatsApp/src')
| -rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp | 13 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp | 20 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h | 1 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp | 82 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/WAConnection.h | 23 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp | 35 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/WALogin.h | 10 | ||||
| -rw-r--r-- | protocols/WhatsApp/src/connection.cpp | 9 | 
8 files changed, 90 insertions, 103 deletions
| diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp index 492dde1027..99c186f126 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp @@ -12,6 +12,8 @@  #include "ProtocolTreeNode.h"
  #include "utilities.h"
 +extern const char *dictionary[], *extended_dict[];
 +
  BinTreeNodeReader::BinTreeNodeReader(WAConnection *conn, ISocketConnection *connection) :
  	buf(BUFFER_SIZE)
  {
 @@ -145,15 +147,12 @@ ReadData* BinTreeNodeReader::readString(int token)  	int bSize;
  	ReadData *ret = new ReadData();
 -	if (token > 2 && token <= WAConnection::DICTIONARY_LEN) {
 -		if (token != WAConnection::DICTIONARY_LEN)
 -			ret->data = new std::string(WAConnection::dictionary[token]);
 +	if (token > 2 && token <= 236) {
 +		if (token != 236)
 +			ret->data = new std::string(dictionary[token]);
  		else {
  			token = readInt8(this->in);
 -			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->data = new std::string(extended_dict[token]);
  		}
  		ret->type = STRING;
 diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp index a4f79baf17..227857a522 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.cpp @@ -17,11 +17,6 @@ BinTreeNodeWriter::BinTreeNodeWriter(WAConnection* conn, ISocketConnection* conn  	this->conn = conn;
  	this->out = new ByteArrayOutputStream(2048);
  	this->realOut = connection;
 -	for (int i = 0; i < WAConnection::DICTIONARY_LEN; i++) {
 -		std::string token(WAConnection::dictionary[i]);
 -		if (token.compare("") != 0)
 -			this->tokenMap[token] = i;
 -	}
  	this->dataBegin = 0;
  }
 @@ -135,9 +130,9 @@ void BinTreeNodeWriter::writeAttributes(std::map<string, string>* attributes)  void BinTreeNodeWriter::writeString(const std::string& tag)
  {
 -	std::map<string, int>::iterator it = this->tokenMap.find(tag);
 -	if (it != this->tokenMap.end())
 -		writeToken(it->second);
 +	int token = WAConnection::tokenLookup(tag);
 +	if (token != -1)
 +		writeToken(token);
  	else {
  		size_t atIndex = tag.find('@');
  		if (atIndex == 0 || atIndex == string::npos)
 @@ -164,12 +159,11 @@ void BinTreeNodeWriter::writeJid(std::string* user, const std::string& server)  void BinTreeNodeWriter::writeToken(int intValue)
  {
 -	if (intValue < 245)
 -		this->out->write(intValue);
 -	else if (intValue <= 500) {
 -		this->out->write(254);
 -		this->out->write(intValue - 245);
 +	if (intValue & 0x100) {
 +		this->out->write(236);
 +		this->out->write(intValue & 0xFF);
  	}
 +	else this->out->write(intValue);
  }
  void BinTreeNodeWriter::writeBytes(unsigned char* bytes, int length)
 diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h index e4a771f231..66d9cbb991 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeWriter.h @@ -35,7 +35,6 @@ class WAConnection;  class BinTreeNodeWriter {
  private:
  	WAConnection* conn;
 -	map<string, int> tokenMap;
  	ISocketConnection *realOut;
  	ByteArrayOutputStream *out;
  	IMutex* mutex;
 diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp index 48300ad530..270c329085 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp @@ -10,7 +10,7 @@  #include "ProtocolTreeNode.h"
  #include "utilities.h"
 -const char* WAConnection::dictionary[] = {
 +const char* dictionary[] = {
  	"", "", "", "account", "ack", "action", "active", "add", "after", "all", "allow", "apple", "auth", "author", "available",  	"bad-protocol", "bad-request", "before", "body", "broadcast", "cancel", "category", "challenge", "chat", "clean", "code",  	"composing", "config", "contacts", "count", "create", "creation", "debug", "default", "delete", "delivery", "delta", "deny", @@ -34,9 +34,7 @@ const char* WAConnection::dictionary[] = {  	"adpcm", "amrnb", "amrwb", "mp3", "pcm", "qcelp", "wma", "h263", "h264", "jpeg"  };
 -const int WAConnection::DICTIONARY_LEN = _countof(WAConnection::dictionary);
 -
 -const char* WAConnection::extended_dict[] = { +const char* 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", @@ -60,41 +58,71 @@ const char* WAConnection::extended_dict[] = {  	"archive", "adm", "plaintext_size", "compressed_size", "delivered", "msg", "pkmsg", "everyone", "v", "transport", "call-id"  }; -const int WAConnection::EXTDICTIONARY_LEN = _countof(WAConnection::extended_dict);
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 +static map<string, int> tokenMap1, tokenMap2;
 -WAConnection::WAConnection(IMutex* mutex, WAListener* event_handler, WAGroupListener* group_event_handler)
 +void WAConnection::globalInit()
  {
 -	this->init(event_handler, group_event_handler, mutex);
 +	for (int i = 0; i < _countof(dictionary); i++)
 +		if (*dictionary[i] != 0)
 +			tokenMap1[dictionary[i]] = i;			
 +
 +	for (int i = 0; i < _countof(extended_dict); i++)
 +		tokenMap2[extended_dict[i]] = i;
  }
 -WAConnection::~WAConnection()
 +int WAConnection::tokenLookup(const std::string &str)
  {
 -	delete this->in;
 -	delete this->out;
 -	std::map<string, IqResultHandler*>::iterator it;
 -	for (it = this->pending_server_requests.begin(); it != this->pending_server_requests.end(); it++)
 -		delete it->second;
 +	std::map<string, int>::iterator it = tokenMap1.find(str);
 +	if (it != tokenMap1.end())
 +		return it->second;
 +
 +	it = tokenMap2.find(str);
 +	if (it != tokenMap2.end())
 +		return it->second + 0x100;
 +
 +	return -1;
  }
 -void WAConnection::init(WAListener* event_handler, WAGroupListener* group_event_handler, IMutex* mutex)
 +/////////////////////////////////////////////////////////////////////////////////////////
 +
 +WAConnection::WAConnection(const std::string &user, const std::string &resource, IMutex *mutex, WAListener *event_handler, WAGroupListener *group_event_handler)
  {
 +	this->mutex = mutex;
  	this->event_handler = event_handler;
  	this->group_event_handler = group_event_handler;
 +
  	this->in = NULL;
  	this->out = NULL;
  	this->msg_id = 0;
  	this->retry = true;
 +	this->user = user;
 +	this->resource = resource;
 +	this->domain = "s.whatsapp.net";
 +	this->jid = user + "@" + domain;
 +
  	this->supports_receipt_acks = false;
  	this->iqid = 0;
  	this->verbose = true;
  	this->lastTreeRead = 0;
  	this->expire_date = 0L;
  	this->account_kind = -1;
 -	this->mutex = mutex;
 +}
 +
 +WAConnection::~WAConnection()
 +{
 +	delete this->in;
 +	delete this->out;
 +	std::map<string, IqResultHandler*>::iterator it;
 +	for (it = this->pending_server_requests.begin(); it != this->pending_server_requests.end(); it++)
 +		delete it->second;
 +}
 +
 +void WAConnection::init(IMutex *mutex, WASocketConnection *conn)
 +{
 +	in = new BinTreeNodeReader(this, conn);
 +	out = new BinTreeNodeWriter(this, conn, mutex);
  }
  void WAConnection::setLogin(WALogin* login)
 @@ -104,11 +132,6 @@ void WAConnection::setLogin(WALogin* login)  	if (login->account_kind != -1)
  		this->account_kind = login->account_kind;
 -
 -	this->jid = user + "@" + domain;
 -
 -	this->in = login->getTreeNodeReader();
 -	this->out = login->getTreeNodeWriter();
  }
  void WAConnection::sendMessageWithMedia(FMessage* message)  throw (WAException)
 @@ -118,7 +141,7 @@ void WAConnection::sendMessageWithMedia(FMessage* message)  throw (WAException)  	if (message->media_wa_type == FMessage::WA_TYPE_SYSTEM)
  		throw new WAException("Cannot send system message over the network");
 -	ProtocolTreeNode* mediaNode;
 +	ProtocolTreeNode *mediaNode;
  	if (message->media_wa_type == FMessage::WA_TYPE_CONTACT && !message->media_name.empty()) {
  		ProtocolTreeNode* vcardNode = new ProtocolTreeNode("vcard", new std::vector<unsigned char>(message->data.begin(), message->data.end()))
  			<< XATTR("name", message->media_name);
 @@ -131,17 +154,12 @@ void WAConnection::sendMessageWithMedia(FMessage* message)  throw (WAException)  	mediaNode << XATTR("xmlns", "urn:xmpp:whatsapp:mms") << XATTR("type", FMessage::getMessage_WA_Type_StrValue(message->media_wa_type));
 -	if (message->media_wa_type == FMessage::WA_TYPE_LOCATION) {
 +	if (message->media_wa_type == FMessage::WA_TYPE_LOCATION)
  		mediaNode << XATTR("latitude", Utilities::doubleToStr(message->latitude)) << XATTR("longitude", Utilities::doubleToStr(message->longitude));
 -	}
  	else {
 -		if (message->media_wa_type != FMessage::WA_TYPE_CONTACT && !message->media_name.empty() && !message->media_url.empty() && message->media_size > 0L) {
 -			mediaNode << XATTR("file", message->media_name) << XATTRI("size", message->media_size) << XATTR("url", message->media_url);
 -		}
 -		else {
 -			mediaNode << XATTR("file", message->media_name) << XATTRI("size", message->media_size)
 -				<< XATTR("url", message->media_url) << XATTRI("seconds", message->media_duration_seconds);
 -		}
 +		mediaNode << XATTR("file", message->media_name) << XATTRI("size", message->media_size) << XATTR("url", message->media_url);
 +		if (message->media_wa_type == FMessage::WA_TYPE_CONTACT || message->media_name.empty() || message->media_url.empty() || message->media_size <= 0)
 +			mediaNode << XATTRI("seconds", message->media_duration_seconds);
  	}
  	this->out->write(WAConnection::getMessageNode(message, mediaNode));
 diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h index 983cb4e4bc..697542e32c 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h @@ -24,6 +24,7 @@  #pragma warning(disable : 4290)
  class WALogin;
 +class WASocketConnection;
  class KeyStream;
  class BinTreeNodeReader;
 @@ -351,18 +352,18 @@ class WAConnection {  		}
  	};
 +	friend class WALogin;
  private:
 -	BinTreeNodeReader* in;
 -	BinTreeNodeWriter* out;
 -	WAListener* event_handler;
 -	WAGroupListener* group_event_handler;
 +	BinTreeNodeReader *in;
 +	BinTreeNodeWriter *out;
 +	WAListener *event_handler;
 +	WAGroupListener *group_event_handler;
  	bool verbose;
  	int iqid;
  	std::map<string, IqResultHandler*> pending_server_requests;
 -	IMutex* mutex;
 +	IMutex *mutex;
 -	void init(WAListener* event_handler, WAGroupListener* group_event_handler, IMutex* mutex);
  	void sendMessageWithMedia(FMessage* message) throw(WAException);
  	void sendMessageWithBody(FMessage* message) throw(WAException);
  	std::map<string, string>* parseCategories(ProtocolTreeNode* node) throw(WAException);
 @@ -379,8 +380,9 @@ private:  	std::vector<ProtocolTreeNode*>* processGroupSettings(const std::vector<GroupSetting>& gruops);
  public:
 -	WAConnection(IMutex* mutex, WAListener* event_handler = NULL, WAGroupListener* group_event_handler = NULL);
 +	WAConnection(const std::string& user, const std::string& resource, IMutex* mutex, WAListener* event_handler, WAGroupListener* group_event_handler);
  	virtual ~WAConnection();
 +	void init(IMutex* mutex, WASocketConnection*);
  	std::string user;
  	std::string domain;
 @@ -395,11 +397,8 @@ public:  	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 void globalInit(void);
 +	static int  tokenLookup(const std::string&);
  	static MessageStore* message_store;
  	KeyStream inputKey, outputKey;
 diff --git a/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp b/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp index c833d30ffe..e009968b59 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp @@ -20,19 +20,17 @@ using namespace Utilities;  const std::string WALogin::NONCE_KEY = "nonce=\"";
 -WALogin::WALogin(WAConnection* connection, BinTreeNodeReader *reader, BinTreeNodeWriter *writer, const std::string& password)
 +WALogin::WALogin(WAConnection* connection, const std::string& password)
  {
  	this->connection = connection;
  	this->password = password;
 -	this->inn = reader;
 -	this->out = writer;
  	this->account_kind = -1;
  	this->expire_date = 0L;
  }
  std::vector<unsigned char>* WALogin::login(const std::vector<unsigned char>& authBlob)
  {
 -	this->out->streamStart(connection->domain, connection->resource);
 +	connection->out->streamStart(connection->domain, connection->resource);
  	_LOGDATA("sent stream start");
 @@ -44,27 +42,17 @@ std::vector<unsigned char>* WALogin::login(const std::vector<unsigned char>& aut  	_LOGDATA("send auth, auth blob size %d", authBlob.size());
 -	this->inn->streamStart();
 +	connection->in->streamStart();
  	_LOGDATA("read stream start");
  	return this->readFeaturesUntilChallengeOrSuccess();
  }
 -BinTreeNodeReader* WALogin::getTreeNodeReader()
 -{
 -	return this->inn;
 -}
 -
 -BinTreeNodeWriter* WALogin::getTreeNodeWriter()
 -{
 -	return this->out;
 -}
 -
  void WALogin::sendResponse(const std::vector<unsigned char>& challengeData)
  {
  	std::vector<unsigned char>* authBlob = this->getAuthBlob(challengeData);
 -	this->out->write(ProtocolTreeNode("response", authBlob));
 +	connection->out->write(ProtocolTreeNode("response", authBlob));
  }
  void WALogin::sendFeatures()
 @@ -76,7 +64,7 @@ void WALogin::sendFeatures()  	ProtocolTreeNode* pictureChild = new ProtocolTreeNode("w:profile:picture") << XATTR("type", "all");
  	children->push_back(pictureChild);
 -	this->out->write(ProtocolTreeNode("stream:features", NULL, children), true);
 +	connection->out->write(ProtocolTreeNode("stream:features", NULL, children), true);
  }
  void WALogin::sendAuth(const std::vector<unsigned char>& existingChallenge)
 @@ -85,7 +73,7 @@ void WALogin::sendAuth(const std::vector<unsigned char>& existingChallenge)  	if (!existingChallenge.empty())
  		data = this->getAuthBlob(existingChallenge);
 -	this->out->write(ProtocolTreeNode("auth", data) << 
 +	connection->out->write(ProtocolTreeNode("auth", data) << 
  		XATTR("mechanism", "WAUTH-2") << XATTR("user", connection->user), true);
  }
 @@ -110,15 +98,13 @@ std::vector<unsigned char>* WALogin::getAuthBlob(const std::vector<unsigned char  std::vector<unsigned char>* WALogin::readFeaturesUntilChallengeOrSuccess()
  {
 -	while (ProtocolTreeNode *root = this->inn->nextTree()) {
 +	while (ProtocolTreeNode *root = connection->in->nextTree()) {
  		if (ProtocolTreeNode::tagEquals(root, "stream:features")) {
  			connection->supports_receipt_acks = root->getChild("receipt_acks") != NULL;
  			delete root;
  			continue;
  		}
  		if (ProtocolTreeNode::tagEquals(root, "challenge")) {
 -			// base64_decode(*root->data);
 -			// _LOGDATA("Challenge data %s (%d)", root->data->c_str(), root->data->length());
  			std::vector<unsigned char> challengedata(root->data->begin(), root->data->end());
  			delete root;
  			this->sendResponse(challengedata);
 @@ -128,7 +114,6 @@ std::vector<unsigned char>* WALogin::readFeaturesUntilChallengeOrSuccess()  			return new std::vector<unsigned char>(data.begin(), data.end());
  		}
  		if (ProtocolTreeNode::tagEquals(root, "success")) {
 -			// base64_decode(*root->data);
  			std::vector<unsigned char>* ret = new std::vector<unsigned char>(root->data->begin(), root->data->end());
  			this->parseSuccessNode(root);
  			delete root;
 @@ -140,6 +125,8 @@ std::vector<unsigned char>* WALogin::readFeaturesUntilChallengeOrSuccess()  void WALogin::parseSuccessNode(ProtocolTreeNode* node)
  {
 +	connection->out->setLoggedIn();
 +
  	const string &expiration = node->getAttributeValue("expiration");
  	if (!expiration.empty()) {
  		this->expire_date = atol(expiration.c_str());
 @@ -158,7 +145,7 @@ void WALogin::parseSuccessNode(ProtocolTreeNode* node)  std::vector<unsigned char> WALogin::readSuccess()
  {
 -	ProtocolTreeNode *node = this->inn->nextTree();
 +	ProtocolTreeNode *node = connection->in->nextTree();
  	if (ProtocolTreeNode::tagEquals(node, "failure")) {
  		delete node;
 @@ -181,8 +168,6 @@ std::vector<unsigned char> WALogin::readSuccess()  	}
  	else this->account_kind = -1;
 -	this->out->setLoggedIn();
 -
  	std::vector<unsigned char> data = *node->data;
  	delete node;
  	return data;
 diff --git a/protocols/WhatsApp/src/WhatsAPI++/WALogin.h b/protocols/WhatsApp/src/WhatsAPI++/WALogin.h index ab1e13472b..440f34f71b 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WALogin.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WALogin.h @@ -44,16 +44,14 @@ public:  class WALogin {
  private:
  	static const std::string NONCE_KEY;
 -	WAConnection* connection;
 -	BinTreeNodeReader* inn;
 -	BinTreeNodeWriter* out;
 +	WAConnection *connection;
  	std::vector<unsigned char>* getAuthBlob(const std::vector<unsigned char>& nonce);
  	void sendResponse(const std::vector<unsigned char>& challengeData);
  	void sendFeatures();
  	void sendAuth(const std::vector<unsigned char>& nonce);
  	std::vector<unsigned char>* readFeaturesUntilChallengeOrSuccess();
 -	void parseSuccessNode(ProtocolTreeNode* node);
 +	void parseSuccessNode(ProtocolTreeNode *node);
  	std::vector<unsigned char> readSuccess();
  public:
 @@ -61,12 +59,10 @@ public:  	int account_kind;
  	std::string password;
 -	WALogin(WAConnection* connection, BinTreeNodeReader *reader, BinTreeNodeWriter *writer, const std::string& password);
 +	WALogin(WAConnection* connection, const std::string& password);
  	~WALogin();
  	std::vector<unsigned char>* login(const std::vector<unsigned char>& blobLength);
 -	BinTreeNodeReader *getTreeNodeReader();
 -	BinTreeNodeWriter *getTreeNodeWriter();
  };
  #endif /* WALOGIN_H_ */
 diff --git a/protocols/WhatsApp/src/connection.cpp b/protocols/WhatsApp/src/connection.cpp index 2acc8a89fa..8c1f16c456 100644 --- a/protocols/WhatsApp/src/connection.cpp +++ b/protocols/WhatsApp/src/connection.cpp @@ -118,13 +118,10 @@ void WhatsAppProto::stayConnectedLoop(void*)  				portNumber = 5222, resource += "-5222";
  			this->conn = new WASocketConnection("c.whatsapp.net", portNumber);
 -			this->connection = new WAConnection(&this->connMutex, this, this);
 -			
 -			this->connection->domain = "s.whatsapp.net";
 -			this->connection->user = this->phoneNumber;
 -			this->connection->resource = resource;
 +			this->connection = new WAConnection(this->phoneNumber, resource, &this->connMutex, this, this);
 +			this->connection->init(&writerMutex, this->conn);
  			{
 -				WALogin login(connection, new BinTreeNodeReader(connection, conn), new BinTreeNodeWriter(connection, conn, &writerMutex), password);
 +				WALogin login(connection, password);
  				std::vector<unsigned char>* nextChallenge = login.login(*this->challenge);
  				delete this->challenge;
 | 
