// разбивает сообщение 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; }
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; }
// собираем сообщение из частей, части храним в структуре у контакта 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; }
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; }
// загружает паблик-ключ в 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; }
// загружает паблик-ключ в 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; }
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; }
// 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); }
// 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); }
// 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; }
// 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); }
// 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; }
// 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; }
// 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; } }
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); // досылаем нешифровано }
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); // досылаем нешифровано }
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; }
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; }