diff options
author | Gluzskiy Alexandr <sss123next@list.ru> | 2011-04-01 02:24:07 +0300 |
---|---|---|
committer | Gluzskiy Alexandr <sss123next@list.ru> | 2011-04-01 02:24:07 +0300 |
commit | a7823b56a5b08f81248e83804349bc8e9fc61206 (patch) | |
tree | 9d2e3a7a558498be03513c96c35796b948418115 | |
parent | b0e1bb306eec7f2d13ff385d4c1191646cc3e7f9 (diff) | |
parent | 8cdda41b119526a2741938d57b7e066e1697315b (diff) |
Merge branch 'new_gpg' into new_gpg_autoexchange
Conflicts:
messages.cpp
-rw-r--r-- | gpg_wrapper.cpp | 23 | ||||
-rw-r--r-- | gpg_wrapper.h | 1 | ||||
-rw-r--r-- | icons.cpp | 12 | ||||
-rw-r--r-- | init.cpp | 2 | ||||
-rw-r--r-- | main.cpp | 54 | ||||
-rw-r--r-- | main.h | 2 | ||||
-rw-r--r-- | messages.cpp | 1061 | ||||
-rw-r--r-- | metacontacts.cpp | 30 | ||||
-rw-r--r-- | metacontacts.h | 1 | ||||
-rw-r--r-- | new_gpg.rc | 18 | ||||
-rw-r--r-- | new_gpg.vcxproj | 12 | ||||
-rw-r--r-- | options.cpp | 7 | ||||
-rw-r--r-- | utilities.cpp | 324 |
13 files changed, 868 insertions, 679 deletions
diff --git a/gpg_wrapper.cpp b/gpg_wrapper.cpp index 3091566..3ed7f4a 100644 --- a/gpg_wrapper.cpp +++ b/gpg_wrapper.cpp @@ -18,12 +18,12 @@ //thx gpg module from Harald Treder, Zakhar V. Bardymov -boost::mutex gpg_mutex; +//boost::mutex gpg_mutex; -pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result) +pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess) { - gpg_mutex.lock(); +// gpg_mutex.lock(); if(!gpg_configured) return pxNotConfigured; extern logtofile debuglog; @@ -80,6 +80,7 @@ pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD if(errno == ENOENT) { mir_free(bin_path); + debuglog<<time_str()<<": GPG executable not found\n"; *result = pxNotFound; return pxNotFound; } @@ -99,8 +100,7 @@ pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD delete [] home_dir; } - debuglog<<time_str()<<": gpg in: "<<commandline; - + debuglog<<time_str()<<": gpg in: "<<commandline<<"\n"; success = CreateProcess(NULL, (TCHAR*)commandline.c_str(), NULL, NULL, TRUE, CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT, (void*)_T("LANGUAGE=en@quot\0LC_ALL=English\0"), NULL, &sinfo, &pri); @@ -110,11 +110,14 @@ pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD CloseHandle(writestdin); CloseHandle(newstdout); CloseHandle(readstdout); - gpg_mutex.unlock(); + debuglog<<time_str()<<": Failed to create process\n"; +// gpg_mutex.unlock(); *result = pxCreateProcessFailed; return pxCreateProcessFailed; } + hProcess = pri.hProcess; + inputpos=ainput; while (TRUE) @@ -147,16 +150,12 @@ pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD CloseHandle(writestdin); *result = pxSuccess; - gpg_mutex.unlock(); +// gpg_mutex.unlock(); return pxSuccess; } void pxEexcute_thread(void *param) { gpg_execution_params *params = (gpg_execution_params*)param; - pxResult result = pxExecute(params->cmd, params->useless, params->out, params->code, params->result); - if(result == pxNotFound) - { - debuglog<<time_str()<<": Gpg binary not found"; - } + pxResult result = pxExecute(params->cmd, params->useless, params->out, params->code, params->result, params->hProcess); } diff --git a/gpg_wrapper.h b/gpg_wrapper.h index d9a02c9..f9d6670 100644 --- a/gpg_wrapper.h +++ b/gpg_wrapper.h @@ -24,6 +24,7 @@ struct gpg_execution_params string *out;
LPDWORD code;
pxResult *result;
+ HANDLE hProcess;
};
void pxEexcute_thread(void *param);
@@ -81,9 +81,11 @@ void setClistIcon(HANDLE hContact) {
bool enabled = isContactSecured(hContact);
extern HANDLE g_hCLIcon;
- HANDLE hMC = metaGetContact(hContact);
+ HANDLE hMC = hContact;
+ if(metaIsProtoMetaContacts(hContact))
+ hMC = metaGetContact(hContact);
if(g_hCLIcon && enabled)
- { // обновить иконки в clist
+ {
HICON icon = IconLibGetIcon("secured");
IconExtraColumn iec = {0};
iec.cbSize = sizeof(iec);
@@ -102,9 +104,11 @@ void setClistIcon(HANDLE hContact) void setSrmmIcon(HANDLE hContact)
{
- hContact = metaGetCurrent(hContact);
+ hContact = metaGetMostOnline(hContact);
bool enabled = isContactSecured(hContact);
- HANDLE hMC = metaGetContact(hContact);
+ HANDLE hMC = hContact;
+ if(metaIsProtoMetaContacts(hContact))
+ hMC = metaGetContact(hContact);
if(ServiceExists(MS_MSG_MODIFYICON))
{ // обновить иконки в srmm
StatusIconData sid = {0};
@@ -42,7 +42,7 @@ std::map<HANDLE, contact_data> hcontact_data; PLUGININFOEX pluginInfo={
sizeof(PLUGININFOEX),
0,
- PLUGIN_MAKE_VERSION(0,0,0,10),
+ PLUGIN_MAKE_VERSION(0,0,0,11),
"new GPG encryption support plugin, based on code from old gpg plugin and secureim",
"sss",
"sss123next@list.ru",
@@ -94,6 +94,7 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -187,6 +188,7 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -255,6 +257,7 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -326,6 +329,7 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) { delete gpg_thread; + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -353,6 +357,7 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) { delete gpg_thread; + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -417,6 +422,7 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM if(!gpg_thread.timed_join(boost::posix_time::minutes(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted"; break; } @@ -447,6 +453,7 @@ static BOOL CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<"GPG execution timed out, aborted\n"; break; } @@ -581,7 +588,11 @@ static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP gpg_configured = true; boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + } gpg_configured = false; DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath"); string::size_type p1 = out.find("(GnuPG) "); @@ -697,7 +708,11 @@ static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP gpg_configured = true; boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + TerminateProcess(params.hProcess, 1); gpg_thread.~thread(); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + } gpg_configured = false; DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath"); string::size_type p1 = out.find("(GnuPG) "); @@ -781,7 +796,11 @@ static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP gpg_configured = true; boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + TerminateProcess(params.hProcess, 1); gpg_thread.~thread(); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + } gpg_configured = false; DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath"); string::size_type p1 = out.find("(GnuPG) "); @@ -870,6 +889,7 @@ static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP if(!gpg_thread.timed_join(boost::posix_time::minutes(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted"; gpg_configured = false; break; @@ -877,7 +897,6 @@ static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP gpg_configured = false; if(result == pxNotFound) break; - DeleteFile(path.c_str()); string::size_type p1 = 0; if((p1 = out.find("key ")) != string::npos) @@ -903,6 +922,7 @@ static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<"GPG execution timed out, aborted\n"; gpg_configured = false; break; @@ -1218,14 +1238,13 @@ static BOOL CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, if(!gpg_thread.timed_join(boost::posix_time::minutes(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); MessageBox(0, _T("GPG execution timed out, aborted"), _T(""), MB_OK); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } if(result == pxNotFound) - { - MessageBox(0, _T("Set path to gpg.exe first!"), _T("Warning"), MB_OK); break; - } } DeleteFile(path.c_str()); DestroyWindow(hwndDlg); @@ -1252,6 +1271,7 @@ static BOOL CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -1412,6 +1432,7 @@ static BOOL CALLBACK DlgProcLoadExistingKey(HWND hwndDlg,UINT msg,WPARAM wParam, if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -1519,6 +1540,7 @@ static BOOL CALLBACK DlgProcLoadExistingKey(HWND hwndDlg,UINT msg,WPARAM wParam, if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; break; } @@ -1628,6 +1650,7 @@ static BOOL CALLBACK DlgProcImportKeyDialog(HWND hwndDlg, UINT msg, WPARAM wPara if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; } MessageBoxA(0, out.c_str(), "GPG output", MB_OK); @@ -1748,12 +1771,18 @@ void InitCheck() if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; return; } if(result == pxNotFound) return; } + TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + wstring tmp_dir = home_dir; + mir_free(home_dir); + tmp_dir += _T("\\tmp"); + _wmkdir(tmp_dir.c_str()); string question = "Your secret key whith id: "; char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); question += keyid; @@ -1811,7 +1840,7 @@ void ImportKey() } } else - DBWriteContactSettingTString(metaGetCurrent(hContact), szGPGModuleName, "GPGPubKey", new_key.c_str()); + DBWriteContactSettingTString(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", new_key.c_str()); } else DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", new_key.c_str()); @@ -1831,7 +1860,7 @@ void ImportKey() DeleteFile(tmp2); wfstream f(tmp2, std::ios::out); if(metaIsProtoMetaContacts(hContact)) - ptmp = UniGetContactSettingUtf(metaGetCurrent(hContact), szGPGModuleName, "GPGPubKey", _T("")); + ptmp = UniGetContactSettingUtf(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", _T("")); else ptmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); wstring new_key = ptmp; @@ -1854,6 +1883,7 @@ void ImportKey() if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; return; } @@ -1930,7 +1960,7 @@ void ImportKey() char *tmp = NULL; string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); string::size_type s2 = output.find(":", s); - DBWriteContactSettingString(metaGetCurrent(hContact), szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); s2+=2; s = output.find("“", s2); if(s == string::npos) @@ -1947,7 +1977,7 @@ void ImportKey() 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(metaGetCurrent(hContact), szGPGModuleName, "KeyMainName", tmp); + DBWriteContactSettingString(metaGetContact(hContact), szGPGModuleName, "KeyMainName", tmp); mir_free(tmp); if((s = output.find(")", s2)) == string::npos) s = output.find(">", s2); @@ -1959,14 +1989,14 @@ void ImportKey() tmp = new char [output.substr(s2,s-s2).length()+1]; strcpy(tmp, output.substr(s2,s-s2).c_str()); mir_utf8decode(tmp, 0); - DBWriteContactSettingString(metaGetCurrent(hContact), szGPGModuleName, "KeyComment", tmp); + DBWriteContactSettingString(metaGetMostOnline(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(metaGetCurrent(hContact), szGPGModuleName, "KeyMainEmail", tmp); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", tmp); mir_free(tmp); } else @@ -1974,10 +2004,10 @@ void ImportKey() tmp = new char [output.substr(s2,s-s2).length()+1]; strcpy(tmp, output.substr(s2,s-s2).c_str()); mir_utf8decode(tmp, 0); - DBWriteContactSettingString(metaGetCurrent(hContact), szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); mir_free(tmp); } - DBDeleteContactSetting(metaGetCurrent(hContact), szGPGModuleName, "bAlwatsTrust"); + DBDeleteContactSetting(metaGetMostOnline(hContact), szGPGModuleName, "bAlwatsTrust"); } } else @@ -18,7 +18,7 @@ struct contact_data
{
- list<string> msgs_to_tag, msgs_to_ignore, msgs_to_send;
+ list<string> msgs_to_send, msgs_to_pass;
string key_in_prescense;
};
diff --git a/messages.cpp b/messages.cpp index 40db55c..ee80e2f 100644 --- a/messages.cpp +++ b/messages.cpp @@ -1,4 +1,4 @@ -// Copyright © 2010-2011 sss +// Copyright пїЅ 2010-2011 sss // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -23,236 +23,12 @@ boost::mutex new_key_hcnt_mutex; bool _terminate = false; int returnNoError(HANDLE hContact); -int RecvMsgSvc(WPARAM w, LPARAM l) -{ - CCSDATA *ccs = (CCSDATA*)l; - if (!ccs) - return CallService(MS_PROTO_CHAINRECV, w, l); - PROTORECVEVENT *pre = (PROTORECVEVENT*)(ccs->lParam); - if (!pre) - return CallService(MS_PROTO_CHAINRECV, w, l); - char *msg = pre->szMessage; - if (!msg) - return CallService(MS_PROTO_CHAINRECV, w, l); - HANDLE hContact = ccs->hContact; - +int RecvMsgSvc_func(HANDLE hContact, std::wstring str, char *msg, DWORD flags) +{ + DWORD dbflags = DBEF_UTF; { //check for gpg related data - 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<<new_key.c_str(); - f.close(); - cmd += _T(" --batch "); - cmd += _T(" --import \""); - cmd += tmp2; - cmd += _T("\""); - } - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &output; - params.code = &exitcode; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return 1; - } - if(result == pxNotFound) - return 1; - { - char *tmp = NULL; - string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); - string::size_type s2 = output.find(":", s); - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); - s2+=2; - s = output.find("“", s2); - if(s == string::npos) - { - s = output.find("\"", s2); - s += 1; - } - else - s += 3; - if((s2 = output.find("(", s)) == string::npos) - s2 = output.find("<", s); - else if(s2 > 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); - void setSrmmIcon(HANDLE); - void setClistIcon(HANDLE); - setSrmmIcon(hContact); - setClistIcon(hContact); - if(metaIsSubcontact(hContact)) - { - setSrmmIcon(metaGetContact(hContact)); - setClistIcon(metaGetContact(hContact)); - HistoryLog(metaGetContact(hContact), "PGP Encryption turned on by key autoexchange feature", EVENTTYPE_MESSAGE, 0); - } - HistoryLog(hContact, "PGP Encryption turned on by key autoexchange feature", EVENTTYPE_MESSAGE, 0); - } - } - 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-----")); - s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); - } - else if((str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")) != wstring::npos)) - { - s2 = str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")); - s1 = str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")); - } - if((s2 != wstring::npos) && (s1 != wstring::npos)) - { //this is public key - if(metaIsSubcontact(hContact)) - return CallService(MS_PROTO_CHAINRECV, w, l); //yet another metacontacts problem - debuglog<<time_str()<<": info: "<<"received key from: "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n"; - 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-----")); - s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); - s2 += _tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")); - } - else if((str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")) != wstring::npos)) - { - s2 = str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")); - s1 = str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")); - s2 += _tcslen(_T("-----END PGP PRIVATE KEY BLOCK-----")); - } - new_key.append(str.substr(s1,s2-s1)); - new_key_hcnt_mutex.lock(); - new_key_hcnt = hContact; - 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 <JabberAccount*> Accounts; - list<JabberAccount*>::iterator end = Accounts.end(); - for(list<JabberAccount*>::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)0, (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)) @@ -260,7 +36,7 @@ int RecvMsgSvc(WPARAM w, LPARAM l) void setSrmmIcon(HANDLE); void setClistIcon(HANDLE); bool isContactHaveKey(HANDLE hContact); - if(!DBGetContactSettingByte(metaGetCurrent(hContact), szGPGModuleName, "GPGEncryption", 0)) + if(!DBGetContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0)) { debuglog<<time_str()<<": info: "<<"received message from: "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<" whith tyrned off encryption\n"; if(bAutoExchange) @@ -300,19 +76,22 @@ int RecvMsgSvc(WPARAM w, LPARAM l) } else { - DBWriteContactSettingByte(metaGetCurrent(hContact), szGPGModuleName, "GPGEncryption", 1); + DBWriteContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 1); setSrmmIcon(hContact); setClistIcon(hContact); } if(isContactHaveKey(hContact)) { - DBWriteContactSettingByte(metaGetCurrent(hContact), szGPGModuleName, "GPGEncryption", 1); + DBWriteContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 1); setSrmmIcon(hContact); setClistIcon(hContact); } } else if(MessageBox(0, _T("Do you want try to decrypt encrypted message ?"), _T("Warning"), MB_YESNO) == IDNO) - return CallService(MS_PROTO_CHAINRECV, w, l); + { + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; + } } { wstring::size_type p = 0; @@ -323,9 +102,14 @@ int RecvMsgSvc(WPARAM w, LPARAM l) char *tmp = mir_t2a(str.substr(s1,s2-s1).c_str()); TCHAR *tmp2 = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); wstring path = tmp2; - path.append(_T("\\encrypted_data.asc")); + wstring encfile = toUTF16(get_random(10)); + wstring decfile = toUTF16(get_random(10)); + path.append(_T("\\tmp\\")); + path.append(encfile); DeleteFile(path.c_str()); fstream f(path.c_str(), std::ios::out); + while(!f.is_open()) + f.open(path.c_str(), std::ios::out); f<<tmp; mir_free(tmp); f.close(); @@ -336,7 +120,7 @@ int RecvMsgSvc(WPARAM w, LPARAM l) wstring cmd; cmd += _T("--batch "); { - char *inkeyid = UniGetContactSettingUtf(metaGetCurrent(hContact), szGPGModuleName, "InKeyID", ""); + char *inkeyid = UniGetContactSettingUtf(metaGetMostOnline(hContact), szGPGModuleName, "InKeyID", ""); TCHAR *pass = NULL; if(strlen(inkeyid) > 0) { @@ -373,12 +157,15 @@ int RecvMsgSvc(WPARAM w, LPARAM l) } { wstring path = tmp2; - path += _T("\\decrypted_data"); + path += _T("\\tmp\\"); + path += decfile; DeleteFile(path.c_str()); } cmd += _T("--output \""); cmd += tmp2; - cmd += _T("\\decrypted_data\""); + cmd += _T("\\tmp\\"); + cmd += decfile; + cmd += _T("\""); cmd += _T(" -d -a \""); cmd += path; cmd += _T("\""); @@ -393,14 +180,17 @@ int RecvMsgSvc(WPARAM w, LPARAM l) if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) { delete gpg_thread; + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; DeleteFile(path.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, l); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } if(result == pxNotFound) { DeleteFile(path.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, l); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } _terminate = false; while(out.find("public key decryption failed: bad passphrase") != string::npos) @@ -413,7 +203,7 @@ int RecvMsgSvc(WPARAM w, LPARAM l) s = out.find(" ID ", s); s += strlen(" ID "); string::size_type s2 = out.find(",",s); - DBWriteContactSettingString(metaGetCurrent(hContact), szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); } void ShowLoadKeyPasswordWindow(); new_key_hcnt_mutex.lock(); @@ -440,14 +230,17 @@ int RecvMsgSvc(WPARAM w, LPARAM l) if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) { delete gpg_thread; + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; DeleteFile(path.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, l); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } if(result == pxNotFound) { DeleteFile(path.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, l); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } } out.clear(); @@ -455,45 +248,48 @@ int RecvMsgSvc(WPARAM w, LPARAM l) if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) { delete gpg_thread; + TerminateProcess(params.hProcess, 1); debuglog<<time_str()<<": GPG execution timed out, aborted\n"; DeleteFile(path.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, l); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } if(result == pxNotFound) { DeleteFile(path.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, l); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); } { wstring tmp = tmp2; - tmp += _T("\\encrypted_data.asc"); + tmp += _T("\\tmp\\"); + tmp += encfile; DeleteFile(tmp.c_str()); } { wstring tmp = tmp2; - tmp += _T("\\decrypted_data"); + tmp += _T("\\tmp\\"); + tmp += decfile; if(_waccess(tmp.c_str(), 0) == -1) { if(errno == ENOENT) { - string str = pre->szMessage; - mir_free((void**)pre->szMessage); + string str = msg; str.insert(0, "Received unencrypted message:\n"); debuglog<<time_str()<<": info: Failed to decrypt GPG encrypted message.\n"; char *tmp = new char [str.length()+1]; strcpy(tmp, str.c_str()); - pre->szMessage = tmp; - return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); + HistoryLog(hContact, tmp, EVENTTYPE_MESSAGE, dbflags); + mir_free(tmp); + return 0; } } } - - str.clear(); { wstring path = tmp2; mir_free(tmp2); - path += _T("\\decrypted_data"); + path += _T("\\tmp\\"); + path += decfile; fstream f(path.c_str(), std::ios::in | std::ios::ate | std::ios::binary); if(f.is_open()) { @@ -510,12 +306,13 @@ int RecvMsgSvc(WPARAM w, LPARAM l) } if(str.empty()) { - string str = pre->szMessage; - mir_free((void**)pre->szMessage); + string str = msg; str.insert(0, "Failed to decrypt GPG encrypted message.\nMessage body for manual decryption:\n"); debuglog<<time_str()<<": info: Failed to decrypt GPG encrypted message.\n"; - pre->szMessage = mir_strdup(str.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); + char *tmp = mir_strdup(str.c_str()); + HistoryLog(hContact, tmp, EVENTTYPE_MESSAGE, dbflags); + mir_free(tmp); + return 0; } else { @@ -527,207 +324,362 @@ int RecvMsgSvc(WPARAM w, LPARAM l) if(metaIsSubcontact(hContact)) { char *msg = mir_strdup(toUTF8(str).c_str()); - HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, DBEF_UTF|DBEF_READ); - HistoryLog(metaGetContact(hContact), msg, EVENTTYPE_MESSAGE, DBEF_UTF); - mir_free(msg); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags|DBEF_READ); + HistoryLog(metaGetContact(hContact), msg, EVENTTYPE_MESSAGE, dbflags); return 1; } - mir_free((void**)pre->szMessage); - pre->szMessage = mir_strdup(toUTF8(str).c_str()); - return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); + char *tmp = mir_strdup(toUTF8(str).c_str()); + HistoryLog(hContact, tmp, EVENTTYPE_MESSAGE, dbflags); + mir_free(tmp); + return 0; } } } } } - if(DBGetContactSettingByte(metaGetCurrent(hContact), szGPGModuleName, "GPGEncryption", 0)) + if(DBGetContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0)) { if(metaIsSubcontact(hContact)) { - HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, DBEF_UTF| DBEF_READ); - HistoryLog(metaGetContact(hContact), msg, EVENTTYPE_MESSAGE, DBEF_UTF); - mir_free(msg); - return 1; + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags| DBEF_READ); + HistoryLog(metaGetContact(hContact), msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } - string str = msg; - mir_free((void**)pre->szMessage); - str.insert(0, "Received unencrypted message:\n"); - pre->szMessage = mir_strdup(str.c_str()); - return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags|DBEF_READ); + return 0; } - return CallService(MS_PROTO_CHAINRECV, w, l); + HistoryLog(hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } -int SendMsgSvc(WPARAM w, LPARAM l) +int RecvMsgSvc(WPARAM w, LPARAM l) { CCSDATA *ccs = (CCSDATA*)l; if (!ccs) - return CallService(MS_PROTO_CHAINSEND, w, l); - - char *msg = (char*)(ccs->lParam); + return CallService(MS_PROTO_CHAINRECV, w, l); + PROTORECVEVENT *pre = (PROTORECVEVENT*)(ccs->lParam); + if (!pre) + return CallService(MS_PROTO_CHAINRECV, w, l); + char *msg = pre->szMessage; if (!msg) - return CallService(MS_PROTO_CHAINSEND, w, l); - if(strstr(msg,"-----BEGIN PGP MESSAGE-----")) //metecontacts .... %) - return CallService(MS_PROTO_CHAINSEND, w, l); - HANDLE hContact = ccs->hContact; - if(metaIsProtoMetaContacts(hContact)) - { - hcontact_data[ccs->hContact].msgs_to_ignore.push_back((char*)ccs->lParam); - return CallService(MS_PROTO_CHAINSEND, w, l); - } - if(!isContactHaveKey(hContact) && bAutoExchange && !strstr(msg, "-----PGP KEY REQUEST-----") && !strstr(msg, "-----BEGIN PGP PUBLIC KEY BLOCK-----") && isGPGConfigured()) + return CallService(MS_PROTO_CHAINRECV, w, l); + wstring str = toUTF16(msg); + wstring::size_type s1 = wstring::npos, s2 = wstring::npos; + DWORD dbflags = DBEF_UTF; + if((str.find(_T("-----PGP KEY RESPONSE-----")) != wstring::npos) && !metaIsProtoMetaContacts(ccs->hContact)) { - 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) + 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) { - 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)) + s2 += _tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")); + DBWriteContactSettingTString(ccs->hContact, szGPGModuleName, "GPGPubKey", str.substr(s1,s2-s1).c_str()); + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "GPGEncryption", 1); + { //gpg execute block + wstring cmd; + TCHAR tmp2[MAX_PATH] = {0}; + TCHAR *ptmp; + string output; + DWORD exitcode; { - 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); + 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); + while(!f.is_open()) + f.open(tmp2, std::ios::out); + ptmp = UniGetContactSettingUtf(ccs->hContact, szGPGModuleName, "GPGPubKey", _T("")); + wstring new_key = ptmp; + mir_free(ptmp); + f<<new_key.c_str(); + f.close(); + cmd += _T(" --batch "); + cmd += _T(" --import \""); + cmd += tmp2; + cmd += _T("\""); } - } - } - else - { - TCHAR *jid = UniGetContactSettingUtf(hContact, proto, "jid", _T("")); - if(jid[0]) - { - extern list <JabberAccount*> Accounts; - list<JabberAccount*>::iterator end = Accounts.end(); - for(list<JabberAccount*>::iterator p = Accounts.begin(); p != end; p++) + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &output; + params.code = &exitcode; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) { - TCHAR *caps = (*p)->getJabberInterface()->Net()->GetResourceFeatures(jid); - if(caps) + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + return 1; + } + if(result == pxNotFound) + return 1; + { + char *tmp = NULL; + string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); + string::size_type s2 = output.find(":", s); + DBWriteContactSettingString(ccs->hContact, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); + s2+=2; + s = output.find("“", s2); + if(s == string::npos) { - 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); - } + s = output.find("\"", s2); + s += 1; } + else + s += 3; + if((s2 = output.find("(", s)) == string::npos) + s2 = output.find("<", s); + else if(s2 > 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(ccs->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(ccs->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(ccs->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(ccs->hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp); + } + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "bAlwatsTrust", 1); + void setSrmmIcon(HANDLE); + void setClistIcon(HANDLE); + setSrmmIcon(ccs->hContact); + setClistIcon(ccs->hContact); + if(metaIsSubcontact(ccs->hContact)) + { + setSrmmIcon(metaGetContact(ccs->hContact)); + setClistIcon(metaGetContact(ccs->hContact)); + HistoryLog(metaGetContact(ccs->hContact), "PGP Encryption turned on by key autoexchange feature", EVENTTYPE_MESSAGE, 0); + } + HistoryLog(ccs->hContact, "PGP Encryption turned on by key autoexchange feature", EVENTTYPE_MESSAGE, 0); + } } + return 1; } } - } - if(!isContactSecured(hContact)) - return CallService(MS_PROTO_CHAINSEND, w, l); - - { //encrypt data here - wstring str; - bool isansi = false; - if(!metaIsSubcontact(hContact)) - str = toUTF16(msg); - else - {//workaround ... - wchar_t *tmp = mir_utf8decodeW(msg); - if(!tmp) - { - tmp = mir_a2t(msg); - isansi = true; - } - str.append(tmp); - mir_free(tmp); + 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-----")); + s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); } + else if((str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")) != wstring::npos)) { - string out; - DWORD code; - wstring cmd; - wstring path; - extern bool bJabberAPI, bIsMiranda09; - char *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID", ""); - if(!tmp[0]) + s2 = str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")); + } + if((s2 != wstring::npos) && (s1 != wstring::npos)) + { //this is public key + if(metaIsSubcontact(ccs->hContact)) { - mir_free(tmp); - HistoryLog(hContact, "Failed to encrypt message with GPG", EVENTTYPE_MESSAGE, DBEF_SENT); - return CallService(MS_PROTO_CHAINSEND, w, l); + HistoryLog(ccs->hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; } - if(!bJabberAPI || !bIsMiranda09) //force jabber to handle encrypted message by itself - cmd += _T("--comment \"\" --no-version "); - if(DBGetContactSettingByte(hContact, szGPGModuleName, "bAlwaysTrust", 0)) - cmd += _T("--trust-model always "); - cmd += _T("--batch --yes -e -a -r "); - TCHAR *tmp2 = mir_a2t(tmp); - mir_free(tmp); - cmd += tmp2; - mir_free(tmp2); - cmd += _T(" \""); - tmp2 = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - path.append(tmp2); - cmd += tmp2; - mir_free(tmp2); - cmd += _T("\\exported_data"); - path.append(_T("\\exported_data")); - cmd += _T("\""); + debuglog<<time_str()<<": info: "<<"received key from: "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ccs->hContact, GCDNF_TCHAR)<<"\n"; + s1 = 0; + while((s1 = str.find(_T("\r"), s1)) != wstring::npos) { - char *tmp; - tmp = mir_strdup(toUTF8(str).c_str()); - fstream f(path.c_str(), std::ios::out); - f<<tmp; - mir_free(tmp); - f.close(); + str.erase(s1, 1); } - 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(10))) + void ShowNewKeyDialog(); + if((str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")) != wstring::npos)) { - gpg_thread.~thread(); - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return CallService(MS_PROTO_CHAINSEND, w, l); + s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); + s2 += _tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")); } - if(result == pxNotFound) - return CallService(MS_PROTO_CHAINSEND, w, l); - if(out.find("There is no assurance this key belongs to the named user") != string::npos) + else if((str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")) != wstring::npos)) { - out.clear(); - if(bAutoExchange) + s2 = str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")); + s2 += _tcslen(_T("-----END PGP PRIVATE KEY BLOCK-----")); + } + new_key.append(str.substr(s1,s2-s1)); + new_key_hcnt_mutex.lock(); + new_key_hcnt = ccs->hContact; + ShowNewKeyDialog(); + HistoryLog(ccs->hContact, msg, EVENTTYPE_MESSAGE, dbflags); + return 0; + } + if(bAutoExchange && strstr(msg, "-----PGP KEY REQUEST-----") && isGPGConfigured()) + { + char *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); + if(tmp[0]) + { + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "GPGEncryption", 0); + string str = "-----PGP KEY RESPONSE-----"; + str.append(tmp); + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)str.c_str()); + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "GPGEncryption", 1); + } + mir_free(tmp); + if(!isContactHaveKey(ccs->hContact) && bAutoExchange && isGPGConfigured()) + { + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); + DWORD uin = DBGetContactSettingDword(ccs->hContact, proto, "UIN", 0); + if(uin) { - DBWriteContactSettingByte(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(10))) + if(ServiceExists("ICQ"PS_ICQ_CHECKCAPABILITY)) { - gpg_thread.~thread(); - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return CallService(MS_PROTO_CHAINSEND, w, l); + ICQ_CUSTOMCAP cap = {0}; + strcpy(cap.caps, "GPG AutoExchange"); + if(CallService("ICQ"PS_ICQ_CHECKCAPABILITY, (WPARAM)ccs->hContact, (LPARAM)&cap)) + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)"-----PGP KEY REQUEST-----"); } - if(result == pxNotFound) - return CallService(MS_PROTO_CHAINSEND, w, l); } - else if(MessageBox(0, _T("We trying to encrypt with untrusted key, do you want to trust this key permanently ?"), _T("Warning"), MB_YESNO) == IDYES) + else + { + TCHAR *jid = UniGetContactSettingUtf(ccs->hContact, proto, "jid", _T("")); + if(jid[0]) + { + extern list <JabberAccount*> Accounts; + list<JabberAccount*>::iterator end = Accounts.end(); + for(list<JabberAccount*>::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(ccs->hContact, PSS_MESSAGE, (WPARAM)0, (LPARAM)"-----PGP KEY REQUEST-----"); + } + } + } + } + } + return 1; + } + if(!(strstr(msg, "-----BEGIN PGP MESSAGE-----") && strstr(msg, "-----END PGP MESSAGE-----"))) + return CallService(MS_PROTO_CHAINRECV, w, l); + boost::thread *thr = new boost::thread(boost::bind(RecvMsgSvc_func, ccs->hContact, str, msg, ccs->wParam)); + return returnNoError(ccs->hContact); +} + +int SendMsgSvc_func(HANDLE hContact, char *msg, DWORD flags) +{ + wstring str; + bool isansi = false; + DWORD dbflags = 0; + if(flags & PREF_UTF) + dbflags |= DBEF_UTF; + if(!metaIsSubcontact(hContact)) + str = toUTF16(msg); + else + {//workaround ... + wchar_t *tmp = mir_utf8decodeW(msg); + if(!tmp) + { + tmp = mir_a2t(msg); + isansi = true; + } + str.append(tmp); + mir_free(tmp); + } + string out; + DWORD code; + wstring cmd; + wstring file = toUTF16(get_random(10)); + wstring path; + extern bool bJabberAPI, bIsMiranda09; + char *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID", ""); + if(!tmp[0]) + { + mir_free(tmp); + HistoryLog(hContact, "Failed to encrypt message with GPG", EVENTTYPE_MESSAGE, DBEF_SENT); + hcontact_data[hContact].msgs_to_pass.push_back("Failed to encrypt message with GPG"); + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); + } + if(!bJabberAPI || !bIsMiranda09) //force jabber to handle encrypted message by itself + cmd += _T("--comment \"\" --no-version "); + if(DBGetContactSettingByte(hContact, szGPGModuleName, "bAlwaysTrust", 0)) + cmd += _T("--trust-model always "); + cmd += _T("--batch --yes -e -a -r "); + TCHAR *tmp2 = mir_a2t(tmp); + mir_free(tmp); + cmd += tmp2; + mir_free(tmp2); + cmd += _T(" \""); + tmp2 = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + path.append(tmp2); + cmd += tmp2; + mir_free(tmp2); + cmd += _T("\\tmp\\"); + cmd += file; + path.append(_T("\\tmp\\")); + path += file; + cmd += _T("\""); + { + char *tmp; + tmp = mir_strdup(toUTF8(str).c_str()); + fstream f(path.c_str(), std::ios::out); + while(!f.is_open()) + f.open(path.c_str(), std::ios::out); + f<<tmp; + mir_free(tmp); + f.close(); + } + 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(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); + } + if(result == pxNotFound) + { + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); + } + if(out.find("There is no assurance this key belongs to the named user") != string::npos) + { + out.clear(); + if(bAutoExchange) { DBWriteContactSettingByte(hContact, szGPGModuleName, "bAlwaysTrust", 1); cmd.insert(0, _T("--trust-model always ")); @@ -748,127 +700,213 @@ int SendMsgSvc(WPARAM w, LPARAM l) if(result == pxNotFound) return CallService(MS_PROTO_CHAINSEND, w, l); } - else - return 0; - } - if(out.find("usage: ") != string::npos) + else 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_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(10))) { - MessageBox(0, _T("Something wrong, gpg does not understand us, aborting encryption."), _T("Warning"), MB_OK); - DeleteFile(path.c_str()); - return CallService(MS_PROTO_CHAINSEND, w, l); + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + debuglog<<time_str()<<": GPG execution timed out, aborted\n"; + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); } - DeleteFile(path.c_str()); - path.append(_T(".asc")); - wfstream f(path.c_str(), std::ios::in | std::ios::ate | std::ios::binary); - str.clear(); - if(f.is_open()) + if(result == pxNotFound) { - std::wifstream::pos_type size = f.tellg(); - TCHAR *tmp = new TCHAR [(std::ifstream::pos_type)size+(std::ifstream::pos_type)1]; - f.seekg(0, std::ios::beg); - f.read(tmp, size); - tmp[size]= '\0'; - str.append(tmp); - delete [] tmp; - f.close(); - DeleteFile(path.c_str()); + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); } - if(str.empty()) + } + else + { + mir_free(msg); + return 0; + } + } + if(out.find("usage: ") != string::npos) + { + MessageBox(0, _T("Something wrong, gpg does not understand us, aborting encryption."), _T("Warning"), MB_OK); + DeleteFile(path.c_str()); + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); + } + DeleteFile(path.c_str()); + path.append(_T(".asc")); + wfstream f(path.c_str(), std::ios::in | std::ios::ate | std::ios::binary); + while(!f.is_open()) + f.open(path.c_str(), std::ios::in | std::ios::ate | std::ios::binary); + str.clear(); + if(f.is_open()) + { + std::wifstream::pos_type size = f.tellg(); + TCHAR *tmp = new TCHAR [(std::ifstream::pos_type)size+(std::ifstream::pos_type)1]; + f.seekg(0, std::ios::beg); + f.read(tmp, size); + tmp[size]= '\0'; + str.append(tmp); + delete [] tmp; + f.close(); + DeleteFile(path.c_str()); + } + if(str.empty()) + { + HistoryLog(hContact, "Failed to encrypt message with GPG", EVENTTYPE_MESSAGE, DBEF_SENT); + hcontact_data[hContact].msgs_to_pass.push_back("Failed to encrypt message with GPG"); + debuglog<<time_str()<<": info: Failed to encrypt message with GPG\n"; + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); + } + string str_event = msg; + if(bAppendTags) + { + str_event.insert(0, toUTF8(outopentag)); + str_event.append(toUTF8(outclosetag)); + } + if(metaIsSubcontact(hContact)) + { + hcontact_data[metaGetContact(hContact)].msgs_to_pass.push_back(str_event); + HistoryLog(metaGetContact(hContact), (char*)str_event.c_str(), EVENTTYPE_MESSAGE, DBEF_SENT|dbflags); + } + hcontact_data[hContact].msgs_to_pass.push_back(str_event); + HistoryLog(hContact, (char*)str_event.c_str(), EVENTTYPE_MESSAGE, dbflags|DBEF_SENT); + if(!(flags & PREF_UTF)) + flags |= PREF_UTF; + CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)toUTF8(str).c_str()); + mir_free(msg); + return 0; +} + +int SendMsgSvc(WPARAM w, LPARAM l) +{ + CCSDATA *ccs = (CCSDATA*)l; + if (!ccs) + return CallService(MS_PROTO_CHAINSEND, w, l); + char *msg = mir_strdup((char*)(ccs->lParam)); + if (!msg) + { + mir_free(msg); + return CallService(MS_PROTO_CHAINSEND, w, l); + } + if(strstr(msg,"-----BEGIN PGP MESSAGE-----")) + return CallService(MS_PROTO_CHAINSEND, w, l); + if(!isContactHaveKey(ccs->hContact)) + { + if(bAutoExchange && !strstr(msg, "-----PGP KEY REQUEST-----") && !strstr(msg, "-----BEGIN PGP PUBLIC KEY BLOCK-----") && isGPGConfigured()) + { + void send_encrypted_msgs_thread(HANDLE hContact); + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); + DWORD uin = DBGetContactSettingDword(ccs->hContact, proto, "UIN", 0); + if(uin) { - HistoryLog(hContact, "Failed to encrypt message with GPG", EVENTTYPE_MESSAGE, DBEF_SENT); - debuglog<<time_str()<<": info: Failed to encrypt message with GPG"; - return CallService(MS_PROTO_CHAINRECV, w, (LPARAM)ccs); + if(ServiceExists("ICQ"PS_ICQ_CHECKCAPABILITY)) + { + ICQ_CUSTOMCAP cap = {0}; + strcpy(cap.caps, "GPG AutoExchange"); + if(CallService("ICQ"PS_ICQ_CHECKCAPABILITY, (WPARAM)ccs->hContact, (LPARAM)&cap)) + { + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)ccs->wParam, (LPARAM)"-----PGP KEY REQUEST-----"); + hcontact_data[ccs->hContact].msgs_to_send.push_back(msg); + boost::thread *thr = new boost::thread(boost::bind(send_encrypted_msgs_thread, ccs->hContact)); + mir_free(msg); + return returnNoError(ccs->hContact); + } + } } - if(metaIsSubcontact(hContact)) - { //dirty hack to avoid metacontacts problem ..., this also broke filters chain - string str_event = (char*)ccs->lParam; - if(bAppendTags) - { //utf8 tag will cause problems here - str_event.insert(0, toUTF8(outopentag)); - str_event.append(toUTF8(outclosetag)); + else + { + TCHAR *jid = UniGetContactSettingUtf(ccs->hContact, proto, "jid", _T("")); + if(jid[0]) + { + extern list <JabberAccount*> Accounts; + list<JabberAccount*>::iterator end = Accounts.end(); + for(list<JabberAccount*>::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(ccs->hContact, PSS_MESSAGE, (WPARAM)ccs->wParam, (LPARAM)"-----PGP KEY REQUEST-----"); + hcontact_data[ccs->hContact].msgs_to_send.push_back(msg); + boost::thread *thr = new boost::thread(boost::bind(send_encrypted_msgs_thread, ccs->hContact)); + mir_free(msg); + return returnNoError(ccs->hContact); + } + } + } } - DWORD flags = 0, flags2 = 0; - if(!isansi) //message from metacontact itself, yet another metacontacts workaround... - flags |= DBEF_UTF; - else - flags2 |= DBEF_READ; - HistoryLog(hContact, (char*)str_event.c_str(), EVENTTYPE_MESSAGE, DBEF_SENT | flags2 | flags); - HistoryLog(metaGetContact(hContact), (char*)str_event.c_str(), EVENTTYPE_MESSAGE, DBEF_SENT | flags); - hcontact_data[hContact].msgs_to_ignore.push_back(msg); - hcontact_data[metaGetContact(hContact)].msgs_to_ignore.push_back(msg); - CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)toUTF8(str).c_str()); - return returnNoError(hContact); } - if(bAppendTags) - hcontact_data[hContact].msgs_to_tag.push_back((char*)ccs->lParam); - ccs->lParam = (LPARAM)mir_strdup(toUTF8(str).c_str()); - } + } + else + { + mir_free(msg); + return CallService(MS_PROTO_CHAINSEND, w, l); + } } - return CallService(MS_PROTO_CHAINSEND, w, l); + if(metaIsProtoMetaContacts(ccs->hContact) || !isContactSecured(ccs->hContact)) + { + mir_free(msg); + return CallService(MS_PROTO_CHAINSEND, w, l); + } + boost::thread *thr = new boost::thread(boost::bind(SendMsgSvc_func, ccs->hContact, msg, (DWORD)ccs->wParam)); + return returnNoError(ccs->hContact); } +boost::mutex event_processing_mutex; + int HookSendMsg(WPARAM w, LPARAM l) -{ //TODO: implement additional filtering for metacontacts data... +{ if(!l) return 0; DBEVENTINFO * dbei = (DBEVENTINFO*)l; - if((dbei->eventType == EVENTTYPE_MESSAGE) && (dbei->flags & DBEF_SENT)) + if(dbei->eventType != EVENTTYPE_MESSAGE) + return 0; + if(dbei->flags & DBEF_SENT) { if(strstr((char*)dbei->pBlob, "-----BEGIN PGP MESSAGE-----") || strstr((char*)dbei->pBlob, "-----PGP KEY RESPONSE-----") || strstr((char*)dbei->pBlob, "-----PGP KEY REQUEST-----") || strstr((char*)dbei->pBlob, "-----PGP KEY RESPONSE-----")) //our service data, can be double added by metacontacts e.t.c. return 1; - HANDLE hContact = NULL; - if(!hcontact_data[(HANDLE)w].msgs_to_ignore.empty()) - hContact = (HANDLE)w; - else if(!hcontact_data[metaGetContact((HANDLE)w)].msgs_to_ignore.empty()) - hContact = metaGetContact((HANDLE)w); - if(hContact) - { - list<string>::iterator end = hcontact_data[hContact].msgs_to_ignore.end(); - for(list<string>::iterator p = hcontact_data[hContact].msgs_to_ignore.begin(); p != end; p++) - { - if(*p == (char*)dbei->pBlob) - { - hcontact_data[hContact].msgs_to_ignore.erase(p); - return 1; - } - } - } } HANDLE hContact = (HANDLE)w; - - - if(metaIsProtoMetaContacts(hContact)) - hContact = metaGetCurrent(hContact); - if(!DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)) - return 0; - - if(bAppendTags) + if(isContactSecured(hContact) && (dbei->flags & DBEF_SENT)) //aggressive outgoing events filtering { - if((dbei->eventType == EVENTTYPE_MESSAGE) && (dbei->flags & DBEF_SENT)) + if(!hcontact_data[hContact].msgs_to_pass.empty()) { - if(!hcontact_data[hContact].msgs_to_tag.empty()) + event_processing_mutex.lock(); + std::list<string>::iterator end = hcontact_data[hContact].msgs_to_pass.end(); + for(std::list<string>::iterator i = hcontact_data[hContact].msgs_to_pass.begin(); i != end; ++i) { - std::list<string>::iterator end = hcontact_data[hContact].msgs_to_tag.end(); - for(std::list<string>::iterator i = hcontact_data[hContact].msgs_to_tag.begin(); i != end; ++i) + if(!strcmp((*i).c_str(), (char*)dbei->pBlob)) { - if(*i == (char*)dbei->pBlob) - { - char *msg = (char*)dbei->pBlob; - wstring str = toUTF16(msg); - str.insert(0, outopentag); - str.append(outclosetag); - char *msg2 = mir_strdup(toUTF8(str).c_str()); - mir_free(dbei->pBlob); - dbei->pBlob = (PBYTE)msg2; - dbei->cbBlob = strlen(msg2)+1; - hcontact_data[hContact].msgs_to_tag.erase(i); - break; - } + hcontact_data[hContact].msgs_to_pass.erase(i); + event_processing_mutex.unlock(); + return 0; } } + event_processing_mutex.unlock(); } + return 1; } - if((dbei->eventType == EVENTTYPE_MESSAGE) && !(dbei->flags & DBEF_SENT) && metaIsProtoMetaContacts((HANDLE)w)) + if(!isContactSecured(hContact)) + return 0; + if(!(dbei->flags & DBEF_SENT) && metaIsProtoMetaContacts((HANDLE)w)) { char tmp[29]; strncpy(tmp, (char*)dbei->pBlob, 27); @@ -879,11 +917,6 @@ int HookSendMsg(WPARAM w, LPARAM l) return 0; } -int TestHook(WPARAM w, LPARAM l) -{ - return 0; -} - static BOOL CALLBACK DlgProcKeyPassword(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { diff --git a/metacontacts.cpp b/metacontacts.cpp index 30d3a75..46185e4 100644 --- a/metacontacts.cpp +++ b/metacontacts.cpp @@ -42,8 +42,9 @@ bool metaIsDefaultSubContact(HANDLE hContact) HANDLE metaGetContact(HANDLE hContact)
{
if(bMetaContacts)
- return (HANDLE)CallService(MS_MC_GETMETACONTACT,(WPARAM)hContact,0);
- return 0;
+ if(metaIsSubcontact(hContact))
+ return (HANDLE)CallService(MS_MC_GETMETACONTACT,(WPARAM)hContact,0);
+ return hContact;
}
bool metaIsSubcontact(HANDLE hContact)
{
@@ -57,30 +58,17 @@ HANDLE metaGetMostOnline(HANDLE hContact) {
if(bMetaContacts)
- return (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(WPARAM)hContact,0);
- return 0;
+ if(metaIsProtoMetaContacts(hContact))
+ return (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(WPARAM)hContact,0);
+ return hContact;
}
HANDLE metaGetDefault(HANDLE hContact)
{
if(bMetaContacts)
- return (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT,(WPARAM)hContact,0);
- return 0;
-}
-
-HANDLE metaGetCurrent(HANDLE hContact)
-{
- bool IsOnline(HANDLE hContact);
- if(bMetaContacts)
- {
- if(!metaIsProtoMetaContacts(hContact))
- return hContact;
- HANDLE hcnt = metaGetMostOnline (hContact);
- if(!hcnt)
- hcnt = metaGetDefault(hContact);
- return hcnt;
- }
- return hContact;
+ if(metaIsProtoMetaContacts(hContact))
+ return (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT,(WPARAM)hContact,0);
+ return hContact;
}
diff --git a/metacontacts.h b/metacontacts.h index b7928a9..f7dcfe7 100644 --- a/metacontacts.h +++ b/metacontacts.h @@ -20,6 +20,5 @@ HANDLE metaGetContact(HANDLE hContact); bool metaIsSubcontact(HANDLE hContact);
HANDLE metaGetMostOnline(HANDLE hContact);
HANDLE metaGetDefault(HANDLE hContact);
-HANDLE metaGetCurrent(HANDLE hContact);
DWORD metaGetContactsNum(HANDLE hContact);
HANDLE metaGetSubcontact(HANDLE hContact, int num);
\ No newline at end of file @@ -13,13 +13,11 @@ #undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
-// русский resources
+// Russian (Russia) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS)
-#ifdef _WIN32
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
#pragma code_page(1251)
-#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@@ -177,7 +175,7 @@ END //
#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
+GUIDELINES DESIGNINFO
BEGIN
IDD_LOAD_PUBLIC_KEY, DIALOG
BEGIN
@@ -263,7 +261,7 @@ IDI_UNSECURED ICON "icons\\unsecured.ico" //
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 0,0,0,10
+ FILEVERSION 0,0,0,11
PRODUCTVERSION 0,9,0,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
@@ -280,7 +278,7 @@ BEGIN BLOCK "041904b0"
BEGIN
VALUE "FileDescription", "new_gpg"
- VALUE "FileVersion", "0.0.0.10"
+ VALUE "FileVersion", "0.0.0.11"
VALUE "InternalName", "new_gpg"
VALUE "LegalCopyright", "Copyright (C) 2010-2011 sss"
VALUE "OriginalFilename", "new_gpg"
@@ -294,18 +292,16 @@ BEGIN END
END
-#endif // русский resources
+#endif // Russian (Russia) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-// английский (США) resources
+// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
-#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
@@ -361,7 +357,7 @@ BEGIN RTEXT "Close:",IDC_STATIC,127,49,23,8
END
-#endif // английский (США) resources
+#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
diff --git a/new_gpg.vcxproj b/new_gpg.vcxproj index 69bf149..a325fb9 100644 --- a/new_gpg.vcxproj +++ b/new_gpg.vcxproj @@ -477,7 +477,7 @@ </Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>x:\temp\windows\libs\utf8cpp\include;X:\temp\windows\libs\Boost\include\boost-1_46;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>e:\temp\windows\libs\utf8cpp\include;e:\temp\windows\libs\Boost\include\boost-1_46;e:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
@@ -501,7 +501,7 @@ <Link>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies) libboost_thread-vc100-mt-sgd-1_46_1.lib</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
- <AdditionalLibraryDirectories>X:\temp\windows\libs\Boost\lib-debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>e:\temp\windows\libs\Boost\lib-debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AssemblyDebug>true</AssemblyDebug>
<GenerateMapFile>false</GenerateMapFile>
@@ -685,7 +685,7 @@ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>x:\temp\windows\libs\utf8cpp\include;X:\temp\windows\libs\Boost\include\boost-1_46;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>e:\temp\windows\libs\utf8cpp\include;e:\temp\windows\libs\Boost\include\boost-1_46;e:\install\git\miranda\miranda-im\miranda\include;e:\install\git\miranda\mim_plugs;../../include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -708,7 +708,7 @@ <Link>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
- <AdditionalLibraryDirectories>X:\temp\windows\libs\Boost\lib-release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>e:\temp\windows\libs\Boost\lib-release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>NotSet</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
@@ -739,7 +739,7 @@ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>x:\temp\windows\libs\utf8cpp\include;X:\temp\windows\libs\Boost\include\boost-1_46;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>e:\temp\windows\libs\utf8cpp\include;e:\temp\windows\libs\Boost\include\boost-1_46;e:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -762,7 +762,7 @@ <Link>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<SuppressStartupBanner>true</SuppressStartupBanner>
- <AdditionalLibraryDirectories>X:\temp\windows\libs\Boost\lib-release-x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalLibraryDirectories>e:\temp\windows\libs\Boost\lib-release-x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>NotSet</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
diff --git a/options.cpp b/options.cpp index f2b658a..04cb56b 100644 --- a/options.cpp +++ b/options.cpp @@ -256,6 +256,7 @@ static BOOL CALLBACK DlgProcGpgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
{
gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
debuglog<<time_str()<<": GPG execution timed out, aborted\n";
mir_free(tmp);
break;
@@ -462,7 +463,10 @@ static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LP params.result = &result;
boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ }
DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp_path);
mir_free(tmp_path);
string::size_type p1 = out.find("(GnuPG) ");
@@ -707,6 +711,7 @@ static BOOL CALLBACK DlgProcLoadPublicKey(HWND hwndDlg,UINT msg,WPARAM wParam,LP if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
{
gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
debuglog<<time_str()<<": GPG execution timed out, aborted\n";
}
if((out.find("-----BEGIN PGP PUBLIC KEY BLOCK-----") != string::npos) && (out.find("-----END PGP PUBLIC KEY BLOCK-----") != string::npos))
@@ -858,6 +863,7 @@ static BOOL CALLBACK DlgProcLoadPublicKey(HWND hwndDlg,UINT msg,WPARAM wParam,LP if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
{
gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
debuglog<<time_str()<<": GPG execution timed out, aborted\n";
break;
}
@@ -1093,6 +1099,7 @@ static BOOL CALLBACK DlgProcLoadPublicKey(HWND hwndDlg,UINT msg,WPARAM wParam,LP if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
{
gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
debuglog<<time_str()<<": GPG execution timed out, aborted\n";
break;
}
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) |