summaryrefslogtreecommitdiff
path: root/plugins/New_GPG
diff options
context:
space:
mode:
authorGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-12-08 07:42:32 +0300
committerGluzskiy Alexandr <sss@sss.chaoslab.ru>2017-12-08 07:42:32 +0300
commitcaff89011ee731657192dc076b6a1ea54fcee520 (patch)
tree2390a84cb56fbd7a472533efda7b24ea409f389e /plugins/New_GPG
parentb3d3b95a16be5b1785681f0f6fdc3bcdb967a42e (diff)
new_gpg: a bit of refactoring
- eliminated few confusing globals (including unnecessary mutex) - implemeted proper way to avoid collisions in some places
Diffstat (limited to 'plugins/New_GPG')
-rwxr-xr-xplugins/New_GPG/src/globals.h3
-rwxr-xr-xplugins/New_GPG/src/init.cpp6
-rwxr-xr-xplugins/New_GPG/src/main.cpp1541
-rwxr-xr-xplugins/New_GPG/src/main.h2
-rwxr-xr-xplugins/New_GPG/src/messages.cpp95
-rwxr-xr-xplugins/New_GPG/src/options.cpp14
-rwxr-xr-xplugins/New_GPG/src/ui.cpp1279
-rwxr-xr-xplugins/New_GPG/src/ui.h120
-rwxr-xr-xplugins/New_GPG/src/utilities.cpp186
-rwxr-xr-xplugins/New_GPG/src/utilities.h3
10 files changed, 1626 insertions, 1623 deletions
diff --git a/plugins/New_GPG/src/globals.h b/plugins/New_GPG/src/globals.h
index 0434802bea..9b63ae4358 100755
--- a/plugins/New_GPG/src/globals.h
+++ b/plugins/New_GPG/src/globals.h
@@ -33,9 +33,6 @@ struct globals_s
std::map<MCONTACT, contact_data> hcontact_data;
map<int, MCONTACT> user_data;
bool _terminate;
- wstring new_key;
- MCONTACT new_key_hcnt;
- boost::mutex new_key_hcnt_mutex;
int item_num; //TODO: get rid of this
diff --git a/plugins/New_GPG/src/init.cpp b/plugins/New_GPG/src/init.cpp
index fc83d06c14..1736462b5e 100755
--- a/plugins/New_GPG/src/init.cpp
+++ b/plugins/New_GPG/src/init.cpp
@@ -215,9 +215,9 @@ extern "C" int __declspec(dllexport) Unload(void)
{
if(!transfers.empty())
{
- for(list<wstring>::iterator p = transfers.begin(); p != transfers.end(); p++)
- if(!(*p).empty())
- boost::filesystem::remove((*p));
+ for(auto p : transfers)
+ if(!p.empty())
+ boost::filesystem::remove(p);
}
mir_free(globals.inopentag);
mir_free(globals.inclosetag);
diff --git a/plugins/New_GPG/src/main.cpp b/plugins/New_GPG/src/main.cpp
index a8404fec3e..fe5db8a1e5 100755
--- a/plugins/New_GPG/src/main.cpp
+++ b/plugins/New_GPG/src/main.cpp
@@ -18,1513 +18,13 @@
#pragma comment(lib, "shlwapi.lib")
-void ShowFirstRunDialog();
-
-HWND hwndFirstRun = nullptr, hwndSetDirs = nullptr, hwndNewKey = nullptr, hwndKeyGen = nullptr, hwndSelectExistingKey = nullptr;
-
-//int itemnum = 0;
-
-HWND hwndList_g = nullptr;
-BOOL CheckStateStoreDB(HWND hwndDlg, int idCtrl, const char* szSetting)
-{
- BOOL state = IsDlgButtonChecked(hwndDlg, idCtrl);
- db_set_b(NULL, szGPGModuleName, szSetting, (BYTE)state);
- return state;
-}
-
-bool gpg_validate_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path)
-{
- wstring tmp = gpg_bin_path;
- if (!tmp.empty()) {
- wchar_t mir_path[MAX_PATH];
- PathToAbsoluteW(L"\\", mir_path);
- SetCurrentDirectoryW(mir_path);
- if (!boost::filesystem::exists(tmp)) {
- MessageBox(nullptr, TranslateT("GPG binary does not exist.\nPlease choose another location"), TranslateT("Warning"), MB_OK);
- return false;
- }
- }
- else {
- MessageBox(nullptr, TranslateT("Please choose GPG binary location"), TranslateT("Warning"), MB_OK);
- return false;
- }
- {
- bool bad_version = false;
- db_set_ws(NULL, szGPGModuleName, "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;
- bool _gpg_valid = globals.gpg_valid;
- globals.gpg_valid = true;
- gpg_launcher(params);
- globals.gpg_valid = _gpg_valid; //TODO: check this
- db_unset(NULL, szGPGModuleName, "szGpgBinPath");
- string::size_type p1 = out.find("(GnuPG) ");
- if (p1 != string::npos) {
- p1 += mir_strlen("(GnuPG) ");
- if (out[p1] != '1')
- bad_version = true;
- }
- else {
- bad_version = false;
- MessageBox(nullptr, TranslateT("This is not GnuPG binary!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Warning"), MB_OK);
- return false;
- }
- if (bad_version)
- MessageBox(nullptr, TranslateT("Unsupported GnuPG version found, use at you own risk!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Warning"), MB_OK);
- }
- tmp = gpg_home_path;
- if (tmp[tmp.length()] == '\\')
- tmp.erase(tmp.length());
- if (tmp.empty()) {
- MessageBox(nullptr, TranslateT("Please set keyring's home directory"), TranslateT("Warning"), MB_OK);
- return false;
- }
- {
- wchar_t *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"");
- DWORD dwFileAttr = GetFileAttributes(path);
- if (dwFileAttr != INVALID_FILE_ATTRIBUTES) {
- dwFileAttr &= ~FILE_ATTRIBUTE_READONLY;
- SetFileAttributes(path, dwFileAttr);
- }
- mir_free(path);
- }
- return true;
-}
-
-void gpg_save_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path)
-{
- db_set_ws(NULL, szGPGModuleName, "szGpgBinPath", gpg_bin_path);
- db_set_ws(NULL, szGPGModuleName, "szHomePath", 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)
-{
- if (gpg_bin_path && gpg_home_dir)
- gpg_save_paths(gpg_bin_path, gpg_home_dir);
- {
- wstring path;
- {
- // generating key file
- wchar_t *tmp = nullptr;
- if (gpg_home_dir)
- tmp = gpg_home_dir;
- else
- tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"");
- path = tmp;
- if(!gpg_home_dir)
- mir_free(tmp);
- path.append(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();
- }
- { // 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);
- gpg_execution_params params(cmd);
- pxResult result;
- params.out = &out;
- params.code = &code;
- params.result = &result;
- if (!gpg_launcher(params, boost::posix_time::minutes(10)))
- return false;
- if (result == pxNotFound)
- return false;
-
- boost::filesystem::remove(path);
- string::size_type p1 = 0;
- if ((p1 = out.find("key ")) != string::npos)
- path = toUTF16(out.substr(p1 + 4, 8));
- else
- path.clear();
- }
- if (!path.empty()) {
- 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);
- 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;
- string::size_type s = 0;
- while ((s = out.find("\r", s)) != string::npos) {
- out.erase(s, 1);
- }
- {
- if (!mir_strcmp(account_name, Translate("Default")))
- {
- db_set_s(NULL, szGPGModuleName, "GPGPubKey", out.c_str());
- db_set_ws(NULL, szGPGModuleName, "KeyID", path.c_str());
- }
- else
- {
- std::string acc_str = account_name;
- acc_str += "_GPGPubKey";
- db_set_s(NULL, szGPGModuleName, acc_str.c_str(), out.c_str());
- acc_str = account_name;
- acc_str += "_KeyID";
- db_set_ws(NULL, szGPGModuleName, acc_str.c_str(), path.c_str());
- }
- }
- }
- }
- return true;
-}
-
-class CDlgFirstRun : public CDlgBase
-{
-public:
- CDlgFirstRun() : CDlgBase(globals.hInst, IDD_FIRST_RUN),
- list_KEY_LIST(this, IDC_KEY_LIST),
- btn_COPY_PUBKEY(this, IDC_COPY_PUBKEY), btn_EXPORT_PRIVATE(this, IDC_EXPORT_PRIVATE), btn_CHANGE_PASSWD(this, IDC_CHANGE_PASSWD), btn_GENERATE_RANDOM(this, IDC_GENERATE_RANDOM),
- btn_GENERATE_KEY(this, IDC_GENERATE_KEY), btn_OTHER(this, IDC_OTHER), btn_DELETE_KEY(this, IDC_DELETE_KEY), btn_OK(this, ID_OK),
- edit_KEY_PASSWORD(this, IDC_KEY_PASSWORD),
- combo_ACCOUNT(this, IDC_ACCOUNT),
- lbl_KEY_ID(this, IDC_KEY_ID), lbl_GENERATING_KEY(this, IDC_GENERATING_KEY)
- {
- fp[0] = 0;
- hwndList_g = list_KEY_LIST.GetHwnd();
-
- btn_COPY_PUBKEY.OnClick = Callback(this, &CDlgFirstRun::onClick_COPY_PUBKEY);
- btn_EXPORT_PRIVATE.OnClick = Callback(this, &CDlgFirstRun::onClick_EXPORT_PRIVATE);
- btn_CHANGE_PASSWD.OnClick = Callback(this, &CDlgFirstRun::onClick_CHANGE_PASSWD);
- btn_GENERATE_RANDOM.OnClick = Callback(this, &CDlgFirstRun::onClick_GENERATE_RANDOM);
- btn_GENERATE_KEY.OnClick = Callback(this, &CDlgFirstRun::onClick_GENERATE_KEY);
- btn_OTHER.OnClick = Callback(this, &CDlgFirstRun::onClick_OTHER);
- btn_DELETE_KEY.OnClick = Callback(this, &CDlgFirstRun::onClick_DELETE_KEY);
- btn_OK.OnClick = Callback(this, &CDlgFirstRun::onClick_OK);
-
- }
- virtual void OnInitDialog() override
- {
- SetWindowPos(m_hwnd, nullptr, globals.firstrun_rect.left, globals.firstrun_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
- SetCaption(TranslateT("Set own key"));
- btn_COPY_PUBKEY.Disable();
- btn_EXPORT_PRIVATE.Disable();
- btn_CHANGE_PASSWD.Disable();
-
- list_KEY_LIST.AddColumn(0, TranslateT("Key ID"), 50);
- list_KEY_LIST.AddColumn(1, TranslateT("Email"), 30);
- list_KEY_LIST.AddColumn(2, TranslateT("Name"), 250);
- list_KEY_LIST.AddColumn(3, TranslateT("Creation date"), 30);
- list_KEY_LIST.AddColumn(4, TranslateT("Expire date"), 30);
- list_KEY_LIST.AddColumn(5, TranslateT("Key length"), 30);
- list_KEY_LIST.AddColumn(6, TranslateT("Accounts"), 30);
- list_KEY_LIST.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_SINGLEROW);
-
- refresh_key_list();
-
- {
- combo_ACCOUNT.AddString(TranslateT("Default"));
- int count = 0;
- PROTOACCOUNT **accounts;
- Proto_EnumAccounts(&count, &accounts);
- for (int n = 0; n < count; n++) {
- if (StriStr(accounts[n]->szModuleName, "metacontacts"))
- continue;
- if (StriStr(accounts[n]->szModuleName, "weather"))
- continue;
- std::string acc = toUTF8(accounts[n]->tszAccountName);
- acc += "(";
- acc += accounts[n]->szModuleName;
- acc += ")";
- //acc += "_KeyID";
- combo_ACCOUNT.AddStringA(acc.c_str());
- }
- combo_ACCOUNT.SelectString(TranslateT("Default"));
- string keyinfo = Translate("key ID");
- keyinfo += ": ";
- char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
- keyinfo += (mir_strlen(keyid) > 0) ? keyid : Translate("not set");
- mir_free(keyid);
- lbl_KEY_ID.SetTextA(keyinfo.c_str());
- }
- combo_ACCOUNT.OnChange = Callback(this, &CDlgFirstRun::onChange_ACCOUNT);
- list_KEY_LIST.OnItemChanged = Callback(this, &CDlgFirstRun::onChange_KEY_LIST);
- }
- void 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();
- }
- }
- void onClick_EXPORT_PRIVATE(CCtrlButton*)
- {
- {
- int i = list_KEY_LIST.GetSelectionMark();
- if (i == -1)
- return;
- wchar_t *p = GetFilePath(L"Choose file to export key", L"*", L"Any file", true);
- if (!p || !p[0]) {
- delete[] p;
- //TODO: handle error
- return;
- }
- char *path = mir_u2a(p);
- delete[] p;
- std::ofstream file;
- file.open(path, std::ios::trunc | std::ios::out);
- mir_free(path);
- 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;
- if (file.is_open())
- file.close();
- }
- }
- void onClick_CHANGE_PASSWD(CCtrlButton*)
- {
- 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::vector<std::wstring> cmd;
- std::string old_pass, new_pass;
- string output;
- DWORD exitcode;
- cmd.push_back(L"--edit-key");
- cmd.push_back(globals.key_id_global);
- cmd.push_back(L"passwd");
- gpg_execution_params_pass params(cmd, old_pass, new_pass);
- pxResult result;
- params.out = &output;
- params.code = &exitcode;
- params.result = &result;
- boost::thread gpg_thread(boost::bind(&pxEexcute_passwd_change_thread, &params));
- if (!gpg_thread.timed_join(boost::posix_time::minutes(10))) {
- gpg_thread.~thread();
- if (params.child)
- boost::process::terminate(*(params.child));
- if (globals.bDebugLog)
- globals.debuglog << std::string(time_str() + ": GPG execution timed out, aborted");
- this->Close();
- }
-
- }
- void onClick_GENERATE_RANDOM(CCtrlButton*)
- {
- lbl_GENERATING_KEY.SendMsg(WM_SETFONT, (WPARAM)globals.bold_font, TRUE);
- lbl_GENERATING_KEY.SetText(TranslateT("Generating new random key, please wait"));
- btn_GENERATE_KEY.Disable();
- btn_OTHER.Disable();
- btn_DELETE_KEY.Disable();
- list_KEY_LIST.Disable();
- btn_GENERATE_RANDOM.Disable();
- gpg_use_new_random_key(combo_ACCOUNT.GetTextA());
- this->Close();
- }
- void onClick_GENERATE_KEY(CCtrlButton*)
- {
- void ShowKeyGenDialog();
- ShowKeyGenDialog();
- refresh_key_list();
- }
- void onClick_OTHER(CCtrlButton*)
- {
- void ShowLoadPublicKeyDialog(bool = false);
- globals.item_num = 0; //black magic here
- globals.user_data[1] = 0;
- ShowLoadPublicKeyDialog(true);
- refresh_key_list();
- }
- void onClick_DELETE_KEY(CCtrlButton*)
- {
- int i = list_KEY_LIST.GetSelectionMark();
- if (i == -1)
- 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;
- if (!gpg_launcher(params))
- return;
- if (result == pxNotFound)
- return;
- string::size_type s = out.find("Key fingerprint = ");
- s += mir_strlen("Key fingerprint = ");
- string::size_type s2 = out.find("\n", s);
- wchar_t *str = nullptr;
- {
- string tmp = out.substr(s, s2 - s - 1).c_str();
- string::size_type p = 0;
- while ((p = tmp.find(" ", p)) != string::npos)
- tmp.erase(p, 1);
-
- 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);
- mir_free(str);
- if (!gpg_launcher(params))
- return;
- if (result == pxNotFound)
- return;
- }
- {
- char *buf = mir_strdup(combo_ACCOUNT.GetTextA());
- if (!mir_strcmp(buf, Translate("Default"))) {
- db_unset(NULL, szGPGModuleName, "GPGPubKey");
- db_unset(NULL, szGPGModuleName, "KeyID");
- db_unset(NULL, szGPGModuleName, "KeyComment");
- db_unset(NULL, szGPGModuleName, "KeyMainName");
- db_unset(NULL, szGPGModuleName, "KeyMainEmail");
- db_unset(NULL, szGPGModuleName, "KeyType");
- }
- else {
- std::string acc_str = buf;
- acc_str += "_GPGPubKey";
- db_unset(NULL, szGPGModuleName, acc_str.c_str());
- acc_str = buf;
- acc_str += "_KeyMainName";
- db_unset(NULL, szGPGModuleName, acc_str.c_str());
- acc_str = buf;
- acc_str += "_KeyID";
- db_unset(NULL, szGPGModuleName, acc_str.c_str());
- acc_str = buf;
- acc_str += "_KeyComment";
- db_unset(NULL, szGPGModuleName, acc_str.c_str());
- acc_str = buf;
- acc_str += "_KeyMainEmail";
- db_unset(NULL, szGPGModuleName, acc_str.c_str());
- acc_str = buf;
- acc_str += "_KeyType";
- db_unset(NULL, szGPGModuleName, acc_str.c_str());
- }
- if (buf)
- mir_free(buf);
- }
- list_KEY_LIST.DeleteItem(i);
- }
- void onClick_OK(CCtrlButton*)
- {
- {
- 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;
- }
-
- boost::algorithm::erase_all(out, "\r");
- {
- char *buf = mir_strdup(combo_ACCOUNT.GetTextA());
- if (!mir_strcmp(buf, Translate("Default"))) {
- db_set_s(NULL, szGPGModuleName, "GPGPubKey", out.c_str());
- db_set_ws(NULL, szGPGModuleName, "KeyMainName", name);
- db_set_ws(NULL, szGPGModuleName, "KeyID", fp);
- }
- else {
- std::string acc_str = buf;
- acc_str += "_GPGPubKey";
- db_set_s(NULL, szGPGModuleName, acc_str.c_str(), out.c_str());
- acc_str = buf;
- acc_str += "_KeyMainName";
- db_set_ws(NULL, szGPGModuleName, acc_str.c_str(), name);
- acc_str = buf;
- acc_str += "_KeyID";
- db_set_ws(NULL, szGPGModuleName, 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";
- db_set_ws(NULL, szGPGModuleName, dbsetting.c_str(), passwd);
- }
- mir_free(passwd);
- delete[] name;
- }
- //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 onChange_ACCOUNT(CCtrlCombo*)
- {
- char *buf = mir_strdup(combo_ACCOUNT.GetTextA());
- if (!mir_strcmp(buf, Translate("Default"))) {
- string keyinfo = Translate("key ID");
- keyinfo += ": ";
- char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
- keyinfo += (mir_strlen(keyid) > 0) ? keyid : Translate("not set");
- mir_free(keyid);
- lbl_KEY_ID.SetTextA(keyinfo.c_str());
- }
- else {
- string keyinfo = Translate("key ID");
- keyinfo += ": ";
- std::string acc_str = buf;
- acc_str += "_KeyID";
- char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, acc_str.c_str(), "");
- keyinfo += (mir_strlen(keyid) > 0) ? keyid : Translate("not set");
- mir_free(keyid);
- lbl_KEY_ID.SetTextA(keyinfo.c_str());
- }
- if (buf)
- mir_free(buf);
- }
- void onChange_KEY_LIST(CCtrlListView::TEventInfo *ev) //TODO: check if this work
- {
- if (ev->nmlv)
- {
- NMLISTVIEW *hdr = ev->nmlv;
-
- if (hdr->hdr.code == NM_CLICK) {
- btn_OK.Enable();
- btn_COPY_PUBKEY.Enable();
- btn_EXPORT_PRIVATE.Enable();
- btn_CHANGE_PASSWD.Enable();
- }
- }
- }
- virtual void OnDestroy() override
- {
- GetWindowRect(m_hwnd, &globals.firstrun_rect);
- db_set_dw(NULL, szGPGModuleName, "FirstrunWindowX", globals.firstrun_rect.left);
- db_set_dw(NULL, szGPGModuleName, "FirstrunWindowY", globals.firstrun_rect.top);
- hwndFirstRun = nullptr;
- delete this;
- }
-
-private:
- void 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())
- 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);
- 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
- int count = 0;
- PROTOACCOUNT **accounts;
- Proto_EnumAccounts(&count, &accounts);
- std::wstring accs;
- for (int n = 0; n < count; n++) {
- std::string setting = toUTF8(accounts[n]->tszAccountName);
- setting += "(";
- setting += accounts[n]->szModuleName;
- setting += ")";
- setting += "_KeyID";
- wchar_t *str = UniGetContactSettingUtf(NULL, szGPGModuleName, setting.c_str(), L"");
- if (key_id == str) {
- if (!accs.empty())
- accs += L",";
- accs += accounts[n]->tszAccountName;
- }
- mir_free(str);
- }
- list_KEY_LIST.SetItemText(row, 6, (wchar_t*)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);
- }
- }
- }
- CCtrlListView list_KEY_LIST;
- CCtrlButton btn_COPY_PUBKEY, btn_EXPORT_PRIVATE, btn_CHANGE_PASSWD, btn_GENERATE_RANDOM, btn_GENERATE_KEY, btn_OTHER, btn_DELETE_KEY, btn_OK;
- CCtrlEdit edit_KEY_PASSWORD;
- CCtrlCombo combo_ACCOUNT;
- CCtrlData lbl_KEY_ID, lbl_GENERATING_KEY;
- wchar_t fp[16];
-};
-
-
-class CDlgGpgBinOpts : public CDlgBase
-{
-public:
- CDlgGpgBinOpts() : CDlgBase(globals.hInst, IDD_BIN_PATH),
- btn_SET_BIN_PATH(this, IDC_SET_BIN_PATH), btn_SET_HOME_DIR(this, IDC_SET_HOME_DIR), btn_OK(this, ID_OK), btn_GENERATE_RANDOM(this, IDC_GENERATE_RANDOM),
- edit_BIN_PATH(this, IDC_BIN_PATH), edit_HOME_DIR(this, IDC_HOME_DIR),
- chk_AUTO_EXCHANGE(this, IDC_AUTO_EXCHANGE)
- {
- btn_SET_BIN_PATH.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_SET_BIN_PATH);
- btn_SET_HOME_DIR.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_SET_HOME_DIR);
- btn_OK.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_OK);
- btn_GENERATE_RANDOM.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_GENERATE_RANDOM);
- }
- virtual void OnInitDialog() override
- {
- CMStringW path;
- bool gpg_exists = false, lang_exists = false;
- {
- wchar_t mir_path[MAX_PATH];
- PathToAbsoluteW(L"\\", mir_path);
- SetCurrentDirectoryW(mir_path);
-
- CMStringW gpg_path(mir_path); gpg_path.Append(L"\\GnuPG\\gpg.exe");
- CMStringW gpg_lang_path(mir_path); gpg_lang_path.Append(L"\\GnuPG\\gnupg.nls\\en@quot.mo");
-
- if (boost::filesystem::exists(gpg_path.c_str())) {
- gpg_exists = true;
- path = L"GnuPG\\gpg.exe";
- }
- else path = gpg_path;
-
- if (boost::filesystem::exists(gpg_lang_path.c_str()))
- lang_exists = true;
- if (gpg_exists && !lang_exists)
- MessageBox(nullptr, TranslateT("GPG binary found in Miranda folder, but English locale does not exist.\nIt's highly recommended that you place \\gnupg.nls\\en@quot.mo in GnuPG folder under Miranda root.\nWithout this file you may experience many problems with GPG output on non-English systems\nand plugin may completely not work.\nYou have been warned."), TranslateT("Warning"), MB_OK);
- }
- DWORD len = MAX_PATH;
- bool bad_version = false;
- {
- ptrW tmp;
- if (!gpg_exists) {
- tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "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))
- MessageBox(nullptr, TranslateT("Wrong GPG binary location found in system.\nPlease choose another location"), TranslateT("Warning"), MB_OK);
- }
- else tmp = mir_wstrdup(path.c_str());
-
- edit_BIN_PATH.SetText(tmp);
- if (gpg_exists/* && lang_exists*/) {
- db_set_ws(NULL, szGPGModuleName, "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;
- bool _gpg_valid = globals.gpg_valid;
- globals.gpg_valid = true;
- gpg_launcher(params);
- globals.gpg_valid = _gpg_valid; //TODO: check this
- db_unset(NULL, szGPGModuleName, "szGpgBinPath");
- string::size_type p1 = out.find("(GnuPG) ");
- if (p1 != string::npos) {
- p1 += mir_strlen("(GnuPG) ");
- if (out[p1] != '1')
- bad_version = true;
- }
- else {
- bad_version = false;
- MessageBox(nullptr, TranslateT("This is not GnuPG binary!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Error"), MB_OK);
- }
- if (bad_version)
- MessageBox(nullptr, TranslateT("Unsupported GnuPG version found, use at you own risk!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Warning"), MB_OK);
- }
- }
- {
- ptrW tmp(UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L""));
- if (!tmp[0]) {
- wchar_t mir_path[MAX_PATH];
- PathToAbsoluteW(L"\\", mir_path);
- mir_wstrcat(mir_path, L"\\gpg");
- if (_waccess(mir_path, 0) != -1) {
- tmp = mir_wstrdup(mir_path);
- MessageBox(nullptr, TranslateT("\"GPG\" directory found in Miranda root.\nAssuming it's GPG home directory.\nGPG home directory set."), TranslateT("Info"), MB_OK);
- }
- else {
- wstring path_ = _wgetenv(L"APPDATA");
- path_ += L"\\GnuPG";
- tmp = mir_wstrdup(path_.c_str());
- }
- }
- edit_HOME_DIR.SetText(!gpg_exists ? tmp : L"gpg");
- }
- //TODO: additional check for write access
- if (gpg_exists && lang_exists && !bad_version)
- MessageBox(nullptr, TranslateT("Your GPG version is supported. The language file was found.\nGPG plugin should work fine.\nPress OK to continue."), TranslateT("Info"), MB_OK);
- chk_AUTO_EXCHANGE.Enable();
- }
- void onClick_SET_BIN_PATH(CCtrlButton*)
- {
- GetFilePath(L"Choose gpg.exe", "szGpgBinPath", L"*.exe", L"EXE Executables");
- CMStringW tmp(ptrW(UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", L"gpg.exe")));
- edit_BIN_PATH.SetText(tmp);
- wchar_t mir_path[MAX_PATH];
- PathToAbsoluteW(L"\\", mir_path);
- if (tmp.Find(mir_path, 0) == 0)
- {
- CMStringW path = tmp.Mid(mir_wstrlen(mir_path));
- edit_BIN_PATH.SetText(path);
- }
-
- }
- void onClick_SET_HOME_DIR(CCtrlButton*)
- {
- GetFolderPath(L"Set home directory", "szHomePath");
- CMStringW tmp(ptrW(UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"")));
- edit_HOME_DIR.SetText(tmp);
- wchar_t mir_path[MAX_PATH];
- PathToAbsoluteW(L"\\", mir_path);
- PathToAbsoluteW(L"\\", mir_path);
- if (tmp.Find(mir_path, 0) == 0) {
- CMStringW path = tmp.Mid(mir_wstrlen(mir_path));
- edit_HOME_DIR.SetText(path);
- }
-
- }
- void onClick_OK(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;
- db_set_b(NULL, szGPGModuleName, "FirstRun", 0);
- this->Hide();
- ShowFirstRunDialog();
- this->Close();
- }
- }
- void 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())
- {
- db_set_b(NULL, szGPGModuleName, "bAutoExchange", globals.bAutoExchange = chk_AUTO_EXCHANGE.GetState());
- globals.gpg_valid = true;
- db_set_b(NULL, szGPGModuleName, "FirstRun", 0);
- this->Close();
- }
- }
- }
- virtual void OnDestroy() override
- {
- hwndSetDirs = nullptr;
- void InitCheck();
- InitCheck();
- delete this;
- }
-private:
- CCtrlButton btn_SET_BIN_PATH, btn_SET_HOME_DIR, btn_OK, btn_GENERATE_RANDOM;
- CCtrlEdit edit_BIN_PATH, edit_HOME_DIR;
- CCtrlCheck chk_AUTO_EXCHANGE;
-};
-
-class CDlgNewKey : public CDlgBase
-{
-public:
- CDlgNewKey() : CDlgBase(globals.hInst, IDD_NEW_KEY),
- lbl_KEY_FROM(this, IDC_KEY_FROM), lbl_MESSAGE(this, IDC_MESSAGE),
- btn_IMPORT(this, ID_IMPORT), btn_IMPORT_AND_USE(this, IDC_IMPORT_AND_USE), btn_IGNORE_KEY(this, IDC_IGNORE_KEY)
- {
- hContact = INVALID_CONTACT_ID;
- btn_IMPORT.OnClick = Callback(this, &CDlgNewKey::onClick_IMPORT);
- btn_IMPORT_AND_USE.OnClick = Callback(this, &CDlgNewKey::onClick_IMPORT_AND_USE);
- btn_IGNORE_KEY.OnClick = Callback(this, &CDlgNewKey::onClick_IGNORE_KEY);
-
- }
- virtual void OnInitDialog() override
- {
- hContact = globals.new_key_hcnt;
- //new_key_hcnt_mutex.unlock();
- SetWindowPos(m_hwnd, nullptr, globals.new_key_rect.left, globals.new_key_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
- wchar_t *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", L"");
- lbl_MESSAGE.SetText(tmp[0] ? TranslateT("There is existing key for contact, would you like to replace it with new key?") : TranslateT("New public key was received, do you want to import it?"));
- btn_IMPORT_AND_USE.Enable(db_get_b(hContact, szGPGModuleName, "GPGEncryption", 0));
- btn_IMPORT.SetText(tmp[0] ? TranslateT("Replace") : TranslateT("Accept"));
- mir_free(tmp);
- tmp = new wchar_t[256];
- mir_snwprintf(tmp, 255 * sizeof(wchar_t), TranslateT("Received key from %s"), pcli->pfnGetContactDisplayName(hContact, 0));
- lbl_KEY_FROM.SetText(tmp);
- mir_free(tmp);
- }
- virtual void OnDestroy() override
- {
- GetWindowRect(m_hwnd, &globals.new_key_rect);
- db_set_dw(NULL, szGPGModuleName, "NewKeyWindowX", globals.new_key_rect.left);
- db_set_dw(NULL, szGPGModuleName, "NewKeyWindowY", globals.new_key_rect.top);
- delete this;
- }
- void onClick_IMPORT(CCtrlButton*)
- {
- void ImportKey();
- ImportKey();
- this->Close();
- }
- void onClick_IMPORT_AND_USE(CCtrlButton*)
- {
- void ImportKey();
- ImportKey();
- db_set_b(hContact, szGPGModuleName, "GPGEncryption", 1);
- void setSrmmIcon(MCONTACT hContact);
- void setClistIcon(MCONTACT hContact);
- setSrmmIcon(hContact);
- setClistIcon(hContact);
- this->Close();
- }
- void onClick_IGNORE_KEY(CCtrlButton*)
- {
- this->Close();
- }
-private:
- MCONTACT hContact;
- CCtrlData lbl_KEY_FROM, lbl_MESSAGE;
- CCtrlButton btn_IMPORT, btn_IMPORT_AND_USE, btn_IGNORE_KEY;
-};
-
-class CDlgKeyGen : public CDlgBase //TODO: in modal mode window destroying on any button press even without direct "Close" call
-{
-public:
- CDlgKeyGen() : CDlgBase(globals.hInst, IDD_KEY_GEN),
- combo_KEY_TYPE(this, IDC_KEY_TYPE),
- edit_KEY_LENGTH(this, IDC_KEY_LENGTH), edit_KEY_PASSWD(this, IDC_KEY_PASSWD), edit_KEY_REAL_NAME(this, IDC_KEY_REAL_NAME), edit_KEY_EMAIL(this, IDC_KEY_EMAIL), edit_KEY_COMMENT(this, IDC_KEY_COMMENT),
- edit_KEY_EXPIRE_DATE(this, IDC_KEY_EXPIRE_DATE),
- lbl_GENERATING_TEXT(this, IDC_GENERATING_TEXT),
- btn_OK(this, IDOK), btn_CANCEL(this, IDCANCEL)
- {
- btn_OK.OnClick = Callback(this, &CDlgKeyGen::onClick_OK);
- btn_CANCEL.OnClick = Callback(this, &CDlgKeyGen::onClick_CANCEL);
- }
- virtual void OnInitDialog() override
- {
- SetWindowPos(m_hwnd, nullptr, globals.key_gen_rect.left, globals.key_gen_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
- SetCaption(TranslateT("Key Generation dialog"));
- combo_KEY_TYPE.AddString(L"RSA");
- combo_KEY_TYPE.AddString(L"DSA");
- combo_KEY_TYPE.SelectString(L"RSA");
- edit_KEY_EXPIRE_DATE.SetText(L"0");
- edit_KEY_LENGTH.SetText(L"4096");
- }
-
- void onClick_OK(CCtrlButton*)
- {
- {
- wstring path;
- { //data sanity checks
- wchar_t *tmp = mir_wstrdup(combo_KEY_TYPE.GetText());
- if (!tmp)
- {
- MessageBox(nullptr, TranslateT("You must set encryption algorithm first"), TranslateT("Error"), MB_OK);
- return;
- }
- if (mir_wstrlen(tmp) < 3)
- {
- mir_free(tmp);
- tmp = nullptr;
- MessageBox(nullptr, TranslateT("You must set encryption algorithm first"), TranslateT("Error"), MB_OK);
- return;
- }
- mir_free(tmp);
- tmp = mir_wstrdup(edit_KEY_LENGTH.GetText());
- if (!tmp)
- {
- MessageBox(nullptr, TranslateT("Key length must be of length from 1024 to 4096 bits"), TranslateT("Error"), MB_OK);
- return;
- }
- int length = _wtoi(tmp);
- mir_free(tmp);
- if (length < 1024 || length > 4096) {
- MessageBox(nullptr, TranslateT("Key length must be of length from 1024 to 4096 bits"), TranslateT("Error"), MB_OK);
- return;
- }
- tmp = mir_wstrdup(edit_KEY_EXPIRE_DATE.GetText());
- if (!tmp)
- {
- MessageBox(nullptr, TranslateT("Invalid date"), TranslateT("Error"), MB_OK);
- return;
- }
- if (mir_wstrlen(tmp) != 10 && tmp[0] != '0') {
- MessageBox(nullptr, TranslateT("Invalid date"), TranslateT("Error"), MB_OK);
- mir_free(tmp);
- return;
- }
- mir_free(tmp);
- tmp = mir_wstrdup(edit_KEY_REAL_NAME.GetText());
- if (!tmp)
- {
- MessageBox(nullptr, TranslateT("Name must contain at least 5 characters"), TranslateT("Error"), MB_OK);
- return;
- }
- if (mir_wstrlen(tmp) < 5) {
- MessageBox(nullptr, TranslateT("Name must contain at least 5 characters"), TranslateT("Error"), MB_OK);
- mir_free(tmp);
- return;
- }
- else if (wcschr(tmp, '(') || wcschr(tmp, ')'))
- {
- MessageBox(nullptr, TranslateT("Name cannot contain '(' or ')'"), TranslateT("Error"), MB_OK);
- mir_free(tmp);
- return;
- }
- mir_free(tmp);
- tmp = mir_wstrdup(edit_KEY_EMAIL.GetText());
- if (!tmp)
- {
- MessageBox(nullptr, TranslateT("Invalid Email"), TranslateT("Error"), MB_OK);
- return;
- }
- if ((mir_wstrlen(tmp)) < 5 || (!wcschr(tmp, '@')) || (!wcschr(tmp, '.'))) {
- MessageBox(nullptr, TranslateT("Invalid Email"), TranslateT("Error"), MB_OK);
- mir_free(tmp);
- return;
- }
- mir_free(tmp);
- }
- { //generating key file
- wchar_t *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"");
- char *tmp2;// = mir_u2a(tmp);
- path = tmp;
- mir_free(tmp);
- // mir_free(tmp2);
- path.append(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;
- }
- f << "Key-Type: ";
- tmp2 = mir_u2a(combo_KEY_TYPE.GetText());
- 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
- mir_strcpy(subkeytype, "ELG-E");
- f << tmp2;
- mir_free(tmp2);
- f << "\n";
- f << "Key-Length: ";
- f << _wtoi(edit_KEY_LENGTH.GetText());
- f << "\n";
- f << "Subkey-Length: ";
- f << _wtoi(edit_KEY_LENGTH.GetText());
- f << "\n";
- f << "Subkey-Type: ";
- f << subkeytype;
- mir_free(subkeytype);
- f << "\n";
- if (edit_KEY_PASSWD.GetText()[0])
- {
- f << "Passphrase: ";
- f << toUTF8(edit_KEY_PASSWD.GetText()).c_str();
- f << "\n";
- }
- f << "Name-Real: ";
- f << toUTF8(edit_KEY_REAL_NAME.GetText()).c_str();
- f << "\n";
- if (edit_KEY_COMMENT.GetText()[0])
- {
- f << "Name-Comment: ";
- f << toUTF8(edit_KEY_COMMENT.GetText()).c_str();
- f << "\n";
- }
- f << "Name-Email: ";
- f << toUTF8(edit_KEY_EMAIL.GetText()).c_str();
- f << "\n";
- f << "Expire-Date: ";
- f << toUTF8(edit_KEY_EXPIRE_DATE.GetText()).c_str();
- 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);
- 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..."));
- btn_CANCEL.Disable();
- btn_OK.Disable();
- combo_KEY_TYPE.Disable();
- edit_KEY_LENGTH.Disable();
- edit_KEY_PASSWD.Disable();
- edit_KEY_REAL_NAME.Disable();
- edit_KEY_EMAIL.Disable();
- edit_KEY_COMMENT.Disable();
- edit_KEY_EXPIRE_DATE.Disable();
- if (!gpg_launcher(params, boost::posix_time::minutes(10)))
- return;
- if (result == pxNotFound)
- return;
- }
- boost::filesystem::remove(path);
- }
- this->Close();
- }
- void onClick_CANCEL(CCtrlButton*)
- {
- this->Close();
- }
- virtual void OnDestroy() override
- {
- GetWindowRect(m_hwnd, &globals.key_gen_rect);
- db_set_dw(NULL, szGPGModuleName, "KeyGenWindowX", globals.key_gen_rect.left);
- db_set_dw(NULL, szGPGModuleName, "KeyGenWindowY", globals.key_gen_rect.top);
- delete this;
- }
-
-private:
- CCtrlCombo combo_KEY_TYPE;
- CCtrlEdit edit_KEY_LENGTH, edit_KEY_PASSWD, edit_KEY_REAL_NAME, edit_KEY_EMAIL, edit_KEY_COMMENT, edit_KEY_EXPIRE_DATE;
- CCtrlData lbl_GENERATING_TEXT;
- CCtrlButton btn_OK, btn_CANCEL;
-
-};
-
-int itemnum2 = 0;
-
-class CDlgLoadExistingKey : public CDlgBase
-{
-public:
- CDlgLoadExistingKey() : CDlgBase(globals.hInst, IDD_LOAD_EXISTING_KEY),
- btn_OK(this, IDOK), btn_CANCEL(this, IDCANCEL),
- list_EXISTING_KEY_LIST(this, IDC_EXISTING_KEY_LIST)
- {
- id[0] = 0;
- btn_OK.OnClick = Callback(this, &CDlgLoadExistingKey::onClick_OK);
- btn_CANCEL.OnClick = Callback(this, &CDlgLoadExistingKey::onClick_CANCEL);
-
- }
- virtual void OnInitDialog() override
- {
- SetWindowPos(m_hwnd, nullptr, globals.load_existing_key_rect.left, globals.load_existing_key_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
-
-
- list_EXISTING_KEY_LIST.AddColumn(0, TranslateT("Key ID"), 50);
- list_EXISTING_KEY_LIST.AddColumn(1, TranslateT("Email"), 30);
- list_EXISTING_KEY_LIST.AddColumn(2, TranslateT("Name"), 250);
- list_EXISTING_KEY_LIST.AddColumn(3, TranslateT("Creation date"), 30);
- list_EXISTING_KEY_LIST.AddColumn(4, TranslateT("Expiration date"), 30);
- list_EXISTING_KEY_LIST.AddColumn(5, TranslateT("Key length"), 30);
- 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;
- if (result == pxNotFound)
- return;
- }
- 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);
- 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);
- mir_free(tmp);
- // p = out.find("sub ", p2) + 6;
- // p = out.find(" ", p) + 1;
- // p2 = out.find("\n", p);
- // tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p-1)).c_str());
- // ListView_SetItemText(hwndList, iRow, 3, 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.OnItemChanged = Callback(this, &CDlgLoadExistingKey::onChange_EXISTING_KEY_LIST);
- }
- virtual void OnDestroy() override
- {
- GetWindowRect(m_hwnd, &globals.load_existing_key_rect);
- db_set_dw(NULL, szGPGModuleName, "LoadExistingKeyWindowX", globals.load_existing_key_rect.left);
- db_set_dw(NULL, szGPGModuleName, "LoadExistingKeyWindowY", globals.load_existing_key_rect.top);
- delete this;
- }
- void onClick_OK(CCtrlButton*)
- {
- int i = list_EXISTING_KEY_LIST.GetSelectionMark();
- if (i == -1)
- return; //TODO: error message
-
- 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;
- if (!gpg_launcher(params))
- return;
- if (result == pxNotFound)
- return;
- string::size_type s = 0;
- while ((s = out.find("\r", s)) != string::npos) {
- out.erase(s, 1);
- }
- std::string::size_type p1 = 0, p2 = 0;
- p1 = out.find("-----BEGIN PGP PUBLIC KEY BLOCK-----");
- if (p1 != std::string::npos) {
- p2 = out.find("-----END PGP PUBLIC KEY BLOCK-----", p1);
- if (p2 != std::string::npos) {
- p2 += mir_strlen("-----END PGP PUBLIC KEY BLOCK-----");
- out = out.substr(p1, p2 - p1);
- wchar_t *tmp = mir_a2u(out.c_str());
- if (edit_p_PubKeyEdit)
- edit_p_PubKeyEdit->SetText(tmp);
- mir_free(tmp);
- }
- else
- MessageBox(nullptr, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK);
- }
- else
- MessageBox(nullptr, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK);
- // SetDlgItemText(hPubKeyEdit, IDC_PUBLIC_KEY_EDIT, tmp);
- this->Close();
- }
- void onClick_CANCEL(CCtrlButton*)
- {
- this->Close();
- }
- void onChange_EXISTING_KEY_LIST(CCtrlListView::TEventInfo * /*ev*/) //TODO: check if this work
- {
- if (list_EXISTING_KEY_LIST.GetSelectionMark() != -1)
- btn_OK.Enable();
- }
-private:
- wchar_t id[16];
- CCtrlButton btn_OK, btn_CANCEL;
- CCtrlListView list_EXISTING_KEY_LIST;
-};
-
-class CDlgImportKey : public CDlgBase
-{
-public:
- CDlgImportKey() : CDlgBase(globals.hInst, IDD_IMPORT_KEY),
- combo_KEYSERVER(this, IDC_KEYSERVER),
- btn_IMPORT(this, IDC_IMPORT)
- {
- hContact = INVALID_CONTACT_ID;
- btn_IMPORT.OnClick = Callback(this, &CDlgImportKey::onClick_IMPORT);
- }
- virtual void OnInitDialog() override
- {
- hContact = globals.new_key_hcnt;
- globals.new_key_hcnt_mutex.unlock();
- SetWindowPos(m_hwnd, nullptr, globals.import_key_rect.left, globals.import_key_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
- combo_KEYSERVER.AddString(L"subkeys.pgp.net");
- combo_KEYSERVER.AddString(L"keys.gnupg.net");
- }
- virtual void OnDestroy() override
- {
- GetWindowRect(m_hwnd, &globals.import_key_rect);
- db_set_dw(NULL, szGPGModuleName, "ImportKeyWindowX", globals.import_key_rect.left);
- db_set_dw(NULL, szGPGModuleName, "ImportKeyWindowY", globals.import_key_rect.top);
- delete this;
- }
- void 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_launcher(params);
- MessageBoxA(nullptr, out.c_str(), "GPG output", MB_OK);
- }
-private:
- MCONTACT hContact;
- CCtrlCombo combo_KEYSERVER;
- CCtrlButton btn_IMPORT;
-};
-
-
-void ShowFirstRunDialog()
-{
- CDlgFirstRun *d = new CDlgFirstRun;
- d->Show();
-}
-
-
-void ShowSetDirsDialog()
-{
- CDlgGpgBinOpts *d = new CDlgGpgBinOpts;
- d->Show();
-}
-
-void ShowNewKeyDialog()
-{
- CDlgNewKey *d = new CDlgNewKey;
- d->Show();
-}
-
-void ShowKeyGenDialog()
-{
- CDlgKeyGen *d = new CDlgKeyGen;
- d->DoModal();
-}
-
-void ShowSelectExistingKeyDialog()
-{
- CDlgLoadExistingKey *d = new CDlgLoadExistingKey;
- d->DoModal();
-}
-
-void ShowImportKeyDialog()
-{
- CDlgImportKey *d = new CDlgImportKey; //TODO: shoud it be modal ?
- d->Show();
-}
void FirstRun()
{
if (!db_get_b(NULL, szGPGModuleName, "FirstRun", 1))
return;
- ShowSetDirsDialog();
+ CDlgGpgBinOpts *d = new CDlgGpgBinOpts;
+ d->Show();
}
void InitCheck()
@@ -1623,7 +123,10 @@ void InitCheck()
question += toUTF8(accounts[i]->tszAccountName);
question += Translate(" deleted from GPG secret keyring.\nDo you want to set another key?");
if (MessageBoxA(nullptr, question.c_str(), Translate("Own secret key warning"), MB_YESNO) == IDYES)
- ShowFirstRunDialog();
+ {
+ CDlgFirstRun *d = new CDlgFirstRun;
+ d->DoModal();
+ }
}
p2 = p;
p = out.find("[", p);
@@ -1661,7 +164,10 @@ void InitCheck()
question += toUTF8(accounts[i]->tszAccountName);
question += Translate(" expired and will not work.\nDo you want to set another key?");
if (MessageBoxA(nullptr, question.c_str(), Translate("Own secret key warning"), MB_YESNO) == IDYES)
- ShowFirstRunDialog();
+ {
+ CDlgFirstRun *d = new CDlgFirstRun;
+ d->DoModal();
+ }
}
mir_free(expire_date);
}
@@ -1677,13 +183,19 @@ void InitCheck()
if (!db_get_b(NULL, szGPGModuleName, "FirstRun", 1) && (!keyid[0] || !key[0])) {
question = Translate("You didn't set a private key.\nWould you like to set it now?");
if (MessageBoxA(nullptr, question.c_str(), Translate("Own private key warning"), MB_YESNO) == IDYES)
- ShowFirstRunDialog();
+ {
+ CDlgFirstRun *d = new CDlgFirstRun;
+ d->DoModal();
+ }
}
if ((p = out.find(keyid)) == string::npos) {
question += keyid;
question += Translate(" deleted from GPG secret keyring.\nDo you want to set another key?");
if (MessageBoxA(nullptr, question.c_str(), Translate("Own secret key warning"), MB_YESNO) == IDYES)
- ShowFirstRunDialog();
+ {
+ CDlgFirstRun *d = new CDlgFirstRun;
+ d->DoModal();
+ }
}
p2 = p;
p = out.find("[", p);
@@ -1719,7 +231,10 @@ void InitCheck()
question += keyid;
question += Translate(" expired and will not work.\nDo you want to set another key?");
if (MessageBoxA(nullptr, question.c_str(), Translate("Own secret key warning"), MB_YESNO) == IDYES)
- ShowFirstRunDialog();
+ {
+ CDlgFirstRun *d = new CDlgFirstRun;
+ d->DoModal();
+ }
}
mir_free(expire_date);
}
@@ -1766,10 +281,8 @@ void InitCheck()
}
}
-void ImportKey()
+void ImportKey(MCONTACT hContact, std::wstring new_key)
{
- MCONTACT hContact = globals.new_key_hcnt;
- globals.new_key_hcnt_mutex.unlock();
bool for_all_sub = false;
if (db_mc_isMeta(hContact)) {
if (MessageBox(nullptr, TranslateT("Do you want to load key for all subcontacts?"), TranslateT("Metacontact detected"), MB_YESNO) == IDYES)
@@ -1780,14 +293,12 @@ void ImportKey()
for (int i = 0; i < count; i++) {
MCONTACT hcnt = db_mc_getSub(hContact, i);
if (hcnt)
- db_set_ws(hcnt, szGPGModuleName, "GPGPubKey", globals.new_key.c_str());
+ db_set_ws(hcnt, szGPGModuleName, "GPGPubKey", new_key.c_str());
}
}
- else db_set_ws(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", globals.new_key.c_str());
+ else db_set_ws(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", new_key.c_str());
}
- else db_set_ws(hContact, szGPGModuleName, "GPGPubKey", globals.new_key.c_str());
-
- globals.new_key.clear();
+ else db_set_ws(hContact, szGPGModuleName, "GPGPubKey", new_key.c_str());
// gpg execute block
std::vector<wstring> cmd;
diff --git a/plugins/New_GPG/src/main.h b/plugins/New_GPG/src/main.h
index fd0d688c6b..096eca802a 100755
--- a/plugins/New_GPG/src/main.h
+++ b/plugins/New_GPG/src/main.h
@@ -22,6 +22,8 @@ struct contact_data
string key_in_prescense;
};
+void ImportKey(MCONTACT hContact, std::wstring new_key);
+
#endif
diff --git a/plugins/New_GPG/src/messages.cpp b/plugins/New_GPG/src/messages.cpp
index fc240c5574..1741708642 100755
--- a/plugins/New_GPG/src/messages.cpp
+++ b/plugins/New_GPG/src/messages.cpp
@@ -214,10 +214,9 @@ void RecvMsgSvc_func(MCONTACT hContact, std::wstring str, char *msg, DWORD, DWOR
s += mir_strlen(" ID ");
db_set_s(db_mc_isMeta(hContact) ? metaGetMostOnline(hContact) : hContact, szGPGModuleName, "InKeyID", out.substr(s, out.find(",", s) - s).c_str());
}
- void ShowLoadKeyPasswordWindow();
- globals.new_key_hcnt_mutex.lock();
- globals.new_key_hcnt = hContact;
- ShowLoadKeyPasswordWindow();
+
+ CDlgKeyPasswordMsgBox *d = new CDlgKeyPasswordMsgBox(hContact);
+ d->DoModal();
std::vector<wstring> cmd2 = cmd;
if (globals.password)
{
@@ -558,15 +557,12 @@ INT_PTR RecvMsgSvc(WPARAM w, LPARAM l)
s1 = 0;
while ((s1 = str.find(L"\r", s1)) != wstring::npos)
str.erase(s1, 1);
- void ShowNewKeyDialog();
if (((s2 = str.find(L"-----END PGP PUBLIC KEY BLOCK-----")) != wstring::npos) && ((s1 = str.find(L"-----BEGIN PGP PUBLIC KEY BLOCK-----")) != wstring::npos))
s2 += mir_wstrlen(L"-----END PGP PUBLIC KEY BLOCK-----");
else if (((s2 = str.find(L"-----BEGIN PGP PRIVATE KEY BLOCK-----")) != wstring::npos) && ((s1 = str.find(L"-----END PGP PRIVATE KEY BLOCK-----")) != wstring::npos))
s2 += mir_wstrlen(L"-----END PGP PRIVATE KEY BLOCK-----");
- globals.new_key.append(str.substr(s1, s2 - s1));
- //new_key_hcnt_mutex.lock();
- globals.new_key_hcnt = ccs->hContact;
- ShowNewKeyDialog();
+ CDlgNewKey *d = new CDlgNewKey(ccs->hContact, str.substr(s1, s2 - s1));
+ d->Show();
HistoryLog(ccs->hContact, db_event(msg, 0, 0, dbflags));
return 0;
}
@@ -992,84 +988,3 @@ int HookSendMsg(WPARAM w, LPARAM l)
return 0;
}
-class CDlgKeyPasswordMsgBox : public CDlgBase //always modal
-{
-public:
- CDlgKeyPasswordMsgBox() : CDlgBase(globals.hInst, IDD_KEY_PASSWD),
- lbl_KEYID(this, IDC_KEYID),
- edit_KEY_PASSWORD(this, IDC_KEY_PASSWORD),
- chk_DEFAULT_PASSWORD(this, IDC_DEFAULT_PASSWORD), chk_SAVE_PASSWORD(this, IDC_SAVE_PASSWORD),
- btn_OK(this, IDOK), btn_CANCEL(this, IDCANCEL)
- {
- btn_OK.OnClick = Callback(this, &CDlgKeyPasswordMsgBox::onClick_OK);
- btn_CANCEL.OnClick = Callback(this, &CDlgKeyPasswordMsgBox::onClick_CANCEL);
- }
- virtual void OnInitDialog() override
- {
- inkeyid = UniGetContactSettingUtf(globals.new_key_hcnt, szGPGModuleName, "InKeyID", "");
- globals.new_key_hcnt_mutex.unlock();
-
- SetWindowPos(m_hwnd, nullptr, globals.key_password_rect.left, globals.key_password_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
- {
- string questionstr = "Please enter password for key with ID: ";
- questionstr += inkeyid;
- mir_free(inkeyid);
- lbl_KEYID.SetTextA(questionstr.c_str());
- chk_DEFAULT_PASSWORD.Disable();
- }
- }
- virtual void OnClose() override
- {
- DestroyWindow(m_hwnd);
- }
- virtual void OnDestroy() override
- {
- mir_free(inkeyid);
- GetWindowRect(m_hwnd, &globals.key_password_rect);
- db_set_dw(NULL, szGPGModuleName, "PasswordWindowX", globals.key_password_rect.left);
- db_set_dw(NULL, szGPGModuleName, "PasswordWindowY", globals.key_password_rect.top);
- delete this;
- }
- void onClick_OK(CCtrlButton*)
- {
- wchar_t *tmp = mir_wstrdup(edit_KEY_PASSWORD.GetText());
- if (tmp && tmp[0]) {
- if (chk_SAVE_PASSWORD.GetState()) {
- inkeyid = UniGetContactSettingUtf(globals.new_key_hcnt, szGPGModuleName, "InKeyID", "");
- if (inkeyid && inkeyid[0] && !chk_DEFAULT_PASSWORD.GetState()) {
- string dbsetting = "szKey_";
- dbsetting += inkeyid;
- dbsetting += "_Password";
- db_set_ws(NULL, szGPGModuleName, dbsetting.c_str(), tmp);
- }
- else
- db_set_ws(NULL, szGPGModuleName, "szKeyPassword", tmp);
- }
- if (globals.password)
- mir_free(globals.password);
- globals.password = (wchar_t*)mir_alloc(sizeof(wchar_t)*(mir_wstrlen(tmp) + 1));
- mir_wstrcpy(globals.password, tmp);
- }
- mir_free(inkeyid);
- DestroyWindow(m_hwnd);
- }
- void onClick_CANCEL(CCtrlButton*)
- {
- globals._terminate = true;
- DestroyWindow(m_hwnd);
- }
-private:
- char *inkeyid = nullptr;
- CCtrlData lbl_KEYID;
- CCtrlEdit edit_KEY_PASSWORD;
- CCtrlCheck chk_DEFAULT_PASSWORD, chk_SAVE_PASSWORD;
- CCtrlButton btn_OK, btn_CANCEL;
-};
-
-
-
-void ShowLoadKeyPasswordWindow()
-{
- CDlgKeyPasswordMsgBox *d = new CDlgKeyPasswordMsgBox;
- d->DoModal();
-}
diff --git a/plugins/New_GPG/src/options.cpp b/plugins/New_GPG/src/options.cpp
index 4d6b3a5bc6..8ff4c114c1 100755
--- a/plugins/New_GPG/src/options.cpp
+++ b/plugins/New_GPG/src/options.cpp
@@ -261,8 +261,8 @@ public:
void onClick_SELECT_KEY(CCtrlButton*)
{
- void ShowFirstRunDialog();
- ShowFirstRunDialog();
+ CDlgFirstRun *d = new CDlgFirstRun;
+ d->Show();
}
void onClick_SAVE_KEY_BUTTON(CCtrlButton*)
@@ -678,8 +678,8 @@ public:
void onClick_SELECT_EXISTING(CCtrlButton*)
{
- void ShowSelectExistingKeyDialog();
- ShowSelectExistingKeyDialog();
+ CDlgLoadExistingKey *d = new CDlgLoadExistingKey;
+ d->Show();
}
void onClick_OK(CCtrlButton*)
@@ -1048,10 +1048,8 @@ public:
}
void onClick_IMPORT(CCtrlButton*)
{
- globals.new_key_hcnt_mutex.lock();
- globals.new_key_hcnt = hContact;
- void ShowImportKeyDialog();
- ShowImportKeyDialog();
+ CDlgImportKey *d = new CDlgImportKey(hContact);
+ d->Show();
}
};
diff --git a/plugins/New_GPG/src/ui.cpp b/plugins/New_GPG/src/ui.cpp
index 4271e8d442..c6d34470d4 100755
--- a/plugins/New_GPG/src/ui.cpp
+++ b/plugins/New_GPG/src/ui.cpp
@@ -17,6 +17,9 @@
#include "stdafx.h"
+//HWND hwndFirstRun = nullptr, hwndSetDirs = nullptr, hwndNewKey = nullptr, hwndKeyGen = nullptr, hwndSelectExistingKey = nullptr;
+
+CCtrlListView *list_hwndList_g = nullptr;
void CDlgEncryptedFileMsgBox::OnInitDialog()
@@ -165,3 +168,1279 @@ void CDlgChangePasswdMsgBox::onClick_OK(CCtrlButton*)
}
this->Close();
}
+
+
+
+CDlgFirstRun::CDlgFirstRun() : CDlgBase(globals.hInst, IDD_FIRST_RUN),
+list_KEY_LIST(this, IDC_KEY_LIST),
+btn_COPY_PUBKEY(this, IDC_COPY_PUBKEY), btn_EXPORT_PRIVATE(this, IDC_EXPORT_PRIVATE), btn_CHANGE_PASSWD(this, IDC_CHANGE_PASSWD), btn_GENERATE_RANDOM(this, IDC_GENERATE_RANDOM),
+btn_GENERATE_KEY(this, IDC_GENERATE_KEY), btn_OTHER(this, IDC_OTHER), btn_DELETE_KEY(this, IDC_DELETE_KEY), btn_OK(this, ID_OK),
+edit_KEY_PASSWORD(this, IDC_KEY_PASSWORD),
+combo_ACCOUNT(this, IDC_ACCOUNT),
+lbl_KEY_ID(this, IDC_KEY_ID), lbl_GENERATING_KEY(this, IDC_GENERATING_KEY)
+{
+ fp[0] = 0;
+ list_hwndList_g = &list_KEY_LIST;
+
+ btn_COPY_PUBKEY.OnClick = Callback(this, &CDlgFirstRun::onClick_COPY_PUBKEY);
+ btn_EXPORT_PRIVATE.OnClick = Callback(this, &CDlgFirstRun::onClick_EXPORT_PRIVATE);
+ btn_CHANGE_PASSWD.OnClick = Callback(this, &CDlgFirstRun::onClick_CHANGE_PASSWD);
+ btn_GENERATE_RANDOM.OnClick = Callback(this, &CDlgFirstRun::onClick_GENERATE_RANDOM);
+ btn_GENERATE_KEY.OnClick = Callback(this, &CDlgFirstRun::onClick_GENERATE_KEY);
+ btn_OTHER.OnClick = Callback(this, &CDlgFirstRun::onClick_OTHER);
+ btn_DELETE_KEY.OnClick = Callback(this, &CDlgFirstRun::onClick_DELETE_KEY);
+ btn_OK.OnClick = Callback(this, &CDlgFirstRun::onClick_OK);
+
+}
+void CDlgFirstRun::OnInitDialog()
+{
+ SetWindowPos(m_hwnd, nullptr, globals.firstrun_rect.left, globals.firstrun_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+ SetCaption(TranslateT("Set own key"));
+ btn_COPY_PUBKEY.Disable();
+ btn_EXPORT_PRIVATE.Disable();
+ btn_CHANGE_PASSWD.Disable();
+
+ list_KEY_LIST.AddColumn(0, TranslateT("Key ID"), 50);
+ list_KEY_LIST.AddColumn(1, TranslateT("Email"), 30);
+ list_KEY_LIST.AddColumn(2, TranslateT("Name"), 250);
+ list_KEY_LIST.AddColumn(3, TranslateT("Creation date"), 30);
+ list_KEY_LIST.AddColumn(4, TranslateT("Expire date"), 30);
+ list_KEY_LIST.AddColumn(5, TranslateT("Key length"), 30);
+ list_KEY_LIST.AddColumn(6, TranslateT("Accounts"), 30);
+ list_KEY_LIST.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_SINGLEROW);
+
+ refresh_key_list();
+
+ {
+ combo_ACCOUNT.AddString(TranslateT("Default"));
+ int count = 0;
+ PROTOACCOUNT **accounts;
+ Proto_EnumAccounts(&count, &accounts);
+ for (int n = 0; n < count; n++) {
+ if (StriStr(accounts[n]->szModuleName, "metacontacts"))
+ continue;
+ if (StriStr(accounts[n]->szModuleName, "weather"))
+ continue;
+ std::string acc = toUTF8(accounts[n]->tszAccountName);
+ acc += "(";
+ acc += accounts[n]->szModuleName;
+ acc += ")";
+ //acc += "_KeyID";
+ combo_ACCOUNT.AddStringA(acc.c_str());
+ }
+ combo_ACCOUNT.SelectString(TranslateT("Default"));
+ string keyinfo = Translate("key ID");
+ keyinfo += ": ";
+ char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
+ keyinfo += (mir_strlen(keyid) > 0) ? keyid : Translate("not set");
+ mir_free(keyid);
+ lbl_KEY_ID.SetTextA(keyinfo.c_str());
+ }
+ combo_ACCOUNT.OnChange = Callback(this, &CDlgFirstRun::onChange_ACCOUNT);
+ list_KEY_LIST.OnItemChanged = Callback(this, &CDlgFirstRun::onChange_KEY_LIST);
+}
+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();
+ }
+}
+void CDlgFirstRun::onClick_EXPORT_PRIVATE(CCtrlButton*)
+{
+ {
+ int i = list_KEY_LIST.GetSelectionMark();
+ if (i == -1)
+ return;
+ wchar_t *p = GetFilePath(L"Choose file to export key", L"*", L"Any file", true);
+ if (!p || !p[0]) {
+ delete[] p;
+ //TODO: handle error
+ return;
+ }
+ char *path = mir_u2a(p);
+ delete[] p;
+ std::ofstream file;
+ file.open(path, std::ios::trunc | std::ios::out);
+ mir_free(path);
+ 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;
+ if (file.is_open())
+ file.close();
+ }
+}
+void CDlgFirstRun::onClick_CHANGE_PASSWD(CCtrlButton*)
+{
+ 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::vector<std::wstring> cmd;
+ std::string old_pass, new_pass;
+ string output;
+ DWORD exitcode;
+ cmd.push_back(L"--edit-key");
+ cmd.push_back(globals.key_id_global);
+ cmd.push_back(L"passwd");
+ gpg_execution_params_pass params(cmd, old_pass, new_pass);
+ pxResult result;
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_passwd_change_thread, &params));
+ if (!gpg_thread.timed_join(boost::posix_time::minutes(10))) {
+ gpg_thread.~thread();
+ if (params.child)
+ boost::process::terminate(*(params.child));
+ if (globals.bDebugLog)
+ globals.debuglog << std::string(time_str() + ": GPG execution timed out, aborted");
+ this->Close();
+ }
+
+}
+void CDlgFirstRun::onClick_GENERATE_RANDOM(CCtrlButton*)
+{
+ lbl_GENERATING_KEY.SendMsg(WM_SETFONT, (WPARAM)globals.bold_font, TRUE);
+ lbl_GENERATING_KEY.SetText(TranslateT("Generating new random key, please wait"));
+ btn_GENERATE_KEY.Disable();
+ btn_OTHER.Disable();
+ btn_DELETE_KEY.Disable();
+ list_KEY_LIST.Disable();
+ btn_GENERATE_RANDOM.Disable();
+ gpg_use_new_random_key(combo_ACCOUNT.GetTextA());
+ this->Close();
+}
+void CDlgFirstRun::onClick_GENERATE_KEY(CCtrlButton*)
+{
+ CDlgKeyGen *d = new CDlgKeyGen;
+ d->DoModal();
+ refresh_key_list();
+}
+void CDlgFirstRun::onClick_OTHER(CCtrlButton*)
+{
+ void ShowLoadPublicKeyDialog(bool = false);
+ globals.item_num = 0; //black magic here
+ globals.user_data[1] = 0;
+ ShowLoadPublicKeyDialog(true);
+ refresh_key_list();
+}
+void CDlgFirstRun::onClick_DELETE_KEY(CCtrlButton*)
+{
+ int i = list_KEY_LIST.GetSelectionMark();
+ if (i == -1)
+ 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;
+ if (!gpg_launcher(params))
+ return;
+ if (result == pxNotFound)
+ return;
+ string::size_type s = out.find("Key fingerprint = ");
+ s += mir_strlen("Key fingerprint = ");
+ string::size_type s2 = out.find("\n", s);
+ wchar_t *str = nullptr;
+ {
+ string tmp = out.substr(s, s2 - s - 1).c_str();
+ string::size_type p = 0;
+ while ((p = tmp.find(" ", p)) != string::npos)
+ tmp.erase(p, 1);
+
+ 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);
+ mir_free(str);
+ if (!gpg_launcher(params))
+ return;
+ if (result == pxNotFound)
+ return;
+ }
+ {
+ char *buf = mir_strdup(combo_ACCOUNT.GetTextA());
+ if (!mir_strcmp(buf, Translate("Default"))) {
+ db_unset(NULL, szGPGModuleName, "GPGPubKey");
+ db_unset(NULL, szGPGModuleName, "KeyID");
+ db_unset(NULL, szGPGModuleName, "KeyComment");
+ db_unset(NULL, szGPGModuleName, "KeyMainName");
+ db_unset(NULL, szGPGModuleName, "KeyMainEmail");
+ db_unset(NULL, szGPGModuleName, "KeyType");
+ }
+ else {
+ std::string acc_str = buf;
+ acc_str += "_GPGPubKey";
+ db_unset(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyMainName";
+ db_unset(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyID";
+ db_unset(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyComment";
+ db_unset(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyMainEmail";
+ db_unset(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyType";
+ db_unset(NULL, szGPGModuleName, acc_str.c_str());
+ }
+ if (buf)
+ mir_free(buf);
+ }
+ list_KEY_LIST.DeleteItem(i);
+}
+void CDlgFirstRun::onClick_OK(CCtrlButton*)
+{
+ {
+ 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;
+ }
+
+ boost::algorithm::erase_all(out, "\r");
+ {
+ char *buf = mir_strdup(combo_ACCOUNT.GetTextA());
+ if (!mir_strcmp(buf, Translate("Default"))) {
+ db_set_s(NULL, szGPGModuleName, "GPGPubKey", out.c_str());
+ db_set_ws(NULL, szGPGModuleName, "KeyMainName", name);
+ db_set_ws(NULL, szGPGModuleName, "KeyID", fp);
+ }
+ else {
+ std::string acc_str = buf;
+ acc_str += "_GPGPubKey";
+ db_set_s(NULL, szGPGModuleName, acc_str.c_str(), out.c_str());
+ acc_str = buf;
+ acc_str += "_KeyMainName";
+ db_set_ws(NULL, szGPGModuleName, acc_str.c_str(), name);
+ acc_str = buf;
+ acc_str += "_KeyID";
+ db_set_ws(NULL, szGPGModuleName, 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";
+ db_set_ws(NULL, szGPGModuleName, dbsetting.c_str(), passwd);
+ }
+ mir_free(passwd);
+ delete[] name;
+ }
+ //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*)
+{
+ char *buf = mir_strdup(combo_ACCOUNT.GetTextA());
+ if (!mir_strcmp(buf, Translate("Default"))) {
+ string keyinfo = Translate("key ID");
+ keyinfo += ": ";
+ char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
+ keyinfo += (mir_strlen(keyid) > 0) ? keyid : Translate("not set");
+ mir_free(keyid);
+ lbl_KEY_ID.SetTextA(keyinfo.c_str());
+ }
+ else {
+ string keyinfo = Translate("key ID");
+ keyinfo += ": ";
+ std::string acc_str = buf;
+ acc_str += "_KeyID";
+ char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, acc_str.c_str(), "");
+ keyinfo += (mir_strlen(keyid) > 0) ? keyid : Translate("not set");
+ mir_free(keyid);
+ lbl_KEY_ID.SetTextA(keyinfo.c_str());
+ }
+ if (buf)
+ mir_free(buf);
+}
+void CDlgFirstRun::onChange_KEY_LIST(CCtrlListView::TEventInfo *ev) //TODO: check if this work
+{
+ if (ev->nmlv)
+ {
+ NMLISTVIEW *hdr = ev->nmlv;
+
+ if (hdr->hdr.code == NM_CLICK) {
+ btn_OK.Enable();
+ btn_COPY_PUBKEY.Enable();
+ btn_EXPORT_PRIVATE.Enable();
+ btn_CHANGE_PASSWD.Enable();
+ }
+ }
+}
+void CDlgFirstRun::OnDestroy()
+{
+ GetWindowRect(m_hwnd, &globals.firstrun_rect);
+ db_set_dw(NULL, szGPGModuleName, "FirstrunWindowX", globals.firstrun_rect.left);
+ db_set_dw(NULL, szGPGModuleName, "FirstrunWindowY", globals.firstrun_rect.top);
+ delete this;
+}
+
+
+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())
+ 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);
+ 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
+ int count = 0;
+ PROTOACCOUNT **accounts;
+ Proto_EnumAccounts(&count, &accounts);
+ std::wstring accs;
+ for (int n = 0; n < count; n++) {
+ std::string setting = toUTF8(accounts[n]->tszAccountName);
+ setting += "(";
+ setting += accounts[n]->szModuleName;
+ setting += ")";
+ setting += "_KeyID";
+ wchar_t *str = UniGetContactSettingUtf(NULL, szGPGModuleName, setting.c_str(), L"");
+ if (key_id == str) {
+ if (!accs.empty())
+ accs += L",";
+ accs += accounts[n]->tszAccountName;
+ }
+ mir_free(str);
+ }
+ list_KEY_LIST.SetItemText(row, 6, (wchar_t*)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);
+ }
+ }
+}
+
+
+
+CDlgGpgBinOpts::CDlgGpgBinOpts() : CDlgBase(globals.hInst, IDD_BIN_PATH),
+btn_SET_BIN_PATH(this, IDC_SET_BIN_PATH), btn_SET_HOME_DIR(this, IDC_SET_HOME_DIR), btn_OK(this, ID_OK), btn_GENERATE_RANDOM(this, IDC_GENERATE_RANDOM),
+edit_BIN_PATH(this, IDC_BIN_PATH), edit_HOME_DIR(this, IDC_HOME_DIR),
+chk_AUTO_EXCHANGE(this, IDC_AUTO_EXCHANGE)
+{
+ btn_SET_BIN_PATH.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_SET_BIN_PATH);
+ btn_SET_HOME_DIR.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_SET_HOME_DIR);
+ btn_OK.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_OK);
+ btn_GENERATE_RANDOM.OnClick = Callback(this, &CDlgGpgBinOpts::onClick_GENERATE_RANDOM);
+}
+void CDlgGpgBinOpts::OnInitDialog()
+{
+ CMStringW path;
+ bool gpg_exists = false, lang_exists = false;
+ {
+ wchar_t mir_path[MAX_PATH];
+ PathToAbsoluteW(L"\\", mir_path);
+ SetCurrentDirectoryW(mir_path);
+
+ CMStringW gpg_path(mir_path); gpg_path.Append(L"\\GnuPG\\gpg.exe");
+ CMStringW gpg_lang_path(mir_path); gpg_lang_path.Append(L"\\GnuPG\\gnupg.nls\\en@quot.mo");
+
+ if (boost::filesystem::exists(gpg_path.c_str())) {
+ gpg_exists = true;
+ path = L"GnuPG\\gpg.exe";
+ }
+ else path = gpg_path;
+
+ if (boost::filesystem::exists(gpg_lang_path.c_str()))
+ lang_exists = true;
+ if (gpg_exists && !lang_exists)
+ MessageBox(nullptr, TranslateT("GPG binary found in Miranda folder, but English locale does not exist.\nIt's highly recommended that you place \\gnupg.nls\\en@quot.mo in GnuPG folder under Miranda root.\nWithout this file you may experience many problems with GPG output on non-English systems\nand plugin may completely not work.\nYou have been warned."), TranslateT("Warning"), MB_OK);
+ }
+ DWORD len = MAX_PATH;
+ bool bad_version = false;
+ {
+ ptrW tmp;
+ if (!gpg_exists) {
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "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))
+ MessageBox(nullptr, TranslateT("Wrong GPG binary location found in system.\nPlease choose another location"), TranslateT("Warning"), MB_OK);
+ }
+ else tmp = mir_wstrdup(path.c_str());
+
+ edit_BIN_PATH.SetText(tmp);
+ if (gpg_exists/* && lang_exists*/) {
+ db_set_ws(NULL, szGPGModuleName, "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;
+ bool _gpg_valid = globals.gpg_valid;
+ globals.gpg_valid = true;
+ gpg_launcher(params);
+ globals.gpg_valid = _gpg_valid; //TODO: check this
+ db_unset(NULL, szGPGModuleName, "szGpgBinPath");
+ string::size_type p1 = out.find("(GnuPG) ");
+ if (p1 != string::npos) {
+ p1 += mir_strlen("(GnuPG) ");
+ if (out[p1] != '1')
+ bad_version = true;
+ }
+ else {
+ bad_version = false;
+ MessageBox(nullptr, TranslateT("This is not GnuPG binary!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Error"), MB_OK);
+ }
+ if (bad_version)
+ MessageBox(nullptr, TranslateT("Unsupported GnuPG version found, use at you own risk!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Warning"), MB_OK);
+ }
+ }
+ {
+ ptrW tmp(UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L""));
+ if (!tmp[0]) {
+ wchar_t mir_path[MAX_PATH];
+ PathToAbsoluteW(L"\\", mir_path);
+ mir_wstrcat(mir_path, L"\\gpg");
+ if (_waccess(mir_path, 0) != -1) {
+ tmp = mir_wstrdup(mir_path);
+ MessageBox(nullptr, TranslateT("\"GPG\" directory found in Miranda root.\nAssuming it's GPG home directory.\nGPG home directory set."), TranslateT("Info"), MB_OK);
+ }
+ else {
+ wstring path_ = _wgetenv(L"APPDATA");
+ path_ += L"\\GnuPG";
+ tmp = mir_wstrdup(path_.c_str());
+ }
+ }
+ edit_HOME_DIR.SetText(!gpg_exists ? tmp : L"gpg");
+ }
+ //TODO: additional check for write access
+ if (gpg_exists && lang_exists && !bad_version)
+ MessageBox(nullptr, TranslateT("Your GPG version is supported. The language file was found.\nGPG plugin should work fine.\nPress OK to continue."), TranslateT("Info"), MB_OK);
+ chk_AUTO_EXCHANGE.Enable();
+}
+void CDlgGpgBinOpts::onClick_SET_BIN_PATH(CCtrlButton*)
+{
+ GetFilePath(L"Choose gpg.exe", "szGpgBinPath", L"*.exe", L"EXE Executables");
+ CMStringW tmp(ptrW(UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", L"gpg.exe")));
+ edit_BIN_PATH.SetText(tmp);
+ wchar_t mir_path[MAX_PATH];
+ PathToAbsoluteW(L"\\", mir_path);
+ if (tmp.Find(mir_path, 0) == 0)
+ {
+ CMStringW path = tmp.Mid(mir_wstrlen(mir_path));
+ edit_BIN_PATH.SetText(path);
+ }
+
+}
+void CDlgGpgBinOpts::onClick_SET_HOME_DIR(CCtrlButton*)
+{
+ GetFolderPath(L"Set home directory", "szHomePath");
+ CMStringW tmp(ptrW(UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"")));
+ edit_HOME_DIR.SetText(tmp);
+ wchar_t mir_path[MAX_PATH];
+ PathToAbsoluteW(L"\\", mir_path);
+ PathToAbsoluteW(L"\\", mir_path);
+ if (tmp.Find(mir_path, 0) == 0) {
+ CMStringW path = tmp.Mid(mir_wstrlen(mir_path));
+ edit_HOME_DIR.SetText(path);
+ }
+
+}
+void CDlgGpgBinOpts::onClick_OK(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;
+ db_set_b(NULL, szGPGModuleName, "FirstRun", 0);
+ this->Hide();
+ CDlgFirstRun *d = new CDlgFirstRun;
+ d->Show();
+ this->Close();
+ }
+}
+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())
+ {
+ db_set_b(NULL, szGPGModuleName, "bAutoExchange", globals.bAutoExchange = chk_AUTO_EXCHANGE.GetState());
+ globals.gpg_valid = true;
+ db_set_b(NULL, szGPGModuleName, "FirstRun", 0);
+ this->Close();
+ }
+ }
+}
+void CDlgGpgBinOpts::OnDestroy()
+{
+ void InitCheck();
+ InitCheck();
+ delete this;
+}
+
+CDlgNewKey::CDlgNewKey(MCONTACT _hContact, wstring _new_key) : CDlgBase(globals.hInst, IDD_NEW_KEY),
+lbl_KEY_FROM(this, IDC_KEY_FROM), lbl_MESSAGE(this, IDC_MESSAGE),
+btn_IMPORT(this, ID_IMPORT), btn_IMPORT_AND_USE(this, IDC_IMPORT_AND_USE), btn_IGNORE_KEY(this, IDC_IGNORE_KEY)
+{
+ hContact = _hContact;
+ new_key = _new_key;
+ btn_IMPORT.OnClick = Callback(this, &CDlgNewKey::onClick_IMPORT);
+ btn_IMPORT_AND_USE.OnClick = Callback(this, &CDlgNewKey::onClick_IMPORT_AND_USE);
+ btn_IGNORE_KEY.OnClick = Callback(this, &CDlgNewKey::onClick_IGNORE_KEY);
+
+}
+void CDlgNewKey::OnInitDialog()
+{
+ //new_key_hcnt_mutex.unlock();
+ SetWindowPos(m_hwnd, nullptr, globals.new_key_rect.left, globals.new_key_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+ wchar_t *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", L"");
+ lbl_MESSAGE.SetText(tmp[0] ? TranslateT("There is existing key for contact, would you like to replace it with new key?") : TranslateT("New public key was received, do you want to import it?"));
+ btn_IMPORT_AND_USE.Enable(db_get_b(hContact, szGPGModuleName, "GPGEncryption", 0));
+ btn_IMPORT.SetText(tmp[0] ? TranslateT("Replace") : TranslateT("Accept"));
+ mir_free(tmp);
+ tmp = new wchar_t[256];
+ mir_snwprintf(tmp, 255 * sizeof(wchar_t), TranslateT("Received key from %s"), pcli->pfnGetContactDisplayName(hContact, 0));
+ lbl_KEY_FROM.SetText(tmp);
+ mir_free(tmp);
+}
+void CDlgNewKey::OnDestroy()
+{
+ GetWindowRect(m_hwnd, &globals.new_key_rect);
+ db_set_dw(NULL, szGPGModuleName, "NewKeyWindowX", globals.new_key_rect.left);
+ db_set_dw(NULL, szGPGModuleName, "NewKeyWindowY", globals.new_key_rect.top);
+ delete this;
+}
+void CDlgNewKey::onClick_IMPORT(CCtrlButton*)
+{
+ ImportKey(hContact, new_key);
+ this->Close();
+}
+void CDlgNewKey::onClick_IMPORT_AND_USE(CCtrlButton*)
+{
+ ImportKey(hContact, new_key);
+ db_set_b(hContact, szGPGModuleName, "GPGEncryption", 1);
+ void setSrmmIcon(MCONTACT hContact);
+ void setClistIcon(MCONTACT hContact);
+ setSrmmIcon(hContact);
+ setClistIcon(hContact);
+ this->Close();
+}
+void CDlgNewKey::onClick_IGNORE_KEY(CCtrlButton*)
+{
+ this->Close();
+}
+
+CDlgKeyGen::CDlgKeyGen() : CDlgBase(globals.hInst, IDD_KEY_GEN),
+combo_KEY_TYPE(this, IDC_KEY_TYPE),
+edit_KEY_LENGTH(this, IDC_KEY_LENGTH), edit_KEY_PASSWD(this, IDC_KEY_PASSWD), edit_KEY_REAL_NAME(this, IDC_KEY_REAL_NAME), edit_KEY_EMAIL(this, IDC_KEY_EMAIL), edit_KEY_COMMENT(this, IDC_KEY_COMMENT),
+edit_KEY_EXPIRE_DATE(this, IDC_KEY_EXPIRE_DATE),
+lbl_GENERATING_TEXT(this, IDC_GENERATING_TEXT),
+btn_OK(this, IDOK), btn_CANCEL(this, IDCANCEL)
+{
+ btn_OK.OnClick = Callback(this, &CDlgKeyGen::onClick_OK);
+ btn_CANCEL.OnClick = Callback(this, &CDlgKeyGen::onClick_CANCEL);
+}
+void CDlgKeyGen::OnInitDialog()
+{
+ SetWindowPos(m_hwnd, nullptr, globals.key_gen_rect.left, globals.key_gen_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+ SetCaption(TranslateT("Key Generation dialog"));
+ combo_KEY_TYPE.AddString(L"RSA");
+ combo_KEY_TYPE.AddString(L"DSA");
+ combo_KEY_TYPE.SelectString(L"RSA");
+ edit_KEY_EXPIRE_DATE.SetText(L"0");
+ edit_KEY_LENGTH.SetText(L"4096");
+}
+
+void CDlgKeyGen::onClick_OK(CCtrlButton*)
+{
+ {
+ wstring path;
+ { //data sanity checks
+ wchar_t *tmp = mir_wstrdup(combo_KEY_TYPE.GetText());
+ if (!tmp)
+ {
+ MessageBox(nullptr, TranslateT("You must set encryption algorithm first"), TranslateT("Error"), MB_OK);
+ return;
+ }
+ if (mir_wstrlen(tmp) < 3)
+ {
+ mir_free(tmp);
+ tmp = nullptr;
+ MessageBox(nullptr, TranslateT("You must set encryption algorithm first"), TranslateT("Error"), MB_OK);
+ return;
+ }
+ mir_free(tmp);
+ tmp = mir_wstrdup(edit_KEY_LENGTH.GetText());
+ if (!tmp)
+ {
+ MessageBox(nullptr, TranslateT("Key length must be of length from 1024 to 4096 bits"), TranslateT("Error"), MB_OK);
+ return;
+ }
+ int length = _wtoi(tmp);
+ mir_free(tmp);
+ if (length < 1024 || length > 4096) {
+ MessageBox(nullptr, TranslateT("Key length must be of length from 1024 to 4096 bits"), TranslateT("Error"), MB_OK);
+ return;
+ }
+ tmp = mir_wstrdup(edit_KEY_EXPIRE_DATE.GetText());
+ if (!tmp)
+ {
+ MessageBox(nullptr, TranslateT("Invalid date"), TranslateT("Error"), MB_OK);
+ return;
+ }
+ if (mir_wstrlen(tmp) != 10 && tmp[0] != '0') {
+ MessageBox(nullptr, TranslateT("Invalid date"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ return;
+ }
+ mir_free(tmp);
+ tmp = mir_wstrdup(edit_KEY_REAL_NAME.GetText());
+ if (!tmp)
+ {
+ MessageBox(nullptr, TranslateT("Name must contain at least 5 characters"), TranslateT("Error"), MB_OK);
+ return;
+ }
+ if (mir_wstrlen(tmp) < 5) {
+ MessageBox(nullptr, TranslateT("Name must contain at least 5 characters"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ return;
+ }
+ else if (wcschr(tmp, '(') || wcschr(tmp, ')'))
+ {
+ MessageBox(nullptr, TranslateT("Name cannot contain '(' or ')'"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ return;
+ }
+ mir_free(tmp);
+ tmp = mir_wstrdup(edit_KEY_EMAIL.GetText());
+ if (!tmp)
+ {
+ MessageBox(nullptr, TranslateT("Invalid Email"), TranslateT("Error"), MB_OK);
+ return;
+ }
+ if ((mir_wstrlen(tmp)) < 5 || (!wcschr(tmp, '@')) || (!wcschr(tmp, '.'))) {
+ MessageBox(nullptr, TranslateT("Invalid Email"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ return;
+ }
+ mir_free(tmp);
+ }
+ { //generating key file
+ wchar_t *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"");
+ char *tmp2;// = mir_u2a(tmp);
+ path = tmp;
+ mir_free(tmp);
+ // mir_free(tmp2);
+ path.append(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;
+ }
+ f << "Key-Type: ";
+ tmp2 = mir_u2a(combo_KEY_TYPE.GetText());
+ 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
+ mir_strcpy(subkeytype, "ELG-E");
+ f << tmp2;
+ mir_free(tmp2);
+ f << "\n";
+ f << "Key-Length: ";
+ f << _wtoi(edit_KEY_LENGTH.GetText());
+ f << "\n";
+ f << "Subkey-Length: ";
+ f << _wtoi(edit_KEY_LENGTH.GetText());
+ f << "\n";
+ f << "Subkey-Type: ";
+ f << subkeytype;
+ mir_free(subkeytype);
+ f << "\n";
+ if (edit_KEY_PASSWD.GetText()[0])
+ {
+ f << "Passphrase: ";
+ f << toUTF8(edit_KEY_PASSWD.GetText()).c_str();
+ f << "\n";
+ }
+ f << "Name-Real: ";
+ f << toUTF8(edit_KEY_REAL_NAME.GetText()).c_str();
+ f << "\n";
+ if (edit_KEY_COMMENT.GetText()[0])
+ {
+ f << "Name-Comment: ";
+ f << toUTF8(edit_KEY_COMMENT.GetText()).c_str();
+ f << "\n";
+ }
+ f << "Name-Email: ";
+ f << toUTF8(edit_KEY_EMAIL.GetText()).c_str();
+ f << "\n";
+ f << "Expire-Date: ";
+ f << toUTF8(edit_KEY_EXPIRE_DATE.GetText()).c_str();
+ 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);
+ 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..."));
+ btn_CANCEL.Disable();
+ btn_OK.Disable();
+ combo_KEY_TYPE.Disable();
+ edit_KEY_LENGTH.Disable();
+ edit_KEY_PASSWD.Disable();
+ edit_KEY_REAL_NAME.Disable();
+ edit_KEY_EMAIL.Disable();
+ edit_KEY_COMMENT.Disable();
+ edit_KEY_EXPIRE_DATE.Disable();
+ if (!gpg_launcher(params, boost::posix_time::minutes(10)))
+ return;
+ if (result == pxNotFound)
+ return;
+ }
+ boost::filesystem::remove(path);
+ }
+ this->Close();
+}
+void CDlgKeyGen::onClick_CANCEL(CCtrlButton*)
+{
+ this->Close();
+}
+void CDlgKeyGen::OnDestroy()
+{
+ GetWindowRect(m_hwnd, &globals.key_gen_rect);
+ db_set_dw(NULL, szGPGModuleName, "KeyGenWindowX", globals.key_gen_rect.left);
+ db_set_dw(NULL, szGPGModuleName, "KeyGenWindowY", globals.key_gen_rect.top);
+ delete this;
+}
+
+CDlgLoadExistingKey::CDlgLoadExistingKey() : CDlgBase(globals.hInst, IDD_LOAD_EXISTING_KEY),
+btn_OK(this, IDOK), btn_CANCEL(this, IDCANCEL),
+list_EXISTING_KEY_LIST(this, IDC_EXISTING_KEY_LIST)
+{
+ id[0] = 0;
+ btn_OK.OnClick = Callback(this, &CDlgLoadExistingKey::onClick_OK);
+ btn_CANCEL.OnClick = Callback(this, &CDlgLoadExistingKey::onClick_CANCEL);
+
+}
+void CDlgLoadExistingKey::OnInitDialog()
+{
+ SetWindowPos(m_hwnd, nullptr, globals.load_existing_key_rect.left, globals.load_existing_key_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+
+
+ list_EXISTING_KEY_LIST.AddColumn(0, TranslateT("Key ID"), 50);
+ list_EXISTING_KEY_LIST.AddColumn(1, TranslateT("Email"), 30);
+ list_EXISTING_KEY_LIST.AddColumn(2, TranslateT("Name"), 250);
+ list_EXISTING_KEY_LIST.AddColumn(3, TranslateT("Creation date"), 30);
+ list_EXISTING_KEY_LIST.AddColumn(4, TranslateT("Expiration date"), 30);
+ list_EXISTING_KEY_LIST.AddColumn(5, TranslateT("Key length"), 30);
+ 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;
+ if (result == pxNotFound)
+ return;
+ }
+ 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);
+ 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);
+ mir_free(tmp);
+ // p = out.find("sub ", p2) + 6;
+ // p = out.find(" ", p) + 1;
+ // p2 = out.find("\n", p);
+ // tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p-1)).c_str());
+ // ListView_SetItemText(hwndList, iRow, 3, 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.OnItemChanged = Callback(this, &CDlgLoadExistingKey::onChange_EXISTING_KEY_LIST);
+}
+void CDlgLoadExistingKey::OnDestroy()
+{
+ GetWindowRect(m_hwnd, &globals.load_existing_key_rect);
+ db_set_dw(NULL, szGPGModuleName, "LoadExistingKeyWindowX", globals.load_existing_key_rect.left);
+ db_set_dw(NULL, szGPGModuleName, "LoadExistingKeyWindowY", globals.load_existing_key_rect.top);
+ delete this;
+}
+void CDlgLoadExistingKey::onClick_OK(CCtrlButton*)
+{
+ int i = list_EXISTING_KEY_LIST.GetSelectionMark();
+ if (i == -1)
+ return; //TODO: error message
+
+ 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;
+ if (!gpg_launcher(params))
+ return;
+ if (result == pxNotFound)
+ return;
+ string::size_type s = 0;
+ while ((s = out.find("\r", s)) != string::npos) {
+ out.erase(s, 1);
+ }
+ std::string::size_type p1 = 0, p2 = 0;
+ p1 = out.find("-----BEGIN PGP PUBLIC KEY BLOCK-----");
+ if (p1 != std::string::npos) {
+ p2 = out.find("-----END PGP PUBLIC KEY BLOCK-----", p1);
+ if (p2 != std::string::npos) {
+ p2 += mir_strlen("-----END PGP PUBLIC KEY BLOCK-----");
+ out = out.substr(p1, p2 - p1);
+ wchar_t *tmp = mir_a2u(out.c_str());
+ if (edit_p_PubKeyEdit)
+ edit_p_PubKeyEdit->SetText(tmp);
+ mir_free(tmp);
+ }
+ else
+ MessageBox(nullptr, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK);
+ }
+ else
+ MessageBox(nullptr, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK);
+ // SetDlgItemText(hPubKeyEdit, IDC_PUBLIC_KEY_EDIT, tmp);
+ this->Close();
+}
+void CDlgLoadExistingKey::onClick_CANCEL(CCtrlButton*)
+{
+ this->Close();
+}
+void CDlgLoadExistingKey::onChange_EXISTING_KEY_LIST(CCtrlListView::TEventInfo * /*ev*/) //TODO: check if this work
+{
+ if (list_EXISTING_KEY_LIST.GetSelectionMark() != -1)
+ btn_OK.Enable();
+}
+
+CDlgImportKey::CDlgImportKey(MCONTACT _hContact) : CDlgBase(globals.hInst, IDD_IMPORT_KEY),
+combo_KEYSERVER(this, IDC_KEYSERVER),
+btn_IMPORT(this, IDC_IMPORT)
+{
+ hContact = _hContact;
+ btn_IMPORT.OnClick = Callback(this, &CDlgImportKey::onClick_IMPORT);
+}
+void CDlgImportKey::OnInitDialog()
+{
+ SetWindowPos(m_hwnd, nullptr, globals.import_key_rect.left, globals.import_key_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+ combo_KEYSERVER.AddString(L"subkeys.pgp.net");
+ combo_KEYSERVER.AddString(L"keys.gnupg.net");
+}
+void CDlgImportKey::OnDestroy()
+{
+ GetWindowRect(m_hwnd, &globals.import_key_rect);
+ db_set_dw(NULL, szGPGModuleName, "ImportKeyWindowX", globals.import_key_rect.left);
+ db_set_dw(NULL, szGPGModuleName, "ImportKeyWindowY", globals.import_key_rect.top);
+ delete this;
+}
+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_launcher(params);
+ MessageBoxA(nullptr, out.c_str(), "GPG output", MB_OK);
+}
+
+
+
+CDlgKeyPasswordMsgBox::CDlgKeyPasswordMsgBox(MCONTACT _hContact) : CDlgBase(globals.hInst, IDD_KEY_PASSWD),
+lbl_KEYID(this, IDC_KEYID),
+edit_KEY_PASSWORD(this, IDC_KEY_PASSWORD),
+chk_DEFAULT_PASSWORD(this, IDC_DEFAULT_PASSWORD), chk_SAVE_PASSWORD(this, IDC_SAVE_PASSWORD),
+btn_OK(this, IDOK), btn_CANCEL(this, IDCANCEL)
+{
+ hContact = _hContact;
+ btn_OK.OnClick = Callback(this, &CDlgKeyPasswordMsgBox::onClick_OK);
+ btn_CANCEL.OnClick = Callback(this, &CDlgKeyPasswordMsgBox::onClick_CANCEL);
+}
+void CDlgKeyPasswordMsgBox::OnInitDialog()
+{
+ inkeyid = UniGetContactSettingUtf(hContact, szGPGModuleName, "InKeyID", "");
+
+ SetWindowPos(m_hwnd, nullptr, globals.key_password_rect.left, globals.key_password_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+ {
+ string questionstr = "Please enter password for key with ID: ";
+ questionstr += inkeyid;
+ mir_free(inkeyid);
+ lbl_KEYID.SetTextA(questionstr.c_str());
+ chk_DEFAULT_PASSWORD.Disable();
+ }
+}
+void CDlgKeyPasswordMsgBox::OnDestroy()
+{
+ mir_free(inkeyid);
+ GetWindowRect(m_hwnd, &globals.key_password_rect);
+ db_set_dw(NULL, szGPGModuleName, "PasswordWindowX", globals.key_password_rect.left);
+ db_set_dw(NULL, szGPGModuleName, "PasswordWindowY", globals.key_password_rect.top);
+ delete this;
+}
+void CDlgKeyPasswordMsgBox::onClick_OK(CCtrlButton*)
+{
+ wchar_t *tmp = mir_wstrdup(edit_KEY_PASSWORD.GetText());
+ if (tmp && tmp[0]) {
+ if (chk_SAVE_PASSWORD.GetState()) {
+ inkeyid = UniGetContactSettingUtf(hContact, szGPGModuleName, "InKeyID", "");
+ if (inkeyid && inkeyid[0] && !chk_DEFAULT_PASSWORD.GetState()) {
+ string dbsetting = "szKey_";
+ dbsetting += inkeyid;
+ dbsetting += "_Password";
+ db_set_ws(NULL, szGPGModuleName, dbsetting.c_str(), tmp);
+ }
+ else
+ db_set_ws(NULL, szGPGModuleName, "szKeyPassword", tmp);
+ }
+ if (globals.password)
+ mir_free(globals.password);
+ globals.password = (wchar_t*)mir_alloc(sizeof(wchar_t)*(mir_wstrlen(tmp) + 1));
+ mir_wstrcpy(globals.password, tmp);
+ }
+ mir_free(inkeyid);
+ DestroyWindow(m_hwnd);
+}
+void CDlgKeyPasswordMsgBox::onClick_CANCEL(CCtrlButton*)
+{
+ globals._terminate = true;
+ DestroyWindow(m_hwnd);
+}
+
diff --git a/plugins/New_GPG/src/ui.h b/plugins/New_GPG/src/ui.h
index 5c017b7e1f..1825175bd7 100755
--- a/plugins/New_GPG/src/ui.h
+++ b/plugins/New_GPG/src/ui.h
@@ -57,7 +57,127 @@ private:
CCtrlEdit edit_NEW_PASSWD1, edit_NEW_PASSWD2, edit_OLD_PASSWD;
};
+class CDlgFirstRun : public CDlgBase
+{
+public:
+ CDlgFirstRun();
+
+ virtual void OnInitDialog() override;
+ void onClick_COPY_PUBKEY(CCtrlButton*);
+ void onClick_EXPORT_PRIVATE(CCtrlButton*);
+ void onClick_CHANGE_PASSWD(CCtrlButton*);
+ void onClick_GENERATE_RANDOM(CCtrlButton*);
+ void onClick_GENERATE_KEY(CCtrlButton*);
+ void onClick_OTHER(CCtrlButton*);
+ void onClick_DELETE_KEY(CCtrlButton*);
+ void onClick_OK(CCtrlButton*);
+ void onChange_ACCOUNT(CCtrlCombo*);
+ void onChange_KEY_LIST(CCtrlListView::TEventInfo *ev);
+ virtual void OnDestroy() override;
+
+private:
+ void refresh_key_list();
+ CCtrlListView list_KEY_LIST;
+ CCtrlButton btn_COPY_PUBKEY, btn_EXPORT_PRIVATE, btn_CHANGE_PASSWD, btn_GENERATE_RANDOM, btn_GENERATE_KEY, btn_OTHER, btn_DELETE_KEY, btn_OK;
+ CCtrlEdit edit_KEY_PASSWORD;
+ CCtrlCombo combo_ACCOUNT;
+ CCtrlData lbl_KEY_ID, lbl_GENERATING_KEY;
+ wchar_t fp[16];
+};
+
+class CDlgGpgBinOpts : public CDlgBase
+{
+public:
+ CDlgGpgBinOpts();
+ virtual void OnInitDialog() override;
+ void onClick_SET_BIN_PATH(CCtrlButton*);
+ void onClick_SET_HOME_DIR(CCtrlButton*);
+ void onClick_OK(CCtrlButton*);
+ void onClick_GENERATE_RANDOM(CCtrlButton*);
+ virtual void OnDestroy() override;
+private:
+ CCtrlButton btn_SET_BIN_PATH, btn_SET_HOME_DIR, btn_OK, btn_GENERATE_RANDOM;
+ CCtrlEdit edit_BIN_PATH, edit_HOME_DIR;
+ CCtrlCheck chk_AUTO_EXCHANGE;
+};
+
+class CDlgNewKey : public CDlgBase
+{
+public:
+ CDlgNewKey(MCONTACT hContact, wstring new_key);
+ virtual void OnInitDialog() override;
+ virtual void OnDestroy() override;
+ void onClick_IMPORT(CCtrlButton*);
+ void onClick_IMPORT_AND_USE(CCtrlButton*);
+ void onClick_IGNORE_KEY(CCtrlButton*);
+private:
+ wstring new_key;
+ MCONTACT hContact;
+ CCtrlData lbl_KEY_FROM, lbl_MESSAGE;
+ CCtrlButton btn_IMPORT, btn_IMPORT_AND_USE, btn_IGNORE_KEY;
+};
+
+class CDlgKeyGen : public CDlgBase //TODO: in modal mode window destroying on any button press even without direct "Close" call
+{
+public:
+ CDlgKeyGen();
+ virtual void OnInitDialog() override;
+
+ void onClick_OK(CCtrlButton*);
+ void onClick_CANCEL(CCtrlButton*);
+ virtual void OnDestroy() override;
+
+private:
+ CCtrlCombo combo_KEY_TYPE;
+ CCtrlEdit edit_KEY_LENGTH, edit_KEY_PASSWD, edit_KEY_REAL_NAME, edit_KEY_EMAIL, edit_KEY_COMMENT, edit_KEY_EXPIRE_DATE;
+ CCtrlData lbl_GENERATING_TEXT;
+ CCtrlButton btn_OK, btn_CANCEL;
+};
+
+class CDlgLoadExistingKey : public CDlgBase
+{
+public:
+ CDlgLoadExistingKey();
+ virtual void OnInitDialog() override;
+ virtual void OnDestroy() override;
+ void onClick_OK(CCtrlButton*);
+ void onClick_CANCEL(CCtrlButton*);
+ void onChange_EXISTING_KEY_LIST(CCtrlListView::TEventInfo * /*ev*/);
+private:
+ wchar_t id[16];
+ CCtrlButton btn_OK, btn_CANCEL;
+ CCtrlListView list_EXISTING_KEY_LIST;
+};
+class CDlgImportKey : public CDlgBase
+{
+public:
+ CDlgImportKey(MCONTACT hContact);
+ virtual void OnInitDialog() override;
+ virtual void OnDestroy() override;
+ void onClick_IMPORT(CCtrlButton*);
+private:
+ MCONTACT hContact;
+ CCtrlCombo combo_KEYSERVER;
+ CCtrlButton btn_IMPORT;
+};
+
+class CDlgKeyPasswordMsgBox : public CDlgBase //always modal
+{
+public:
+ CDlgKeyPasswordMsgBox(MCONTACT _hContact);
+ virtual void OnInitDialog() override;
+ virtual void OnDestroy() override;
+ void onClick_OK(CCtrlButton*);
+ void onClick_CANCEL(CCtrlButton*);
+private:
+ char *inkeyid = nullptr;
+ MCONTACT hContact;
+ CCtrlData lbl_KEYID;
+ CCtrlEdit edit_KEY_PASSWORD;
+ CCtrlCheck chk_DEFAULT_PASSWORD, chk_SAVE_PASSWORD;
+ CCtrlButton btn_OK, btn_CANCEL;
+};
#endif // UI_H \ No newline at end of file
diff --git a/plugins/New_GPG/src/utilities.cpp b/plugins/New_GPG/src/utilities.cpp
index a7802c3558..1c0d383eac 100755
--- a/plugins/New_GPG/src/utilities.cpp
+++ b/plugins/New_GPG/src/utilities.cpp
@@ -365,10 +365,8 @@ int onProtoAck(WPARAM, LPARAM l)
else
db_set_s(ack->hContact, szGPGModuleName, "InKeyID", out.substr(s, s2 - s).c_str());
}
- void ShowLoadKeyPasswordWindow();
- globals.new_key_hcnt_mutex.lock();
- globals.new_key_hcnt = ack->hContact;
- ShowLoadKeyPasswordWindow();
+ CDlgKeyPasswordMsgBox *d = new CDlgKeyPasswordMsgBox(ack->hContact);
+ d->DoModal();
std::vector<wstring> cmd2 = cmd;
if (globals.password) {
if (globals.bDebugLog)
@@ -1837,3 +1835,183 @@ void clean_temp_dir()
}
}
}
+
+bool gpg_validate_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path)
+{
+ wstring tmp = gpg_bin_path;
+ if (!tmp.empty()) {
+ wchar_t mir_path[MAX_PATH];
+ PathToAbsoluteW(L"\\", mir_path);
+ SetCurrentDirectoryW(mir_path);
+ if (!boost::filesystem::exists(tmp)) {
+ MessageBox(nullptr, TranslateT("GPG binary does not exist.\nPlease choose another location"), TranslateT("Warning"), MB_OK);
+ return false;
+ }
+ }
+ else {
+ MessageBox(nullptr, TranslateT("Please choose GPG binary location"), TranslateT("Warning"), MB_OK);
+ return false;
+ }
+ {
+ bool bad_version = false;
+ db_set_ws(NULL, szGPGModuleName, "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;
+ bool _gpg_valid = globals.gpg_valid;
+ globals.gpg_valid = true;
+ gpg_launcher(params);
+ globals.gpg_valid = _gpg_valid; //TODO: check this
+ db_unset(NULL, szGPGModuleName, "szGpgBinPath");
+ string::size_type p1 = out.find("(GnuPG) ");
+ if (p1 != string::npos) {
+ p1 += mir_strlen("(GnuPG) ");
+ if (out[p1] != '1')
+ bad_version = true;
+ }
+ else {
+ bad_version = false;
+ MessageBox(nullptr, TranslateT("This is not GnuPG binary!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Warning"), MB_OK);
+ return false;
+ }
+ if (bad_version)
+ MessageBox(nullptr, TranslateT("Unsupported GnuPG version found, use at you own risk!\nIt is recommended that you use GnuPG v1.x.x with this plugin."), TranslateT("Warning"), MB_OK);
+ }
+ tmp = gpg_home_path;
+ if (tmp[tmp.length()] == '\\')
+ tmp.erase(tmp.length());
+ if (tmp.empty()) {
+ MessageBox(nullptr, TranslateT("Please set keyring's home directory"), TranslateT("Warning"), MB_OK);
+ return false;
+ }
+ {
+ wchar_t *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"");
+ DWORD dwFileAttr = GetFileAttributes(path);
+ if (dwFileAttr != INVALID_FILE_ATTRIBUTES) {
+ dwFileAttr &= ~FILE_ATTRIBUTE_READONLY;
+ SetFileAttributes(path, dwFileAttr);
+ }
+ mir_free(path);
+ }
+ return true;
+}
+
+void gpg_save_paths(wchar_t *gpg_bin_path, wchar_t *gpg_home_path)
+{
+ db_set_ws(NULL, szGPGModuleName, "szGpgBinPath", gpg_bin_path);
+ db_set_ws(NULL, szGPGModuleName, "szHomePath", gpg_home_path);
+}
+
+bool gpg_use_new_random_key(char *account_name, wchar_t *gpg_bin_path, wchar_t *gpg_home_dir)
+{
+ if (gpg_bin_path && gpg_home_dir)
+ gpg_save_paths(gpg_bin_path, gpg_home_dir);
+ {
+ wstring path;
+ {
+ // generating key file
+ wchar_t *tmp = nullptr;
+ if (gpg_home_dir)
+ tmp = gpg_home_dir;
+ else
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", L"");
+ path = tmp;
+ if (!gpg_home_dir)
+ mir_free(tmp);
+ path.append(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();
+ }
+ { // 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);
+ gpg_execution_params params(cmd);
+ pxResult result;
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ if (!gpg_launcher(params, boost::posix_time::minutes(10)))
+ return false;
+ if (result == pxNotFound)
+ return false;
+
+ boost::filesystem::remove(path);
+ string::size_type p1 = 0;
+ if ((p1 = out.find("key ")) != string::npos)
+ path = toUTF16(out.substr(p1 + 4, 8));
+ else
+ path.clear();
+ }
+ if (!path.empty()) {
+ 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);
+ 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;
+ string::size_type s = 0;
+ while ((s = out.find("\r", s)) != string::npos) {
+ out.erase(s, 1);
+ }
+ {
+ if (!mir_strcmp(account_name, Translate("Default")))
+ {
+ db_set_s(NULL, szGPGModuleName, "GPGPubKey", out.c_str());
+ db_set_ws(NULL, szGPGModuleName, "KeyID", path.c_str());
+ }
+ else
+ {
+ std::string acc_str = account_name;
+ acc_str += "_GPGPubKey";
+ db_set_s(NULL, szGPGModuleName, acc_str.c_str(), out.c_str());
+ acc_str = account_name;
+ acc_str += "_KeyID";
+ db_set_ws(NULL, szGPGModuleName, acc_str.c_str(), path.c_str());
+ }
+ }
+ }
+ }
+ return true;
+}
diff --git a/plugins/New_GPG/src/utilities.h b/plugins/New_GPG/src/utilities.h
index b14f50dd69..1d2d6c7de7 100755
--- a/plugins/New_GPG/src/utilities.h
+++ b/plugins/New_GPG/src/utilities.h
@@ -109,5 +109,8 @@ void strip_line_term(std::wstring &s);
void strip_line_term(std::string &s);
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);
#endif