From 600b2da3d6e94cb4f0b78a82c66c6c324a8446ee Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Fri, 29 Oct 2010 04:39:53 +0300 Subject: modified: main.h modified: messages.cpp modified: options.cpp modified: utilities.cpp modified: utilities.h --- main.h | 3 +- messages.cpp | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- options.cpp | 2 +- utilities.cpp | 45 ++++++++++-- utilities.h | 2 + 5 files changed, 269 insertions(+), 8 deletions(-) diff --git a/main.h b/main.h index 1cc67c9..6478467 100644 --- a/main.h +++ b/main.h @@ -18,11 +18,12 @@ struct contact_data { - list msgs_to_tag, msgs_to_ignore; + list msgs_to_tag, msgs_to_ignore, msgs_to_send; string key_in_prescense; }; extern std::map hcontact_data; +extern bool bAutoExchange; #endif diff --git a/messages.cpp b/messages.cpp index a026bcc..12dede3 100644 --- a/messages.cpp +++ b/messages.cpp @@ -41,6 +41,116 @@ int RecvMsgSvc(WPARAM w, LPARAM l) wstring str = toUTF16(msg); wstring::size_type s1 = wstring::npos, s2 = wstring::npos; + if((str.find(_T("-----PGP KEY RESPONSE-----")) != wstring::npos) && !metaIsProtoMetaContacts(ccs->hContact)) + { + s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); + if(s1 != wstring::npos && s2 != wstring::npos) + { + s2 += _tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")); + DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", str.substr(s1,s2-s1).c_str()); + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); + { //gpg execute block + wstring 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")); + DeleteFile(tmp2); + wfstream f(tmp2, std::ios::out); + ptmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); + wstring new_key = ptmp; + mir_free(ptmp); + f< output.find("<", s)) + s2 = output.find("<", s); + tmp = new char [output.substr(s,s2-s-1).length()+1]; + strcpy(tmp, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", tmp); + mir_free(tmp); + 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] == ')') + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", tmp); + mir_free(tmp); + s+=3; + s2 = output.find(">", s); + tmp = new char [output.substr(s,s2-s).length()+1]; + strcpy(tmp, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", tmp); + mir_free(tmp); + } + else + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp); + } + DBWriteContactSettingByte(hContact, szGPGModuleName, "bAlwatsTrust", 1); + } + } + hcontact_data[hContact].msgs_to_ignore.push_back(msg); + return 1; + } + } if((str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")) != wstring::npos)) { s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); @@ -56,12 +166,12 @@ int RecvMsgSvc(WPARAM w, LPARAM l) if(metaIsSubcontact(hContact)) return CallService(MS_PROTO_CHAINRECV, w, l); //yet another metacontacts problem debuglog<<"info: "<<"received key from: "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n"; - void ShowNewKeyDialog(); s1 = 0; while((s1 = str.find(_T("\r"), s1)) != wstring::npos) { str.erase(s1, 1); } + void ShowNewKeyDialog(); if((str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")) != wstring::npos)) { s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); @@ -80,6 +190,62 @@ int RecvMsgSvc(WPARAM w, LPARAM l) ShowNewKeyDialog(); return CallService(MS_PROTO_CHAINRECV, w, l); } + if(bAutoExchange && strstr(msg, "-----PGP KEY REQUEST-----") && isGPGConfigured()) + { + char *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); + if(tmp[0]) + { + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + string str = "-----PGP KEY RESPONSE-----"; + str.append(tmp); + CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)str.c_str()); + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); + } + mir_free(tmp); + if(!isContactHaveKey(hContact) && bAutoExchange && isGPGConfigured()) + { + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + DWORD uin = DBGetContactSettingDword(hContact, proto, "UIN", 0); + if(uin) + { + if(ServiceExists("ICQ"PS_ICQ_CHECKCAPABILITY)) + { + ICQ_CUSTOMCAP cap = {0}; + strcpy(cap.caps, "GPG AutoExchange"); + if(CallService("ICQ"PS_ICQ_CHECKCAPABILITY, (WPARAM)hContact, (LPARAM)&cap)) + CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)"-----PGP KEY REQUEST-----"); + } + } + else + { + TCHAR *jid = UniGetContactSettingUtf(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) + { + 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_Key_Auto_Exchange:0")) != string::npos) + CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)"-----PGP KEY REQUEST-----"); + } + } + } + } + } + return 1; + } s1 = str.find(_T("-----BEGIN PGP MESSAGE-----")); s2 = str.find(_T("-----END PGP MESSAGE-----")); if((s2 != wstring::npos) && (s1 != wstring::npos)) @@ -377,7 +543,62 @@ int SendMsgSvc(WPARAM w, LPARAM l) hcontact_data[ccs->hContact].msgs_to_ignore.push_back((char*)ccs->lParam); return CallService(MS_PROTO_CHAINSEND, w, l); } - if(!DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)) + if(!isContactHaveKey(hContact) && bAutoExchange && !strstr(msg, "-----PGP KEY REQUEST-----") && !strstr(msg, "-----BEGIN PGP PUBLIC KEY BLOCK-----") && isGPGConfigured()) //TODO: add all mesages to list, and send after key exchange done, encrypted + { + void send_encrypted_msgs_thread(HANDLE hContact); + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + DWORD uin = DBGetContactSettingDword(hContact, proto, "UIN", 0); + if(uin) + { + if(ServiceExists("ICQ"PS_ICQ_CHECKCAPABILITY)) + { + ICQ_CUSTOMCAP cap = {0}; + strcpy(cap.caps, "GPG AutoExchange"); + if(CallService("ICQ"PS_ICQ_CHECKCAPABILITY, (WPARAM)hContact, (LPARAM)&cap)) + { + CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)"-----PGP KEY REQUEST-----"); + hcontact_data[hContact].msgs_to_ignore.push_back(msg); + hcontact_data[hContact].msgs_to_send.push_back(msg); + boost::thread *thr = new boost::thread(boost::bind(send_encrypted_msgs_thread, hContact)); + return returnNoError(hContact); + } + } + } + else + { + TCHAR *jid = UniGetContactSettingUtf(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) + { + 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_Key_Auto_Exchange:0")) != string::npos) + { + CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)"-----PGP KEY REQUEST-----"); + hcontact_data[hContact].msgs_to_ignore.push_back(msg); + hcontact_data[hContact].msgs_to_send.push_back(msg); + boost::thread *thr = new boost::thread(boost::bind(send_encrypted_msgs_thread, hContact)); + return returnNoError(hContact); + } + } + } + } + } + } + if(!isContactSecured(hContact)) return CallService(MS_PROTO_CHAINSEND, w, l); diff --git a/options.cpp b/options.cpp index a560168..22edd1c 100644 --- a/options.cpp +++ b/options.cpp @@ -390,7 +390,7 @@ static BOOL CALLBACK DlgProcGpgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA case PSN_APPLY: { - extern bool bDebugLog, bJabberAPI, bFileTransfers, bAutoExchange; + extern bool bDebugLog, bJabberAPI, bFileTransfers; bDebugLog = CheckStateStoreDB(hwndDlg, IDC_DEBUG_LOG, "bDebugLog"); if(bDebugLog) debuglog.init(); diff --git a/utilities.cpp b/utilities.cpp index 2dc210e..d281283 100644 --- a/utilities.cpp +++ b/utilities.cpp @@ -798,9 +798,9 @@ static JABBER_HANDLER_FUNC PrescenseHandler(IJabberInterface *ji, HXML node, voi void AddHandlers() { - extern list Accounts; - list ::iterator p = Accounts.begin(); - for(unsigned int i = 0; i < Accounts.size(); i++, p++) + extern list Accounts; + list::iterator end = Accounts.end(); + for(list::iterator p = Accounts.begin(); p != end; p++) { if(!(*p)) break; @@ -812,7 +812,6 @@ void AddHandlers() { (*p)->setPrescenseHandler((*p)->getJabberInterface()->Net()->AddPresenceHandler((JABBER_HANDLER_FUNC)PrescenseHandler)); } - extern bool bAutoExchange; 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)")); @@ -845,6 +844,21 @@ bool isContactHaveKey(HANDLE hContact) 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) @@ -956,3 +970,26 @@ string get_random(int length) data += chars[gen()]; return data; } + +void send_encrypted_msgs_thread(HANDLE hContact) +{ + while(true) + { + char *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); + if(!key[0]) + boost::this_thread::sleep(boost::posix_time::seconds(1)); + else if(!hcontact_data[hContact].msgs_to_send.empty()) + { + 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; + } +} \ No newline at end of file diff --git a/utilities.h b/utilities.h index 0971265..e055f18 100644 --- a/utilities.h +++ b/utilities.h @@ -28,6 +28,8 @@ void storeOutput(HANDLE ahandle, string *output); void HistoryLog(HANDLE hContact, char *data, int event_type, int flags); int ComboBoxAddStringUtf(HWND hCombo, const TCHAR *szString, DWORD data); bool isContactSecured(HANDLE hContact); +bool isContactHaveKey(HANDLE hContact); +bool isGPGConfigured(); const bool StriStr(const char *str, const char *substr); string toUTF8(wstring str); wstring toUTF16(string str); -- cgit v1.2.3