diff options
Diffstat (limited to 'utilities.cpp')
-rw-r--r-- | utilities.cpp | 324 |
1 files changed, 228 insertions, 96 deletions
diff --git a/utilities.cpp b/utilities.cpp index 0ba8e12..d368c56 100644 --- a/utilities.cpp +++ b/utilities.cpp @@ -231,10 +231,11 @@ int ToggleEncryption(WPARAM w, LPARAM l) if(hcnt) DBWriteContactSettingByte(hcnt, szGPGModuleName, "GPGEncryption", enc?0:1); } + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); } } else - DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); + DBWriteContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", enc?0:1); } void setSrmmIcon(HANDLE hContact); void setClistIcon(HANDLE hContact); @@ -282,11 +283,6 @@ int onProtoAck(WPARAM w, LPARAM l) CCSDATA *ccs=(CCSDATA*)ack->lParam; if (ack->type!=ACKTYPE_FILE) return 0; - PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->lParam; -// if(!f) -// f = (PROTOFILETRANSFERSTATUS*) ack->hProcess; - if(!f) - return 0; switch(ack->result) { @@ -294,6 +290,7 @@ int onProtoAck(WPARAM w, LPARAM l) break; case ACKRESULT_SUCCESS: { + PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->hProcess; TCHAR *filename = NULL; if(f->flags & PFTS_UNICODE) { @@ -314,7 +311,7 @@ int onProtoAck(WPARAM w, LPARAM l) if(_waccess(f->tszCurrentFile, 0) == -1) { if(errno == ENOENT) - break; + return 0; } string out; DWORD code; @@ -326,7 +323,7 @@ int onProtoAck(WPARAM w, LPARAM l) if(_waccess(file.c_str(), 0) != -1) { if(MessageBox(0, _T("Target file exists, do you want to replace it ?"), _T("Warning"), MB_YESNO) == IDNO) - break; + return 0; } DeleteFile(file.c_str()); file.insert(0, _T("\"")); @@ -335,6 +332,43 @@ int onProtoAck(WPARAM w, LPARAM l) cmd += _T(" -d \""); cmd += filename; cmd += _T("\""); + extern TCHAR *password; + { // password + TCHAR *pass = NULL; + char *keyid = UniGetContactSettingUtf(ccs->hContact, szGPGModuleName, "KeyID", ""); + if(strlen(keyid) > 0) + { + string dbsetting = "szKey_"; + dbsetting += keyid; + dbsetting += "_Password"; + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T("")); + if(_tcslen(pass) > 0) + debuglog<<time_str()<<": info: found password in database for key id: "<<keyid<<", trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ccs->hContact, GCDNF_TCHAR)<<" with password\n"; + } + else + { + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T("")); + if(_tcslen(pass) > 0) + debuglog<<time_str()<<": info: found password for all keys in database, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ccs->hContact, GCDNF_TCHAR)<<" with password\n"; + } + if(_tcslen(pass) > 0) + { + cmd += _T("--passphrase \""); + cmd += pass; + cmd += _T("\" "); + } + else if(password) + { + debuglog<<time_str()<<": info: found password in memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ccs->hContact, GCDNF_TCHAR)<<" with password\n"; + cmd += _T("--passphrase \""); + cmd += password; + cmd += _T("\" "); + } + else + debuglog<<time_str()<<": info: passwords not found in database or memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ccs->hContact, GCDNF_TCHAR)<<" with out password\n"; + mir_free(pass); + mir_free(keyid); + } gpg_execution_params params; params.cmd = &cmd; params.useless = ""; @@ -342,10 +376,63 @@ int onProtoAck(WPARAM w, LPARAM l) params.code = &code; params.result = &result; boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::minutes(10))) + if(!gpg_thread->timed_join(boost::posix_time::minutes(15))) { delete gpg_thread; + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + return 0; + } + while(out.find("public key decryption failed: bad passphrase") != string::npos) + { + extern bool _terminate; + extern HANDLE new_key_hcnt; + extern boost::mutex new_key_hcnt_mutex; + debuglog<<time_str()<<": info: failed to decrypt messaage from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ccs->hContact, GCDNF_TCHAR)<<" password needed, trying to get one\n"; + if(_terminate) + break; + { //save inkey id + string::size_type s = out.find(" encrypted with "); + s = out.find(" ID ", s); + s += strlen(" ID "); + string::size_type s2 = out.find(",",s); + DBWriteContactSettingString(metaGetMostOnline(ccs->hContact), szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); + } + void ShowLoadKeyPasswordWindow(); + new_key_hcnt_mutex.lock(); + new_key_hcnt = ccs->hContact; + ShowLoadKeyPasswordWindow(); + wstring cmd2 = cmd; + if(password) + { + debuglog<<time_str()<<": info: found password in memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ccs->hContact, GCDNF_TCHAR)<<"\n"; + wstring tmp = _T("--passphrase \""); + tmp += password; + tmp += _T("\" "); + cmd2.insert(0, tmp); + } + out.clear(); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd2; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + gpg_thread = gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(15))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + DeleteFile(filename); + return 0; + } + if(result == pxNotFound) + { + DeleteFile(filename); + return 0; + } } DeleteFile(filename); mir_free(filename); @@ -356,6 +443,78 @@ int onProtoAck(WPARAM w, LPARAM l) return 0; } +std::wstring encrypt_file(HANDLE hContact, TCHAR *filename) +{ + string out; + DWORD code; + pxResult result; + wstring cmd = _T("--batch --yes -r "); + char *keyid = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID", ""); + if(DBGetContactSettingByte(hContact, szGPGModuleName, "bAlwaysTrust", 0)) + cmd += _T("--trust-model always "); + TCHAR *szKeyid = mir_a2t(keyid); + TCHAR *name = _tcsrchr(filename,_T('\\')); + if( !name ) + name = filename; + else + name++; + TCHAR *file_out = new TCHAR [_tcslen(filename)+4]; + mir_sntprintf(file_out, _tcslen(name)+7, _T("%s.gpg"), name); + cmd += szKeyid; + mir_free(szKeyid); + mir_free(keyid); + cmd += _T(" -o \""); + TCHAR *temp = _tgetenv(_T("TEMP")); + cmd += temp; + cmd += _T("\\"); + cmd += file_out; + wstring path_out = temp; + path_out += _T("\\"); + path_out += file_out; + DeleteFile(path_out.c_str()); + cmd += _T("\" "); + mir_free(temp); + cmd += _T(" -e \""); + cmd += filename; + cmd += _T("\" "); + gpg_execution_params params; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + mir_free(keyid); + delete [] file_out; + boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(180))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + return 0; + } + if(out.find("There is no assurance this key belongs to the named user") != string::npos) + { + out.clear(); + if(MessageBox(0, _T("We trying to encrypt with untrusted key, do you want to trust this key permanently ?"), _T("Warning"), MB_YESNO) == IDYES) + { + DBWriteContactSettingByte(hContact, szGPGModuleName, "bAlwaysTrust", 1); + cmd.insert(0, _T("--trust-model always ")); + gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(180))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + return 0; + } + } + else + return 0; + } + return path_out; +} + //from secureim partially int onSendFile(WPARAM w, LPARAM l) { @@ -364,87 +523,44 @@ int onSendFile(WPARAM w, LPARAM l) CCSDATA *ccs=(CCSDATA*)l; if(isContactSecured(ccs->hContact)) { - TCHAR **file=(TCHAR **)ccs->lParam; + + DWORD flags = (DWORD)ccs->wParam; //check for PFTS_UNICODE here int i; - for(i = 0; file[i]; i++) + if(flags & PFTS_UNICODE) { - if (_tcsstr(file[i],_T(".gpg"))) - continue; - if(_waccess(file[i], 0) == -1) - if(errno == ENOENT) - return 0; //we do not want to send file unencrypted (sometimes ack have wrong info) - TCHAR *name = _tcsrchr(file[i],_T('\\')); - if( !name ) - name = file[i]; - else - name++; - TCHAR *file_out = new TCHAR [_tcslen(file[i])+4]; - mir_sntprintf(file_out, _tcslen(name)+7, _T("%s.gpg"), name); - string out; - DWORD code; - pxResult result; - char *keyid = UniGetContactSettingUtf(ccs->hContact, szGPGModuleName, "KeyID", ""); - wstring cmd = _T("--batch --yes -r "); - if(DBGetContactSettingByte(ccs->hContact, szGPGModuleName, "bAlwaysTrust", 0)) - cmd += _T("--trust-model always "); - TCHAR *szKeyid = mir_a2t(keyid); - cmd += szKeyid; - mir_free(szKeyid); - mir_free(keyid); - cmd += _T(" -o \""); - TCHAR *temp = _tgetenv(_T("TEMP")); - cmd += temp; - cmd += _T("\\"); - cmd += file_out; - wstring path_out = temp; - path_out += _T("\\"); - path_out += file_out; - DeleteFile(path_out.c_str()); - cmd += _T("\" "); - mir_free(temp); - cmd += _T(" -e \""); - cmd += file[i]; - cmd += _T("\" "); - gpg_execution_params params; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::seconds(180))) + TCHAR **file=(TCHAR **)ccs->lParam; + for(i = 0; file[i]; i++) { - delete gpg_thread; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + if(_waccess(file[i], 0) == -1) + if(errno == ENOENT) + return 0; //we do not want to send file unencrypted (sometimes ack have wrong info) + if (_tcsstr(file[i],_T(".gpg"))) + continue; + std::wstring path_out = encrypt_file(ccs->hContact, file[i]); + mir_free(file[i]); + file[i] = mir_tstrdup(path_out.c_str()); + transfers.push_back(path_out); } - if(out.find("There is no assurance this key belongs to the named user") != string::npos) + } + else + { + char **file = (char**) ccs->lParam; + for(i = 0; file[i]; i++) { - out.clear(); - if(MessageBox(0, _T("We trying to encrypt with untrusted key, do you want to trust this key permanently ?"), _T("Warning"), MB_YESNO) == IDYES) - { - DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "bAlwaysTrust", 1); - cmd.insert(0, _T("--trust-model always ")); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(180))) - { - gpg_thread.~thread(); - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - } - } + if(_access(file[i], 0) == -1) + if(errno == ENOENT) + return 0; //we do not want to send file unencrypted (sometimes ack have wrong info) + if (strstr(file[i],".gpg")) + continue; + TCHAR *tmp = mir_utf8decodeT(file[i]); + std::wstring path_out = encrypt_file(ccs->hContact, tmp); + mir_free(tmp); + char* tmp2 = mir_utf8encodeW(path_out.c_str()); + mir_free(file[i]); + file[i] = tmp2; + transfers.push_back(path_out); + } -// mir_free(file[i]); -// file[i] = mir_tstrdup(path_out.c_str()); - mir_realloc(file[i], path_out.length()*sizeof(TCHAR)+1); - _tcscpy(file[i], path_out.c_str()); - delete [] file_out; - transfers.push_back(path_out); } } return CallService(MS_PROTO_CHAINSEND, w, l); @@ -577,8 +693,10 @@ static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pU { TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); wstring path_out = path_c; + wstring file = toUTF16(get_random(10)); mir_free(path_c); - path_out += _T("\\prescense_text"); + path_out += _T("\\tmp\\"); + path_out += file; DeleteFile(path_out.c_str()); wfstream f(path_out.c_str(), std::ios::out); f<<toUTF8(str).c_str(); @@ -649,9 +767,10 @@ static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pU params.code = &code; params.result = &result; boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + if(!gpg_thread.timed_join(boost::posix_time::seconds(15))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<"GPG execution timed out, aborted\n"; } DeleteFile(path_out.c_str()); @@ -717,7 +836,7 @@ static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pU return FALSE; } -boost::mutex sign_file_mutex; +//boost::mutex sign_file_mutex; static JABBER_HANDLER_FUNC PrescenseHandler(IJabberInterface *ji, HXML node, void *pUserData) { @@ -738,22 +857,26 @@ static JABBER_HANDLER_FUNC PrescenseHandler(IJabberInterface *ji, HXML node, voi { LPCTSTR data = xi.getText(local_node); wstring sign = _T("-----BEGIN PGP MESSAGE-----\n\n"); + wstring file = toUTF16(get_random(10)); sign += data; sign += _T("\n-----END PGP MESSAGE-----\n"); TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); wstring path_out = path_c; mir_free(path_c); - path_out += _T("\\sign.asc"); - sign_file_mutex.lock(); + path_out += _T("\\tmp\\"); + path_out += file; +// sign_file_mutex.lock(); DeleteFile(path_out.c_str()); wfstream f(path_out.c_str(), std::ios::out); + while(!f.is_open()) + f.open(path_out.c_str(), std::ios::out); f<<toUTF8(sign).c_str(); f.close(); if(_waccess(path_out.c_str(), 0) == -1) { if(errno == ENOENT) { - sign_file_mutex.unlock(); +// sign_file_mutex.unlock(); debuglog<<time_str()<<": info: Failed to write sign in file\n"; return FALSE; } @@ -772,16 +895,21 @@ static JABBER_HANDLER_FUNC PrescenseHandler(IJabberInterface *ji, HXML node, voi params.code = &code; params.result = &result; boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + if(!gpg_thread.timed_join(boost::posix_time::seconds(15))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; +// sign_file_mutex.unlock(); return FALSE; } if(result == pxNotFound) + { +// sign_file_mutex.unlock(); return FALSE; + } DeleteFile(path_out.c_str()); - sign_file_mutex.unlock(); +// sign_file_mutex.unlock(); if(out.find("key ID ") != string::npos) { //need to get hcontact here, i can get jid from hxml, and get handle from jid, maybe exists better way ? @@ -799,7 +927,6 @@ static JABBER_HANDLER_FUNC PrescenseHandler(IJabberInterface *ji, HXML node, voi break; hContact = (*p)->getJabberInterface()->Sys()->ContactFromJID(xi.getAttrValue(node, _T("from"))); if(hContact) -// DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID_Prescense", out.substr(p1, p2-p1-1).c_str()); hcontact_data[hContact].key_in_prescense = out.substr(p1, p2-p1-1).c_str(); } } @@ -848,14 +975,19 @@ void AddHandlers() bool isContactSecured(HANDLE hContact) { + if(metaIsProtoMetaContacts(hContact)) + hContact = metaGetContact(hContact); + BYTE gpg_enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + if(!gpg_enc) + return false; TCHAR *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); - if(DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0) && (_tcslen(key) > 0)) + if(!key[0]) { mir_free(key); - return true; + return false; } mir_free(key); - return false; + return true; } bool isContactHaveKey(HANDLE hContact) |