// Copyright © 2010 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 (DBGetContactSettingTString(hContact, szModule, szSetting, &dbv)) return _tcsdup(szDef); if(dbv.pszVal) szRes = _tcsdup(dbv.ptszVal); DBFreeVariant(&dbv); return szRes; } char* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, char* szDef) { DBVARIANT dbv = {DBVT_DELETED}; char* szRes; if (DBGetContactSettingString(hContact, szModule, szSetting, &dbv)) return _strdup(szDef); if(dbv.pszVal) szRes = _strdup(dbv.pszVal); DBFreeVariant(&dbv); return szRes; } char *date() { setlocale( LC_ALL, "C" ); static char d[11]; char *tmp = __DATE__, m[4], mn[3] = "01"; m[0]=tmp[0]; m[1]=tmp[1]; m[2]=tmp[2]; if(strstr(m,"Jan")) strcpy(mn,"01"); else if(strstr(m,"Feb")) strcpy(mn,"02"); else if(strstr(m,"Mar")) strcpy(mn,"03"); else if(strstr(m,"Apr")) strcpy(mn,"04"); else if(strstr(m,"May")) strcpy(mn,"05"); else if(strstr(m,"Jun")) strcpy(mn,"06"); else if(strstr(m,"Jul")) strcpy(mn,"07"); else if(strstr(m,"Aug")) strcpy(mn,"08"); else if(strstr(m,"Sep")) strcpy(mn,"09"); else if(strstr(m,"Oct")) strcpy(mn,"10"); else if(strstr(m,"Nov")) strcpy(mn,"11"); else if(strstr(m,"Dec")) strcpy(mn,"12"); d[0]=tmp[7]; d[1]=tmp[8]; d[2]=tmp[9]; d[3]=tmp[10]; d[4]='.'; d[5]=mn[0]; d[6]=mn[1]; d[7]='.'; if (tmp[4] == ' ') d[8] = '0'; else d[8]=tmp[4]; d[9]=tmp[5]; return d; } 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; DBWriteContactSettingTString(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)) { DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", path); } IMalloc * imalloc = 0; if (SUCCEEDED(SHGetMalloc(&imalloc))) { imalloc->Free(pidl); imalloc->Release(); } } } int LoadKey(WPARAM w, LPARAM l) { void ShowLoadPublicKeyDialog(); extern map user_data; extern int item_num; item_num = 0; //black magic here user_data[1] = (HANDLE)w; ShowLoadPublicKeyDialog(); return 0; } int SendKey(WPARAM w, LPARAM l) { HANDLE hContact = (HANDLE)w; if(metaIsProtoMetaContacts(hContact)) hContact = metaGetMostOnline(hContact); char *szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); if(strlen(szMessage) > 1) { BYTE enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)szMessage); HistoryLog(hContact, "Public key sent", EVENTTYPE_MESSAGE, DBEF_SENT); DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc); } mir_free(szMessage); return 0; } extern HANDLE hLoadPublicKey, hToggleEncryption; int ToggleEncryption(WPARAM w, LPARAM l) { HANDLE hContact = (HANDLE)w; BYTE enc = 0; if(metaIsProtoMetaContacts(hContact)) enc = DBGetContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0); else enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); { if(metaIsProtoMetaContacts(hContact)) { HANDLE hcnt = NULL; if(MessageBox(0, _T("Do you want to toggle encryption for all subcontacts ?"), _T("Metacontact detected"), MB_YESNO) == IDYES) { int count = metaGetContactsNum(hContact); for(int i = 0; i < count; i++) { hcnt = metaGetSubcontact(hContact, i); if(hcnt) DBWriteContactSettingByte(hcnt, szGPGModuleName, "GPGEncryption", enc?0:1); } } } else DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); } void setSrmmIcon(HANDLE hContact); void setClistIcon(HANDLE hContact); setSrmmIcon(hContact); setClistIcon(hContact); enc = enc?0:1; CLISTMENUITEM mi = {0}; mi.cbSize=sizeof(mi); mi.flags = CMIM_NAME; enc?mi.pszName="Turn off GPG encryption":mi.pszName="Turn on GPG encryption"; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi); return 0; } int OnPreBuildContactMenu(WPARAM w, LPARAM l) { HANDLE hContact = (HANDLE)w; if(metaIsProtoMetaContacts(hContact)) hContact = metaGetMostOnline(hContact); CLISTMENUITEM mi = {0}; mi.cbSize=sizeof(mi); mi.flags = CMIM_NAME; TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); if(_tcslen(tmp) < 1) { DBDeleteContactSetting(hContact, szGPGModuleName, "GPGEncryption"); mi.flags += CMIM_FLAGS | CMIF_GRAYED; } else mi.flags = CMIM_NAME | CMIM_FLAGS; mi.pszName = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)?"Turn off GPG encryption":"Turn on GPG encryption"; CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi); return 0; } list transfers; extern bool bFileTransfers; int onProtoAck(WPARAM w, LPARAM l) { if(!bFileTransfers) return 0; ACKDATA *ack=(ACKDATA*)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) { case ACKRESULT_DENIED: case ACKRESULT_FAILED: break; case ACKRESULT_SUCCESS: { 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(_waccess(f->tszCurrentFile, 0) == -1) { if(errno == ENOENT) return 0; } string out; DWORD code; pxResult result; wstring cmd = _T("-o "); wstring file = filename; wstring::size_type p1 = file.rfind(_T(".gpg")); file.erase(p1, _tcslen(_T(".gpg"))); 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) return 0; } DeleteFile(file.c_str()); file.insert(0, _T("\"")); file.insert(file.length(), _T("\" ")); cmd += file; 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<hContact, GCDNF_TCHAR)<<" with password\n"; } else { pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T("")); if(_tcslen(pass) > 0) debuglog<hContact, GCDNF_TCHAR)<<" with password\n"; } if(_tcslen(pass) > 0) { cmd += _T("--passphrase \""); cmd += pass; cmd += _T("\" "); } else if(password) { debuglog<hContact, GCDNF_TCHAR)<<" with password\n"; cmd += _T("--passphrase \""); cmd += password; cmd += _T("\" "); } else debuglog<hContact, GCDNF_TCHAR)<<" with out password\n"; mir_free(pass); mir_free(keyid); } 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::minutes(10))) { delete gpg_thread; debuglog<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(metaGetCurrent(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<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(10))) { delete gpg_thread; debuglog<hContact)) { TCHAR **file=(TCHAR **)ccs->lParam; int i; for(i = 0; file[i]; i++) { 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; wstring cmd = _T("--batch --yes -r "); char *keyid = UniGetContactSettingUtf(ccs->hContact, szGPGModuleName, "KeyID", ""); 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; mir_free(keyid); 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; debuglog<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; debuglog<append(readbuffer, 4096); } while (available>0); } void HistoryLog(HANDLE hContact, char *data, int event_type, int flags) { DBEVENTINFO Event = {0}; Event.cbSize = sizeof(Event); Event.szModule = szGPGModuleName; Event.eventType = event_type; Event.flags = flags; Event.timestamp = (DWORD)time(NULL); Event.cbBlob = strlen(data)+1; Event.pBlob = (PBYTE)_strdup(data); CallService(MS_DB_EVENT_ADD, (WPARAM)(HANDLE)hContact,(LPARAM)&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); 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+=2; wstring::size_type p2 = data.find(_T("-----END PGP MESSAGE-----")); HXML encrypted_data = xi.addChild(node, _T("x"), data.substr(p1, p2-p1).c_str()); xi.addAttr(encrypted_data, _T("xmlns"), _T("jabber:x:encrypted")); return FALSE; } } if(nodename) { if(_tcsstr(nodename, _T("status"))) { TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); wstring path_out = path_c; mir_free(path_c); path_out += _T("\\prescense_text"); DeleteFile(path_out.c_str()); wfstream f(path_out.c_str(), std::ios::out); f< 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_ERROR,0 ,0)); 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 Miranda IM plugin)")); (*p)->getJabberInterface()->Net()->AddFeatures(_T("GPG_Key_Auto_Exchange:0\0\0")); } } } bool isContactSecured(HANDLE hContact) { TCHAR *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); if(!key[0]) { mir_free(key); key = UniGetContactSettingUtf(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", _T("")); } if((DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0) > 0 || DBGetContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0) > 0) && (_tcslen(key) > 0)) { mir_free(key); return true; } mir_free(key); return false; } bool isContactHaveKey(HANDLE hContact) { TCHAR *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); if(_tcslen(key) > 0) { mir_free(key); return true; } mir_free(key); return false; } bool isGPGConfigured() { 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; } #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(DBGetContactSettingByte(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 = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); ack.hContact = hContact; ack.type = type; ack.result = result; ack.hProcess = 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; utf8::utf16to8(str.begin(), str.end(), back_inserter(ustr)); return ustr; } wstring toUTF16(string str) //convert as much as possible { wstring ustr; string tmpstr; utf8::replace_invalid(str.begin(), str.end(), back_inserter(tmpstr)); utf8::utf8to16(tmpstr.begin(), tmpstr.end(), back_inserter(ustr)); return ustr; } string get_random(int length) { string chars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); string data; boost::random_device rng; boost::variate_generator> 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(); for(list::iterator p = hcontact_data[hContact].msgs_to_send.begin(); p != end; ++p) { CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)p->c_str()); HistoryLog(hContact, (char*)p->c_str(), EVENTTYPE_MESSAGE, DBEF_SENT); boost::this_thread::sleep(boost::posix_time::seconds(1)); } 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); }