diff options
author | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-03 15:46:24 +0200 |
---|---|---|
committer | Gluzskiy Alexandr <sss@sss.chaoslab.ru> | 2013-02-03 15:46:24 +0200 |
commit | 5657453dcc8626b9f7f13f7ade1eb3e5afa13cc8 (patch) | |
tree | 9e0f6204a546a3e4da38b2747cd85a550bb58c59 | |
parent | 9e7bea7606d6fed31cb71a9e1682757be47a8b8f (diff) |
ability to change key password (because of fucked gpg which does not want to give us his stdin/stdout only via ugly windows console)
-rwxr-xr-x | commonheaders.h | 3 | ||||
-rwxr-xr-x | gpg_wrapper.cpp | 177 | ||||
-rwxr-xr-x | gpg_wrapper.h | 19 | ||||
-rwxr-xr-x | main.cpp | 50 | ||||
-rwxr-xr-x | new_gpg.rc | 35 | ||||
-rwxr-xr-x | new_gpg.vcxproj | 2 | ||||
-rwxr-xr-x | resource.h | 10 | ||||
-rwxr-xr-x | utilities.cpp | 123 |
8 files changed, 398 insertions, 21 deletions
diff --git a/commonheaders.h b/commonheaders.h index 459d76e..5dc34a3 100755 --- a/commonheaders.h +++ b/commonheaders.h @@ -49,6 +49,9 @@ using std::fstream; #include <boost/random/variate_generator.hpp> #include <boost/random/uniform_int.hpp> #include <boost/date_time.hpp> +#include <boost/iostreams/stream.hpp> +//boost process +#include <boost/process.hpp> //utf8cpp diff --git a/gpg_wrapper.cpp b/gpg_wrapper.cpp index f253b25..adce958 100755 --- a/gpg_wrapper.cpp +++ b/gpg_wrapper.cpp @@ -173,3 +173,180 @@ void pxEexcute_thread(void *param) gpg_execution_params *params = (gpg_execution_params*)param; pxResult result = pxExecute(params->cmd, params->useless, params->out, params->code, params->result, params->hProcess, params->proc); } + + + +pxResult pxExecute_passwd_change(std::vector<std::wstring> &aargv, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr, string &old_pass, string &new_pass) +{ +// gpg_mutex.lock(); + if(!gpg_valid) + return pxNotConfigured; + extern logtofile debuglog; + + TCHAR *bin_path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("")); + { + if(_waccess(bin_path, 0) == -1) + { + if(errno == ENOENT) + { + mir_free(bin_path); + if(bDebugLog) + debuglog<<std::string(time_str()+": GPG executable not found"); + *result = pxNotFound; + return pxNotFound; + } + } + } + + using namespace boost::process; + using namespace boost::process::initializers; + using namespace boost::iostreams; + + + std::vector<std::wstring> argv; + std::vector<std::wstring> env; + env.push_back(L"LANGUAGE=en@quot"); + env.push_back(L"LC_ALL=English"); + argv.push_back(bin_path); + argv.push_back(L"--homedir"); + TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + argv.push_back(home_dir); + mir_free(home_dir); + argv.push_back(L"--display-charset"); + argv.push_back(L"utf-8"); + argv.push_back(L"-z9"); + argv.insert(argv.end(), aargv.begin(), aargv.end()); + +// pipe pout = create_pipe(); + pipe pin = create_pipe(); +// file_descriptor_sink sout(pout.sink, close_handle); + file_descriptor_source sin(pin.source, close_handle); + + char *mir_path = new char [MAX_PATH]; + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + + //execute(set_args(argv), bind_stdout(sout), bind_stdin(sin), show_window(SW_HIDE), hide_console(), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path))); + child c = execute(set_args(argv), bind_stdin(sin), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path))); + //child c = execute(run_exe("c:\\windows\\system32\\cmd.exe"), bind_stdin(sin), inherit_env(), set_env(env), start_in_dir(toUTF16(mir_path))); + + delete [] mir_path; + +// file_descriptor_source source(pout.source, close_handle); +/* file_descriptor_sink _sin(pin.sink, close_handle); + + stream<file_descriptor_sink> out(_sin); + + + std::wstring cmd; + for(int i = 0; i < argv.size(); i++) + { + cmd += argv[i]; + cmd += L" "; + } + */ +// out<<toUTF8(cmd)<<std::endl; + + //fucked gpg does not want to give us stdin/stdout + wait_for_exit(c); + +/* out<<old_pass<<std::endl; + out<<new_pass<<std::endl; + out<<new_pass<<std::endl; + out<<"save"<<std::endl; */ + +// stream<file_descriptor_source> is(source); +/* std::string s; + + is>>s; + + MessageBoxA(NULL, s.c_str(), "", MB_OK); */ + + +/* ctx.environment = boost::process::self::get_environment(); + ctx.environment.insert(boost::process::environment::value_type("LANGUAGE", "en@quot")); + ctx.environment["LC_ALL"] = "English"; + + char *mir_path = new char [MAX_PATH]; + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + ctx.work_directory = mir_path; + delete [] mir_path; + + boost::process::win32_child proc = boost::process::win32_launch(toUTF8(bin_path), argv, ctx); + + mir_free(bin_path); + +// boost::process::pistream &_stdout = proc.get_stdout(); + boost::process::postream &_stdin = proc.get_stdin(); + + boost::this_thread::sleep(boost::posix_time::milliseconds(50)); + + std::string buf; */ + + +/* std::getline(_stdout, buf); + while(_stdout.good()) + { + *aoutput += buf; + if(aoutput->find("Enter passphrase") != std::string::npos) + break; + boost::this_thread::sleep(boost::posix_time::milliseconds(50)); + std::getline(_stdout, buf); + } + *aoutput += buf; */ + + //_stdin<<old_pass<<std::endl; + +/* std::getline(_stdout, buf); + while(_stdout.good()) + { + *aoutput += buf; + if(aoutput->find("Enter the new passphrase for this secret key.") != std::string::npos) + break; + boost::this_thread::sleep(boost::posix_time::milliseconds(50)); + std::getline(_stdout, buf); + } + + *aoutput += buf; + + if(aoutput->find("Enter passphrase") != std::string::npos)*/ + //_stdin<<new_pass<<std::endl; + +/* std::getline(_stdout, buf); + while(_stdout.good()) + { + *aoutput += buf; + if(aoutput->find("Repeat passphrase") != std::string::npos) + break; + boost::this_thread::sleep(boost::posix_time::milliseconds(50)); + std::getline(_stdout, buf); + } + *aoutput += buf; */ + + //_stdin<<new_pass<<std::endl; + +/* std::getline(_stdout, buf); + while(_stdout.good()) + { + *aoutput += buf; + if(aoutput->find("Command") != std::string::npos) + break; + boost::this_thread::sleep(boost::posix_time::milliseconds(50)); + std::getline(_stdout, buf); + } + *aoutput += buf; */ + + //_stdin<<"save"<<std::endl; + + //proc.wait(); + + //MessageBoxA(NULL, aoutput->c_str(), "info", MB_OK); + + return pxSuccess; +} + + +void pxEexcute_passwd_change_thread(void *param) +{ + gpg_execution_params_pass *params = (gpg_execution_params_pass*)param; + pxResult result = pxExecute_passwd_change(params->args, params->useless, params->out, params->code, params->result, params->hProcess, params->proc, params->old_pass, params->new_pass); +} diff --git a/gpg_wrapper.h b/gpg_wrapper.h index 5501297..44b2f4f 100755 --- a/gpg_wrapper.h +++ b/gpg_wrapper.h @@ -32,7 +32,8 @@ typedef enum { } pxResult; -pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result); +pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr); +pxResult pxExecute_passwd_change(std::vector<std::string> &aargv, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr, string &old_pass, string &new_pass); struct gpg_execution_params { @@ -45,6 +46,22 @@ struct gpg_execution_params PROCESS_INFORMATION *proc; }; +struct gpg_execution_params_pass +{ + std::vector<std::wstring> &args; + string &old_pass, &new_pass; + char *useless; + string *out; + LPDWORD code; + pxResult *result; + HANDLE hProcess; + PROCESS_INFORMATION *proc; + gpg_execution_params_pass(std::vector<std::wstring> &a, std::string &o, std::string &n): args(a), old_pass(o), new_pass(n) + {} +}; + + void pxEexcute_thread(void *param); +void pxEexcute_passwd_change_thread(void *param); #endif
\ No newline at end of file @@ -27,6 +27,8 @@ int itemnum = 0; HWND hwndList_g = NULL; BOOL CheckStateStoreDB(HWND hwndDlg, int idCtrl, const char* szSetting); +TCHAR key_id_global[17] = {0};
+
static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) { HWND hwndList=GetDlgItem(hwndDlg, IDC_KEY_LIST); @@ -44,6 +46,7 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR SetWindowText(hwndDlg, TranslateT("Set own key")); EnableWindow(GetDlgItem(hwndDlg, IDC_COPY_PUBKEY), 0);
EnableWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PRIVATE), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE_PASSWD), 0);
col.pszText = _T("Key ID"); col.mask = LVCF_TEXT | LVCF_WIDTH; col.fmt = LVCFMT_LEFT; @@ -178,8 +181,8 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR if(expired)
{
mir_free(key_len);
- mir_free(expire_date);
mir_free(creation_date);
+ mir_free(expire_date);
//mimic normal behaviour
p = out.find("uid ", p);
p2 = out.find_first_not_of(" ", p+5);
@@ -187,15 +190,18 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR p++;
p2 = out.find(">", p);
//
- continue;
+ continue; //does not add to key list
}
}
}
iRow = ListView_InsertItem(hwndList, &item);
ListView_SetItemText(hwndList, iRow, 3, creation_date);
mir_free(creation_date);
- ListView_SetItemText(hwndList, iRow, 4, expire_date);
- mir_free(expire_date);
+ if(expire_date)
+ {
+ ListView_SetItemText(hwndList, iRow, 4, expire_date);
+ mir_free(expire_date);
+ }
ListView_SetItemText(hwndList, iRow, 5, key_len);
mir_free(key_len);
ListView_SetItemText(hwndList, iRow, 0, (TCHAR*)key_id.c_str());
@@ -811,7 +817,40 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR file.close();
}
break;
- + case IDC_CHANGE_PASSWD:
+ ListView_GetItemText(hwndList, itemnum, 0, key_id_global, 16);
+// extern void ShowChangePasswdDlg();
+// ShowChangePasswdDlg();
+ //temporary code follows
+ std::vector<std::wstring> cmd;
+ std::string old_pass, new_pass;
+ TCHAR tmp2[MAX_PATH] = {0};
+ string output;
+ DWORD exitcode;
+ cmd.push_back(L"--edit-key");
+ cmd.push_back(key_id_global);
+ cmd.push_back(L"passwd");
+ gpg_execution_params_pass params(cmd, old_pass, new_pass);
+ pxResult result;
+ params.useless = "";
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_passwd_change_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::minutes(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ if(bDebugLog)
+ debuglog<<std::string(time_str()+": GPG execution timed out, aborted");
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ //
+ break;
} break; } @@ -825,6 +864,7 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR EnableWindow(GetDlgItem(hwndDlg, ID_OK), 1); EnableWindow(GetDlgItem(hwndDlg, IDC_COPY_PUBKEY), 1);
EnableWindow(GetDlgItem(hwndDlg, IDC_EXPORT_PRIVATE), 1);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGE_PASSWD), 1);
itemnum = hdr->iItem; } } @@ -83,6 +83,7 @@ BEGIN COMBOBOX IDC_ACCOUNT,66,9,104,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Copy public key",IDC_COPY_PUBKEY,7,169,101,14
PUSHBUTTON "Export private key",IDC_EXPORT_PRIVATE,182,169,102,14
+ PUSHBUTTON "Change password",IDC_CHANGE_PASSWD,182,187,102,14
END
IDD_BIN_PATH DIALOGEX 0, 0, 354, 108
@@ -199,6 +200,19 @@ BEGIN CONTROL "Export public and private keys",IDC_ALL,"Button",BS_AUTORADIOBUTTON,15,50,248,10
END
+IDD_CHANGE_PASSWD DIALOGEX 0, 0, 256, 74
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Change private key password"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_OLD_PASSWD,81,16,158,14,ES_PASSWORD | ES_AUTOHSCROLL
+ EDITTEXT IDC_NEW_PASSWD1,82,33,156,14,ES_PASSWORD | ES_AUTOHSCROLL
+ EDITTEXT IDC_NEW_PASSWD2,81,50,157,14,ES_PASSWORD | ES_AUTOHSCROLL
+ LTEXT "Current password:",IDC_STATIC,7,17,61,8
+ LTEXT "New password twice:",IDC_STATIC,7,32,69,8
+ PUSHBUTTON "Ok",IDC_OK,7,55,50,14
+END
+
/////////////////////////////////////////////////////////////////////////////
//
@@ -226,6 +240,7 @@ BEGIN HORZGUIDE, 20
HORZGUIDE, 166
HORZGUIDE, 183
+ HORZGUIDE, 201
END
IDD_BIN_PATH, DIALOG
@@ -293,6 +308,14 @@ BEGIN BOTTOMMARGIN, 85
HORZGUIDE, 70
END
+
+ IDD_CHANGE_PASSWD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 249
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 69
+ END
END
#endif // APSTUDIO_INVOKED
@@ -431,18 +454,6 @@ END #ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
- IDD_OPT_GPG, DIALOG
- BEGIN
- END
-
- IDD_OPT_GPG_BIN, DIALOG
- BEGIN
- END
-
- IDD_OPT_GPG_MESSAGES, DIALOG
- BEGIN
- END
-
IDD_OPT_GPG_ADVANCED, DIALOG
BEGIN
VERTGUIDE, 12
diff --git a/new_gpg.vcxproj b/new_gpg.vcxproj index 45d9be6..c6de2ed 100755 --- a/new_gpg.vcxproj +++ b/new_gpg.vcxproj @@ -745,7 +745,7 @@ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
- <AdditionalIncludeDirectories>x:\temp\windows\libs\utf8cpp\include;x:\temp\windows\libs\Boost\include;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>X:\temp\windows\libs\boost_process;x:\temp\windows\libs\utf8cpp\include;x:\temp\windows\libs\Boost\include;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -18,6 +18,7 @@ #define IDD_OPT_GPG_ADVANCED 113
#define IDD_ENCRYPTED_FILE_MSG_BOX 114
#define IDD_EXPORT_TYPE 115
+#define IDD_CHANGE_PASSWD 116
#define IDC_SET_BIN_PATH 1016
#define IDC_SET_HOME_DIR 1017
#define IDC_BIN_PATH 1018
@@ -97,14 +98,19 @@ #define IDC_PRIVATE 1074
#define IDC_ALL 1075
#define IDC_EXPORT_PRIVATE 1076
+#define IDC_CHANGE_PASSWD 1077
+#define IDC_OLD_PASSWD 1078
+#define IDC_NEW_PASSWD1 1079
+#define IDC_NEW_PASSWD2 1080
+
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 115
+#define _APS_NEXT_RESOURCE_VALUE 117
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1077
+#define _APS_NEXT_CONTROL_VALUE 1081
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/utilities.cpp b/utilities.cpp index dd94ac9..b42d8e7 100755 --- a/utilities.cpp +++ b/utilities.cpp @@ -2253,3 +2253,126 @@ void ShowExportKeysDlg() extern HINSTANCE hInst;
DialogBox(hInst, MAKEINTRESOURCE(IDD_EXPORT_TYPE), NULL, DlgProcExportKeys);
}
+
+static INT_PTR CALLBACK DlgProcChangePasswd(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ return TRUE;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_OK:
+ //TODO: show some prgress
+ {
+ std::string old_pass, new_pass;
+ extern TCHAR key_id_global[17];
+ TCHAR buf[256] = {0};
+ GetDlgItemText(hwndDlg, IDC_NEW_PASSWD1, buf, 255);
+ new_pass = toUTF8(buf);
+ GetDlgItemText(hwndDlg, IDC_NEW_PASSWD2, buf, 255);
+ if(new_pass != toUTF8(buf))
+ {
+ MessageBox(hwndDlg, TranslateT("New passwords not match"), TranslateT("Error"), MB_OK);
+ //key_id_global[0] = 0;
+ break;
+ }
+ GetDlgItemText(hwndDlg, IDC_OLD_PASSWD, buf, 255);
+ old_pass = toUTF8(buf);
+ bool old_pass_match = false;
+ TCHAR *pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T(""));
+ if(!_tcscmp(pass,buf))
+ old_pass_match = true;
+ mir_free(pass);
+ if(!old_pass_match)
+ { + if(key_id_global[0]) + { + string dbsetting = "szKey_"; + dbsetting += toUTF8(key_id_global); + dbsetting += "_Password"; + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T("")); + if(!_tcscmp(pass,buf)) + old_pass_match = true; + mir_free(pass); + } + }
+ if(!old_pass_match)
+ {
+ if(MessageBox(hwndDlg, TranslateT("Old password not match, you can continue, but gpg will reject wrong password.\nDo you want to continue?"), TranslateT("Error"), MB_YESNO) == IDNO)
+ {
+ //key_id_global[0] = 0;
+ break;
+ }
+ }
+ std::vector<std::wstring> cmd;
+ TCHAR tmp2[MAX_PATH] = {0};
+ string output;
+ DWORD exitcode;
+ cmd.push_back(L"--edit-key");
+ cmd.push_back(key_id_global);
+ cmd.push_back(L"passwd");
+ gpg_execution_params_pass params(cmd, old_pass, new_pass);
+ pxResult result;
+ params.useless = "";
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_passwd_change_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(100)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ if(bDebugLog)
+ debuglog<<std::string(time_str()+": GPG execution timed out, aborted");
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ //if(result == pxSuccess)
+ //TODO: save to db
+
+
+ }
+ DestroyWindow(hwndDlg);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ {
+ extern TCHAR key_id_global[17];
+ key_id_global[0] = 0;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+void ShowChangePasswdDlg()
+{
+ extern HINSTANCE hInst;
+ HWND hwndPaaswdDlg = NULL;
+ hwndPaaswdDlg = CreateDialog(hInst, MAKEINTRESOURCE(IDD_CHANGE_PASSWD), NULL, DlgProcChangePasswd);
+ SetForegroundWindow(hwndPaaswdDlg);
+}
|