From 03e7b6d63bdfff3e4b5b7d0eb6899e5bf0108e4e Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 17 May 2013 21:10:14 +0000 Subject: - New_GPG: reinstated git-svn-id: http://svn.miranda-ng.org/main/trunk@4716 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/New_GPG/src/utilities.cpp | 2238 +++++++++++++++++++++++++++++++++++++ 1 file changed, 2238 insertions(+) create mode 100644 plugins/New_GPG/src/utilities.cpp (limited to 'plugins/New_GPG/src/utilities.cpp') diff --git a/plugins/New_GPG/src/utilities.cpp b/plugins/New_GPG/src/utilities.cpp new file mode 100644 index 0000000000..ce78023bdf --- /dev/null +++ b/plugins/New_GPG/src/utilities.cpp @@ -0,0 +1,2238 @@ +// Copyright � 2010-2012 sss +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#include "commonheaders.h" + + +TCHAR* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef) +{ + DBVARIANT dbv = {DBVT_DELETED}; + TCHAR* szRes; + if (db_get_ts(hContact, szModule, szSetting, &dbv)) + return mir_tstrdup(szDef); + if(dbv.pszVal) + szRes = mir_tstrdup(dbv.ptszVal); + db_free(&dbv); + return szRes; +} + +char* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, char* szDef) +{ + DBVARIANT dbv = {DBVT_DELETED}; + char* szRes; + if (db_get_s(hContact, szModule, szSetting, &dbv)) + return mir_strdup(szDef); + if(dbv.pszVal) + szRes = mir_strdup(dbv.pszVal); + db_free(&dbv); + return szRes; +} + +void GetFilePath(TCHAR *WindowTittle, char *szSetting, TCHAR *szExt, TCHAR *szExtDesc) +{ + TCHAR str[MAX_PATH+2] = {0}, *tmp; + OPENFILENAME ofn={0}; + TCHAR filter[512], *pfilter; + ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName); + ofn.Flags=OFN_EXPLORER; + ofn.lpstrTitle=TranslateW(WindowTittle); + _tcscpy(filter,TranslateW(szExtDesc)); + pfilter=filter+_tcslen(filter)+1; + _tcscpy(pfilter, szExt); + pfilter[_tcslen(pfilter)+1] = '\0'; + pfilter[_tcslen(pfilter)+2] = '\0'; + ofn.lpstrFilter=filter; + tmp = UniGetContactSettingUtf(0, szGPGModuleName, szSetting, _T("")); + _tcscpy(str, tmp); + mir_free(tmp); + if(_tcslen(str)< 2) + str[0] = '\0'; + ofn.lpstrFile=str; + ofn.nMaxFile=_MAX_PATH; + ofn.nMaxFileTitle=MAX_PATH; + if(!GetOpenFileName(&ofn)) + return; + db_set_ts(0, szGPGModuleName, szSetting, str); +} + +TCHAR *GetFilePath(TCHAR *WindowTittle, TCHAR *szExt, TCHAR *szExtDesc, bool save_file) +{ + TCHAR *str = new TCHAR [MAX_PATH+2]; + OPENFILENAME ofn={0}; + TCHAR filter[512], *pfilter; + ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName); + ofn.Flags=OFN_EXPLORER; + ofn.lpstrTitle=TranslateW(WindowTittle); + _tcscpy(filter,TranslateW(szExtDesc)); + pfilter=filter+_tcslen(filter)+1; + _tcscpy(pfilter, szExt); + pfilter[_tcslen(pfilter)+1] = '\0'; + pfilter[_tcslen(pfilter)+2] = '\0'; + ofn.lpstrFilter=filter; + _tcscpy(str, _T("")); + if(_tcslen(str)< 2) + str[0] = '\0'; + ofn.lpstrFile=str; + ofn.nMaxFile=_MAX_PATH; + ofn.nMaxFileTitle=MAX_PATH; + if(!save_file) + { + if(!GetOpenFileName(&ofn)) + { + delete [] str; + return NULL; + } + } + else + { + if(!GetSaveFileName(&ofn)) + { + delete [] str; + return NULL; + } + } + return str; +} + +void GetFolderPath(TCHAR *WindowTittle, char *szSetting) +{ + BROWSEINFO pbi = {0}; + pbi.lpszTitle = WindowTittle; + pbi.ulFlags = BIF_EDITBOX|BIF_NEWDIALOGSTYLE|BIF_SHAREABLE; + LPITEMIDLIST pidl = SHBrowseForFolder(&pbi); + if (pidl != 0) + { + TCHAR path[MAX_PATH]; + if (SHGetPathFromIDList(pidl, path)) + { + db_set_ts(NULL, szGPGModuleName, "szHomePath", path); + } + IMalloc * imalloc = 0; + if (SUCCEEDED(SHGetMalloc(&imalloc))) + { + imalloc->Free(pidl); + imalloc->Release(); + } + } +} + +INT_PTR LoadKey(WPARAM w, LPARAM l) +{ + void ShowLoadPublicKeyDialog(); + extern map user_data; + user_data[1] = (HANDLE)w; + ShowLoadPublicKeyDialog(); + return 0; +} + +INT_PTR SendKey(WPARAM w, LPARAM l) +{ + HANDLE hContact = (HANDLE)w; + if(metaIsProtoMetaContacts(hContact)) + hContact = metaGetMostOnline(hContact); + char *szMessage; + std::string key_id_str; + { + LPSTR proto = GetContactProto(hContact); + PROTOACCOUNT *acc = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)proto); + std::string acc_str; + if(acc) + { + acc_str = toUTF8(acc->tszAccountName); + acc_str += "("; + acc_str += acc->szModuleName; + acc_str += ")" ; + key_id_str = acc_str; + key_id_str += "_KeyID"; + acc_str += "_GPGPubKey"; + } + szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, acc_str.empty()?"GPGPubKey":acc_str.c_str(), ""); + if(!szMessage[0]) + { + mir_free(szMessage); + szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); //try to get default key as fallback in any way + } + } + if(szMessage[0]) + { + BYTE enc = db_get_b(hContact, szGPGModuleName, "GPGEncryption", 0); + db_set_b(hContact, szGPGModuleName, "GPGEncryption", 0); + CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)szMessage); + std::string msg = "Public key "; + char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, key_id_str.c_str(), ""); + if(!keyid[0]) + { + mir_free(keyid); + keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); + } + msg += keyid; + mir_free(keyid); + msg += " sent"; + mir_free(szMessage); + szMessage = mir_strdup(msg.c_str()); + HistoryLog(hContact, db_event(szMessage, 0, 0, DBEF_SENT)); + db_set_b(hContact, szGPGModuleName, "GPGEncryption", enc); + } + else + mir_free(szMessage); + return 0; +} + +extern HANDLE hLoadPublicKey; +extern HGENMENU hToggleEncryption, hSendKey; + +INT_PTR ToggleEncryption(WPARAM w, LPARAM l) +{ + HANDLE hContact = (HANDLE)w; + BYTE enc = 0; + if(metaIsProtoMetaContacts(hContact)) + enc = db_get_b(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0); + else + enc = db_get_b(hContact, szGPGModuleName, "GPGEncryption", 0); + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(MessageBox(0, TranslateT("Do you want to toggle encryption for all subcontacts ?"), TranslateT("Metacontact detected"), MB_YESNO) == IDYES) + { + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + db_set_b(hcnt, szGPGModuleName, "GPGEncryption", enc?0:1); + } + db_set_b(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); + } + } + else + db_set_b(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); + void setSrmmIcon(HANDLE hContact); + void setClistIcon(HANDLE hContact); + setSrmmIcon(hContact); + setClistIcon(hContact); + enc = enc?0:1; + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_NAME; + enc?mi.pszName="Turn off GPG encryption":mi.pszName="Turn on GPG encryption"; + Menu_ModifyItem(hToggleEncryption, &mi); + return 0; +} + +int OnPreBuildContactMenu(WPARAM w, LPARAM l) +{ + HANDLE hContact = (HANDLE)w; + if(metaIsProtoMetaContacts(hContact)) + hContact = metaGetMostOnline(hContact); + + { + CLISTMENUITEM mi2 = { sizeof(mi2) }; + LPSTR proto = GetContactProto(hContact); + PROTOACCOUNT *acc = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)proto); + std::string setting; + if(acc) + { + setting = toUTF8(acc->tszAccountName); + setting += "("; + setting += acc->szModuleName; + setting += ")" ; + setting += "_KeyID"; + } + char *keyid = keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, setting.c_str(), ""); + if(!keyid[0]) + { + mir_free(keyid); + keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); + } + TCHAR buf[128] = {0}; + mir_sntprintf(buf, 127 * sizeof(TCHAR), _T("%s: %s"), TranslateT("Send publick key"), toUTF16(keyid).c_str()); + mi2.ptszName = buf; + mi2.flags = CMIM_NAME | CMIF_TCHAR; + Menu_ModifyItem(hSendKey, &mi2); + } + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_NAME; + TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); + if(_tcslen(tmp) < 1) + { + db_unset(hContact, szGPGModuleName, "GPGEncryption"); + mi.flags += CMIM_FLAGS | CMIF_GRAYED; + } + else + mi.flags = CMIM_NAME | CMIM_FLAGS; + mi.pszName = db_get_b(hContact, szGPGModuleName, "GPGEncryption", 0)?"Turn off GPG encryption":"Turn on GPG encryption"; + Menu_ModifyItem(hToggleEncryption, &mi); + return 0; +} + + +list transfers; + +DWORD file_msg_state = -1; + +int onProtoAck(WPARAM w, LPARAM l) +{ + ACKDATA *ack=(ACKDATA*)l; + CCSDATA *ccs=(CCSDATA*)ack->lParam; + + if(ack->type == ACKTYPE_FILE) + { + switch(ack->result) + { + case ACKRESULT_DENIED: case ACKRESULT_FAILED: + break; + case ACKRESULT_SUCCESS: + { + PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->hProcess; + if((f->flags & PFTS_SENDING) != PFTS_SENDING) + { + TCHAR *filename = NULL; + if(f->flags & PFTS_UNICODE) + { + if(f->tszCurrentFile && f->tszCurrentFile[0]) + filename = mir_wstrdup(f->tszCurrentFile); + if(!filename) + return 0; + } + else + { + if(f->szCurrentFile && f->szCurrentFile[0]) + filename = mir_utf8decodeT(f->szCurrentFile); + if(!filename) + return 0; + } + if(_tcsstr(filename, _T(".gpg"))) //decrypt it + { //process encrypted file + if(!bFileTransfers && !bSameAction) + { + void ShowEncryptedFileMsgBox(); + ShowEncryptedFileMsgBox(); + } + if(!bFileTransfers && bSameAction) + return 0; + if(file_msg_state < 1) + return 0; + HistoryLog(ack->hContact, db_event("Recieved encrypted file, trying to decrypt", 0,0, 0)); + if(!boost::filesystem::exists(f->tszCurrentFile)) + return 0; + string out; + DWORD code; + pxResult result; + std::vector cmd; + cmd.push_back(L"-o"); + wstring file = filename; + wstring::size_type p1 = file.rfind(_T(".gpg")); + file.erase(p1, _tcslen(_T(".gpg"))); + if(boost::filesystem::exists(file)) + { + if(MessageBox(0, TranslateT("Target file exists, do you want to replace it ?"), TranslateT("Warning"), MB_YESNO) == IDNO) + return 0; + } + cmd.push_back(file); + boost::filesystem::remove(file); + extern TCHAR *password; + { // password + TCHAR *pass = NULL; + char *keyid = UniGetContactSettingUtf(ack->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 && bDebugLog) + debuglog<hContact, GCDNF_TCHAR))+" with password"); + } + else + { + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T("")); + if(_tcslen(pass) > 0 && bDebugLog) + debuglog<hContact, GCDNF_TCHAR))+" with password"); + } + if(_tcslen(pass) > 0) + { + cmd.push_back(L"--passphrase"); + cmd.push_back(pass); + } + else if(password) + { + if(bDebugLog) + debuglog<hContact, GCDNF_TCHAR))+" with password"); + cmd.push_back(L"--passphrase"); + cmd.push_back(password); + } + else if (bDebugLog) + debuglog<hContact, GCDNF_TCHAR))+" with out password"); + mir_free(pass); + mir_free(keyid); + } + cmd.push_back(L"-d"); + cmd.push_back(filename); + gpg_execution_params params(cmd); + params.out = &out; + params.code = &code; + params.result = &result; + if(!gpg_launcher(params, boost::posix_time::minutes(15))) + 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; + if(bDebugLog) + debuglog<hContact, GCDNF_TCHAR))+" password needed, trying to get one"); + 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); + if(metaIsProtoMetaContacts(ack->hContact)) + db_set_s(metaGetMostOnline(ack->hContact), szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); + else + db_set_s(ack->hContact, szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); + } + void ShowLoadKeyPasswordWindow(); + new_key_hcnt_mutex.lock(); + new_key_hcnt = ack->hContact; + ShowLoadKeyPasswordWindow(); + std::vector cmd2 = cmd; + if(password) + { + if(bDebugLog) + debuglog<hContact, GCDNF_TCHAR))); + std::vector tmp; + tmp.push_back(L"--passphrase"); + tmp.push_back(password); + cmd2.insert(cmd2.begin(), tmp.begin(), tmp.end()); + } + out.clear(); + gpg_execution_params params(cmd2); + //pxResult result; + params.out = &out; + params.code = &code; + params.result = &result; + if(!gpg_launcher(params, boost::posix_time::seconds(15))) + { + //boost::filesystem::remove(filename); + return 0; + } + if(result == pxNotFound) + { + //boost::filesystem::remove(filename); + return 0; + } + } + if(result == pxSuccess) + boost::filesystem::remove(filename); + mir_free(filename); + } + } + } + break; + } + } + else if(ack->type == ACKTYPE_MESSAGE) + { + extern std::list sent_msgs; + if(!sent_msgs.empty()) + { + if(ack->result == ACKRESULT_FAILED) + { + std::list::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess); + if(it != sent_msgs.end()) + { + HistoryLog(ack->hContact, db_event("Failed to send encrypted message", 0,0, 0)); + + } + } + else if(ack->result == ACKRESULT_SUCCESS) + { + std::list::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess); + if(it != sent_msgs.end()) + sent_msgs.erase(it); + } + } + } + return 0; +} + +std::wstring encrypt_file(HANDLE hContact, TCHAR *filename) +{ + string out; + DWORD code; + pxResult result; + HANDLE hcnt = metaIsProtoMetaContacts(hContact)?metaGetMostOnline(hContact):hContact; + std::vector cmd; + cmd.push_back(L"--batch"); + cmd.push_back(L"--tes"); + cmd.push_back(L"-r"); + char *keyid = UniGetContactSettingUtf(hcnt, szGPGModuleName, "KeyID", ""); + 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.push_back(szKeyid); + if(db_get_b(hcnt, szGPGModuleName, "bAlwaysTrust", 0)) + { + cmd.push_back(L"--trust-model"); + cmd.push_back(L"always"); + } + mir_free(szKeyid); + mir_free(keyid); + cmd.push_back(L"-o"); + TCHAR *temp = _tgetenv(_T("TEMP")); + cmd.push_back(wstring(temp) + L"\\" + file_out); + wstring path_out = temp; + path_out += _T("\\"); + path_out += file_out; + boost::filesystem::remove(path_out); + cmd.push_back(L"-e"); + cmd.push_back(filename); + gpg_execution_params params(cmd); + params.out = &out; + params.code = &code; + params.result = &result; + delete [] file_out; + if(!gpg_launcher(params, boost::posix_time::minutes(3))) + return 0; + if(out.find("There is no assurance this key belongs to the named user") != string::npos) + { + out.clear(); + if(MessageBox(0, TranslateT("We trying to encrypt with untrusted key, do you want to trust this key permanently ?"), TranslateT("Warning"), MB_YESNO) == IDYES) + { + db_set_b(hcnt, szGPGModuleName, "bAlwaysTrust", 1); + std::vector tmp; + tmp.push_back(L"--trust-model"); + tmp.push_back(L"always"); + cmd.insert(cmd.begin(), tmp.begin(), tmp.end()); + if(!gpg_launcher(params, boost::posix_time::minutes(3))) + return 0; + } + else + return 0; + } + return path_out; +} + +//from secureim partially +INT_PTR onSendFile(WPARAM w, LPARAM l) +{ + if(!bFileTransfers) + return CallService(MS_PROTO_CHAINSEND, w, l); + CCSDATA *ccs=(CCSDATA*)l; + if(isContactSecured(ccs->hContact)) + { + char *proto = GetContactProto(ccs->hContact); + DWORD uin = db_get_dw(ccs->hContact, proto, "UIN", 0); + bool cap_found = false, supported_proto = false; + if(uin) + { + char svc[64]; + strcpy(svc, proto); + strcat(svc, PS_ICQ_CHECKCAPABILITY); + if(ServiceExists(svc)) + { + supported_proto = true; + ICQ_CUSTOMCAP cap = {0}; + strcpy(cap.caps, "GPG FileTransfer"); + if(CallService(svc, (WPARAM)ccs->hContact, (LPARAM)&cap)) + cap_found = true; + } + } + else + { + TCHAR *jid = UniGetContactSettingUtf(ccs->hContact, proto, "jid", _T("")); + if(jid[0]) + { + extern list Accounts; + list::iterator end = Accounts.end(); + for(list::iterator p = Accounts.begin(); p != end; p++) + { + TCHAR *caps = (*p)->getJabberInterface()->Net()->GetResourceFeatures(jid); + if(caps) + { + supported_proto = true; + wstring str; + for(int i=0;;i++) + { + str.push_back(caps[i]); + if(caps[i] == '\0') + if(caps[i+1] == '\0') + break; + } + mir_free(caps); + if(str.find(_T("GPG_Encrypted_FileTransfers:0")) != string::npos) + cap_found = true; + } + } + } + } + if(supported_proto && !cap_found) + { + if(MessageBox(0, TranslateT("Capability to decrypt file not found on other side\nRecipient may be unable to decrypt file(s)\nDo you want to encrypt file(s) anyway?"), TranslateT("Filetransfer warning"), MB_YESNO) == IDNO) + return CallService(MS_PROTO_CHAINSEND, w, l); + } + if(!supported_proto) + { + if(MessageBox(0, TranslateT("Unable to check encryption support on other side\nRecipient may be unable to decrypt file(s)\nCurrently capability check supported only for ICQ and Jabber protocols.\nIt will work for any other proto if Miranda with new_gpg used on other side.\nDo you want to encrypt file(s) anyway?"), TranslateT("Filetransfer warning"), MB_YESNO) == IDNO) + return CallService(MS_PROTO_CHAINSEND, w, l); + } + HistoryLog(ccs->hContact, db_event(Translate("encrypting file for transfer"), 0, 0, DBEF_SENT)); + DWORD flags = (DWORD)ccs->wParam; //check for PFTS_UNICODE here + int i; +// if(flags & PFTS_UNICODE) //this does not work .... + if(StriStr(ccs->szProtoService, "/sendfilew")) + { + TCHAR **file=(TCHAR **)ccs->lParam; + for(i = 0; file[i]; i++) + { + if(!boost::filesystem::exists(file[i])) + 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); + } + } + else + { + char **file = (char**) ccs->lParam; + for(i = 0; file[i]; i++) + { + if(!boost::filesystem::exists(file[i])) + 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); + + } + } + } + return CallService(MS_PROTO_CHAINSEND, w, l); +} + + +void HistoryLog(HANDLE hContact, db_event evt) +{ + DBEVENTINFO Event = { sizeof(Event) }; + Event.szModule = szGPGModuleName; + Event.eventType = evt.eventType; + Event.flags = evt.flags; + if(!evt.timestamp) + Event.timestamp = (DWORD)time(NULL); + else + Event.timestamp = evt.timestamp; + Event.cbBlob = strlen((char*)evt.pBlob)+1; + Event.pBlob = (PBYTE)_strdup((char*)evt.pBlob); + db_event_add(hContact, &Event); +} + +static int ControlAddStringUtf(HWND ctrl, DWORD msg, const TCHAR *szString) +{ + int item = -1; + item = SendMessage(ctrl, msg, 0, (LPARAM)szString); + return item; +} + +int ComboBoxAddStringUtf(HWND hCombo, const TCHAR *szString, DWORD data) +{ + int item = ControlAddStringUtf(hCombo, CB_ADDSTRING, szString); + SendMessage(hCombo, CB_SETITEMDATA, item, data); + + return item; +} + + +int GetJabberInterface(WPARAM w, LPARAM l) //get interface for all jabber accounts, options later +{ + extern list Accounts; + void AddHandlers(); + int count = 0; + PROTOACCOUNT **accounts; + ProtoEnumAccounts(&count, &accounts); + list ::iterator p; + Accounts.clear(); + Accounts.push_back(new JabberAccount); + p = Accounts.begin(); + (*p)->setAccountNumber(0); + for(int i = 0; i < count; i++) //get only jabber accounts from all accounts + { + IJabberInterface *JIftmp = getJabberApi(accounts[i]->szModuleName); + int a = 0; + if(JIftmp) + { + (*p)->setJabberInterface(JIftmp); + if(accounts[i]->tszAccountName) + { + TCHAR* tmp = mir_tstrdup(accounts[i]->tszAccountName); + (*p)->setAccountName(tmp); + } + else + { + TCHAR *tmp = mir_a2t(accounts[i]->szModuleName); + (*p)->setAccountName(tmp); + } + (*p)->setAccountNumber(a); + a++; + Accounts.push_back(new JabberAccount); + p++; + } + } + Accounts.pop_back(); + AddHandlers(); + return 0; +} + +static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pUserData) +{ + HXML local_node = node; + for(int n = 0; n <= xi.getChildCount(node); n++) + { + LPCTSTR str = xi.getText(local_node); + LPCTSTR nodename = xi.getName(local_node); + LPCTSTR attr = xi.getAttrValue(local_node, _T("to")); + if(attr) + { + HANDLE hContact = ji->Sys()->ContactFromJID(attr); + if(hContact) + if(!isContactSecured(hContact)) + return FALSE; + } + if(str) + { + if(_tcsstr(str, _T("-----BEGIN PGP MESSAGE-----")) && _tcsstr(str, _T("-----END PGP MESSAGE-----"))) + { + wstring data = str; + xi.setText(local_node, _T("This message is encrypted.")); + wstring::size_type p1 = data.find(_T("-----BEGIN PGP MESSAGE-----")) + _tcslen(_T("-----BEGIN PGP MESSAGE-----")); + while(data.find(_T("Version: "), p1) != wstring::npos) + { + p1 = data.find(_T("Version: "), p1); + p1 = data.find(_T("\n"), p1); + } + while(data.find(_T("Comment: "), p1) != wstring::npos) + { + p1 = data.find(_T("Comment: "), p1); + p1 = data.find(_T("\n"), p1); + } + while(data.find(_T("Encoding: "), p1) != wstring::npos) + { + p1 = data.find(_T("Encoding: "), p1); + p1 = data.find(_T("\n"), p1); + } + p1+=3; + wstring::size_type p2 = data.find(_T("-----END PGP MESSAGE-----")); + wstring data2 = data.substr(p1, p2-p1-2); + strip_line_term(data2); + HXML encrypted_data = xi.addChild(node, _T("x"), data2.c_str()); + xi.addAttr(encrypted_data, _T("xmlns"), _T("jabber:x:encrypted")); + return FALSE; + } + } + if(bPresenceSigning && nodename) + { + if(_tcsstr(nodename, _T("status"))) + { + 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("\\tmp\\"); + path_out += file; + boost::filesystem::remove(path_out); + wfstream f(path_out.c_str(), std::ios::out); + f< cmd; + { + char *inkeyid; + { + char *proto = ji->Sys()->GetModuleName(); + char setting[64]; + strcpy(setting, proto); + strcat(setting, "_KeyID"); + inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, setting, ""); + if(!inkeyid[0]) + { + mir_free(inkeyid); + inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); + } + } + TCHAR *pass = NULL; + if(inkeyid[0]) + { + string dbsetting = "szKey_"; + dbsetting += inkeyid; + dbsetting += "_Password"; + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T("")); + if(pass[0] && bDebugLog) + debuglog< cmd; + cmd.push_back(L"--verify"); + cmd.push_back(L"-a"); + cmd.push_back(path_out); + cmd.push_back(status_file_out); + gpg_execution_params params(cmd); + pxResult result; + params.out = &out; + params.code = &code; + params.result = &result; + if(!gpg_launcher(params, boost::posix_time::seconds(15))) + { + return FALSE; + } + if(result == pxNotFound) + { + return FALSE; + } + boost::filesystem::remove(path_out); + boost::filesystem::remove(status_file_out); + 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 ? + string::size_type p1 = out.find("key ID ") + strlen("key ID "); + string::size_type p2 = out.find("\n", p1); + if(p1 != string::npos && p2 != string::npos) + { + HANDLE hContact = NULL; + { + extern list Accounts; + list ::iterator p = Accounts.begin(); + for(unsigned int i = 0; i < Accounts.size(); i++, p++) + { + if(!(*p)) + break; + hContact = (*p)->getJabberInterface()->Sys()->ContactFromJID(xi.getAttrValue(node, _T("from"))); + if(hContact) + hcontact_data[hContact].key_in_prescense = out.substr(p1, p2-p1-1).c_str(); + } + } + } + } + } + return FALSE; + } + } + } + } + local_node = xi.getChild(node, n); + } + return FALSE; +} + +static JABBER_HANDLER_FUNC MessageHandler(IJabberInterface *ji, HXML node, void *pUserData) +{ + return FALSE; +} + + + + +void AddHandlers() +{ + extern list Accounts; + list::iterator end = Accounts.end(); + for(list::iterator p = Accounts.begin(); p != end; p++) + { + if(!(*p)) + break; + if((*p)->getSendHandler() == INVALID_HANDLE_VALUE) + (*p)->setSendHandler((*p)->getJabberInterface()->Net()->AddSendHandler((JABBER_HANDLER_FUNC)SendHandler)); + if((*p)->getPrescenseHandler() == INVALID_HANDLE_VALUE) + (*p)->setPrescenseHandler((*p)->getJabberInterface()->Net()->AddPresenceHandler((JABBER_HANDLER_FUNC)PrescenseHandler)); +// if((*p)->getMessageHandler() == INVALID_HANDLE_VALUE) +// (*p)->setMessageHandler((*p)->getJabberInterface()->Net()->AddMessageHandler((JABBER_HANDLER_FUNC)MessageHandler, JABBER_MESSAGE_TYPE_ANY ,NULL,NULL)); + if(bAutoExchange) + { + (*p)->getJabberInterface()->Net()->RegisterFeature(_T("GPG_Key_Auto_Exchange:0"), _T("Indicates that gpg installed and configured to public key auto exchange (currently implemented in new_gpg plugin for Miranda IM and Miranda NG)")); + (*p)->getJabberInterface()->Net()->AddFeatures(_T("GPG_Key_Auto_Exchange:0\0\0")); + } + if(bFileTransfers) + { + (*p)->getJabberInterface()->Net()->RegisterFeature(_T("GPG_Encrypted_FileTransfers:0"), _T("Indicates that gpg installed and configured to encrypt files (currently implemented in new_gpg plugin for Miranda IM and Miranda NG)")); + (*p)->getJabberInterface()->Net()->AddFeatures(_T("GPG_Encrypted_FileTransfers:0\0\0")); + } + } +} + +bool isContactSecured(HANDLE hContact) +{ + BYTE gpg_enc = db_get_b(hContact, szGPGModuleName, "GPGEncryption", 0); + if(!gpg_enc) + { + if(bDebugLog) + debuglog< 0) + { + mir_free(key); + return true; + } + mir_free(key); + return false; +} + +bool isGPGKeyExist() +{ + TCHAR *id = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", _T("")); + char *key = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); + if(id[0] && key[0]) + { + mir_free(id); + mir_free(key); + return true; + } + mir_free(id); + mir_free(key); + return false; +} +bool isGPGValid() +{ + TCHAR *tmp; + bool gpg_exists = false, is_valid = true; + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("")); + if(_waccess(tmp, 0) != -1) + gpg_exists = true; + else + { + mir_free(tmp); + TCHAR *path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH); + char *mir_path = (char*)mir_alloc(MAX_PATH); + PathToAbsolute("\\", mir_path); + SetCurrentDirectoryA(mir_path); + tmp = mir_a2t(mir_path); + mir_free(mir_path); + //mir_realloc(path, (_tcslen(path)+64)*sizeof(TCHAR)); + TCHAR *gpg_path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH); + _tcscpy(gpg_path, tmp); + _tcscat(gpg_path, _T("\\GnuPG\\gpg.exe")); + mir_free(tmp); + if(_waccess(gpg_path, 0) != -1) + { + gpg_exists = true; + _tcscpy(path, _T("GnuPG\\gpg.exe")); + } + mir_free(gpg_path); + tmp = mir_tstrdup(path); + mir_free(path); + } + DWORD len = MAX_PATH; + if(gpg_exists) + { + db_set_ts(NULL, szGPGModuleName, "szGpgBinPath", tmp); + string out; + DWORD code; + std::vector cmd; + cmd.push_back(L"--version"); + gpg_execution_params params(cmd); + pxResult result; + params.out = &out; + params.code = &code; + params.result = &result; + gpg_valid = true; + gpg_launcher(params); + gpg_valid = false; + string::size_type p1 = out.find("(GnuPG) "); + if(p1 == string::npos) + is_valid = false; + } + mir_free(tmp); tmp = NULL; + if(!gpg_exists) + { + wstring path_ = _wgetenv(_T("APPDATA")); + path_ += _T("\\GnuPG"); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", (TCHAR*)path_.c_str()); + } + if(tmp) + mir_free(tmp); + return is_valid; +} + +#define NEWTSTR_MALLOC(A) (A==NULL)?NULL:strcpy((char*)mir_alloc(sizeof(char)*(strlen(A)+1)),A) + +const bool StriStr(const char *str, const char *substr) +{ + bool i = false; + char *str_up = NEWTSTR_MALLOC(str); + char *substr_up = NEWTSTR_MALLOC(substr); + + CharUpperBuffA(str_up, strlen(str_up)); + CharUpperBuffA(substr_up, strlen(substr_up)); + + if(strstr (str_up, substr_up)) + i = true; + + mir_free(str_up); + mir_free(substr_up); + + return i; +} + +bool IsOnline(HANDLE hContact) +{ + if(db_get_b(hContact, szGPGModuleName, "Status", 0) == ID_STATUS_OFFLINE) + return false; + return true; +} + +//from secureim +#include + +struct TFakeAckParams { + inline TFakeAckParams( HANDLE p1, HANDLE p2, LONG p3, LPCSTR p4 ) : + hEvent( p1 ), + hContact( p2 ), + id( p3 ), + msg( p4 ) + {} + + HANDLE hEvent; + HANDLE hContact; + LONG id; + LPCSTR msg; +}; + +int SendBroadcast( HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam ) { + ACKDATA ack; + memset(&ack,0,sizeof(ack)); + ack.cbSize = sizeof( ACKDATA ); + ack.szModule = GetContactProto(hContact);//szGPGModuleName; + ack.hContact = hContact; + ack.type = type; + ack.result = result; + ack.hProcess = (HANDLE)777;//hProcess; + ack.lParam = lParam; + return CallService( MS_PROTO_BROADCASTACK, 0, ( LPARAM )&ack ); +} + + + +unsigned __stdcall sttFakeAck( LPVOID param ) { + + TFakeAckParams* tParam = ( TFakeAckParams* )param; + WaitForSingleObject( tParam->hEvent, INFINITE ); + + Sleep( 100 ); + if ( tParam->msg == NULL ) + SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, ( HANDLE )tParam->id, 0 ); + else + SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, ( HANDLE )tParam->id, LPARAM( tParam->msg )); + + CloseHandle( tParam->hEvent ); + delete tParam; + + return 0; +} + + +int returnNoError(HANDLE hContact) { + HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + unsigned int tID; + CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttFakeAck, new TFakeAckParams(hEvent,hContact,777,0), 0, &tID) ); + SetEvent( hEvent ); + return 777; +} +// end from secureim + + + +string toUTF8(wstring str) +{ + string ustr; + try{ + utf8::utf16to8(str.begin(), str.end(), back_inserter(ustr)); + } + catch(const utf8::exception& e) + { + if(bDebugLog) + debuglog<> gen(rng, boost::uniform_int<>(0, chars.length()-1)); + for(int i = 0; i < length; ++i) + data += chars[gen()]; + return data; +} + +void send_encrypted_msgs_thread(HANDLE hContact) +{ + while(true) + { + char *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); + while(!isContactSecured(hContact)) + boost::this_thread::sleep(boost::posix_time::seconds(1)); + if(!hcontact_data[hContact].msgs_to_send.empty()) + { + boost::this_thread::sleep(boost::posix_time::seconds(1)); + list::iterator end = hcontact_data[hContact].msgs_to_send.end(); + extern std::list sent_msgs; + for(list::iterator p = hcontact_data[hContact].msgs_to_send.begin(); p != end; ++p) + { + sent_msgs.push_back((HANDLE)CallContactService(hContact, PSS_MESSAGE, PREF_UTF, (LPARAM)p->c_str())); + HistoryLog(hContact, db_event((char*)p->c_str(),0,0, DBEF_SENT)); + boost::this_thread::sleep(boost::posix_time::seconds(1)); + } + hcontact_data[hContact].msgs_to_send.clear(); + return; + } + else + return; + } +} + +string time_str() +{ + boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); + return (string)boost::posix_time::to_simple_string(now); +} + +int handleEnum(const char *szSetting, LPARAM lParam) +{ + if(!*(bool*)lParam && szSetting[0] && StriStr(szSetting, "tabsrmm")) + { + bool f = false, *found = (bool*)lParam; + f = !db_get_b(NULL, "PluginDisable", szSetting, 0); + if(f) + *found = f; + } + return 0; +} + +bool isTabsrmmUsed() +{ + DBCONTACTENUMSETTINGS enm = {0}; + bool found = false; + enm.lParam = (LPARAM)&found; + enm.pfnEnumProc = (DBSETTINGENUMPROC)&handleEnum; + enm.szModule = "PluginDisable"; + if(CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&enm) == -1) + return false; + + return found; +} + +void ExportGpGKeysFunc(int type) +{ + TCHAR *p = GetFilePath(_T("Choose file to export keys"), _T("*"), _T("Any file"), true); + if(!p || !p[0]) + { + delete [] p; + //TODO: handle error + return; + } + char *path = mir_t2a(p); + delete [] p; + std::ofstream file; + file.open(path, std::ios::trunc | std::ios::out); + mir_free(path); + int exported_keys = 0; + if(!file.is_open()) + return; //TODO: handle error + if(!type || type == 2) { + for(HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + char *k = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); + if(!k[0]) + { + mir_free(k); + continue; + } + std::string key = k; + mir_free(k); + + const char* proto = (const char*)GetContactProto(hContact); + std::string id = "Comment: login "; + const char * uid = (const char*)CallProtoService(proto, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = proto; + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs); + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + id += " contact_id "; + ZeroMemory(&dbv, sizeof(dbv)); + ZeroMemory(&dbcgs, sizeof(dbcgs)); + dbcgs.pValue = &dbv; + dbcgs.szModule = proto; + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + std::string::size_type p1 = key.find("-----BEGIN PGP PUBLIC KEY BLOCK-----"); + if(p1 == std::string::npos) + continue; + p1 += strlen("-----BEGIN PGP PUBLIC KEY BLOCK-----"); + p1 ++; + id += '\n'; + key.insert(p1, id); + file< cmd; + cmd.push_back(L"--batch"); + cmd.push_back(L"-export-secret-keys"); + cmd.push_back(L"-a"); + gpg_execution_params params(cmd); + params.out = &out; + params.code = &code; + params.result = &result; + gpg_launcher(params); //TODO: handle errors + { + file<szModuleName, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = accs[i]->szModuleName; + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs); + std::string id; + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + } + if(acc.length()) + { + const char * uid = (const char*)CallProtoService(acc.c_str(), PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + for(HANDLE hContact = db_find_first(acc.c_str()); hContact; hContact = db_find_next(hContact, acc.c_str())) { + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = acc.c_str(); + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); + std::string id; + bool found = false; + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == contact_id) + found = true; + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == contact_id) + found = true; + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + if(found) + { + wstring path; + std::vector cmd; + TCHAR *ptmp; + string output; + DWORD exitcode; + { + HANDLE hcnt = hContact; + ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + path = ptmp; + mir_free(ptmp); + mir_free(ptmp); + wstring rand = toUTF16(get_random(10)); + path += L"\\"; + path += rand; + boost::filesystem::remove(path); + wfstream f(path, std::ios::out); + f< output.find("<", s)) + s2 = output.find("<", s); + if(s2 != string::npos) + { + tmp2 = (char*)mir_alloc((output.substr(s,s2-s-1).length()+1) * sizeof(char)); + strcpy(tmp2, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + { + db_set_s(hContact, szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str()); + } + mir_free(tmp2); + if((s = output.find(")", s2)) == string::npos) + s = output.find(">", s2); + else if(s > output.find(">", s2)) + s = output.find(">", s2); + s2++; + if(output[s] == ')') + { + tmp2 = (char*)mir_alloc((output.substr(s2,s-s2).length()+1) * sizeof(char)); + strcpy(tmp2, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + db_set_s(hContact, szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str()); + mir_free(tmp2); + s+=3; + s2 = output.find(">", s); + tmp2 = (char*)mir_alloc((output.substr(s,s2-s).length()+1) * sizeof(char)); + strcpy(tmp2, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + db_set_s(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str()); + mir_free(tmp2); + } + else + { + tmp2 = (char*)mir_alloc((output.substr(s2,s-s2).length()+1) * sizeof(char)); + strcpy(tmp2, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + db_set_s(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp2); + } + } + db_set_b(hContact, szGPGModuleName, "GPGEncryption", 1); + db_set_ts(hContact, szGPGModuleName, "GPGPubKey", toUTF16(key).c_str()); + } + boost::filesystem::remove(path); + break; + } + } + } + key.clear(); + } + if(strstr(line, "-----END PGP PRIVATE KEY BLOCK-----")) + { + std::vector cmd; + TCHAR tmp2[MAX_PATH] = {0}; + TCHAR *ptmp; + string output; + DWORD exitcode; + { + ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + _tcscpy(tmp2, ptmp); + mir_free(ptmp); + _tcscat(tmp2, _T("\\")); + _tcscat(tmp2, _T("temporary_exported.asc")); + boost::filesystem::remove(tmp2); + wfstream f(tmp2, std::ios::out); + f< cmd; + TCHAR tmp2[MAX_PATH] = {0}; + string output; + DWORD exitcode; + cmd.push_back(L"--edit-key"); + cmd.push_back(key_id_global); + cmd.push_back(L"passwd"); + gpg_execution_params_pass params(cmd, old_pass, new_pass); + pxResult result; + params.out = &output; + params.code = &exitcode; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_passwd_change_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::minutes(10))) + { + gpg_thread.~thread(); + if(params.child) + boost::process::terminate(*(params.child)); + if(bDebugLog) + debuglog<path())) + { + if((i->path().filename().generic_string().length() == 10 && (i->path().filename().generic_string().find(".") == std::string::npos)) || + i->path().extension() == ".sig" || i->path().extension() == ".asc" || i->path().extension() == ".status") + boost::filesystem::remove(i->path()); + } + } + } +} \ No newline at end of file -- cgit v1.2.3