示例#1
0
// разбивает сообщение szMsg на части длиной iLen, возвращает строку вида PARTzPARTzz
LPSTR splitMsg(LPSTR szMsg, int iLen)
{
	Sent_NetLog("split: msg: -----\n%s\n-----\n", szMsg);

	size_t len = strlen(szMsg);
	LPSTR out = (LPSTR)mir_alloc(len * 2);
	LPSTR buf = out;

	WORD msg_id = db_get_w(0, MODULENAME, "msgid", 0) + 1;
	db_set_w(0, MODULENAME, "msgid", msg_id);

	size_t part_all = (len + iLen - 1) / iLen;
	for (size_t part_num = 0; part_num<part_all; part_num++) {
		size_t sz = (len>iLen) ? iLen : len;
		mir_snprintf(buf, 32, "%s%04X%02X%02X", SIG_SECP, msg_id, part_num, part_all);
		memcpy(buf + LEN_SECP + 8, szMsg, sz);
		*(buf + LEN_SECP + 8 + sz) = '\0';

		Sent_NetLog("split: part: %s", buf);

		buf += LEN_SECP + 8 + sz + 1;
		szMsg += sz;
		len -= sz;
	}
	*buf = '\0';
	return out;
}
示例#2
0
int __cdecl rsa_check_pub(HANDLE context, PBYTE pub, int pubLen, PBYTE sig, int sigLen) {
    int v=0, k=0;
    pUinKey ptr = getUinCtx(context);
    if(!ptr) return 0;
    LPSTR cnm = (LPSTR) mir_alloc(NAMSIZE);
    getContactNameA(ptr->hContact,cnm);
    LPSTR uin = (LPSTR) mir_alloc(KEYSIZE);
    getContactUinA(ptr->hContact,uin);
    LPSTR msg = (LPSTR) mir_alloc(MSGSIZE);
    LPSTR sha = mir_strdup(to_hex(sig,sigLen));
    LPSTR sha_old = NULL;
#if defined(_DEBUG) || defined(NETLIB_LOG)
    Sent_NetLog("rsa_check_pub: %s %s %s", cnm, uin, sha);
#endif
    DBVARIANT dbv;
    dbv.type = DBVT_BLOB;
    if( DBGetContactSetting(ptr->hContact,szModuleName,"rsa_pub",&dbv) == 0 ) {
        k = 1;
        PBYTE buf = (PBYTE) alloca(sigLen);
        int len;
        exp->rsa_get_hash((PBYTE)dbv.pbVal,dbv.cpbVal,(PBYTE)buf,&len);
        sha_old = mir_strdup(to_hex(buf,len));
        DBFreeVariant(&dbv);
    }
    if( bAAK ) {
        if( k )	mir_snprintf(msg,MSGSIZE,Translate(sim523),cnm,uin,sha,sha_old);
        else	mir_snprintf(msg,MSGSIZE,Translate(sim521),cnm,uin,sha);
        showPopUpKRmsg(ptr->hContact,msg);
        HistoryLog(ptr->hContact,msg);
        v = 1;
#if defined(_DEBUG) || defined(NETLIB_LOG)
        Sent_NetLog("rsa_check_pub: auto accepted");
#endif
    }
    else {
        if( k ) mir_snprintf(msg,MSGSIZE,Translate(sim522),cnm,sha,sha_old);
        else	mir_snprintf(msg,MSGSIZE,Translate(sim520),cnm,sha);
        v = (msgbox(0,msg,szModuleName,MB_YESNO|MB_ICONQUESTION)==IDYES);
#if defined(_DEBUG) || defined(NETLIB_LOG)
        Sent_NetLog("rsa_check_pub: manual accepted %d",v);
#endif
    }
    if(v) {
        DBCONTACTWRITESETTING cws;
        cws.szModule = szModuleName;
        cws.szSetting = "rsa_pub";
        cws.value.type = DBVT_BLOB;
        cws.value.pbVal = pub;
        cws.value.cpbVal = pubLen;
        CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)ptr->hContact, (LPARAM)&cws);
        ptr->keyLoaded = true;
    }
    mir_free(cnm);
    mir_free(uin);
    mir_free(msg);
    mir_free(sha);
    SAFE_FREE(sha_old);
    return v;
}
示例#3
0
// собираем сообщение из частей, части храним в структуре у контакта
LPSTR combineMessage(pUinKey ptr, LPSTR szMsg)
{
	Sent_NetLog("combine: part: %s", szMsg);

	int msg_id, part_num, part_all;
	sscanf(szMsg, "%4X%2X%2X", &msg_id, &part_num, &part_all);
	//
	pPM ppm = NULL, pm = ptr->msgPart;
	if (!ptr->msgPart) {
		pm = ptr->msgPart = new partitionMessage;
		memset(pm, 0, sizeof(partitionMessage));
		pm->id = msg_id;
		pm->message = new LPSTR[part_all];
		memset(pm->message, 0, sizeof(LPSTR)*part_all);
	}
	else
		while (pm) {
		if (pm->id == msg_id) break;
		ppm = pm; pm = pm->nextMessage;
		}
	if (!pm) { // nothing to found
		pm = ppm->nextMessage = new partitionMessage;
		memset(pm, 0, sizeof(partitionMessage));
		pm->id = msg_id;
		pm->message = new LPSTR[part_all];
		memset(pm->message, 0, sizeof(LPSTR)*part_all);
	}
	pm->message[part_num] = new char[strlen(szMsg)];
	strcpy(pm->message[part_num], szMsg + 8);

	Sent_NetLog("combine: save part: %s", pm->message[part_num]);

	int len = 0, i;
	for (i = 0; i < part_all; i++) {
		if (pm->message[i] == NULL) break;
		len += (int)strlen(pm->message[i]);
	}
	if (i == part_all) { // combine message
		SAFE_FREE(ptr->tmp);
		ptr->tmp = (LPSTR)mir_alloc(len + 1); *(ptr->tmp) = '\0';
		for (i = 0; i < part_all; i++) {
			strcat(ptr->tmp, pm->message[i]);
			delete pm->message[i];
		}
		delete pm->message;
		if (ppm) ppm->nextMessage = pm->nextMessage;
		else 	ptr->msgPart = pm->nextMessage;
		delete pm;

		Sent_NetLog("combine: all parts: -----\n%s\n-----\n", ptr->tmp);
		// combined one message
		return ptr->tmp;
	}

	Sent_NetLog("combine: not all parts");
	// not combined yet
	return NULL;
}
示例#4
0
int __cdecl rsa_check_pub(HANDLE context, PBYTE pub, int pubLen, PBYTE sig, int sigLen)
{
	int v = 0, k = 0;
	pUinKey ptr = getUinCtx(context); if (!ptr) return 0;
	LPSTR cnm = (LPSTR)mir_alloc(NAMSIZE); getContactNameA(ptr->hContact, cnm);
	LPSTR uin = (LPSTR)mir_alloc(KEYSIZE); getContactUinA(ptr->hContact, uin);
	LPSTR msg = (LPSTR)mir_alloc(MSGSIZE);
	LPSTR sha = mir_strdup(to_hex(sig, sigLen));
	LPSTR sha_old = NULL;

	Sent_NetLog("rsa_check_pub: %s %s %s", cnm, uin, sha);

	DBVARIANT dbv;
	dbv.type = DBVT_BLOB;
	if (db_get(ptr->hContact, MODULENAME, "rsa_pub", &dbv) == 0) {
		k = 1;
		PBYTE buf = (PBYTE)alloca(sigLen); int len;
		mir_exp->rsa_get_hash((PBYTE)dbv.pbVal, dbv.cpbVal, (PBYTE)buf, &len);
		sha_old = mir_strdup(to_hex(buf, len));
		db_free(&dbv);
	}
	if (bAAK) {
		if (k)	mir_snprintf(msg, MSGSIZE, Translate(sim523), cnm, uin, sha, sha_old);
		else	mir_snprintf(msg, MSGSIZE, Translate(sim521), cnm, uin, sha);
		showPopupKRmsg(ptr->hContact, msg);
		HistoryLog(ptr->hContact, msg);
		v = 1;
#if defined(_DEBUG) || defined(NETLIB_LOG)
		Sent_NetLog("rsa_check_pub: auto accepted");
#endif
	}
	else {
		if (k) mir_snprintf(msg, MSGSIZE, Translate(sim522), cnm, sha, sha_old);
		else	mir_snprintf(msg, MSGSIZE, Translate(sim520), cnm, sha);
		v = (msgbox(0, msg, MODULENAME, MB_YESNO | MB_ICONQUESTION) == IDYES);
#if defined(_DEBUG) || defined(NETLIB_LOG)
		Sent_NetLog("rsa_check_pub: manual accepted %d", v);
#endif
	}
	if (v) {
		db_set_blob(ptr->hContact, MODULENAME, "rsa_pub", pub, pubLen);
		ptr->keyLoaded = true;
	}
	mir_free(cnm);
	mir_free(uin);
	mir_free(msg);
	mir_free(sha);
	SAFE_FREE(sha_old);
	return v;
}
示例#5
0
// загружает паблик-ключ в RSA контекст
BYTE loadRSAkey(pUinKey ptr)
{
	if (!ptr->keyLoaded) {
		DBVARIANT dbv;
		dbv.type = DBVT_BLOB;
		if (db_get(ptr->hContact, MODULENAME, "rsa_pub", &dbv) == 0) {
			ptr->keyLoaded = mir_exp->rsa_set_pubkey(ptr->cntx, dbv.pbVal, dbv.cpbVal);
			Sent_NetLog("loadRSAkey %d", ptr->keyLoaded);
			db_free(&dbv);
		}
	}
	return ptr->keyLoaded;
}
示例#6
0
// загружает паблик-ключ в RSA контекст
BYTE loadRSAkey(pUinKey ptr) {
    if( !ptr->keyLoaded ) {
        DBVARIANT dbv;
        dbv.type = DBVT_BLOB;
        if(	DBGetContactSetting(ptr->hContact,szModuleName,"rsa_pub",&dbv) == 0 ) {
            ptr->keyLoaded = exp->rsa_set_pubkey(ptr->cntx,dbv.pbVal,dbv.cpbVal);
#if defined(_DEBUG) || defined(NETLIB_LOG)
            Sent_NetLog("loadRSAkey %d", ptr->keyLoaded);
#endif
            DBFreeVariant(&dbv);
        }
    }
    return ptr->keyLoaded;
}
示例#7
0
int __cdecl rsa_inject(HANDLE context, LPCSTR msg) {
	pUinKey ptr = getUinCtx(context); if(!ptr) return 0;
#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("rsa_inject: '%s'", msg);
#endif
	int len = strlen(msg)+1;
	LPSTR buf = (LPSTR) mir_alloc(LEN_SECU+len);
	memcpy(buf,SIG_SECU,LEN_SECU);
	memcpy(buf+LEN_SECU,msg,len);
	// отправляем сообщение
	splitMessageSend(ptr,buf);
	mir_free(buf);
	return 1;
}
示例#8
0
// store KeyB into context
int InitKeyB(pUinKey ptr,LPCSTR key) {
#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("InitKeyB: %s", key);
#endif
	if(!ptr->cntx)
		ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0);

	if(!cpp_keyp(ptr->cntx)) {
		char *tmp = myDBGetString(ptr->hContact,szModuleName,"PSK");
		if(tmp) {
		    cpp_init_keyp(ptr->cntx,tmp);	// make pre-shared key from password
		    mir_free(tmp);
		}
	}

	cpp_init_keyb(ptr->cntx,key);
	ptr->features = cpp_get_features(ptr->cntx);

	return cpp_get_error(ptr->cntx);
}
示例#9
0
// store KeyB into context
int InitKeyB(pUinKey ptr,LPCSTR key)
{
	Sent_NetLog("InitKeyB: %s", key);

	if (!ptr->cntx)
		ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0);

	if (!cpp_keyp(ptr->cntx)) {
		char *tmp = db_get_sa(ptr->hContact,MODULENAME,"PSK");
		if (tmp) {
		    cpp_init_keyp(ptr->cntx,tmp);	// make pre-shared key from password
		    mir_free(tmp);
		}
	}

	cpp_init_keyb(ptr->cntx,key);
	ptr->features = cpp_get_features(ptr->cntx);

	return cpp_get_error(ptr->cntx);
}
示例#10
0
// generate KeyA pair and return public key
LPSTR InitKeyA(pUinKey ptr,int features) {
#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("InitKeyA: %04x", features);
#endif
	if( !ptr->cntx )
		ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0);

	char *tmp = myDBGetString(ptr->hContact,szModuleName,"PSK");
	if(tmp) {
	    cpp_init_keyp(ptr->cntx,tmp);	// make pre-shared key from password
	    mir_free(tmp);
	}

	LPSTR pub_text = cpp_init_keya(ptr->cntx,features);	// calculate public and private key & fill KeyA

	LPSTR keysig;
	if(features&CPP_FEATURES_NEWPG) {
		if(features&KEY_B_SIG)
			keysig = (LPSTR)SIG_KEYB;
		else
			keysig = (LPSTR)SIG_KEYA;
	}
	else
	if(isProtoSmallPackets(ptr->hContact))
		keysig = (LPSTR)SIG_KEY4;
	else
		keysig = (LPSTR)SIG_KEY3;

	int slen = strlen(keysig);
	int tlen = strlen(pub_text);

	LPSTR keyToSend = (LPSTR) mir_alloc(slen+tlen+1);

	memcpy(keyToSend,keysig,slen);
	memcpy(keyToSend+slen,pub_text,tlen+1);

	return keyToSend;
}
示例#11
0
// add message to user queue for send later
void addMsg2Queue(pUinKey ptr,WPARAM wParam,LPSTR szMsg)
{
	Sent_NetLog("addMsg2Queue: msg: -----\n%s\n-----\n",szMsg);

	pWM ptrMessage;

	EnterCriticalSection(&localQueueMutex);

	if (ptr->msgQueue == NULL){
		// create new
		ptr->msgQueue = (pWM) mir_alloc(sizeof(struct waitingMessage));
		ptrMessage = ptr->msgQueue;
	}
	else {
		// add to list
		ptrMessage = ptr->msgQueue;
		while (ptrMessage->nextMessage) {
			ptrMessage = ptrMessage->nextMessage;
		}
		ptrMessage->nextMessage = (pWM) mir_alloc(sizeof(struct waitingMessage));
		ptrMessage = ptrMessage->nextMessage;
	}

	ptrMessage->wParam = wParam;
	ptrMessage->nextMessage = NULL;

	if (wParam & PREF_UNICODE) {
		int slen = (int)strlen(szMsg)+1;
		int wlen = (int)wcslen((wchar_t *)(szMsg+slen))+1;
		ptrMessage->Message = (LPSTR) mir_alloc(slen+wlen*sizeof(WCHAR));
		memcpy(ptrMessage->Message,szMsg,slen+wlen*sizeof(WCHAR));
	}
	else{
		ptrMessage->Message = mir_strdup(szMsg);
	}

	LeaveCriticalSection(&localQueueMutex);
}
示例#12
0
// generate KeyA pair, return public key as ASCII
LPSTR __cdecl cpp_init_keya(HANDLE context, int features) {

	pCNTX ptr = get_context_on_id(context); if(!ptr) return NULL;
	pSIMDATA p = (pSIMDATA) cpp_alloc_pdata(ptr);

	int send_features = FEATURES;
	if(p->KeyP) send_features |= FEATURES_PSK;

	SAFE_DELETE(p->dh);
	if(features & FEATURES_NEWPG) {
		Integer p0("0x865734026113B4DF0082CED84C197718516088FBDA406CFDFD7F033694E11E46F01C8F01E0E5AE6B09F6284691C7DD30A5BA8A74BA4B780198624B84BC8DAF6E0DFF874C0440ABB5C043C82E9E9C9E6F1A470B6A2A6BCEAC9460C43B1BB1331DF0FFD898DB74D22E8A71DB2659F1B0F52F337718D233DED611DA25AEAA90F3BE0C42FA9E541D0487DF58A77E2F44D295AD0C54C369CE260C969CA12F690EAAFAEEF8676C631AF29A3DE3389D3000B94EFA775E31FCA879AEB00A4D05EEF50D4C084A049EB12EF4CDFBD48E36B29CEAF8978D535D6C70BB274D1FEA02ABD521D2EF482A76326C17AF597FCB9B8BF37D9110E22AB0746D6A9779DF5133822E3F15");
		Integer q0("0xF1515160E1BFC7636338C13AD5BA775318E287147A1F96B73CF0FB4D97EFFB9D1FCDCF31AB9D92C4F49C9F8D50F06E697D2313E2EBAC7781312A51F458D66FFC687960CAA86BDF150A36ED53D79FBDB4F501FD25E37C181B45F9555D7F1C6124CAB29A822AD1E7BF5DA93C2FDB12A61919B5E5359793CBB16E71516919040A7F");
		Integer g0("0x434158F2FF2CF667E3CC1A707770DDE7B56048F6C5005473C6DC4A5E3FC490667F2908C44F9ADC2071EB8A8A1EC6AD6901CDAAAFE806626E3F4C5E69D4FCBF9DF1B67D574DC61C687C4BEF3ACF77A7256752F4D3A7EAEEE5874ED4912AB10C5B122A24E698B14CAC3E0FD006E0DB02714E028AECCA25BAB9DDCA2CF6405E862B403C61BC381D64B46BD96D3FEFBE22B7497FCBDA2B49C840C1B2853502A5216B036F83D2EAD8F835B603FC5BA1EFB816C7634915B1D43963FDD1B1ED626F48CCF8F152392E4693D38C566016708FA9E9598AECF95A8B067212669247552418E538A706564F855D3D5D50717D356259A20D8FD0C6B2A9FCC045D3F7AED1E857C5");
		p->dh = new DH(p0,q0,g0);
	}
	else {
		Integer p0("0xD494AAFBCD2EAC6A36DB8E7DD4A2A64512A5BBB15B9BFB581C7C1CAFB647D4612973C3770C2166D75EEA695F67EA8261557591DB78BCF5A886AA5294F3AEE4D25B57C8EE8C7FE8DBF70C132CD7FFCB6F89426F807F552C5DAE2FB1F329E340094E4B30D8EF6265AB4D350E9837B151C86AC524DE4E1FC04746C668BE318275E420D51AEDDFBDF887D435CDEEF6AC81293DB45287132F8236A43AD8F4D6642D7CA6732DA06A1DE008259008C9D74403B68ADAC788CF8AB5BEFFC310DCCCD32901D1F290E5B7A993D2CF6A652AF81B6DA0FD2E70678D1AE086150E41444522F20621195AD2A1F0975652B4AF7DE5261A9FD46B9EA8B443641F3BBA695B9B020103");
		Integer g0("0x12A567BC9ABCDEF1234567823BCDEF1E");
		p->dh = new DH(p0,g0);
	}

	BYTE priv1[KEYSIZE];	// private key of 2048 bit
	BYTE publ1[KEYSIZE+2];	// public key of 2048 bit + faetures field

	memset(priv1,0,sizeof(priv1));
	memset(publ1,0,sizeof(publ1));

	AutoSeededRandomPool autorng;
	p->dh->GenerateKeyPair(autorng, priv1, publ1);

	SAFE_FREE(p->PubA);
	p->PubA = (PBYTE) malloc(KEYSIZE);
	memcpy(p->PubA,publ1,KEYSIZE);

	SAFE_FREE(p->KeyA);
	p->KeyA = (PBYTE) malloc(KEYSIZE);
	memcpy(p->KeyA,priv1,KEYSIZE);

	if(p->KeyP) {
		// encrypt PUBLIC use PSK
		string ciphered;
		CFB_Mode<AES>::Encryption enc(p->KeyP,Tiger::DIGESTSIZE,IV);
		StreamTransformationFilter cbcEncryptor(enc,new StringSink(ciphered));

		cbcEncryptor.Put(publ1,KEYSIZE);
		cbcEncryptor.MessageEnd();
		memcpy(publ1,ciphered.data(),ciphered.length());
#if defined(_DEBUG) || defined(NETLIB_LOG)
		Sent_NetLog("cpp_init_keya: %d %d",KEYSIZE,ciphered.length());
#endif
	}
	memcpy((PVOID)&publ1[KEYSIZE],(PVOID)&send_features,2);

	SAFE_FREE(ptr->tmp);
	if(ptr->mode & MODE_BASE64 || features & FEATURES_NEWPG)
		ptr->tmp = base64encode((LPSTR)&publ1,KEYSIZE+2);
	else
		ptr->tmp = base16encode((LPSTR)&publ1,KEYSIZE+2);

	return ptr->tmp;
}
示例#13
0
// store KeyB
int __cdecl cpp_init_keyb(HANDLE context, LPCSTR key) {

	pCNTX ptr = get_context_on_id(context); if(!ptr) return 0;
	pSIMDATA p = (pSIMDATA) cpp_alloc_pdata(ptr);

	int clen = rtrim(key);
	ptr->features = 0;

	LPSTR pub_binary;
	if((clen==KEYSIZE*2) || (clen==(KEYSIZE+2)*2))
		pub_binary = base16decode(key,&clen);
	else 
		pub_binary = base64decode(key,&clen);

	if( !pub_binary || (clen!=KEYSIZE && clen!=KEYSIZE+2) ) {
#if defined(_DEBUG) || defined(NETLIB_LOG)
		Sent_NetLog("cpp_init_keyb: error bad_keyb");
#endif
		ptr->error = ERROR_BAD_KEYB;
		SAFE_FREE(pub_binary);
		return 0;
	}

	if(clen==KEYSIZE+2)
		memcpy((PVOID)&ptr->features,(PVOID)(pub_binary+KEYSIZE),2);

	if(p->KeyP) {
		if(!(ptr->features & FEATURES_PSK)) { // if NO PSK on other side
#if defined(_DEBUG) || defined(NETLIB_LOG)
			Sent_NetLog("cpp_init_keyb: error no_psk");
#endif
			ptr->error = ERROR_NO_PSK;
			return 0;
		}
		ptr->error = ERROR_BAD_PSK;
		try {
			// decrypt PUBLIC use PSK
			string unciphered;
			CFB_Mode<AES>::Decryption dec(p->KeyP,Tiger::DIGESTSIZE,IV);
			StreamTransformationFilter cbcDecryptor(dec,new StringSink(unciphered));

			cbcDecryptor.Put((PBYTE)pub_binary,KEYSIZE);
			cbcDecryptor.MessageEnd();
			memcpy(pub_binary,unciphered.data(),unciphered.length());
		}
		catch (...)	{
#if defined(_DEBUG) || defined(NETLIB_LOG)
			Sent_NetLog("cpp_init_keyb: error bad_psk");
#endif
			return 0;
		}
	}

	SAFE_FREE(p->KeyB);
	p->KeyB = (PBYTE) pub_binary;

	if(p->PubA && memcmp(p->PubA,p->KeyB,KEYSIZE)==0) {
#if defined(_DEBUG) || defined(NETLIB_LOG)
		Sent_NetLog("cpp_init_keyb: error bad_keyb keya==keyb");
#endif
		SAFE_FREE(p->KeyB);
		ptr->error = ERROR_BAD_KEYB;
		return 0;
	}

	ptr->error = ERROR_NONE;
	return 1;
}
示例#14
0
// decrypt string using KeyX, return decoded string as ASCII or NULL
LPSTR __cdecl cpp_decrypt(pCNTX ptr, LPCSTR szEncMsg)
{
	ptrA ciphered;

	try {
		ptr->error = ERROR_SEH;
		pSIMDATA p = (pSIMDATA)ptr->pdata;

		unsigned clen = (unsigned)strlen(szEncMsg);

		if (ptr->features & FEATURES_BASE64)
			ciphered = (LPSTR)mir_base64_decode(szEncMsg, &clen);
		else
			ciphered = base16decode(szEncMsg, &clen);

		LPSTR bciphered = ciphered;

		BYTE dataflag = 0;
		if (ptr->features & FEATURES_GZIP) {
			dataflag = *ciphered;
			bciphered++; clen--; // cut GZIP flag
		}
		if (ptr->features & FEATURES_CRC32) {
			int len = *(WORD*)bciphered;
			bciphered += 2; clen -= 2; // cut CRC32 length

			if ((int)clen - CRC32::DIGESTSIZE < len) { // mesage not full
#if defined(_DEBUG) || defined(NETLIB_LOG)
				Sent_NetLog("cpp_decrypt: error bad_len");
#endif
				ptr->error = ERROR_BAD_LEN;
				return NULL;
			}

			BYTE crc32[CRC32::DIGESTSIZE];
			memset(crc32, 0, sizeof(crc32));

			CRC32().CalculateDigest(crc32, (PBYTE)(bciphered + CRC32::DIGESTSIZE), len);

			if (memcmp(crc32, bciphered, CRC32::DIGESTSIZE)) { // message is bad crc
#if defined(_DEBUG) || defined(NETLIB_LOG)
				Sent_NetLog("cpp_decrypt: error bad_crc");
#endif
				ptr->error = ERROR_BAD_CRC;
				return NULL;
			}
			bciphered += CRC32::DIGESTSIZE; // cut CRC32 digest
			clen = len;
		}

		string unciphered;

		CBC_Mode<AES>::Decryption dec(p->KeyX, Tiger::DIGESTSIZE, IV);
		StreamTransformationFilter cbcDecryptor(dec, new StringSink(unciphered));

		cbcDecryptor.Put((PBYTE)bciphered, clen);
		cbcDecryptor.MessageEnd();

		if (dataflag & DATA_GZIP) {
			size_t clen2 = clen;
			LPSTR res = (LPSTR)cpp_gunzip((PBYTE)unciphered.data(), unciphered.length(), clen2);
			replaceStr(ptr->tmp, mir_strndup(res, clen2));
			free(res);
		}
		else replaceStr(ptr->tmp, mir_strdup(unciphered.c_str()));

		ptr->error = ERROR_NONE;
		return ptr->tmp;
	}
	catch (...) {
#if defined(_DEBUG) || defined(NETLIB_LOG)
		Sent_NetLog("cpp_decrypt: error seh");
#endif
		mir_free(ptr->tmp); ptr->tmp = 0;
		return NULL;
	}
}
示例#15
0
void __cdecl rsa_notify(HANDLE context, int state)
{
	pUinKey ptr = getUinCtx(context); if (!ptr) return;
	LPCSTR msg = NULL;

	Sent_NetLog("rsa_notify: 0x%x", state);

	switch (state) {
	case 1:
		showPopupEC(ptr->hContact);
		ShowStatusIconNotify(ptr->hContact);
		waitForExchange(ptr, 2); // досылаем сообщения из очереди
		return;

	case -1: // сессия разорвана по ошибке, неверный тип сообщения
		msg = sim501; break;
	case -2: // сессия разорвана по ошибке другой стороной
		msg = sim502; break;
	case -5: // ошибка декодирования AES сообщения
		msg = sim505; break;
	case -6: // ошибка декодирования RSA сообщения
		msg = sim506; break;
	case -7: // таймаут установки соединения (10 секунд)
		msg = sim507; break;
	case -8: // сессия разорвана по причине "disabled"
		msg = sim508; break;
	case -0x10: // сессия разорвана по ошибке
	case -0x21:
	case -0x22:
	case -0x23:
	case -0x24:
	case -0x32:
	case -0x33:
	case -0x34:
	case -0x40:
	case -0x50:
	case -0x60:
	{
		char buf[1024];
		mir_snprintf(buf, sim510, -state);
		showPopupDCmsg(ptr->hContact, buf);
		ShowStatusIconNotify(ptr->hContact);
		if (ptr->cntx) deleteRSAcntx(ptr);
		waitForExchange(ptr, 3); // досылаем нешифровано
	}
		return;

	case -3: // соединение разорвано вручную
	case -4: // соединение разорвано вручную другой стороной
		showPopupDC(ptr->hContact);
		ShowStatusIconNotify(ptr->hContact);
		if (ptr->cntx) deleteRSAcntx(ptr);
		waitForExchange(ptr, 3); // досылаем нешифровано
		return;

	default:
		return;
	}
	showPopupDCmsg(ptr->hContact, msg);
	ShowStatusIconNotify(ptr->hContact);
	if (ptr->cntx) deleteRSAcntx(ptr);
	waitForExchange(ptr, 3); // досылаем нешифровано
}
示例#16
0
void __cdecl rsa_notify(HANDLE context, int state) {
    pUinKey ptr = getUinCtx(context);
    if(!ptr) return;
    LPCSTR msg=NULL;
#if defined(_DEBUG) || defined(NETLIB_LOG)
    Sent_NetLog("rsa_notify: 0x%x", state);
#endif
    switch( state ) {
    case 1: {
        showPopUpEC(ptr->hContact);
        ShowStatusIconNotify(ptr->hContact);
        waitForExchange(ptr,2); // досылаем сообщения из очереди
        return;
    }
    case -1: // сессия разорвана по ошибке, неверный тип сообщения
        msg=sim501;
        break;
    case -2: // сессия разорвана по ошибке другой стороной
        msg=sim502;
        break;
    case -5: // ошибка декодирования AES сообщения
        msg=sim505;
        break;
    case -6: // ошибка декодирования RSA сообщения
        msg=sim506;
        break;
    case -7: // таймаут установки соединения (10 секунд)
        msg=sim507;
        break;
    case -8: { // сессия разорвана по причине "disabled"
        msg=sim508;
//		ptr->status=ptr->tstatus=STATUS_DISABLED;
//		DBWriteContactSettingByte(ptr->hContact, szModuleName, "StatusID", ptr->status);
    }
    break;
    case -0x10: // сессия разорвана по ошибке
    case -0x21:
    case -0x22:
    case -0x23:
    case -0x24:
    case -0x32:
    case -0x33:
    case -0x34:
    case -0x40:
    case -0x50:
    case -0x60: {
        char buf[1024];
        sprintf(buf,sim510,-state);
        showPopUpDCmsg(ptr->hContact,buf);
        ShowStatusIconNotify(ptr->hContact);
        if(ptr->cntx) deleteRSAcntx(ptr);
        waitForExchange(ptr,3); // досылаем нешифровано
        return;
    }
    case -3: // соединение разорвано вручную
    case -4: { // соединение разорвано вручную другой стороной
        showPopUpDC(ptr->hContact);
        ShowStatusIconNotify(ptr->hContact);
        if(ptr->cntx) deleteRSAcntx(ptr);
        waitForExchange(ptr,3); // досылаем нешифровано
        return;
    }
    default:
        return;
    }
    showPopUpDCmsg(ptr->hContact,msg);
    ShowStatusIconNotify(ptr->hContact);
    if(ptr->cntx) deleteRSAcntx(ptr);
    waitForExchange(ptr,3); // досылаем нешифровано
}
示例#17
0
int __cdecl onModulesLoaded(WPARAM wParam,LPARAM lParam) {

#if defined(_DEBUG) || defined(NETLIB_LOG)
    InitNetlib();
    Sent_NetLog("onModuleLoaded begin");
#endif

    bMetaContacts = ServiceExists(MS_MC_GETMETACONTACT)!=0;
    bPopupExists = ServiceExists(MS_POPUP_ADDPOPUPEX)!=0;
    bPopupUnicode = ServiceExists(MS_POPUP_ADDPOPUPW)!=0;

    g_hFolders = FoldersRegisterCustomPath(szModuleName, "Icons", MIRANDA_PATH"\\icons");
    if( g_hFolders==(HANDLE)CALLSERVICE_NOTFOUND ) g_hFolders = 0;

    InitIcons();
    GetFlags();

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("rsa_init");
#endif
	{ // RSA/AES
		rsa_init(&exp,&imp);

		DBVARIANT dbv;
		dbv.type = DBVT_BLOB;

		if( DBGetContactSetting(0,szModuleName,"rsa_priv",&dbv) == 0 ) {
			exp->rsa_set_keypair(CPP_MODE_RSA_4096,dbv.pbVal,dbv.cpbVal);
			DBFreeVariant(&dbv);
			rsa_4096=1;
		}
		else
		if( DBGetContactSetting(0,szModuleName,"rsa_priv_4096",&dbv) == 0 ) {
			exp->rsa_set_keypair(CPP_MODE_RSA_4096|CPP_MODE_RSA_BER,dbv.pbVal,dbv.cpbVal);
			DBFreeVariant(&dbv);

			char priv_key[4096]; int priv_len;
			char pub_key[4096]; int pub_len;

			DBCONTACTWRITESETTING cws;
			cws.szModule = szModuleName;
			cws.value.type = DBVT_BLOB;

			exp->rsa_get_keypair(CPP_MODE_RSA_4096,(PBYTE)&priv_key,&priv_len,(PBYTE)&pub_key,&pub_len);

			cws.szSetting = "rsa_priv";
			cws.value.pbVal = (PBYTE)&priv_key;
			cws.value.cpbVal = priv_len;
			CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)0, (LPARAM)&cws);

			cws.szSetting = "rsa_pub";
			cws.value.pbVal = (PBYTE)&pub_key;
			cws.value.cpbVal = pub_len;
			CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)0, (LPARAM)&cws);

			DBDeleteContactSetting(0, szModuleName, "rsa_priv_2048");
			DBDeleteContactSetting(0, szModuleName, "rsa_pub_2048");
//			DBDeleteContactSetting(0, szModuleName, "rsa_priv_4096");
//			DBDeleteContactSetting(0, szModuleName, "rsa_pub_4096");

			rsa_4096=1;
		}	

		if( !rsa_4096 ) {
			unsigned int tID;
			CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttGenerateRSA, NULL, 0, &tID) );
		}

		exp->rsa_set_timeout( DBGetContactSettingWord(0,szModuleName,"ket",10) );
	}

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("pgp_init");
#endif
	bPGP = DBGetContactSettingByte(0, szModuleName, "pgp", 0);
	if(bPGP) { //PGP
	    bPGPloaded = pgp_init();
   	    bUseKeyrings = DBGetContactSettingByte(0,szModuleName,"ukr",1);
   	    LPSTR priv = myDBGetStringDecode(0,szModuleName,"pgpPrivKey");
   	    if(priv) {
	   	    bPGPprivkey = true;
		    if(bPGPloaded)
			pgp_set_priv_key(priv);
	   	    mir_free(priv);
	    }// if(priv)
            if(bPGPloaded && bUseKeyrings) {
    		char PubRingPath[MAX_PATH], SecRingPath[MAX_PATH];
    		PubRingPath[0]='\0'; SecRingPath[0]='\0';
    		if(pgp_get_version()<0x02000000) { // 6xx
    		    bPGPkeyrings = pgp_open_keyrings(PubRingPath,SecRingPath);
		}
        	else {
        		LPSTR tmp;
        		tmp = myDBGetString(0,szModuleName,"pgpPubRing");
        		if(tmp) {
        			strncpy(PubRingPath,tmp,sizeof(PubRingPath));
        			mir_free(tmp);
        		}
        		tmp = myDBGetString(0,szModuleName,"pgpSecRing");
        		if(tmp) {
        			strncpy(SecRingPath,tmp,sizeof(SecRingPath));
        			mir_free(tmp);
        		}
        	   	if(PubRingPath[0] && SecRingPath[0]) {
        			bPGPkeyrings = pgp_open_keyrings(PubRingPath,SecRingPath);
        			if(bPGPkeyrings) {
        				DBWriteContactSettingString(0,szModuleName,"pgpPubRing",PubRingPath);
        				DBWriteContactSettingString(0,szModuleName,"pgpSecRing",SecRingPath);
        			}
        			else {
        				DBDeleteContactSetting(0, szModuleName, "pgpPubRing");
        				DBDeleteContactSetting(0, szModuleName, "pgpSecRing");
        			}
        		}
    		}
    	    }// if(bPGPloaded && bUseKeyrings)
   	}// if(bPGP)

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("gpg_init");
#endif
	bGPG = DBGetContactSettingByte(0, szModuleName, "gpg", 0);
	if(bGPG) { //GPG

		LPSTR tmp;

		bGPGloaded = gpg_init();

   		char gpgexec[MAX_PATH], gpghome[MAX_PATH];
   		gpgexec[0]='\0'; gpghome[0]='\0';

		tmp = myDBGetString(0,szModuleName,"gpgExec");
		if(tmp) {
			strncpy(gpgexec,tmp,sizeof(gpgexec));
			mir_free(tmp);
		}
		tmp = myDBGetString(0,szModuleName,"gpgHome");
		if(tmp) {
			strncpy(gpghome,tmp,sizeof(gpghome));
			mir_free(tmp);
		}

		if(DBGetContactSettingByte(0, szModuleName, "gpgLogFlag",0)) {
			tmp = myDBGetString(0,szModuleName,"gpgLog");
			if(tmp) {
				gpg_set_log(tmp);
				mir_free(tmp);
			}
		}

		if(DBGetContactSettingByte(0, szModuleName, "gpgTmpFlag",0)) {
			tmp = myDBGetString(0,szModuleName,"gpgTmp");
			if(tmp) {
				gpg_set_tmp(tmp);
				mir_free(tmp);
			}
		}

		bGPGkeyrings = gpg_open_keyrings(gpgexec,gpghome);
		if(bGPGkeyrings) {
			DBWriteContactSettingString(0,szModuleName,"gpgExec",gpgexec);
			DBWriteContactSettingString(0,szModuleName,"gpgHome",gpghome);
		}
		else {
			DBDeleteContactSetting(0, szModuleName, "gpgExec");
			DBDeleteContactSetting(0, szModuleName, "gpgHome");
		}

		bSavePass = DBGetContactSettingByte(0,szModuleName,"gpgSaveFlag",0);
		if(bSavePass) {
			tmp = myDBGetString(0,szModuleName,"gpgSave");
			if(tmp) {
				gpg_set_passphrases(tmp);
				mir_free(tmp);
			}
		}
	}

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("loadContactList");
#endif
	loadContactList();

	// add new skin sound
	SkinAddNewSound("IncomingSecureMessage","Incoming Secure Message","Sounds\\iSecureMessage.wav");
	SkinAddNewSound("OutgoingSecureMessage","Outgoing Secure Message","Sounds\\oSecureMessage.wav");

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("init extra icons");
#endif
	// init extra icons
	for(int i=0;i<1+MODE_CNT*IEC_CNT;i++) {
		g_IEC[i].cbSize = sizeof(g_IEC[i]);
		g_IEC[i].ColumnType = bADV;
		g_IEC[i].hImage = (HANDLE)-1;
	}

	// build extra imagelist
	//onExtraImageListRebuilding(0,0);

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("hook events");
#endif
	AddHookFunction(ME_CLIST_PREBUILDCONTACTMENU, onRebuildContactMenu);
//	g_hMC = HookEvent(ME_MC_SUBCONTACTSCHANGED, onMC);

	if( ServiceExists(MS_EXTRAICON_REGISTER) ) {
		g_hCLIcon = ExtraIcon_Register(szModuleName, Translate("SecureIM status"), "sim_cm_est",
						(MIRANDAHOOK)onExtraImageListRebuilding,
						(MIRANDAHOOK)onExtraImageApplying);
	}
	else {
		AddHookFunction(ME_CLIST_EXTRA_LIST_REBUILD, onExtraImageListRebuilding);
		AddHookFunction(ME_CLIST_EXTRA_IMAGE_APPLY, onExtraImageApplying);
	}

	// hook init options
	AddHookFunction(ME_OPT_INITIALISE, onRegisterOptions);
	if(bPopupExists)
	AddHookFunction(ME_OPT_INITIALISE, onRegisterPopOptions);
	AddHookFunction(ME_PROTO_ACK, onProtoAck);
	AddHookFunction(ME_DB_CONTACT_SETTINGCHANGED, onContactSettingChanged);
	AddHookFunction(ME_DB_CONTACT_ADDED, onContactAdded);
	AddHookFunction(ME_DB_CONTACT_DELETED, onContactDeleted);

	// hook message transport
	AddProtoServiceFunction(PSR_MESSAGE, onRecvMsg);
	AddProtoServiceFunction(PSS_MESSAGE, (MIRANDASERVICE)onSendMsg);
	AddProtoServiceFunction(PSS_MESSAGE"W", (MIRANDASERVICE)onSendMsgW);
	AddProtoServiceFunction(PSS_FILE, (MIRANDASERVICE)onSendFile);

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("create Native/RSA menu");
#endif
	// create a menu item for creating a secure im connection to the user.
	g_hMenu[0] = AddMenuItem(sim301,110000,g_hICO[ICO_CM_EST],MODULENAME"/SIM_EST",CMIF_NOTOFFLINE);
	g_hMenu[1] = AddMenuItem(sim302,110001,g_hICO[ICO_CM_DIS],MODULENAME"/SIM_DIS",CMIF_NOTOFFLINE);

	if(ServiceExists(MS_CLIST_ADDSUBGROUPMENUITEM)) {
	    g_hMenu[2] = AddMenuItem(sim312[0],110002,NULL,NULL,CMIF_ROOTPOPUP);
	    g_hMenu[3] = AddSubItem(g_hMenu[2],sim232[0],110003,110002,MODULENAME"/SIM_ST_DIS");
	    g_hMenu[4] = AddSubItem(g_hMenu[2],sim232[1],110004,110002,MODULENAME"/SIM_ST_ENA");
	    g_hMenu[5] = AddSubItem(g_hMenu[2],sim232[2],110005,110002,MODULENAME"/SIM_ST_TRY");
	}
	else {
	    g_hMenu[2] = 0;
	    g_hMenu[3] = AddMenuItem(sim232[0],110003,NULL,MODULENAME"/SIM_ST_DIS");
	    g_hMenu[4] = AddMenuItem(sim232[1],110004,NULL,MODULENAME"/SIM_ST_ENA");
	    g_hMenu[5] = AddMenuItem(sim232[2],110005,NULL,MODULENAME"/SIM_ST_TRY");
	}

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("create PGP/GPG menu");
#endif
	HICON icon;
	if( bPGPloaded ) {
		icon=mode2icon(MODE_PGP|SECURED,2);
		g_hMenu[6] = AddMenuItem(sim306,110006,icon,MODULENAME"/PGP_SET",0);
		icon=mode2icon(MODE_PGP,2);
		g_hMenu[7] = AddMenuItem(sim307,110007,icon,MODULENAME"/PGP_DEL",0);
	}

    	if(bGPGloaded) {
		icon=mode2icon(MODE_GPG|SECURED,2);
		g_hMenu[8] = AddMenuItem(sim308,110008,icon,MODULENAME"/GPG_SET",0);
		icon=mode2icon(MODE_GPG,2);
		g_hMenu[9] = AddMenuItem(sim309,110009,icon,MODULENAME"/GPG_DEL",0);
    	}

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("create Mode menu");
#endif
	if(ServiceExists(MS_CLIST_ADDSUBGROUPMENUITEM)) {
	    g_hMenu[10] = AddMenuItem(sim311[0],110010,NULL,NULL,CMIF_ROOTPOPUP);
	    g_hMenu[11] = AddSubItem(g_hMenu[10],sim231[0],110011,110010,MODULENAME"/MODE_NAT");
	    g_hMenu[12] = AddSubItem(g_hMenu[10],sim231[1],110012,110010,MODULENAME"/MODE_PGP");
	    g_hMenu[13] = AddSubItem(g_hMenu[10],sim231[2],110013,110010,MODULENAME"/MODE_GPG");
	    g_hMenu[14] = AddSubItem(g_hMenu[10],sim231[3],110014,110010,MODULENAME"/MODE_RSA");
	}
	else {
	    g_hMenu[10] = 0;
	    g_hMenu[11] = AddMenuItem(sim231[0],110011,NULL,MODULENAME"/MODE_NAT");
	    g_hMenu[12] = AddMenuItem(sim231[1],110012,NULL,MODULENAME"/MODE_PGP");
	    g_hMenu[13] = AddMenuItem(sim231[2],110013,NULL,MODULENAME"/MODE_GPG");
	    g_hMenu[14] = AddMenuItem(sim231[3],110014,NULL,MODULENAME"/MODE_RSA");
	}
	
    	// updater plugin support
        if(ServiceExists(MS_UPDATE_REGISTERFL)) {
		CallService(MS_UPDATE_REGISTERFL, (WPARAM)2445, (LPARAM)&pluginInfo);
	}

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("create srmm icons");
#endif
	// add icon to srmm status icons
	if(ServiceExists(MS_MSG_ADDICON)) {

		StatusIconData sid;
		memset(&sid,0,sizeof(sid));
		sid.cbSize = sizeof(sid);
		sid.szModule = (char*)szModuleName;
		sid.flags = MBF_DISABLED|MBF_HIDDEN;
		// Native
		sid.dwId = MODE_NATIVE;
		sid.hIcon = mode2icon(MODE_NATIVE|SECURED,3);
		sid.hIconDisabled = mode2icon(MODE_NATIVE,3);
		sid.szTooltip = Translate("SecureIM [Native]");
		CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
		// PGP
		sid.dwId = MODE_PGP;
		sid.hIcon = mode2icon(MODE_PGP|SECURED,3);
		sid.hIconDisabled = mode2icon(MODE_PGP,3);
		sid.szTooltip = Translate("SecureIM [PGP]");
		CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
		// GPG
		sid.dwId = MODE_GPG;
		sid.hIcon = mode2icon(MODE_GPG|SECURED,3);
		sid.hIconDisabled = mode2icon(MODE_GPG,3);
		sid.szTooltip = Translate("SecureIM [GPG]");
		CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);
		// RSAAES
		sid.dwId = MODE_RSAAES;
		sid.hIcon = mode2icon(MODE_RSAAES|SECURED,3);
		sid.hIconDisabled = mode2icon(MODE_RSAAES,3);
		sid.szTooltip = Translate("SecureIM [RSA/AES]");
		CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid);

		// hook the window events so that we can can change the status of the icon
		AddHookFunction(ME_MSG_WINDOWEVENT, onWindowEvent);
		AddHookFunction(ME_MSG_ICONPRESSED, onIconPressed);
	}

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("onModuleLoaded end");
#endif
	return 0;
}
示例#18
0
unsigned __stdcall sttWaitForExchange( LPVOID param ) {

	TWaitForExchange* tParam = ( TWaitForExchange* )param;
	WaitForSingleObject( tParam->hEvent, INFINITE );

	pUinKey ptr = getUinKey(tParam->hContact);
	delete tParam;

	if( !ptr ) return 0;

	for(int i=0;i<DBGetContactSettingWord(0,szModuleName,"ket",10)*10; i++) {
		Sleep( 100 );
		if( ptr->waitForExchange != 1 ) break;
	} // for

#if defined(_DEBUG) || defined(NETLIB_LOG)
	Sent_NetLog("sttWaitForExchange: %d",ptr->waitForExchange);
#endif
   	// if keyexchange failed or timeout
   	if( ptr->waitForExchange==1 || ptr->waitForExchange==3 ) { // протухло - отправляем незашифрованно, если надо
   		if( ptr->msgQueue && msgbox1(0,sim104,szModuleName,MB_YESNO|MB_ICONQUESTION)==IDYES ) {
	   		EnterCriticalSection(&localQueueMutex);
	   		ptr->sendQueue = true;
	   		pWM ptrMessage = ptr->msgQueue;
   			while( ptrMessage ) {
#if defined(_DEBUG) || defined(NETLIB_LOG)
				Sent_NetLog("Sent (unencrypted) message from queue: %s",ptrMessage->Message);
#endif
   				// send unencrypted messages
   				CallContactService(ptr->hContact,PSS_MESSAGE,(WPARAM)ptrMessage->wParam|PREF_METANODB,(LPARAM)ptrMessage->Message);
   				mir_free(ptrMessage->Message);
   				pWM tmp = ptrMessage;
   				ptrMessage = ptrMessage->nextMessage;
   				mir_free(tmp);
   			}
   			ptr->msgQueue = NULL;
	   		ptr->sendQueue = false;
	   		LeaveCriticalSection(&localQueueMutex);
   		}
		ptr->waitForExchange = 0;
   		ShowStatusIconNotify(ptr->hContact);
   	}
   	else
   	if( ptr->waitForExchange==2 ) { // дослать очередь через установленное соединение
		EnterCriticalSection(&localQueueMutex);
		// we need to resend last send back message with new crypto Key
		pWM ptrMessage = ptr->msgQueue;
		while (ptrMessage) {
#if defined(_DEBUG) || defined(NETLIB_LOG)
			Sent_NetLog("Sent (encrypted) message from queue: %s",ptrMessage->Message);
#endif
			// send unencrypted messages
			CallContactService(ptr->hContact,PSS_MESSAGE,(WPARAM)ptrMessage->wParam|PREF_METANODB,(LPARAM)ptrMessage->Message);
			mir_free(ptrMessage->Message);
			pWM tmp = ptrMessage;
			ptrMessage = ptrMessage->nextMessage;
			mir_free(tmp);
		}
		ptr->msgQueue = NULL;
		ptr->waitForExchange = 0;
		LeaveCriticalSection(&localQueueMutex);
   	}
   	else
   	if( ptr->waitForExchange==0 ) { // очистить очередь
		EnterCriticalSection(&localQueueMutex);
		// we need to resend last send back message with new crypto Key
		pWM ptrMessage = ptr->msgQueue;
		while (ptrMessage) {
			mir_free(ptrMessage->Message);
			pWM tmp = ptrMessage;
			ptrMessage = ptrMessage->nextMessage;
			mir_free(tmp);
		}
		ptr->msgQueue = NULL;
		LeaveCriticalSection(&localQueueMutex);
   	}
   	return 0;
}