diff options
-rwxr-xr-x | plugins/New_GPG/src/gpg_wrapper.cpp | 66 | ||||
-rw-r--r-- | plugins/New_GPG/src/gpg_wrapper.h | 44 | ||||
-rwxr-xr-x | plugins/New_GPG/src/main.cpp | 80 | ||||
-rwxr-xr-x | plugins/New_GPG/src/messages.cpp | 166 | ||||
-rwxr-xr-x | plugins/New_GPG/src/options.cpp | 109 | ||||
-rwxr-xr-x | plugins/New_GPG/src/ui.cpp | 912 | ||||
-rwxr-xr-x | plugins/New_GPG/src/ui.h | 1 | ||||
-rwxr-xr-x | plugins/New_GPG/src/utilities.cpp | 424 | ||||
-rwxr-xr-x | plugins/New_GPG/src/utilities.h | 2 |
9 files changed, 768 insertions, 1036 deletions
diff --git a/plugins/New_GPG/src/gpg_wrapper.cpp b/plugins/New_GPG/src/gpg_wrapper.cpp index bac0dabaf3..b81a6c95ad 100755 --- a/plugins/New_GPG/src/gpg_wrapper.cpp +++ b/plugins/New_GPG/src/gpg_wrapper.cpp @@ -16,7 +16,10 @@ #include "stdafx.h" -pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD aexitcode, pxResult *result, boost::process::child *_child) +using namespace boost::process::initializers; +using namespace boost::iostreams; + +pxResult gpg_execution_params::pxExecute() { if (!globals.gpg_valid) return pxNotConfigured; @@ -25,14 +28,9 @@ pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD ae if (!boost::filesystem::exists(bin_path.c_str())) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": GPG executable not found"); - *result = pxNotFound; - return pxNotFound; + return result = pxNotFound; } - using namespace boost::process; - using namespace boost::process::initializers; - using namespace boost::iostreams; - std::vector<std::wstring> argv; std::vector<std::wstring> env; env.push_back(L"LANGUAGE=en@quot"); @@ -61,9 +59,10 @@ pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD ae globals.debuglog << std::string(time_str() + ": gpg in: " + toUTF8(args)); } - pipe pout = create_pipe(); - pipe perr = create_pipe(); - child *c = nullptr; + out.Empty(); + boost::process::pipe pout = boost::process::create_pipe(); + boost::process::pipe perr = boost::process::create_pipe(); + boost::process::child *c = nullptr; { file_descriptor_sink sout(pout.sink, close_handle); file_descriptor_sink serr(perr.sink, close_handle); @@ -71,8 +70,8 @@ pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD ae wchar_t *mir_path = new wchar_t[MAX_PATH]; PathToAbsoluteW(L"\\", mir_path); - c = new child(execute(set_args(argv), bind_stdout(sout), bind_stderr(serr), close_stdin(),/*bind_stdin(sin),*/ show_window(SW_HIDE), hide_console(), inherit_env(), set_env(env), start_in_dir(mir_path))); - _child = c; + c = new boost::process::child(boost::process::execute(set_args(argv), bind_stdout(sout), bind_stderr(serr), close_stdin(), show_window(SW_HIDE), hide_console(), inherit_env(), set_env(env), start_in_dir(mir_path))); + this->child = c; delete[] mir_path; } @@ -84,13 +83,13 @@ pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD ae try { std::string s; while (std::getline(is, s)) { - aoutput->append(s); - aoutput->append("\n"); + out.Append(s.c_str()); + out.Append("\n"); } } catch (const std::exception &e) { if (globals.bDebugLog) - globals.debuglog << std::string(time_str() + ": failed to read from stream with error: " + e.what() + "\n\tSuccesfully read : " + *aoutput); + globals.debuglog << std::string(time_str() + ": failed to read from stream with error: " + e.what() + "\n\tSuccesfully read : " + out.c_str()); } file_descriptor_source source2(perr.source, close_handle); @@ -100,28 +99,28 @@ pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD ae try { std::string s; while (std::getline(is2, s)) { - aoutput->append(s); - aoutput->append("\n"); + out.Append(s.c_str()); + out.Append("\n"); } } catch (const std::exception &e) { if (globals.bDebugLog) - globals.debuglog << std::string(time_str() + ": failed to read from stream with error: " + e.what() + "\n\tSuccesfully read : " + *aoutput); + globals.debuglog << std::string(time_str() + ": failed to read from stream with error: " + e.what() + "\n\tSuccesfully read : " + out.c_str()); } - fix_line_term(*aoutput); + out.Replace("\r\r", ""); if (globals.bDebugLog) - globals.debuglog << std::string(time_str() + ": gpg out: " + *aoutput); + globals.debuglog << std::string(time_str() + ": gpg out: " + out.c_str()); auto ec = wait_for_exit(*c); delete c; - *aexitcode = ec; - _child = nullptr; + this->code = ec; + this->child = nullptr; - if (*aexitcode) { + if (ec) { if (globals.bDebugLog) - globals.debuglog << std::string(time_str() + ": warning: wrong gpg exit status, gpg output: " + *aoutput); + globals.debuglog << std::string(time_str() + ": warning: wrong gpg exit status, gpg output: " + out.c_str()); return pxSuccessExitCodeInvalid; } @@ -130,14 +129,13 @@ pxResult pxExecute(std::vector<std::wstring> &aargv, string *aoutput, LPDWORD ae void pxEexcute_thread(gpg_execution_params *params) { - pxExecute(params->aargv, params->out, params->code, params->result, params->child); - delete params; + params->pxExecute(); } bool gpg_launcher(gpg_execution_params ¶ms, boost::posix_time::time_duration t) { bool ret = true; - HANDLE hThread = mir_forkThread<gpg_execution_params>(pxEexcute_thread, new gpg_execution_params(params)); + HANDLE hThread = mir_forkThread<gpg_execution_params>(pxEexcute_thread, ¶ms); if (WaitForSingleObject(hThread, t.total_milliseconds()) == WAIT_TIMEOUT) { ret = false; if (params.child) @@ -248,7 +246,7 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, pxResult *res while(_stdout.good()) { *aoutput += buf; - if(aoutput->find("Enter passphrase") != std::string::npos) + if(out.find("Enter passphrase") != std::string::npos) break; ::Sleep(50); std::getline(_stdout, buf); @@ -261,7 +259,7 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, pxResult *res while(_stdout.good()) { *aoutput += buf; - if(aoutput->find("Enter the new passphrase for this secret key.") != std::string::npos) + if(out.find("Enter the new passphrase for this secret key.") != std::string::npos) break; ::Sleep(50); std::getline(_stdout, buf); @@ -269,14 +267,14 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, pxResult *res *aoutput += buf; - if(aoutput->find("Enter passphrase") != std::string::npos)*/ + if(out.find("Enter passphrase") != std::string::npos)*/ //_stdin<<new_pass<<std::endl; /* std::getline(_stdout, buf); while(_stdout.good()) { *aoutput += buf; - if(aoutput->find("Repeat passphrase") != std::string::npos) + if(out.find("Repeat passphrase") != std::string::npos) break; ::Sleep(50); std::getline(_stdout, buf); @@ -289,7 +287,7 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, pxResult *res while(_stdout.good()) { *aoutput += buf; - if(aoutput->find("Command") != std::string::npos) + if(out.find("Command") != std::string::npos) break; ::Sleep(50); std::getline(_stdout, buf); @@ -300,7 +298,7 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, pxResult *res //proc.wait(); - //MessageBoxA(NULL, aoutput->c_str(), "info", MB_OK); + //MessageBoxA(NULL, out.c_str(), "info", MB_OK); return pxSuccess; } @@ -308,5 +306,5 @@ pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, pxResult *res void pxEexcute_passwd_change_thread(void *param) { gpg_execution_params_pass *params = (gpg_execution_params_pass*)param; - pxExecute_passwd_change(params->args, params->result, params->child); + pxExecute_passwd_change(params->aargv, ¶ms->result, params->child); } diff --git a/plugins/New_GPG/src/gpg_wrapper.h b/plugins/New_GPG/src/gpg_wrapper.h index 8abf9ef498..9e9e14f522 100644 --- a/plugins/New_GPG/src/gpg_wrapper.h +++ b/plugins/New_GPG/src/gpg_wrapper.h @@ -17,7 +17,8 @@ #ifndef GPG_WRAPPER_H #define GPG_WRAPPER_H -typedef enum { +enum pxResult +{ pxSuccess, pxSuccessExitCodeInvalid, pxCreatePipeFailed, @@ -29,40 +30,31 @@ typedef enum { pxBufferOverflow, pxNotFound, pxNotConfigured -} -pxResult; - -pxResult pxExecute(std::vector<std::string> &aargv, string *aoutput, LPDWORD aexitcode, pxResult *result); +}; struct gpg_execution_params { - std::vector<std::wstring> &aargv; -// char *useless; - string *out; - LPDWORD code; - pxResult *result; - boost::process::child *child; -// HANDLE hProcess; -// PROCESS_INFORMATION *proc; - gpg_execution_params(std::vector<std::wstring> &a): aargv(a) - { - child = nullptr; + std::vector<std::wstring> aargv; + CMStringA out; + DWORD code = 0; + pxResult result = pxSuccess; + boost::process::child *child = nullptr; + + __forceinline void addParam(const std::wstring ¶m) + { aargv.push_back(param); } + + pxResult pxExecute(); }; -struct gpg_execution_params_pass +struct gpg_execution_params_pass : public gpg_execution_params { - std::vector<std::wstring> &args; string &old_pass, &new_pass; - string *out; - LPDWORD code; - pxResult *result; - boost::process::child *child; -// HANDLE hProcess; -// PROCESS_INFORMATION *proc; - gpg_execution_params_pass(std::vector<std::wstring> &a, std::string &o, std::string &n): args(a), old_pass(o), new_pass(n) + + gpg_execution_params_pass(std::string &o, std::string &n): + old_pass(o), + new_pass(n) { - child = nullptr; } }; diff --git a/plugins/New_GPG/src/main.cpp b/plugins/New_GPG/src/main.cpp index ad96b2bda9..5f63adcc85 100755 --- a/plugins/New_GPG/src/main.cpp +++ b/plugins/New_GPG/src/main.cpp @@ -18,8 +18,37 @@ #pragma comment(lib, "shlwapi.lib") +static int EnumProc(const char *szSetting, void *param) +{ + auto *list = (OBJLIST<CMStringA> *)param; + if (strchr(szSetting, '(') && strchr(szSetting, ')')) + list->insert(new CMStringA(szSetting)); + return 0; +} + void FirstRun() { + if (g_plugin.getByte("CompatLevel") != 1) { + OBJLIST<CMStringA> settings(1); + db_enum_settings(0, EnumProc, MODULENAME, &settings); + + for (auto &it : settings) { + CMStringA newName(*it); + int p1 = newName.Find('('); + newName.Delete(0, p1+1); + int p2 = newName.Find(')'); + if (p2 == -1) + continue; + newName.Delete(p2, 1); + + CMStringW val = g_plugin.getMStringW(it->c_str()); + g_plugin.delSetting(it->c_str()); + g_plugin.setWString(newName, val); + } + + g_plugin.setByte("CompatLevel", 1); + } + if (!g_plugin.getByte("FirstRun", 1)) return; CDlgGpgBinOpts *d = new CDlgGpgBinOpts; @@ -73,25 +102,19 @@ void InitCheck() if (!globals.gpg_valid) return; globals.gpg_keyexist = isGPGKeyExist(); - string out; - DWORD code; - pxResult result; + wstring::size_type p = 0, p2 = 0; - { - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--list-secret-keys"); - gpg_execution_params params(cmd); - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params)) - return; - if (result == pxNotFound) - return; - } + + gpg_execution_params params; + params.addParam(L"--list-secret-keys"); + params.addParam(L"--batch"); + if (!gpg_launcher(params)) + return; + if (params.result == pxNotFound) + return; _wmkdir(g_plugin.getMStringW("szHomePath") + L"\\tmp"); + string out(params.out); CMStringW wszQuestion; for (auto &pa : Accounts()) { @@ -99,10 +122,8 @@ void InitCheck() continue; if (StriStr(pa->szModuleName, "weather")) continue; - std::string acc = toUTF8(pa->tszAccountName); - acc += "("; - acc += pa->szModuleName; - acc += ")"; + + std::string acc = pa->szModuleName; acc += "_KeyID"; CMStringA keyid = g_plugin.getMStringA(acc.c_str()); if (!keyid.IsEmpty()) { @@ -267,23 +288,16 @@ void ImportKey(MCONTACT hContact, std::wstring new_key) f << ptmp.c_str(); f.close(); - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--import"); - cmd.push_back(tmp2.c_str()); - - gpg_execution_params params(cmd); - string output; - DWORD exitcode; - pxResult result; - params.out = &output; - params.code = &exitcode; - params.result = &result; + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--import"); + params.addParam(tmp2.c_str()); if (!gpg_launcher(params)) return; - if (result == pxNotFound) + if (params.result == pxNotFound) return; + string output(params.out); if (db_mc_isMeta(hContact)) { if (for_all_sub) { int count = db_mc_getSubCount(hContact); diff --git a/plugins/New_GPG/src/messages.cpp b/plugins/New_GPG/src/messages.cpp index 40cd491462..797afd030f 100755 --- a/plugins/New_GPG/src/messages.cpp +++ b/plugins/New_GPG/src/messages.cpp @@ -109,10 +109,9 @@ static void RecvMsgSvc_func(RecvParams *param) mir_free(tmp); f.close(); } - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); + + gpg_execution_params params; + params.addParam(L"--batch"); { CMStringA inkeyid = g_plugin.getMStringA(db_mc_isMeta(hContact) ? metaGetMostOnline(hContact) : hContact, "InKeyID"); CMStringW pass; @@ -130,14 +129,14 @@ static void RecvMsgSvc_func(RecvParams *param) globals.debuglog << std::string(time_str() + ": info: found password for all keys in database, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(hContact)) + " with password"); } if (!pass.IsEmpty()) { - cmd.push_back(L"--passphrase"); - cmd.push_back(pass.c_str()); + params.addParam(L"--passphrase"); + params.addParam(pass.c_str()); } else if (!globals.wszPassword.IsEmpty()) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: found password in memory, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(hContact)) + " with password"); - cmd.push_back(L"--passphrase"); - cmd.push_back(globals.wszPassword.c_str()); + params.addParam(L"--passphrase"); + params.addParam(globals.wszPassword.c_str()); } else if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: passwords not found in database or memory, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(hContact)) + " with out password"); @@ -148,17 +147,12 @@ static void RecvMsgSvc_func(RecvParams *param) boost::filesystem::remove(wstring(ptszHomePath) + L"\\tmp\\" + decfile, e); } - cmd.push_back(L"--output"); - cmd.push_back(std::wstring(ptszHomePath) + L"\\tmp\\" + decfile); - cmd.push_back(L"-d"); - cmd.push_back(L"-a"); - cmd.push_back(path); + params.addParam(L"--output"); + params.addParam(std::wstring(ptszHomePath) + L"\\tmp\\" + decfile); + params.addParam(L"-d"); + params.addParam(L"-a"); + params.addParam(path); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; if (!gpg_launcher(params)) { if (!globals.bDebugLog) { boost::system::error_code e; @@ -173,7 +167,7 @@ static void RecvMsgSvc_func(RecvParams *param) delete param; return; } - if (result == pxNotFound) { + if (params.result == pxNotFound) { if (!globals.bDebugLog) { boost::system::error_code e; boost::filesystem::remove(path, e); @@ -186,6 +180,8 @@ static void RecvMsgSvc_func(RecvParams *param) // TODO: check gpg output for errors globals._terminate = false; + + string out(params.out); while (out.find("public key decryption failed: bad passphrase") != string::npos) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: failed to decrypt messaage from " + toUTF8(Clist_GetContactDisplayName(hContact)) + " password needed, trying to get one"); @@ -206,21 +202,17 @@ static void RecvMsgSvc_func(RecvParams *param) CDlgKeyPasswordMsgBox *d = new CDlgKeyPasswordMsgBox(hContact); d->DoModal(); - std::vector<wstring> cmd2 = cmd; + + gpg_execution_params params2; + params2.aargv = params.aargv; if (!globals.wszPassword.IsEmpty()) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: found password in memory, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(hContact))); - std::vector<wstring> tmp3; - tmp3.push_back(L"--passphrase"); - tmp3.push_back(globals.wszPassword.c_str()); - cmd2.insert(cmd2.begin(), tmp3.begin(), tmp3.end()); + + params2.addParam(L"--passphrase"); + params2.addParam(globals.wszPassword.c_str()); } - out.clear(); - gpg_execution_params params2(cmd2); - pxResult result2; - params2.out = &out; - params2.code = &code; - params2.result = &result2; + if (!gpg_launcher(params2)) { if (!globals.bDebugLog) { boost::system::error_code e; @@ -236,7 +228,7 @@ static void RecvMsgSvc_func(RecvParams *param) delete param; return; } - if (result2 == pxNotFound) { + if (params2.result == pxNotFound) { if (!globals.bDebugLog) { boost::system::error_code e; boost::filesystem::remove(path, e); @@ -264,7 +256,7 @@ static void RecvMsgSvc_func(RecvParams *param) return; } - if (result == pxNotFound) { + if (params.result == pxNotFound) { if (!globals.bDebugLog) { boost::system::error_code e; boost::filesystem::remove(path, e); @@ -395,10 +387,6 @@ INT_PTR RecvMsgSvc(WPARAM w, LPARAM l) g_plugin.setWString(ccs->hContact, "GPGPubKey", str.substr(s1, s2 - s1).c_str()); { // gpg execute block - std::vector<wstring> cmd; - string output; - DWORD exitcode; - CMStringW tmp2(g_plugin.getMStringW("szHomePath")); tmp2 += L"\\"; tmp2 += get_random(5).c_str(); @@ -427,24 +415,22 @@ INT_PTR RecvMsgSvc(WPARAM w, LPARAM l) } f << g_plugin.getMStringW(ccs->hContact, "GPGPubKey").c_str(); f.close(); - cmd.push_back(L"--batch"); - cmd.push_back(L"--import"); - cmd.push_back(tmp2.c_str()); - - gpg_execution_params params(cmd); - pxResult result; - params.out = &output; - params.code = &exitcode; - params.result = &result; + + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--import"); + params.addParam(tmp2.c_str()); if (!gpg_launcher(params)) return 1; + if (!globals.bDebugLog) { boost::system::error_code e; boost::filesystem::remove(tmp2.c_str(), e); } - if (result == pxNotFound) + if (params.result == pxNotFound) return 1; + string output(params.out); s1 = output.find("gpg: key ") + mir_strlen("gpg: key "); s2 = output.find(":", s1); g_plugin.setString(ccs->hContact, "KeyID", output.substr(s1, s2 - s1).c_str()); @@ -581,15 +567,10 @@ void SendMsgSvc_func(MCONTACT hContact, char *msg, DWORD flags) globals.debuglog << std::string(time_str() + ": info: stripping tags in outgoing message, name: " + toUTF8(Clist_GetContactDisplayName(hContact))); strip_tags(str); } - /* for(std::wstring::size_type i = str.find(L"\r\n"); i != std::wstring::npos; i = str.find(L"\r\n", i+1)) - str.replace(i, 2, L"\n"); */ - string out; - DWORD code; + wstring file = toUTF16(get_random(10)); - std::vector<std::wstring> cmd; + gpg_execution_params params; { - wchar_t *tmp2; - CMStringA tmp(g_plugin.getMStringA(hContact, "KeyID")); if (tmp.IsEmpty()) { HistoryLog(hContact, db_event("Failed to encrypt message with GPG (not found key for encryption in db)", 0, 0, DBEF_SENT)); @@ -598,27 +579,27 @@ void SendMsgSvc_func(MCONTACT hContact, char *msg, DWORD flags) } if (!globals.bJabberAPI) { //force jabber to handle encrypted message by itself - cmd.push_back(L"--comment"); - cmd.push_back(L"\"\""); - cmd.push_back(L"--no-version"); + params.addParam(L"--comment"); + params.addParam(L"\"\""); + params.addParam(L"--no-version"); } if (g_plugin.getByte(hContact, "bAlwaysTrust", 0)) { - cmd.push_back(L"--trust-model"); - cmd.push_back(L"always"); + params.addParam(L"--trust-model"); + params.addParam(L"always"); } - cmd.push_back(L"--batch"); - cmd.push_back(L"--yes"); - cmd.push_back(L"-eatr"); - tmp2 = mir_a2u(tmp); + params.addParam(L"--batch"); + params.addParam(L"--yes"); + params.addParam(L"-eatr"); + wchar_t *tmp2 = mir_a2u(tmp); - cmd.push_back(tmp2); + params.addParam(tmp2); mir_free(tmp2); } CMStringW path(g_plugin.getMStringW("szHomePath")); path += L"\\tmp\\"; path += file.c_str(); - cmd.push_back(path.c_str()); + params.addParam(path.c_str()); const int timeout = 5000, step = 100; int count = 0; @@ -642,50 +623,37 @@ void SendMsgSvc_func(MCONTACT hContact, char *msg, DWORD flags) f.close(); } } - pxResult result; - { - gpg_execution_params params(cmd); - params.out = &out; - params.code = &code; - params.result = &result; + + if (!gpg_launcher(params)) { + ProtoChainSend(hContact, PSS_MESSAGE, flags, (LPARAM)msg); + return; + } + + if (params.result == pxNotFound) { + ProtoChainSend(hContact, PSS_MESSAGE, flags, (LPARAM)msg); + return; + } + + if (params.out.Find("There is no assurance this key belongs to the named user") != -1) { + if (IDYES != MessageBox(nullptr, TranslateT("We're trying to encrypt with untrusted key. Do you want to trust this key permanently?"), TranslateT("Warning"), MB_YESNO)) + return; + + g_plugin.setByte(hContact, "bAlwaysTrust", 1); + + params.addParam(L"--trust-model"); + params.addParam(L"always"); if (!gpg_launcher(params)) { - //mir_free(msg); ProtoChainSend(hContact, PSS_MESSAGE, flags, (LPARAM)msg); return; } - if (result == pxNotFound) { - //mir_free(msg); + if (params.result == pxNotFound) { ProtoChainSend(hContact, PSS_MESSAGE, flags, (LPARAM)msg); return; } + //TODO: check gpg output for errors } - if (out.find("There is no assurance this key belongs to the named user") != string::npos) { - out.clear(); - if (MessageBox(nullptr, TranslateT("We're trying to encrypt with untrusted key. Do you want to trust this key permanently?"), TranslateT("Warning"), MB_YESNO) == IDYES) { - g_plugin.setByte(hContact, "bAlwaysTrust", 1); - std::vector<std::wstring> tmp; - tmp.push_back(L"--trust-model"); - tmp.push_back(L"always"); - cmd.insert(cmd.begin(), tmp.begin(), tmp.end()); - gpg_execution_params params(cmd); - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params)) { - ProtoChainSend(hContact, PSS_MESSAGE, flags, (LPARAM)msg); - return; - } - if (result == pxNotFound) { - ProtoChainSend(hContact, PSS_MESSAGE, flags, (LPARAM)msg); - return; - } - //TODO: check gpg output for errors - } - else return; - } - - if (out.find("usage: ") != string::npos) { + if (params.out.Find("usage: ") != -1) { MessageBox(nullptr, TranslateT("Something is wrong, GPG does not understand us, aborting encryption."), TranslateT("Warning"), MB_OK); //mir_free(msg); ProtoChainSend(hContact, PSS_MESSAGE, flags, (LPARAM)msg); diff --git a/plugins/New_GPG/src/options.cpp b/plugins/New_GPG/src/options.cpp index c907cf2165..504ed6bdef 100755 --- a/plugins/New_GPG/src/options.cpp +++ b/plugins/New_GPG/src/options.cpp @@ -164,27 +164,20 @@ public: if (!keep) if (MessageBox(nullptr, TranslateT("This key is not used by any contact. Do you want to remove it from public keyring?"), TranslateT("Key info"), MB_YESNO) == IDYES) { - std::vector<wstring> cmd; - string output; - DWORD exitcode; - cmd.push_back(L"--batch"); - cmd.push_back(L"--yes"); - cmd.push_back(L"--delete-key"); + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--yes"); + params.addParam(L"--delete-key"); ptmp = mir_a2u(tmp); - cmd.push_back(ptmp); + params.addParam(ptmp); mir_free(ptmp); - gpg_execution_params params(cmd); - pxResult result; - params.out = &output; - params.code = &exitcode; - params.result = &result; if (!gpg_launcher(params)) return; - if (result == pxNotFound) + if (params.result == pxNotFound) return; - if (output.find("--delete-secret-keys") != string::npos) + if (params.out.Find("--delete-secret-keys") != -1) MessageBox(nullptr, TranslateT("we have secret key for this public key, do not removing from GPG keyring"), TranslateT("info"), MB_OK); else MessageBox(nullptr, TranslateT("Key removed from GPG keyring"), TranslateT("info"), MB_OK); @@ -388,25 +381,20 @@ public: bool bad_version = false; CMStringW tmp_path = g_plugin.getMStringW("szGpgBinPath", L""); g_plugin.setWString("szGpgBinPath", tmp); - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--version"); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + + gpg_execution_params params; + params.addParam(L"--version"); + bool old_gpg_state = globals.gpg_valid; globals.gpg_valid = true; gpg_launcher(params); globals.gpg_valid = old_gpg_state; g_plugin.setWString("szGpgBinPath", tmp_path); - string::size_type p1 = out.find("(GnuPG) "); + int p1 = params.out.Find("(GnuPG) "); if (p1 != string::npos) { p1 += mir_strlen("(GnuPG) "); - if (out[p1] != '1') + if (params.out[p1] != '1') bad_version = true; } else { @@ -597,22 +585,16 @@ public: if (!globals.hcontact_data[hcnt].key_in_prescense.empty()) { if (g_plugin.getMStringA(hcnt, "KeyID").IsEmpty()) { - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--export"); - cmd.push_back(L"-a"); - cmd.push_back(toUTF16(globals.hcontact_data[hcnt].key_in_prescense)); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + gpg_execution_params params; + params.addParam(L"--export"); + params.addParam(L"-a"); + params.addParam(toUTF16(globals.hcontact_data[hcnt].key_in_prescense)); gpg_launcher(params); //TODO: handle errors - if ((out.find("-----BEGIN PGP PUBLIC KEY BLOCK-----") != string::npos) && (out.find("-----END PGP PUBLIC KEY BLOCK-----") != string::npos)) { - boost::algorithm::replace_all(out, "\n", "\r\n"); - wchar_t *tmp3 = mir_a2u(out.c_str()); + if ((params.out.Find("-----BEGIN PGP PUBLIC KEY BLOCK-----") != -1) && (params.out.Find("-----END PGP PUBLIC KEY BLOCK-----") != -1)) { + params.out.Replace("\n", "\r\n"); + + wchar_t *tmp3 = mir_a2u(params.out.c_str()); str.clear(); str.append(tmp3); mir_free(tmp3); @@ -702,8 +684,6 @@ public: { //gpg execute block std::vector<wstring> cmd; CMStringW tmp2; - string output; - DWORD exitcode; { MCONTACT hcnt = db_mc_tryMeta(hContact); tmp2 = g_plugin.getMStringW("szHomePath"); @@ -715,20 +695,17 @@ public: str.Replace(L"\r", L""); f << str.c_str(); f.close(); - - cmd.push_back(L"--batch"); - cmd.push_back(L"--import"); - cmd.push_back(tmp2.c_str()); } - gpg_execution_params params(cmd); - pxResult result; - params.out = &output; - params.code = &exitcode; - params.result = &result; + + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--import"); + params.addParam(tmp2.c_str()); if (!gpg_launcher(params)) return; - if (result == pxNotFound) + if (params.result == pxNotFound) return; + mir_free(begin); mir_free(end); if (hContact) { @@ -745,6 +722,8 @@ public: } else g_plugin.delSetting(hContact, "bAlwatsTrust"); } + + string output(params.out); { if (output.find("already in secret keyring") != string::npos) { MessageBox(nullptr, TranslateT("Key already in secret keyring."), TranslateT("Info"), MB_OK); @@ -903,28 +882,18 @@ public: } } if (!hContact) { - string out; - DWORD code; - std::vector<wstring> cmds; - cmds.push_back(L"--batch"); - cmds.push_back(L"-a"); - cmds.push_back(L"--export"); - cmds.push_back(g_plugin.getMStringW(hContact, "KeyID").c_str()); - - gpg_execution_params params2(cmds); - pxResult result2; - params2.out = &out; - params2.code = &code; - params2.result = &result2; + gpg_execution_params params2; + params.addParam(L"--batch"); + params.addParam(L"-a"); + params.addParam(L"--export"); + params.addParam(g_plugin.getMStringW(hContact, "KeyID").c_str()); if (!gpg_launcher(params2)) return; - if (result2 == pxNotFound) + if (params2.result == pxNotFound) return; - string::size_type s = 0; - while ((s = out.find("\r", s)) != string::npos) { - out.erase(s, 1); - } - g_plugin.setString(hContact, "GPGPubKey", out.c_str()); + + params2.out.Remove('\r'); + g_plugin.setString(hContact, "GPGPubKey", params2.out.c_str()); } MessageBoxA(nullptr, output.c_str(), "", MB_OK); boost::filesystem::remove(tmp2.c_str()); diff --git a/plugins/New_GPG/src/ui.cpp b/plugins/New_GPG/src/ui.cpp index 04c308410e..41ae530378 100755 --- a/plugins/New_GPG/src/ui.cpp +++ b/plugins/New_GPG/src/ui.cpp @@ -123,30 +123,21 @@ bool CDlgChangePasswdMsgBox::OnApply() if (MessageBox(m_hwnd, TranslateT("Old password does not match, you can continue, but GPG will reject wrong password.\nDo you want to continue?"), TranslateT("Error"), MB_YESNO) == IDNO) return false; - string output; - DWORD exitcode; - pxResult result; - - std::vector<std::wstring> cmd; - cmd.push_back(L"--edit-key"); - cmd.push_back(globals.key_id_global); - cmd.push_back(L"passwd"); + gpg_execution_params_pass params(old_pass, new_pass); + params.addParam(L"--edit-key"); + params.addParam(globals.key_id_global); + params.addParam(L"passwd"); - gpg_execution_params_pass *params = new gpg_execution_params_pass(cmd, old_pass, new_pass); - params->out = &output; - params->code = &exitcode; - params->result = &result; - - HANDLE hThread = mir_forkthread(&pxEexcute_passwd_change_thread, params); + HANDLE hThread = mir_forkthread(&pxEexcute_passwd_change_thread, ¶ms); if (WaitForSingleObject(hThread, 600000) != WAIT_OBJECT_0) { - if (params->child) - boost::process::terminate(*(params->child)); + if (params.child) + boost::process::terminate(*(params.child)); if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": GPG execution timed out, aborted"); return true; } - return (result != pxNotFound); + return params.result != pxNotFound; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -178,6 +169,9 @@ CDlgFirstRun::CDlgFirstRun() : btn_DELETE_KEY.OnClick = Callback(this, &CDlgFirstRun::onClick_DELETE_KEY); btn_OK.OnClick = Callback(this, &CDlgFirstRun::onClick_OK); + combo_ACCOUNT.OnChange = Callback(this, &CDlgFirstRun::onChange_ACCOUNT); + + list_KEY_LIST.OnClick = Callback(this, &CDlgFirstRun::onChange_KEY_LIST); } bool CDlgFirstRun::OnInitDialog() @@ -207,18 +201,14 @@ bool CDlgFirstRun::OnInitDialog() if (StriStr(pa->szModuleName, "weather")) continue; - CMStringW wszAcc(FORMAT, L"%s (%S)", pa->tszAccountName, pa->szModuleName); - combo_ACCOUNT.AddString(wszAcc); + combo_ACCOUNT.AddString(pa->tszAccountName, (LPARAM)pa->szModuleName); } - combo_ACCOUNT.SelectString(TranslateT("Default")); + combo_ACCOUNT.SetCurSel(0); CMStringW keyinfo = TranslateT("key ID"); keyinfo += L": "; keyinfo += g_plugin.getMStringW("KeyID", TranslateT("not set")); lbl_KEY_ID.SetText(keyinfo); - - combo_ACCOUNT.OnChange = Callback(this, &CDlgFirstRun::onChange_ACCOUNT); - list_KEY_LIST.OnClick = Callback(this, &CDlgFirstRun::onChange_KEY_LIST); return true; } @@ -227,119 +217,103 @@ void CDlgFirstRun::onClick_COPY_PUBKEY(CCtrlButton*) int i = list_KEY_LIST.GetSelectionMark(); if (i == -1) return; - if (OpenClipboard(m_hwnd)) { - list_KEY_LIST.GetItemText(i, 0, fp, _countof(fp)); - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"-a"); - cmd.push_back(L"--export"); - cmd.push_back(fp); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params)) - return; - if (result == pxNotFound) - return; - boost::algorithm::erase_all(out, "\r"); - HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, out.size() + 1); - if (!hMem) { - MessageBox(nullptr, TranslateT("Failed to allocate memory"), TranslateT("Error"), MB_OK); - return; - } - char *szKey = (char*)GlobalLock(hMem); - if (!szKey) { - wchar_t msg[64]; - mir_snwprintf(msg, TranslateT("Failed to lock memory with error %d"), GetLastError()); - MessageBox(nullptr, msg, TranslateT("Error"), MB_OK); - GlobalFree(hMem); - } - memcpy(szKey, out.c_str(), out.size()); - szKey[out.size()] = '\0'; - EmptyClipboard(); - GlobalUnlock(hMem); - if (!SetClipboardData(CF_OEMTEXT, hMem)) { - GlobalFree(hMem); - wchar_t msg[64]; - mir_snwprintf(msg, TranslateT("Failed write to clipboard with error %d"), GetLastError()); - MessageBox(nullptr, msg, TranslateT("Error"), MB_OK); - } - CloseClipboard(); + + if (!OpenClipboard(m_hwnd)) + return; + + list_KEY_LIST.GetItemText(i, 0, fp, _countof(fp)); + + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"-a"); + params.addParam(L"--export"); + params.addParam(fp); + if (!gpg_launcher(params)) + return; + if (params.result == pxNotFound) + return; + + params.out.Remove('\r'); + HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, params.out.GetLength() + 1); + if (!hMem) { + MessageBox(nullptr, TranslateT("Failed to allocate memory"), TranslateT("Error"), MB_OK); + return; + } + char *szKey = (char*)GlobalLock(hMem); + if (!szKey) { + wchar_t msg[64]; + mir_snwprintf(msg, TranslateT("Failed to lock memory with error %d"), GetLastError()); + MessageBox(nullptr, msg, TranslateT("Error"), MB_OK); + GlobalFree(hMem); + } + + memcpy(szKey, params.out.c_str(), params.out.GetLength()); + szKey[params.out.GetLength()] = '\0'; + + EmptyClipboard(); + GlobalUnlock(hMem); + if (!SetClipboardData(CF_OEMTEXT, hMem)) { + GlobalFree(hMem); + wchar_t msg[64]; + mir_snwprintf(msg, TranslateT("Failed write to clipboard with error %d"), GetLastError()); + MessageBox(nullptr, msg, TranslateT("Error"), MB_OK); } + CloseClipboard(); } void CDlgFirstRun::onClick_EXPORT_PRIVATE(CCtrlButton*) { - { - int i = list_KEY_LIST.GetSelectionMark(); - if (i == -1) - return; + int i = list_KEY_LIST.GetSelectionMark(); + if (i == -1) + return; - ptrW p(GetFilePath(L"Choose file to export key", L"*", L"Any file", true)); - if (!p || !p[0]) - return; + ptrW p(GetFilePath(L"Choose file to export key", L"*", L"Any file", true)); + if (!p || !p[0]) + return; - std::ofstream file; - file.open(p, std::ios::trunc | std::ios::out); - if (!file.is_open()) - return; //TODO: handle error - - list_KEY_LIST.GetItemText(i, 0, fp, _countof(fp)); - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"-a"); - cmd.push_back(L"--export-secret-keys"); - cmd.push_back(fp); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params)) { - return; - } - if (result == pxNotFound) - return; - boost::algorithm::erase_all(out, "\r"); - file << out.c_str(); - if (file.is_open()) - file.close(); - } + std::ofstream file; + file.open(p, std::ios::trunc | std::ios::out); + if (!file.is_open()) + return; //TODO: handle error + + list_KEY_LIST.GetItemText(i, 0, fp, _countof(fp)); + + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"-a"); + params.addParam(L"--export-secret-keys"); + params.addParam(fp); + if (!gpg_launcher(params)) + return; + if (params.result == pxNotFound) + return; + + params.out.Remove('\r'); + file << params.out.c_str(); + if (file.is_open()) + file.close(); } void CDlgFirstRun::onClick_CHANGE_PASSWD(CCtrlButton*) { - int i = list_KEY_LIST.GetSelectionMark(); + int i = list_KEY_LIST.GetSelectionMark(); if (i == -1) return; + list_KEY_LIST.GetItemText(i, 0, globals.key_id_global, _countof(globals.key_id_global)); // temporary code follows std::string old_pass, new_pass; - string output; - DWORD exitcode; - pxResult result; - - std::vector<std::wstring> cmd; - cmd.push_back(L"--edit-key"); - cmd.push_back(globals.key_id_global); - cmd.push_back(L"passwd"); - - gpg_execution_params_pass *params = new gpg_execution_params_pass(cmd, old_pass, new_pass); - params->out = &output; - params->code = &exitcode; - params->result = &result; - - HANDLE hThread = mir_forkthread(pxEexcute_passwd_change_thread, params); + + gpg_execution_params_pass params(old_pass, new_pass); + params.addParam(L"--edit-key"); + params.addParam(globals.key_id_global); + params.addParam(L"passwd"); + + HANDLE hThread = mir_forkthread(pxEexcute_passwd_change_thread, ¶ms); if (WaitForSingleObject(hThread, 600000) != WAIT_OBJECT_0) { - if (params->child) - boost::process::terminate(*(params->child)); + if (params.child) + boost::process::terminate(*(params.child)); if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": GPG execution timed out, aborted"); this->Close(); @@ -355,7 +329,7 @@ void CDlgFirstRun::onClick_GENERATE_RANDOM(CCtrlButton*) btn_DELETE_KEY.Disable(); list_KEY_LIST.Disable(); btn_GENERATE_RANDOM.Disable(); - gpg_use_new_random_key(combo_ACCOUNT.GetTextA()); + gpg_use_new_random_key(m_szCurrAcc); this->Close(); } @@ -382,21 +356,16 @@ void CDlgFirstRun::onClick_DELETE_KEY(CCtrlButton*) return; list_KEY_LIST.GetItemText(i, 0, fp, _countof(fp)); { - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--fingerprint"); - cmd.push_back(fp); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--fingerprint"); + params.addParam(fp); if (!gpg_launcher(params)) return; - if (result == pxNotFound) + if (params.result == pxNotFound) return; + + string out(params.out); string::size_type s = out.find("Key fingerprint = "); s += mir_strlen("Key fingerprint = "); string::size_type s2 = out.find("\n", s); @@ -409,150 +378,111 @@ void CDlgFirstRun::onClick_DELETE_KEY(CCtrlButton*) str = mir_a2u(tmp.c_str()); } - cmd.clear(); - out.clear(); - cmd.push_back(L"--batch"); - cmd.push_back(L"--delete-secret-and-public-key"); - cmd.push_back(L"--fingerprint"); - cmd.push_back(str); + + params.addParam(L"--batch"); + params.addParam(L"--delete-secret-and-public-key"); + params.addParam(L"--fingerprint"); + params.addParam(str); mir_free(str); if (!gpg_launcher(params)) return; - if (result == pxNotFound) + if (params.result == pxNotFound) return; } - { - char *buf = mir_strdup(combo_ACCOUNT.GetTextA()); - if (!mir_strcmp(buf, Translate("Default"))) { - g_plugin.delSetting("GPGPubKey"); - g_plugin.delSetting("KeyID"); - g_plugin.delSetting("KeyComment"); - g_plugin.delSetting("KeyMainName"); - g_plugin.delSetting("KeyMainEmail"); - g_plugin.delSetting("KeyType"); - } - else { - std::string acc_str = buf; - acc_str += "_GPGPubKey"; - g_plugin.delSetting(acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyMainName"; - g_plugin.delSetting(acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyID"; - g_plugin.delSetting(acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyComment"; - g_plugin.delSetting(acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyMainEmail"; - g_plugin.delSetting(acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyType"; - g_plugin.delSetting(acc_str.c_str()); - } - if (buf) - mir_free(buf); + + if (m_szCurrAcc == nullptr) { + g_plugin.delSetting("GPGPubKey"); + g_plugin.delSetting("KeyID"); + g_plugin.delSetting("KeyComment"); + g_plugin.delSetting("KeyMainName"); + g_plugin.delSetting("KeyMainEmail"); + g_plugin.delSetting("KeyType"); + } + else { + CMStringA acc_str = m_szCurrAcc; + g_plugin.delSetting(acc_str + "_GPGPubKey"); + g_plugin.delSetting(acc_str + "_KeyMainName"); + g_plugin.delSetting(acc_str + "_KeyID"); + g_plugin.delSetting(acc_str + "_KeyComment"); + g_plugin.delSetting(acc_str + "_KeyMainEmail"); + g_plugin.delSetting(acc_str + "_KeyType"); } + list_KEY_LIST.DeleteItem(i); } void CDlgFirstRun::onClick_OK(CCtrlButton*) { - { - int i = list_KEY_LIST.GetSelectionMark(); - if (i == -1) - return; + int i = list_KEY_LIST.GetSelectionMark(); + if (i == -1) + return; - list_KEY_LIST.GetItemText(i, 0, fp, _countof(fp)); - wchar_t *name = new wchar_t[65]; - list_KEY_LIST.GetItemText(i, 2, name, 64); - { - if (wcschr(name, '(')) { - wstring str = name; - wstring::size_type p = str.find(L"(") - 1; - mir_wstrcpy(name, str.substr(0, p).c_str()); - } - } - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"-a"); - cmd.push_back(L"--export"); - cmd.push_back(fp); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params)) { - delete[] name; - return; - } - if (result == pxNotFound) { - delete[] name; - return; + list_KEY_LIST.GetItemText(i, 0, fp, _countof(fp)); + wchar_t name[65]; + list_KEY_LIST.GetItemText(i, 2, name, 64); + { + if (wcschr(name, '(')) { + wstring str = name; + wstring::size_type p = str.find(L"(") - 1; + mir_wstrcpy(name, str.substr(0, p).c_str()); } + } - boost::algorithm::erase_all(out, "\r"); - { - char *buf = mir_strdup(combo_ACCOUNT.GetTextA()); - if (!mir_strcmp(buf, Translate("Default"))) { - g_plugin.setString("GPGPubKey", out.c_str()); - g_plugin.setWString("KeyMainName", name); - g_plugin.setWString("KeyID", fp); - } - else { - std::string acc_str = buf; - acc_str += "_GPGPubKey"; - g_plugin.setString(acc_str.c_str(), out.c_str()); - acc_str = buf; - acc_str += "_KeyMainName"; - g_plugin.setWString(acc_str.c_str(), name); - acc_str = buf; - acc_str += "_KeyID"; - g_plugin.setWString(acc_str.c_str(), fp); - } - if (!mir_strcmp(buf, Translate("Default"))) { - wstring keyinfo = TranslateT("Default private key ID"); - keyinfo += L": "; - keyinfo += (fp[0]) ? fp : L"not set"; - extern HWND hwndCurKey_p; - SetWindowText(hwndCurKey_p, keyinfo.c_str()); - } - if (buf) - mir_free(buf); - } - wchar_t *passwd = mir_wstrdup(edit_KEY_PASSWORD.GetText()); - if (passwd && passwd[0]) { - string dbsetting = "szKey_"; - char *keyid = mir_u2a(fp); - dbsetting += keyid; - mir_free(keyid); - dbsetting += "_Password"; - g_plugin.setWString(dbsetting.c_str(), passwd); - } - mir_free(passwd); - delete[] name; + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"-a"); + params.addParam(L"--export"); + params.addParam(fp); + if (!gpg_launcher(params)) + return; + if (params.result == pxNotFound) + return; + + params.out.Remove('\r'); + + if (m_szCurrAcc == nullptr) { + g_plugin.setString("GPGPubKey", params.out.c_str()); + g_plugin.setWString("KeyMainName", name); + g_plugin.setWString("KeyID", fp); + + wstring keyinfo = TranslateT("Default private key ID"); + keyinfo += L": "; + keyinfo += (fp[0]) ? fp : L"not set"; + extern HWND hwndCurKey_p; + SetWindowText(hwndCurKey_p, keyinfo.c_str()); } + else { + CMStringA acc_str = m_szCurrAcc; + g_plugin.setString(acc_str + "_GPGPubKey", params.out.c_str()); + g_plugin.setWString(acc_str + "_KeyMainName", name); + g_plugin.setWString(acc_str + "_KeyID", fp); + } + + ptrW passwd(edit_KEY_PASSWORD.GetText()); + if (mir_wstrlen(passwd)) { + string dbsetting = "szKey_"; + dbsetting += _T2A(fp); + dbsetting += "_Password"; + g_plugin.setWString(dbsetting.c_str(), passwd); + } + //bAutoExchange = CheckStateStoreDB(hwndDlg, IDC_AUTO_EXCHANGE, "bAutoExchange") != 0; //TODO: check is it just typo, or doing something globals.gpg_valid = isGPGValid(); globals.gpg_keyexist = isGPGKeyExist(); DestroyWindow(m_hwnd); } -void CDlgFirstRun::onChange_ACCOUNT(CCtrlCombo*) +void CDlgFirstRun::onChange_ACCOUNT(CCtrlCombo *pCombo) { CMStringW keyinfo = TranslateT("key ID"); keyinfo += ": "; - ptrA buf(combo_ACCOUNT.GetTextA()); - if (!mir_strcmp(buf, Translate("Default"))) { + m_szCurrAcc = (const char *)pCombo->GetItemData(pCombo->GetCurSel()); + if (m_szCurrAcc == nullptr) { keyinfo += g_plugin.getMStringW("KeyID", TranslateT("not set")); } else { - std::string acc_str = buf; + std::string acc_str = m_szCurrAcc; acc_str += "_KeyID"; keyinfo += g_plugin.getMStringW(acc_str.c_str(), TranslateT("not set")); } @@ -584,142 +514,129 @@ void CDlgFirstRun::refresh_key_list() { list_KEY_LIST.DeleteAllItems(); int i = 1; - { - { - //parse gpg output - string out; - DWORD code; - pxResult result; - wstring::size_type p = 0, p2 = 0, stop = 0; - { - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--list-secret-keys"); - gpg_execution_params params(cmd); - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params)) - return; - if (result == pxNotFound) - return; - } - while (p != string::npos) { - if ((p = out.find("sec ", p)) == string::npos) - break; - p += 5; - if (p < stop) - break; - stop = p; - p2 = out.find("/", p) - 1; - wchar_t *key_len = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()), *creation_date = nullptr, *expire_date = nullptr; - p2 += 2; - p = out.find(" ", p2); - std::wstring key_id = toUTF16(out.substr(p2, p - p2)); - p += 1; - p2 = out.find(" ", p); - std::string::size_type p3 = out.find("\n", p); - if ((p2 != std::string::npos) && (p3 < p2)) { - p2 = p3; - creation_date = mir_wstrdup(toUTF16(out.substr(p, p2 - p - 1)).c_str()); - } - else { - creation_date = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); - p2 = out.find("[", p2); - p2 = out.find("expires:", p2); - p2 += mir_strlen("expires:"); - if (p2 != std::string::npos) { - p2++; - p = p2; - p2 = out.find("]", p); - expire_date = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); - //check expiration - bool expired = false; - { - boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - wchar_t buf[5]; - wcsncpy_s(buf, expire_date, _TRUNCATE); - int year = _wtoi(buf); - if (year < now.date().year()) + + // parse gpg output + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--list-secret-keys"); + if (!gpg_launcher(params)) + return; + if (params.result == pxNotFound) + return; + + wstring::size_type p = 0, p2 = 0, stop = 0; + string out(params.out); + while (p != string::npos) { + if ((p = out.find("sec ", p)) == string::npos) + break; + p += 5; + if (p < stop) + break; + stop = p; + p2 = out.find("/", p) - 1; + wchar_t *key_len = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()), *creation_date = nullptr, *expire_date = nullptr; + p2 += 2; + p = out.find(" ", p2); + std::wstring key_id = toUTF16(out.substr(p2, p - p2)); + p += 1; + p2 = out.find(" ", p); + std::string::size_type p3 = out.find("\n", p); + if ((p2 != std::string::npos) && (p3 < p2)) { + p2 = p3; + creation_date = mir_wstrdup(toUTF16(out.substr(p, p2 - p - 1)).c_str()); + } + else { + creation_date = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); + p2 = out.find("[", p2); + p2 = out.find("expires:", p2); + p2 += mir_strlen("expires:"); + if (p2 != std::string::npos) { + p2++; + p = p2; + p2 = out.find("]", p); + expire_date = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); + //check expiration + bool expired = false; + { + boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); + wchar_t buf[5]; + wcsncpy_s(buf, expire_date, _TRUNCATE); + int year = _wtoi(buf); + if (year < now.date().year()) + expired = true; + else if (year == now.date().year()) { + wcsncpy_s(buf, (expire_date + 5), _TRUNCATE); + int month = _wtoi(buf); + if (month < now.date().month()) + expired = true; + else if (month == now.date().month()) { + wcsncpy_s(buf, (expire_date + 8), _TRUNCATE); + unsigned day = _wtoi(buf); + if (day <= now.date().day_number()) expired = true; - else if (year == now.date().year()) { - wcsncpy_s(buf, (expire_date + 5), _TRUNCATE); - int month = _wtoi(buf); - if (month < now.date().month()) - expired = true; - else if (month == now.date().month()) { - wcsncpy_s(buf, (expire_date + 8), _TRUNCATE); - unsigned day = _wtoi(buf); - if (day <= now.date().day_number()) - expired = true; - } - } - } - if (expired) { - mir_free(key_len); - mir_free(creation_date); - mir_free(expire_date); - //mimic normal behaviour - p = out.find("uid ", p); - p2 = out.find_first_not_of(" ", p + 5); - p = out.find("<", p2); - p++; - //p2 = out.find(">", p); - // - continue; //does not add to key list } } } - int row = list_KEY_LIST.AddItem(L"", 0); - list_KEY_LIST.SetItemText(row, 3, creation_date); - mir_free(creation_date); - if (expire_date) { - list_KEY_LIST.SetItemText(row, 4, expire_date); + if (expired) { + mir_free(key_len); + mir_free(creation_date); mir_free(expire_date); + //mimic normal behaviour + p = out.find("uid ", p); + p2 = out.find_first_not_of(" ", p + 5); + p = out.find("<", p2); + p++; + //p2 = out.find(">", p); + // + continue; //does not add to key list } - list_KEY_LIST.SetItemText(row, 5, key_len); - mir_free(key_len); - list_KEY_LIST.SetItemText(row, 0, (wchar_t*)key_id.c_str()); - p = out.find("uid ", p); - p2 = out.find_first_not_of(" ", p + 5); - p = out.find("<", p2); - - wstring tmp = toUTF16(out.substr(p2, p - p2)); - list_KEY_LIST.SetItemText(row, 2, (wchar_t*)tmp.c_str()); - - p++; - p2 = out.find(">", p); - - tmp = toUTF16(out.substr(p, p2 - p)); - list_KEY_LIST.SetItemText(row, 1, (wchar_t*)tmp.c_str()); - - // get accounts - std::wstring accs; - for (auto &pa : Accounts()) { - std::string setting = toUTF8(pa->tszAccountName); - setting += "("; - setting += pa->szModuleName; - setting += ")"; - setting += "_KeyID"; - ptrW str(g_plugin.getWStringA(setting.c_str(), L"")); - if (key_id == str.get()) { - if (!accs.empty()) - accs += L","; - accs += pa->tszAccountName; - } - } - list_KEY_LIST.SetItemText(row, 6, accs.c_str()); } - i++; - list_KEY_LIST.SetColumnWidth(0, LVSCW_AUTOSIZE); - list_KEY_LIST.SetColumnWidth(1, LVSCW_AUTOSIZE); - list_KEY_LIST.SetColumnWidth(2, LVSCW_AUTOSIZE); - list_KEY_LIST.SetColumnWidth(3, LVSCW_AUTOSIZE); - list_KEY_LIST.SetColumnWidth(4, LVSCW_AUTOSIZE); - list_KEY_LIST.SetColumnWidth(5, LVSCW_AUTOSIZE); - list_KEY_LIST.SetColumnWidth(6, LVSCW_AUTOSIZE); } + int row = list_KEY_LIST.AddItem(L"", 0); + list_KEY_LIST.SetItemText(row, 3, creation_date); + mir_free(creation_date); + if (expire_date) { + list_KEY_LIST.SetItemText(row, 4, expire_date); + mir_free(expire_date); + } + list_KEY_LIST.SetItemText(row, 5, key_len); + mir_free(key_len); + list_KEY_LIST.SetItemText(row, 0, (wchar_t *)key_id.c_str()); + p = out.find("uid ", p); + p2 = out.find_first_not_of(" ", p + 5); + p = out.find("<", p2); + + wstring tmp = toUTF16(out.substr(p2, p - p2)); + list_KEY_LIST.SetItemText(row, 2, (wchar_t *)tmp.c_str()); + + p++; + p2 = out.find(">", p); + + tmp = toUTF16(out.substr(p, p2 - p)); + list_KEY_LIST.SetItemText(row, 1, (wchar_t *)tmp.c_str()); + + // get accounts + std::wstring accs; + for (auto &pa : Accounts()) { + std::string setting = pa->szModuleName; + setting += "_KeyID"; + ptrW str(g_plugin.getWStringA(setting.c_str(), L"")); + if (key_id == str.get()) { + if (!accs.empty()) + accs += L","; + accs += pa->tszAccountName; + } + } + list_KEY_LIST.SetItemText(row, 6, accs.c_str()); } + i++; + list_KEY_LIST.SetColumnWidth(0, LVSCW_AUTOSIZE); + list_KEY_LIST.SetColumnWidth(1, LVSCW_AUTOSIZE); + list_KEY_LIST.SetColumnWidth(2, LVSCW_AUTOSIZE); + list_KEY_LIST.SetColumnWidth(3, LVSCW_AUTOSIZE); + list_KEY_LIST.SetColumnWidth(4, LVSCW_AUTOSIZE); + list_KEY_LIST.SetColumnWidth(5, LVSCW_AUTOSIZE); + list_KEY_LIST.SetColumnWidth(6, LVSCW_AUTOSIZE); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -768,9 +685,9 @@ bool CDlgGpgBinOpts::OnInitDialog() { ptrW tmp; if (!gpg_exists) { - tmp = g_plugin.getWStringA("szGpgBinPath", (SHGetValueW(HKEY_CURRENT_USER, L"Software\\GNU\\GnuPG", L"gpgProgram", 0, (void*)path.c_str(), &len) == ERROR_SUCCESS) ? path.c_str() : L""); + tmp = g_plugin.getWStringA("szGpgBinPath", (SHGetValueW(HKEY_CURRENT_USER, L"Software\\GNU\\GnuPG", L"gpgProgram", 0, (void *)path.c_str(), &len) == ERROR_SUCCESS) ? path.c_str() : L""); if (tmp[0]) - if (!boost::filesystem::exists((wchar_t*)tmp)) + if (!boost::filesystem::exists((wchar_t *)tmp)) MessageBoxW(nullptr, TranslateT("Wrong GPG binary location found in system.\nPlease choose another location"), TranslateT("Warning"), MB_OK); } else tmp = mir_wstrdup(path.c_str()); @@ -778,24 +695,18 @@ bool CDlgGpgBinOpts::OnInitDialog() edit_BIN_PATH.SetText(tmp); if (gpg_exists/* && lang_exists*/) { g_plugin.setWString("szGpgBinPath", tmp); - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--version"); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + + gpg_execution_params params; + params.addParam(L"--version"); bool _gpg_valid = globals.gpg_valid; globals.gpg_valid = true; gpg_launcher(params); globals.gpg_valid = _gpg_valid; //TODO: check this g_plugin.delSetting("szGpgBinPath"); - string::size_type p1 = out.find("(GnuPG) "); - if (p1 != string::npos) { + int p1 = params.out.Find("(GnuPG) "); + if (p1 != -1) { p1 += mir_strlen("(GnuPG) "); - if (out[p1] != '1') + if (params.out[p1] != '1') bad_version = true; } else { @@ -878,7 +789,7 @@ void CDlgGpgBinOpts::onClick_GENERATE_RANDOM(CCtrlButton*) if (gpg_validate_paths(edit_BIN_PATH.GetText(), edit_HOME_DIR.GetText())) { gpg_save_paths(edit_BIN_PATH.GetText(), edit_HOME_DIR.GetText()); globals.gpg_valid = true; - if (gpg_use_new_random_key()) { + if (gpg_use_new_random_key(nullptr)) { g_plugin.setByte("bAutoExchange", globals.bAutoExchange = chk_AUTO_EXCHANGE.GetState()); globals.gpg_valid = true; g_plugin.setByte("FirstRun", 0); @@ -1028,7 +939,7 @@ bool CDlgKeyGen::OnApply() f << "Key-Type: "; char *tmp2 = mir_u2a(combo_KEY_TYPE.GetText()); - char *subkeytype = (char*)mir_alloc(6); + char *subkeytype = (char *)mir_alloc(6); if (strstr(tmp2, "RSA")) mir_strcpy(subkeytype, "RSA"); else if (strstr(tmp2, "DSA")) //this is useless check for now, but it will be required if someone add another key types support @@ -1067,19 +978,6 @@ bool CDlgKeyGen::OnApply() f << "\n"; f.close(); - // gpg execution - DWORD code; - string out; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--yes"); - cmd.push_back(L"--gen-key"); - cmd.push_back(path.c_str()); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; lbl_GENERATING_TEXT.SendMsg(WM_SETFONT, (WPARAM)globals.bold_font, TRUE); lbl_GENERATING_TEXT.SetText(TranslateT("Generating new key, please wait...")); combo_KEY_TYPE.Disable(); @@ -1089,9 +987,16 @@ bool CDlgKeyGen::OnApply() edit_KEY_EMAIL.Disable(); edit_KEY_COMMENT.Disable(); edit_KEY_EXPIRE_DATE.Disable(); + + // gpg execution + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--yes"); + params.addParam(L"--gen-key"); + params.addParam(path.c_str()); if (!gpg_launcher(params, boost::posix_time::minutes(10))) return false; - if (result == pxNotFound) + if (params.result == pxNotFound) return false; boost::filesystem::remove(path.c_str()); @@ -1127,89 +1032,81 @@ bool CDlgLoadExistingKey::OnInitDialog() list_EXISTING_KEY_LIST.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_SINGLEROW); int i = 1; { - {//parse gpg output - string out; - DWORD code; - string::size_type p = 0, p2 = 0, stop = 0; - { - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--list-keys"); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params)) - return false; - if (result == pxNotFound) - return false; - } - while (p != string::npos) { - if ((p = out.find("pub ", p)) == string::npos) - break; - p += 5; - if (p < stop) - break; - stop = p; - p2 = out.find("/", p) - 1; - wchar_t *tmp = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); - int row = list_EXISTING_KEY_LIST.AddItem(L"", 0); - list_EXISTING_KEY_LIST.SetItemText(row, 5, tmp); - mir_free(tmp); - p2 += 2; - p = out.find(" ", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2, p - p2)).c_str()); - list_EXISTING_KEY_LIST.SetItemText(row, 0, tmp); - mir_free(tmp); - p++; - p2 = out.find("\n", p); - string::size_type p3 = out.substr(p, p2 - p).find("["); - if (p3 != string::npos) { - p3 += p; - p2 = p3; - p2--; - p3++; - p3 += mir_strlen("expires: "); - string::size_type p4 = out.find("]", p3); - tmp = mir_wstrdup(toUTF16(out.substr(p3, p4 - p3)).c_str()); - list_EXISTING_KEY_LIST.SetItemText(row, 4, tmp); - mir_free(tmp); - } - else - p2--; - tmp = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); - list_EXISTING_KEY_LIST.SetItemText(row, 3, tmp); + // parse gpg output + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--list-keys"); + if (!gpg_launcher(params)) + return false; + if (params.result == pxNotFound) + return false; + + string out(params.out); + string::size_type p = 0, p2 = 0, stop = 0; + while (p != string::npos) { + if ((p = out.find("pub ", p)) == string::npos) + break; + p += 5; + if (p < stop) + break; + stop = p; + p2 = out.find("/", p) - 1; + wchar_t *tmp = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); + int row = list_EXISTING_KEY_LIST.AddItem(L"", 0); + list_EXISTING_KEY_LIST.SetItemText(row, 5, tmp); + mir_free(tmp); + p2 += 2; + p = out.find(" ", p2); + tmp = mir_wstrdup(toUTF16(out.substr(p2, p - p2)).c_str()); + list_EXISTING_KEY_LIST.SetItemText(row, 0, tmp); + mir_free(tmp); + p++; + p2 = out.find("\n", p); + string::size_type p3 = out.substr(p, p2 - p).find("["); + if (p3 != string::npos) { + p3 += p; + p2 = p3; + p2--; + p3++; + p3 += mir_strlen("expires: "); + string::size_type p4 = out.find("]", p3); + tmp = mir_wstrdup(toUTF16(out.substr(p3, p4 - p3)).c_str()); + list_EXISTING_KEY_LIST.SetItemText(row, 4, tmp); mir_free(tmp); - p = out.find("uid ", p); - p += mir_strlen("uid "); - p2 = out.find("\n", p); - p3 = out.substr(p, p2 - p).find("<"); - if (p3 != string::npos) { - p3 += p; - p2 = p3; - p2--; - p3++; - string::size_type p4 = out.find(">", p3); - tmp = mir_wstrdup(toUTF16(out.substr(p3, p4 - p3)).c_str()); - list_EXISTING_KEY_LIST.SetItemText(row, 1, tmp); - mir_free(tmp); - } - else - p2--; - p = out.find_first_not_of(" ", p); - tmp = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); - list_EXISTING_KEY_LIST.SetItemText(row, 2, tmp); + } + else + p2--; + tmp = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); + list_EXISTING_KEY_LIST.SetItemText(row, 3, tmp); + mir_free(tmp); + p = out.find("uid ", p); + p += mir_strlen("uid "); + p2 = out.find("\n", p); + p3 = out.substr(p, p2 - p).find("<"); + if (p3 != string::npos) { + p3 += p; + p2 = p3; + p2--; + p3++; + string::size_type p4 = out.find(">", p3); + tmp = mir_wstrdup(toUTF16(out.substr(p3, p4 - p3)).c_str()); + list_EXISTING_KEY_LIST.SetItemText(row, 1, tmp); mir_free(tmp); - - list_EXISTING_KEY_LIST.SetColumnWidth(0, LVSCW_AUTOSIZE);// not sure about this - list_EXISTING_KEY_LIST.SetColumnWidth(1, LVSCW_AUTOSIZE); - list_EXISTING_KEY_LIST.SetColumnWidth(2, LVSCW_AUTOSIZE); - list_EXISTING_KEY_LIST.SetColumnWidth(3, LVSCW_AUTOSIZE); - list_EXISTING_KEY_LIST.SetColumnWidth(4, LVSCW_AUTOSIZE); - list_EXISTING_KEY_LIST.SetColumnWidth(5, LVSCW_AUTOSIZE); - i++; } + else + p2--; + p = out.find_first_not_of(" ", p); + tmp = mir_wstrdup(toUTF16(out.substr(p, p2 - p)).c_str()); + list_EXISTING_KEY_LIST.SetItemText(row, 2, tmp); + mir_free(tmp); + + list_EXISTING_KEY_LIST.SetColumnWidth(0, LVSCW_AUTOSIZE);// not sure about this + list_EXISTING_KEY_LIST.SetColumnWidth(1, LVSCW_AUTOSIZE); + list_EXISTING_KEY_LIST.SetColumnWidth(2, LVSCW_AUTOSIZE); + list_EXISTING_KEY_LIST.SetColumnWidth(3, LVSCW_AUTOSIZE); + list_EXISTING_KEY_LIST.SetColumnWidth(4, LVSCW_AUTOSIZE); + list_EXISTING_KEY_LIST.SetColumnWidth(5, LVSCW_AUTOSIZE); + i++; } } list_EXISTING_KEY_LIST.OnClick = Callback(this, &CDlgLoadExistingKey::onChange_EXISTING_KEY_LIST); @@ -1231,27 +1128,18 @@ bool CDlgLoadExistingKey::OnApply() list_EXISTING_KEY_LIST.GetItemText(i, 0, id, _countof(id)); extern CCtrlEdit *edit_p_PubKeyEdit; - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"-a"); - cmd.push_back(L"--export"); - cmd.push_back(id); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"-a"); + params.addParam(L"--export"); + params.addParam(id); if (!gpg_launcher(params)) return false; - if (result == pxNotFound) + if (params.result == pxNotFound) return false; - string::size_type s = 0; - while ((s = out.find("\r", s)) != string::npos) { - out.erase(s, 1); - } + string out(params.out); std::string::size_type p1 = 0, p2 = 0; p1 = out.find("-----BEGIN PGP PUBLIC KEY BLOCK-----"); if (p1 != std::string::npos) { @@ -1271,7 +1159,7 @@ bool CDlgLoadExistingKey::OnApply() return true; } -void CDlgLoadExistingKey::onChange_EXISTING_KEY_LIST(CCtrlListView::TEventInfo * /*ev*/) +void CDlgLoadExistingKey::onChange_EXISTING_KEY_LIST(CCtrlListView::TEventInfo*) { EnableWindow(GetDlgItem(m_hwnd, IDOK), TRUE); } @@ -1304,20 +1192,14 @@ void CDlgImportKey::OnDestroy() void CDlgImportKey::onClick_IMPORT(CCtrlButton*) { - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--keyserver"); - cmd.push_back(combo_KEYSERVER.GetText()); - cmd.push_back(L"--recv-keys"); - cmd.push_back(toUTF16(globals.hcontact_data[hContact].key_in_prescense)); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + gpg_execution_params params; + params.addParam(L"--keyserver"); + params.addParam(combo_KEYSERVER.GetText()); + params.addParam(L"--recv-keys"); + params.addParam(toUTF16(globals.hcontact_data[hContact].key_in_prescense)); gpg_launcher(params); - MessageBoxA(nullptr, out.c_str(), "GPG output", MB_OK); + + MessageBoxA(nullptr, params.out.c_str(), "GPG output", MB_OK); } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/New_GPG/src/ui.h b/plugins/New_GPG/src/ui.h index fcbbe60caa..02e3fcb579 100755 --- a/plugins/New_GPG/src/ui.h +++ b/plugins/New_GPG/src/ui.h @@ -60,6 +60,7 @@ class CDlgFirstRun : public CDlgBase CCtrlCombo combo_ACCOUNT; CCtrlData lbl_KEY_ID, lbl_GENERATING_KEY; wchar_t fp[16]; + const char *m_szCurrAcc = nullptr; public: CDlgFirstRun(); diff --git a/plugins/New_GPG/src/utilities.cpp b/plugins/New_GPG/src/utilities.cpp index cef68df7e3..31a470aaba 100755 --- a/plugins/New_GPG/src/utilities.cpp +++ b/plugins/New_GPG/src/utilities.cpp @@ -104,25 +104,22 @@ INT_PTR LoadKey(WPARAM w, LPARAM) INT_PTR SendKey(WPARAM w, LPARAM) { MCONTACT hContact = db_mc_tryMeta(w); - CMStringA szMessage; std::string key_id_str; - { - LPSTR proto = Proto_GetBaseAccountName(hContact); - PROTOACCOUNT *acc = Proto_GetAccount(proto); - std::string acc_str; - if (acc) { - acc_str = toUTF8(acc->tszAccountName); - acc_str += "("; - acc_str += acc->szModuleName; - acc_str += ")"; - key_id_str = acc_str; - key_id_str += "_KeyID"; - acc_str += "_GPGPubKey"; - } - szMessage = g_plugin.getMStringA(acc_str.empty() ? "GPGPubKey" : acc_str.c_str()); - if (szMessage.IsEmpty()) - szMessage = g_plugin.getMStringA("GPGPubKey"); //try to get default key as fallback in any way + + LPSTR proto = Proto_GetBaseAccountName(hContact); + PROTOACCOUNT *acc = Proto_GetAccount(proto); + std::string acc_str; + if (acc) { + acc_str = acc->szModuleName; + key_id_str = acc_str; + key_id_str += "_KeyID"; + acc_str += "_GPGPubKey"; } + + CMStringA szMessage = g_plugin.getMStringA(acc_str.empty() ? "GPGPubKey" : acc_str.c_str()); + if (szMessage.IsEmpty()) + szMessage = g_plugin.getMStringA("GPGPubKey"); //try to get default key as fallback in any way + if (!szMessage.IsEmpty()) { BYTE enc = g_plugin.getByte(hContact, "GPGEncryption", 0); g_plugin.setByte(hContact, "GPGEncryption", 0); @@ -179,10 +176,7 @@ int OnPreBuildContactMenu(WPARAM w, LPARAM) PROTOACCOUNT *acc = Proto_GetAccount(proto); std::string setting; if (acc) { - setting = toUTF8(acc->tszAccountName); - setting += "("; - setting += acc->szModuleName; - setting += ")"; + setting = acc->szModuleName; setting += "_KeyID"; } @@ -252,11 +246,9 @@ int onProtoAck(WPARAM, LPARAM l) HistoryLog(ack->hContact, db_event("Received encrypted file, trying to decrypt", 0, 0, 0)); if (!boost::filesystem::exists(f->szCurrentFile.w)) return 0; - string out; - DWORD code; - pxResult result; - std::vector<wstring> cmd; - cmd.push_back(L"-o"); + + gpg_execution_params params; + params.addParam(L"-o"); wstring file = filename; wstring::size_type p1 = file.rfind(L".gpg"); file.erase(p1, mir_wstrlen(L".gpg")); @@ -264,7 +256,7 @@ int onProtoAck(WPARAM, LPARAM l) if (MessageBox(nullptr, TranslateT("Target file exists, do you want to replace it?"), TranslateT("Warning"), MB_YESNO) == IDNO) return 0; } - cmd.push_back(file); + params.addParam(file); boost::filesystem::remove(file); { // password @@ -284,26 +276,24 @@ int onProtoAck(WPARAM, LPARAM l) globals.debuglog << std::string(time_str() + ": info: found password for all keys in database, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(ack->hContact)) + " with password"); } if (!pass.IsEmpty()) { - cmd.push_back(L"--passphrase"); - cmd.push_back(pass.c_str()); + params.addParam(L"--passphrase"); + params.addParam(pass.c_str()); } else if (!globals.wszPassword.IsEmpty()) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: found password in memory, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(ack->hContact)) + " with password"); - cmd.push_back(L"--passphrase"); - cmd.push_back(globals.wszPassword.c_str()); + params.addParam(L"--passphrase"); + params.addParam(globals.wszPassword.c_str()); } else if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: passwords not found in database or memory, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(ack->hContact)) + " with out password"); } - cmd.push_back(L"-d"); - cmd.push_back(filename); - gpg_execution_params params(cmd); - params.out = &out; - params.code = &code; - params.result = &result; + params.addParam(L"-d"); + params.addParam(filename); if (!gpg_launcher(params, boost::posix_time::minutes(15))) return 0; + + string out(params.out); while (out.find("public key decryption failed: bad passphrase") != string::npos) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: failed to decrypt messaage from " + toUTF8(Clist_GetContactDisplayName(ack->hContact)) + " password needed, trying to get one"); @@ -321,26 +311,21 @@ int onProtoAck(WPARAM, LPARAM l) } CDlgKeyPasswordMsgBox *d = new CDlgKeyPasswordMsgBox(ack->hContact); d->DoModal(); - std::vector<wstring> cmd2 = cmd; + if (!globals.wszPassword.IsEmpty()) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: found password in memory, trying to decrypt message from " + toUTF8(Clist_GetContactDisplayName(ack->hContact))); - std::vector<wstring> tmp; - tmp.push_back(L"--passphrase"); - tmp.push_back(globals.wszPassword.c_str()); - cmd2.insert(cmd2.begin(), tmp.begin(), tmp.end()); + + params.addParam(L"--passphrase"); + params.addParam(globals.wszPassword.c_str()); } - out.clear(); - gpg_execution_params params2(cmd2); - params2.out = &out; - params2.code = &code; - params2.result = &result; - if (!gpg_launcher(params2, boost::posix_time::seconds(15))) + + if (!gpg_launcher(params, boost::posix_time::seconds(15))) return 0; - if (result == pxNotFound) + if (params.result == pxNotFound) return 0; } - if (result == pxSuccess) + if (params.result == pxSuccess) boost::filesystem::remove(filename); } mir_free(filename); @@ -369,14 +354,12 @@ int onProtoAck(WPARAM, LPARAM l) std::wstring encrypt_file(MCONTACT hContact, wchar_t *filename) { - string out; - DWORD code; - pxResult result; MCONTACT hcnt = db_mc_isMeta(hContact) ? metaGetMostOnline(hContact) : hContact; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--tes"); - cmd.push_back(L"-r"); + + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--tes"); + params.addParam(L"-r"); CMStringW keyid = g_plugin.getMStringW(hcnt, "KeyID"); wchar_t *name = wcsrchr(filename, '\\'); @@ -386,41 +369,36 @@ std::wstring encrypt_file(MCONTACT hContact, wchar_t *filename) name++; wchar_t *file_out = new wchar_t[mir_wstrlen(name) + mir_wstrlen(L".gpg") + 1]; mir_snwprintf(file_out, mir_wstrlen(name) + mir_wstrlen(L".gpg") + 1, L"%s.gpg", name); - cmd.push_back(keyid.c_str()); + params.addParam(keyid.c_str()); if (g_plugin.getByte(hcnt, "bAlwaysTrust")) { - cmd.push_back(L"--trust-model"); - cmd.push_back(L"always"); + params.addParam(L"--trust-model"); + params.addParam(L"always"); } - cmd.push_back(L"-o"); + params.addParam(L"-o"); wchar_t *temp = _tgetenv(L"TEMP"); - cmd.push_back(wstring(temp) + L"\\" + file_out); + params.addParam(wstring(temp) + L"\\" + file_out); wstring path_out = temp; path_out += L"\\"; path_out += file_out; boost::filesystem::remove(path_out); - cmd.push_back(L"-e"); - cmd.push_back(filename); - gpg_execution_params params(cmd); - params.out = &out; - params.code = &code; - params.result = &result; + params.addParam(L"-e"); + params.addParam(filename); delete[] file_out; + if (!gpg_launcher(params, boost::posix_time::minutes(3))) return nullptr; - if (out.find("There is no assurance this key belongs to the named user") != string::npos) { - out.clear(); - if (MessageBox(nullptr, TranslateT("We're trying to encrypt with untrusted key. Do you want to trust this key permanently?"), TranslateT("Warning"), MB_YESNO) == IDYES) { - g_plugin.setByte(hcnt, "bAlwaysTrust", 1); - std::vector<std::wstring> tmp; - tmp.push_back(L"--trust-model"); - tmp.push_back(L"always"); - cmd.insert(cmd.begin(), tmp.begin(), tmp.end()); - if (!gpg_launcher(params, boost::posix_time::minutes(3))) - return nullptr; - } - else + + if (params.out.Find("There is no assurance this key belongs to the named user") != -1) { + if (IDYES != MessageBox(nullptr, TranslateT("We're trying to encrypt with untrusted key. Do you want to trust this key permanently?"), TranslateT("Warning"), MB_YESNO)) + return nullptr; + + g_plugin.setByte(hcnt, "bAlwaysTrust", 1); + + params.addParam(L"--trust-model"); + params.addParam(L"always"); + if (!gpg_launcher(params, boost::posix_time::minutes(3))) return nullptr; } return path_out; @@ -627,9 +605,7 @@ static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, TiXmlElement *node, break; } - string out; - DWORD code; - std::vector<wstring> cmd; + gpg_execution_params params; { char setting[64]; mir_snprintf(setting, sizeof(setting) - 1, "%s_KeyID", ji->GetModuleName()); @@ -652,33 +628,29 @@ static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, TiXmlElement *node, globals.debuglog << std::string(time_str() + ": info: found password for all keys in database, trying to encrypt message from self with password"); } if (pass[0]) { - cmd.push_back(L"--passphrase"); - cmd.push_back(pass.c_str()); + params.addParam(L"--passphrase"); + params.addParam(pass.c_str()); } else if (!globals.wszPassword.IsEmpty()) { if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: found password in memory, trying to encrypt message from self with password"); - cmd.push_back(L"--passphrase"); - cmd.push_back(globals.wszPassword.c_str()); + params.addParam(L"--passphrase"); + params.addParam(globals.wszPassword.c_str()); } else if (globals.bDebugLog) globals.debuglog << std::string(time_str() + ": info: passwords not found in database or memory, trying to encrypt message from self with out password"); } - cmd.push_back(L"--local-user"); - cmd.push_back(g_plugin.getMStringW("KeyID").c_str()); - cmd.push_back(L"--default-key"); - cmd.push_back(g_plugin.getMStringW("KeyID").c_str()); - cmd.push_back(L"--batch"); - cmd.push_back(L"--yes"); - cmd.push_back(L"-abs"); - cmd.push_back(Utf2T(path_out.c_str()).get()); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + params.addParam(L"--local-user"); + params.addParam(g_plugin.getMStringW("KeyID").c_str()); + params.addParam(L"--default-key"); + params.addParam(g_plugin.getMStringW("KeyID").c_str()); + params.addParam(L"--batch"); + params.addParam(L"--yes"); + params.addParam(L"-abs"); + params.addParam(Utf2T(path_out.c_str()).get()); gpg_launcher(params, boost::posix_time::seconds(15)); // TODO: handle errors + boost::filesystem::remove(path_out); path_out += ".asc"; f.open(path_out.c_str(), std::ios::in | std::ios::ate | std::ios::binary); @@ -794,27 +766,22 @@ static JABBER_HANDLER_FUNC PresenceHandler(IJabberInterface*, TiXmlElement* node globals.debuglog << std::string(time_str() + ": info: Failed to write sign in file"); return FALSE; } - { //gpg - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--verify"); - cmd.push_back(L"-a"); - cmd.push_back(path_out.c_str()); - cmd.push_back(status_file_out.c_str()); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; - if (!gpg_launcher(params, boost::posix_time::seconds(15))) { + { + // gpg + gpg_execution_params params; + params.addParam(L"--verify"); + params.addParam(L"-a"); + params.addParam(path_out.c_str()); + params.addParam(status_file_out.c_str()); + if (!gpg_launcher(params, boost::posix_time::seconds(15))) return FALSE; - } - if (result == pxNotFound) { + if (params.result == pxNotFound) return FALSE; - } + boost::filesystem::remove(path_out.c_str()); boost::filesystem::remove(status_file_out.c_str()); + + string out(params.out); if (out.find("key ID ") != string::npos) { //need to get hcontact here, i can get jid from hxml, and get handle from jid, maybe exists better way ? string::size_type p1 = out.find("key ID ") + mir_strlen("key ID "); @@ -925,21 +892,14 @@ bool isGPGValid() if (gpg_exists) { g_plugin.setWString("szGpgBinPath", tmp); - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--version"); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + gpg_execution_params params; + params.addParam(L"--version"); bool _gpg_valid = globals.gpg_valid; globals.gpg_valid = true; gpg_launcher(params); globals.gpg_valid = _gpg_valid; //TODO: check this - string::size_type p1 = out.find("(GnuPG) "); - if (p1 == string::npos) + int p1 = params.out.Find("(GnuPG) "); + if (p1 == -1) is_valid = false; } @@ -1255,22 +1215,14 @@ void ExportGpGKeysFunc(int type) } if (type == 1 || type == 2) { - string out; - DWORD code; - pxResult result; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"-export-secret-keys"); - cmd.push_back(L"-a"); - gpg_execution_params params(cmd); - params.out = &out; - params.code = &code; - params.result = &result; + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"-export-secret-keys"); + params.addParam(L"-a"); gpg_launcher(params); //TODO: handle errors - { - file << out.c_str(); - file << std::endl; - } + + file << params.out.c_str(); + file << std::endl; } if (file.is_open()) file.close(); @@ -1467,9 +1419,8 @@ INT_PTR ImportGpGKeys(WPARAM, LPARAM) } if (found) { CMStringW path = g_plugin.getMStringW("szHomePath"); - std::vector<std::wstring> cmd; - string output; - DWORD exitcode; + + gpg_execution_params params; { wstring rand = toUTF16(get_random(10)); path += L"\\"; @@ -1478,22 +1429,18 @@ INT_PTR ImportGpGKeys(WPARAM, LPARAM) wfstream f(path, std::ios::out); f << toUTF16(key).c_str(); f.close(); - cmd.push_back(L"--batch"); - cmd.push_back(L"--import"); - cmd.push_back(path.c_str()); + params.addParam(L"--batch"); + params.addParam(L"--import"); + params.addParam(path.c_str()); } - gpg_execution_params params(cmd); - pxResult result; - params.out = &output; - params.code = &exitcode; - params.result = &result; if (!gpg_launcher(params)) break; - if (result == pxNotFound) + if (params.result == pxNotFound) break; - if (result == pxSuccess) + if (params.result == pxSuccess) processed_keys++; { + string output(params.out); if (output.find("already in secret keyring") != string::npos) { MessageBox(nullptr, TranslateT("Key already in secret keyring."), TranslateT("Info"), MB_OK); boost::filesystem::remove(path.c_str()); @@ -1567,10 +1514,6 @@ INT_PTR ImportGpGKeys(WPARAM, LPARAM) key.clear(); } else if (strstr(line, "-----END PGP PRIVATE KEY BLOCK-----")) { - std::vector<wstring> cmd; - string output; - DWORD exitcode; - CMStringW tmp2 = g_plugin.getMStringW("szHomePath"); tmp2 += L"\\temporary_exported.asc"; boost::filesystem::remove(tmp2.c_str()); @@ -1578,20 +1521,16 @@ INT_PTR ImportGpGKeys(WPARAM, LPARAM) wfstream f(tmp2, std::ios::out); f << toUTF16(key).c_str(); f.close(); - cmd.push_back(L"--batch"); - cmd.push_back(L"--import"); - cmd.push_back(tmp2.c_str()); - gpg_execution_params params(cmd); - - pxResult result; - params.out = &output; - params.code = &exitcode; - params.result = &result; + + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--import"); + params.addParam(tmp2.c_str()); if (!gpg_launcher(params)) break; - if (result == pxNotFound) + if (params.result == pxNotFound) break; - if (result == pxSuccess) + if (params.result == pxSuccess) processed_private_keys++; key.clear(); } @@ -1701,24 +1640,18 @@ bool gpg_validate_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path) { bool bad_version = false; g_plugin.setWString("szGpgBinPath", tmp.c_str()); - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--version"); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + + gpg_execution_params params; + params.addParam(L"--version"); bool _gpg_valid = globals.gpg_valid; globals.gpg_valid = true; gpg_launcher(params); globals.gpg_valid = _gpg_valid; //TODO: check this g_plugin.delSetting("szGpgBinPath"); - string::size_type p1 = out.find("(GnuPG) "); - if (p1 != string::npos) { + int p1 = params.out.Find("(GnuPG) "); + if (p1 != -1) { p1 += mir_strlen("(GnuPG) "); - if (out[p1] != '1') + if (params.out[p1] != '1') bad_version = true; } else { @@ -1753,103 +1686,78 @@ void gpg_save_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path) g_plugin.setWString("szHomePath", gpg_home_path); } -bool gpg_use_new_random_key(char *account_name, wchar_t *gpg_bin_path, wchar_t *gpg_home_dir) +bool gpg_use_new_random_key(const char *account_name) { - if (gpg_bin_path && gpg_home_dir) - gpg_save_paths(gpg_bin_path, gpg_home_dir); - - CMStringW path; - { - // generating key file - if (gpg_home_dir) - path = gpg_home_dir; - else - path = g_plugin.getMStringW("szHomePath"); + CMStringW path = g_plugin.getMStringW("szHomePath"); + path += L"\\new_key"; - path += L"\\new_key"; - wfstream f(path.c_str(), std::ios::out); - if (!f.is_open()) { - MessageBox(nullptr, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK); - return false; - } - f << "Key-Type: RSA"; - f << "\n"; - f << "Key-Length: 4096"; - f << "\n"; - f << "Subkey-Type: RSA"; - f << "\n"; - f << "Name-Real: "; - f << get_random(6).c_str(); - f << "\n"; - f << "Name-Email: "; - f << get_random(5).c_str(); - f << "@"; - f << get_random(5).c_str(); - f << "."; - f << get_random(3).c_str(); - f << "\n"; - f.close(); + // generating key file + wfstream f(path.c_str(), std::ios::out); + if (!f.is_open()) { + MessageBox(nullptr, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK); + return false; } - { // gpg execution - DWORD code; - string out; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"--yes"); - cmd.push_back(L"--gen-key"); - cmd.push_back(path.c_str()); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + f << "Key-Type: RSA"; + f << "\n"; + f << "Key-Length: 4096"; + f << "\n"; + f << "Subkey-Type: RSA"; + f << "\n"; + f << "Name-Real: "; + f << get_random(6).c_str(); + f << "\n"; + f << "Name-Email: "; + f << get_random(5).c_str(); + f << "@"; + f << get_random(5).c_str(); + f << "."; + f << get_random(3).c_str(); + f << "\n"; + f.close(); + + { + // gpg execution + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"--yes"); + params.addParam(L"--gen-key"); + params.addParam(path.c_str()); if (!gpg_launcher(params, boost::posix_time::minutes(10))) return false; - if (result == pxNotFound) + if (params.result == pxNotFound) return false; boost::filesystem::remove(path.c_str()); - string::size_type p1 = 0; - if ((p1 = out.find("key ")) != string::npos) - path = toUTF16(out.substr(p1 + 4, 8)).c_str(); + string out(params.out); + int p1 = params.out.Find("key "); + if (p1 != -1) + path = ptrW(mir_utf8decodeW(params.out.Mid(p1 + 4, 8).c_str())); else path.Empty(); } if (!path.IsEmpty()) { - string out; - DWORD code; - std::vector<wstring> cmd; - cmd.push_back(L"--batch"); - cmd.push_back(L"-a"); - cmd.push_back(L"--export"); - cmd.push_back(path.c_str()); - gpg_execution_params params(cmd); - pxResult result; - params.out = &out; - params.code = &code; - params.result = &result; + gpg_execution_params params; + params.addParam(L"--batch"); + params.addParam(L"-a"); + params.addParam(L"--export"); + params.addParam(path.c_str()); if (!gpg_launcher(params)) return false; - if (result == pxNotFound) + if (params.result == pxNotFound) return false; - string::size_type s = 0; - while ((s = out.find("\r", s)) != string::npos) - out.erase(s, 1); + params.out.Remove('\r'); - if (!mir_strcmp(account_name, Translate("Default"))) { - g_plugin.setString("GPGPubKey", out.c_str()); + if (account_name == nullptr) { + g_plugin.setString("GPGPubKey", params.out.c_str()); g_plugin.setWString("KeyID", path.c_str()); } else { - std::string acc_str = account_name; - acc_str += "_GPGPubKey"; - g_plugin.setString(acc_str.c_str(), out.c_str()); - acc_str = account_name; - acc_str += "_KeyID"; - g_plugin.setWString(acc_str.c_str(), path.c_str()); + CMStringA acc_str = account_name; + g_plugin.setString(acc_str + "_GPGPubKey", params.out.c_str()); + g_plugin.setWString(acc_str + "_KeyID", path.c_str()); } } return true; diff --git a/plugins/New_GPG/src/utilities.h b/plugins/New_GPG/src/utilities.h index 46dc1a2c15..3cb8f20314 100755 --- a/plugins/New_GPG/src/utilities.h +++ b/plugins/New_GPG/src/utilities.h @@ -107,6 +107,6 @@ void strip_tags(std::wstring &s); void clean_temp_dir(); bool gpg_validate_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path); void gpg_save_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path); -bool gpg_use_new_random_key(char *account_name = Translate("Default"), wchar_t *gpg_bin_path = nullptr, wchar_t *gpg_home_dir = nullptr); +bool gpg_use_new_random_key(const char *account_name); #endif |