diff options
author | Alexander Gluzsky <sss123next@list.ru> | 2012-12-23 22:54:47 +0000 |
---|---|---|
committer | Alexander Gluzsky <sss123next@list.ru> | 2012-12-23 22:54:47 +0000 |
commit | c86d58e9d199a7fd46ce81550b4299e8cad23718 (patch) | |
tree | be801b241a42d27bc79e3a1b06b924998b3cac92 /plugins/New_GPG/src | |
parent | 8f68d08a3f50ccad862d01d11114bbe0092a81bd (diff) |
fixed prescense signing bugs
git-svn-id: http://svn.miranda-ng.org/main/trunk@2824 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/New_GPG/src')
-rwxr-xr-x | plugins/New_GPG/src/gpg_wrapper.cpp | 2 | ||||
-rwxr-xr-x | plugins/New_GPG/src/main.cpp | 4702 | ||||
-rwxr-xr-x | plugins/New_GPG/src/messages.cpp | 5 | ||||
-rwxr-xr-x | plugins/New_GPG/src/utilities.cpp | 3625 | ||||
-rwxr-xr-x | plugins/New_GPG/src/utilities.h | 4 |
5 files changed, 4203 insertions, 4135 deletions
diff --git a/plugins/New_GPG/src/gpg_wrapper.cpp b/plugins/New_GPG/src/gpg_wrapper.cpp index e420faac92..d743af4c8b 100755 --- a/plugins/New_GPG/src/gpg_wrapper.cpp +++ b/plugins/New_GPG/src/gpg_wrapper.cpp @@ -140,6 +140,8 @@ pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD storeOutput(readstdout,aoutput); + fix_line_term(*aoutput); + debuglog<<time_str()<<": gpg out: "<<aoutput->c_str(); WaitForSingleObject(pri.hProcess,INFINITE); diff --git a/plugins/New_GPG/src/main.cpp b/plugins/New_GPG/src/main.cpp index 9918b66cc7..8c66eee04a 100755 --- a/plugins/New_GPG/src/main.cpp +++ b/plugins/New_GPG/src/main.cpp @@ -1,156 +1,156 @@ -// Copyright © 2010-2012 sss -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - - - -#include "commonheaders.h" - - -HWND hwndFirstRun = NULL, hwndSetDirs = NULL, hwndNewKey = NULL, hwndKeyGen = NULL, hwndSelectExistingKey = NULL; - -int itemnum = 0; - -HWND hwndList_g = NULL; -BOOL CheckStateStoreDB(HWND hwndDlg, int idCtrl, const char* szSetting); - -static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) -{ - HWND hwndList=GetDlgItem(hwndDlg, IDC_KEY_LIST); - hwndList_g = hwndList; - LVCOLUMN col = {0}; - LVITEM item = {0}; - NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; - TCHAR fp[16] = {0}; - switch (msg) - { - case WM_INITDIALOG: - { - SetWindowPos(hwndDlg, 0, firstrun_rect.left, firstrun_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); - TranslateDialogDefault(hwndDlg); - SetWindowText(hwndDlg, TranslateT("Set own key")); - col.pszText = _T("Key ID"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 50; - ListView_InsertColumn(hwndList, 0, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = TranslateT("Email"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 30; - ListView_InsertColumn(hwndList, 1, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = TranslateT("Name"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 250; - ListView_InsertColumn(hwndList, 2, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = TranslateT("Creation date"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 30; - ListView_InsertColumn(hwndList, 3, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = TranslateT("Key length"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 30; - ListView_InsertColumn(hwndList, 4, &col); +// Copyright © 2010-2012 sss
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+
+
+#include "commonheaders.h"
+
+
+HWND hwndFirstRun = NULL, hwndSetDirs = NULL, hwndNewKey = NULL, hwndKeyGen = NULL, hwndSelectExistingKey = NULL;
+
+int itemnum = 0;
+
+HWND hwndList_g = NULL;
+BOOL CheckStateStoreDB(HWND hwndDlg, int idCtrl, const char* szSetting);
+
+static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ HWND hwndList=GetDlgItem(hwndDlg, IDC_KEY_LIST);
+ hwndList_g = hwndList;
+ LVCOLUMN col = {0};
+ LVITEM item = {0};
+ NMLISTVIEW * hdr = (NMLISTVIEW *) lParam;
+ TCHAR fp[16] = {0};
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SetWindowPos(hwndDlg, 0, firstrun_rect.left, firstrun_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW);
+ TranslateDialogDefault(hwndDlg);
+ SetWindowText(hwndDlg, TranslateT("Set own key"));
+ col.pszText = _T("Key ID");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 50;
+ ListView_InsertColumn(hwndList, 0, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = TranslateT("Email");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 30;
+ ListView_InsertColumn(hwndList, 1, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = TranslateT("Name");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 250;
+ ListView_InsertColumn(hwndList, 2, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = TranslateT("Creation date");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 30;
+ ListView_InsertColumn(hwndList, 3, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = TranslateT("Key length");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 30;
+ ListView_InsertColumn(hwndList, 4, &col);
ZeroMemory(&col,sizeof(col));
col.pszText = TranslateT("Accounts");
col.mask = LVCF_TEXT | LVCF_WIDTH;
col.fmt = LVCFMT_LEFT;
col.cx = 30;
ListView_InsertColumn(hwndList, 5, &col);
- ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_FULLROWSELECT); - int i = 1, iRow = 0; - { - item.mask = LVIF_TEXT; - item.iItem = i; - item.iSubItem = 0; - item.pszText = _T(""); - {//parse gpg output - string out; - DWORD code; - pxResult result; - wstring::size_type p = 0, p2 = 0, stop = 0; - { - gpg_execution_params params; - wstring cmd = _T("--batch --list-secret-keys"); - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - } - 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; - TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - item.pszText = tmp; - iRow = ListView_InsertItem(hwndList, &item); - ListView_SetItemText(hwndList, iRow, 4, tmp); - mir_free(tmp); - p2+=2; - p = out.find(" ", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str()); - ListView_SetItemText(hwndList, iRow, 0, tmp); + ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_FULLROWSELECT);
+ int i = 1, iRow = 0;
+ {
+ item.mask = LVIF_TEXT;
+ item.iItem = i;
+ item.iSubItem = 0;
+ item.pszText = _T("");
+ {//parse gpg output
+ string out;
+ DWORD code;
+ pxResult result;
+ wstring::size_type p = 0, p2 = 0, stop = 0;
+ {
+ gpg_execution_params params;
+ wstring cmd = _T("--batch --list-secret-keys");
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ }
+ 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;
+ TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ item.pszText = tmp;
+ iRow = ListView_InsertItem(hwndList, &item);
+ ListView_SetItemText(hwndList, iRow, 4, tmp);
+ mir_free(tmp);
+ p2+=2;
+ p = out.find(" ", p2);
+ tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str());
+ ListView_SetItemText(hwndList, iRow, 0, tmp);
std::wstring key_id = tmp;
- mir_free(tmp); - p = out.find("uid ", p); - p2 = out.find_first_not_of(" ", p+5); - p = out.find("<", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str()); - ListView_SetItemText(hwndList, iRow, 2, tmp); - mir_free(tmp); - p++; - p2 = out.find(">", p); - tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - ListView_SetItemText(hwndList, iRow, 1, tmp); - mir_free(tmp); - p = out.find("ssb ", 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); - ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this - ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); + mir_free(tmp);
+ p = out.find("uid ", p);
+ p2 = out.find_first_not_of(" ", p+5);
+ p = out.find("<", p2);
+ tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str());
+ ListView_SetItemText(hwndList, iRow, 2, tmp);
+ mir_free(tmp);
+ p++;
+ p2 = out.find(">", p);
+ tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ ListView_SetItemText(hwndList, iRow, 1, tmp);
+ mir_free(tmp);
+ p = out.find("ssb ", 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);
+ ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this
+ ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE);
{ //get accounts
int count = 0;
PROTOACCOUNT **accounts;
@@ -178,2210 +178,2210 @@ static INT_PTR CALLBACK DlgProcFirstRun(HWND hwndDlg,UINT msg,WPARAM wParam,LPAR ListView_SetItemText(hwndList, iRow, 5, (TCHAR*)accs.c_str());
ListView_SetColumnWidth(hwndList, 5, LVSCW_AUTOSIZE);
}
- i++; - } - } - } - { - SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_ADDSTRING, 0, (LPARAM)Translate("Default")); - int count = 0; - PROTOACCOUNT **accounts; - ProtoEnumAccounts(&count, &accounts); - for(int i = 0; i < count; i++) - { - if(StriStr(accounts[i]->szModuleName, "metacontacts")) - continue; - if(StriStr(accounts[i]->szModuleName, "weather")) - continue; - std::string acc = toUTF8(accounts[i]->tszAccountName); - acc += "("; - acc += accounts[i]->szModuleName; - acc += ")"; - //acc += "_KeyID"; - SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_ADDSTRING, 0, (LPARAM)acc.c_str()); - } - SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_SELECTSTRING, 0, (LPARAM)Translate("Default")); - string keyinfo = Translate("key id"); - keyinfo += ": "; - char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); - keyinfo += (strlen(keyid) > 0)?keyid:Translate("not set"); - mir_free(keyid); - SetDlgItemTextA(hwndDlg, IDC_KEY_ID, keyinfo.c_str()); - } - return TRUE; - } - - - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_GENERATE_KEY: - void ShowKeyGenDialog(); - ShowKeyGenDialog(); - break; - case ID_OK: - { - ListView_GetItemText(hwndList, itemnum, 0, fp, 16); - TCHAR *name = new TCHAR [64]; - ListView_GetItemText(hwndList, itemnum, 2, name, 64); - { - if(_tcschr(name, _T('('))) - { - wstring str = name; - wstring::size_type p = str.find(_T("("))-1; - _tcscpy(name, str.substr(0, p).c_str()); - } - } - string out; - DWORD code; - wstring cmd = _T("--batch -a --export "); - cmd += fp; -// cmd += _T("\""); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - string::size_type s = 0; - while((s = out.find("\r", s)) != string::npos) - { - out.erase(s, 1); - } - { - char buf[64]; - GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63); - if(!strcmp(buf, Translate("Default"))) - { - DBWriteContactSettingString(NULL, szGPGModuleName, "GPGPubKey", out.c_str()); - DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyMainName", name); - DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyID", fp); - } - else - { - std::string acc_str = buf; - acc_str += "_GPGPubKey"; - DBWriteContactSettingString(NULL, szGPGModuleName, acc_str.c_str(), out.c_str()); - acc_str = buf; - acc_str += "_KeyMainName"; - DBWriteContactSettingTString(NULL, szGPGModuleName, acc_str.c_str(), name); - acc_str = buf; - acc_str += "_KeyID"; - DBWriteContactSettingTString(NULL, szGPGModuleName, acc_str.c_str(), fp); - } - if(!strcmp(buf, Translate("Default"))) - { - wstring keyinfo = TranslateT("Default private key id"); - keyinfo += _T(": "); - keyinfo += (fp[0])?fp:_T("not set"); - extern HWND hwndCurKey_p; - SetWindowText(hwndCurKey_p, keyinfo.c_str()); - } - } - TCHAR passwd[64]; - GetDlgItemText(hwndDlg, IDC_KEY_PASSWORD, passwd, 64); - if(passwd[0]) - { - string dbsetting = "szKey_"; - char *keyid = mir_t2a(fp); - dbsetting += keyid; - mir_free(keyid); - dbsetting += "_Password"; - DBWriteContactSettingTString(NULL, szGPGModuleName, dbsetting.c_str(), passwd); - } - delete [] name; - } - bAutoExchange = CheckStateStoreDB(hwndDlg, IDC_AUTO_EXCHANGE, "bAutoExchange"); - gpg_valid = isGPGValid(); - gpg_keyexist = isGPGKeyExist(); - DestroyWindow(hwndDlg); - break; - case IDC_OTHER: - { - void ShowLoadPublicKeyDialog(); - extern map<int, HANDLE> user_data; - extern int item_num; - item_num = 0; //black magic here - user_data[1] = 0; - ShowLoadPublicKeyDialog(); - ListView_DeleteAllItems(hwndList); - { - int i = 1, iRow = 0; - item.mask = LVIF_TEXT; - item.iItem = i; - item.iSubItem = 0; - item.pszText = _T(""); - {//parse gpg output - string out; - DWORD code; - wstring::size_type p = 0, p2 = 0, stop = 0; - { - wstring cmd = _T("--batch --list-secret-keys"); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - } - 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; - TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - item.pszText = tmp; - iRow = ListView_InsertItem(hwndList, &item); - ListView_SetItemText(hwndList, iRow, 4, tmp); - mir_free(tmp); - p2+=2; - p = out.find(" ", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str()); - ListView_SetItemText(hwndList, iRow, 0, tmp); - mir_free(tmp); - p = out.find("uid ", p); - p2 = out.find_first_not_of(" ", p+5); - p = out.find("<", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str()); - ListView_SetItemText(hwndList, iRow, 2, tmp); - mir_free(tmp); - p++; - p2 = out.find(">", p); - tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - ListView_SetItemText(hwndList, iRow, 1, tmp); - mir_free(tmp); - p = out.find("ssb ", 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); - ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this - ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); - i++; - } - } - } - } - break; - case IDC_DELETE_KEY: - ListView_GetItemText(hwndList, itemnum, 0, fp, 16); - { - string out; - DWORD code; - wstring cmd = _T("--batch --fingerprint "); - cmd += fp; - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) - { - delete gpg_thread; - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - string::size_type s = out.find("Key fingerprint = "); - s += strlen("Key fingerprint = "); - string::size_type s2 = out.find("\n", s); - TCHAR *fp = NULL; - { - 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); - } - fp = mir_a2t(tmp.c_str()); - } - cmd.clear(); - out.clear(); - cmd += _T("--batch --delete-secret-and-public-key --fingerprint "); - cmd += fp; - mir_free(fp); - gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) - { - delete gpg_thread; - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - } - { - char buf[64]; - GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63); - if(!strcmp(buf, Translate("Default"))) - { - DBDeleteContactSetting(NULL, szGPGModuleName, "GPGPubKey"); - DBDeleteContactSetting(NULL, szGPGModuleName, "KeyID"); - DBDeleteContactSetting(NULL, szGPGModuleName, "KeyComment"); - DBDeleteContactSetting(NULL, szGPGModuleName, "KeyMainName"); - DBDeleteContactSetting(NULL, szGPGModuleName, "KeyMainEmail"); - DBDeleteContactSetting(NULL, szGPGModuleName, "KeyType"); - } - else - { - std::string acc_str = buf; - acc_str += "_GPGPubKey"; - DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyMainName"; - DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyID"; - DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyComment"; - DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyMainEmail"; - DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str()); - acc_str = buf; - acc_str += "_KeyType"; - DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str()); - } - } - ListView_DeleteItem(hwndList, itemnum); - break; - case IDC_GENERATE_RANDOM: - { - wstring path; - { //generating key file - TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - path = tmp; - mir_free(tmp); - path.append(_T("\\new_key")); - wfstream f(path.c_str(), std::ios::out); - if(!f.is_open()) - { - MessageBox(0, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK); - break; - } - 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; - wstring cmd; - cmd += _T("--batch --yes --gen-key \""); - cmd += path; - cmd += _T("\""); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - SetWindowTextA(GetDlgItem(hwndDlg, IDC_GENERATING_KEY), Translate("Generating new random key, please wait")); - EnableWindow(GetDlgItem(hwndDlg, IDC_GENERATE_KEY), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_OTHER), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_KEY), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_LIST), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_GENERATE_RANDOM), 0); - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::minutes(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted"; - break; - } - if(result == pxNotFound) - break; - - DeleteFile(path.c_str()); - 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; - wstring cmd = _T("--batch -a --export "); - cmd += path; - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<"GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - string::size_type s = 0; - while((s = out.find("\r", s)) != string::npos) - { - out.erase(s, 1); - } - { - char buf[64]; - GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63); - if(!strcmp(buf, Translate("Default"))) - { - DBWriteContactSettingString(NULL, szGPGModuleName, "GPGPubKey", out.c_str()); - DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyID", fp); - } - else - { - std::string acc_str = buf; - acc_str += "_GPGPubKey"; - DBWriteContactSettingString(NULL, szGPGModuleName, acc_str.c_str(), out.c_str()); - acc_str = buf; - acc_str += "_KeyID"; - DBWriteContactSettingTString(NULL, szGPGModuleName, acc_str.c_str(), fp); - } - } - extern HWND hwndCurKey_p; - SetWindowText(hwndCurKey_p, path.c_str()); - } - } - DestroyWindow(hwndDlg); - break; - case IDC_ACCOUNT: - { - char buf[64]; - GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63); - if(!strcmp(buf, Translate("Default"))) - { - string keyinfo = Translate("key id"); - keyinfo += ": "; - char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); - keyinfo += (strlen(keyid) > 0)?keyid:Translate("not set"); - mir_free(keyid); - SetDlgItemTextA(hwndDlg, IDC_KEY_ID, 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 += (strlen(keyid) > 0)?keyid:Translate("not set"); - mir_free(keyid); - SetDlgItemTextA(hwndDlg, IDC_KEY_ID, keyinfo.c_str()); - } - } - break; - - } - break; - } - - case WM_NOTIFY: - { - if(hdr && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1)) - { - if(hdr->hdr.code == NM_CLICK) - { - EnableWindow(GetDlgItem(hwndDlg, ID_OK), 1); - itemnum = hdr->iItem; - } - } -/* switch(LOWORD(wParam)) - { - default: - break; - }; */ -/* switch (((LPNMHDR)lParam)->code) - { - default: - break; - } */ - } - break; - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - case WM_DESTROY: - { - GetWindowRect(hwndDlg, &firstrun_rect); - DBWriteContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowX", firstrun_rect.left); - DBWriteContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowY", firstrun_rect.top); - } - hwndFirstRun = NULL; - break; - - } - - return FALSE; -} - -void ShowFirstRunDialog(); - -static INT_PTR CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TCHAR *tmp = NULL; - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - TCHAR *path = new TCHAR [MAX_PATH]; - bool gpg_exists = false, lang_exists = false; - { - char *mir_path = new char [MAX_PATH]; - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); - SetCurrentDirectoryA(mir_path); - tmp = mir_a2t(mir_path); - mir_free(mir_path); - mir_realloc(path, (_tcslen(path)+128)*sizeof(TCHAR)); - TCHAR *gpg_path = new TCHAR [MAX_PATH], *gpg_lang_path = new TCHAR [MAX_PATH]; - _tcscpy(gpg_path, tmp); - _tcscat(gpg_path, _T("\\GnuPG\\gpg.exe")); - _tcscpy(gpg_lang_path, tmp); - _tcscat(gpg_lang_path, _T("\\GnuPG\\gnupg.nls\\en@quot.mo")); - mir_free(tmp); - if(_waccess(gpg_path, 0) != -1) - { - gpg_exists = true; - _tcscpy(path, _T("GnuPG\\gpg.exe")); - } - if(_waccess(gpg_lang_path, 0) != -1) - lang_exists = true; - if(gpg_exists && !lang_exists) //TODO: check gpg version - MessageBox(0, TranslateT("gpg binary found in miranda folder, but english locale does not exists.\nit's highly recommended to place \\gnupg.nls\\en@quot.mo in gnupg folder under miranda root.\nwithout this file you may expirense many problem with gpg output on non english systems.\nand plugin may completely do not work.\nyou have beed warned."), TranslateT("Warning"), MB_OK); - mir_free(gpg_path); - mir_free(gpg_lang_path); - } - DWORD len = MAX_PATH; - if(!gpg_exists) - { - tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", (SHGetValue(HKEY_CURRENT_USER, _T("Software\\GNU\\GnuPG"), _T("gpgProgram"), 0, path, &len) == ERROR_SUCCESS)?path:_T("")); - if(tmp[0]) - { - char *mir_path = new char [MAX_PATH]; - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); - SetCurrentDirectoryA(mir_path); - delete [] mir_path; - if(_waccess(tmp, 0) == -1) - { - if(errno == ENOENT) - MessageBox(0, TranslateT("wrong gpg binary location found in system.\nplease choose another location"), TranslateT("Warning"), MB_OK); - } - } - } - else - tmp = mir_wstrdup(path); - delete [] path; - SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp); - bool bad_version = false; - if(gpg_exists && lang_exists) - { - DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); - string out; - DWORD code; - wstring cmd = _T("--version"); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - gpg_valid = true; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - } - gpg_valid = false; - DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath"); - string::size_type p1 = out.find("(GnuPG) "); - if(p1 != string::npos) - { - p1 += strlen("(GnuPG) "); - if(out[p1] != '1') - bad_version = true; - } - else - { - bad_version = false; - MessageBox(0, TranslateT("This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK); - } - if(bad_version) - MessageBox(0, TranslateT("Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK); - } - mir_free(tmp); - if(!gpg_exists) - { - wstring path_ = _wgetenv(_T("APPDATA")); - path_ += _T("\\GnuPG"); - tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", (TCHAR*)path_.c_str()); - } - SetDlgItemText(hwndDlg, IDC_HOME_DIR, !gpg_exists?tmp:_T("gpg")); - mir_free(tmp); - if(gpg_exists && lang_exists && !bad_version) - MessageBox(0, TranslateT("Your GPG version is supported. The language file was found.\nGPG plugin should work fine.\nPress OK to continue."), TranslateT("Info"), MB_OK); - extern bool bIsMiranda09; - EnableWindow(GetDlgItem(hwndDlg, IDC_AUTO_EXCHANGE), bIsMiranda09); - return TRUE; - } - - - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_SET_BIN_PATH: - { - GetFilePath(_T("Choose gpg.exe"), "szGpgBinPath", _T("*.exe"), _T("EXE Executables")); - tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("gpg.exe")); - SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp); - char mir_path[MAX_PATH]; - char *atmp = mir_t2a(tmp); - mir_free(tmp); - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); - char* p_path = NULL; - if(StriStr(atmp, mir_path)) - { - p_path = atmp + strlen(mir_path); - tmp = mir_a2t(p_path); - SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp); - } - } - break; - case IDC_SET_HOME_DIR: - { - GetFolderPath(_T("Set home diractory"), "szHomePath"); - tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - SetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp); - char mir_path[MAX_PATH]; - char *atmp = mir_t2a(tmp); - mir_free(tmp); - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); - char* p_path = NULL; - if(StriStr(atmp, mir_path)) - { - p_path = atmp + strlen(mir_path); - tmp = mir_a2t(p_path); - SetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp); - } - } - break; - case ID_OK: - { - TCHAR tmp[512]; - GetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp, 512); - if(tmp[0]) - { - char *mir_path = new char [MAX_PATH]; - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); - SetCurrentDirectoryA(mir_path); - delete [] mir_path; - if(_waccess(tmp, 0) == -1) - { - if(errno == ENOENT) - { - MessageBox(0, TranslateT("gpg binary does not exists.\nplease choose another location"), TranslateT("Warning"), MB_OK); - break; - } - } - } - else - { - MessageBox(0, TranslateT("please choose gpg binary location"), TranslateT("Warning"), MB_OK); - break; - } - { - bool bad_version = false; - DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); - string out; - DWORD code; - wstring cmd = _T("--version"); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - gpg_valid = true; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - gpg_thread.~thread(); - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - } - gpg_valid = false; - DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath"); - string::size_type p1 = out.find("(GnuPG) "); - if(p1 != string::npos) - { - p1 += strlen("(GnuPG) "); - if(out[p1] != '1') - bad_version = true; - } - else - { - bad_version = false; - MessageBox(0, TranslateT("This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK); - } - if(bad_version) - MessageBox(0, TranslateT("Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK); - } - DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); - GetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp, 512); - while(tmp[_tcslen(tmp)-1] == '\\') - tmp[_tcslen(tmp)-1] = '\0'; - if(!tmp[0]) - { - MessageBox(0, TranslateT("please set keyring's home directory"), TranslateT("Warning"), MB_OK); - break; - } - DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", tmp); - { - TCHAR *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - DWORD dwFileAttr = GetFileAttributes(path); - if (dwFileAttr != INVALID_FILE_ATTRIBUTES) - { - dwFileAttr &=~ FILE_ATTRIBUTE_READONLY; - SetFileAttributes(path, dwFileAttr); - } - mir_free(path); - } - gpg_valid = true; - DBWriteContactSettingByte(NULL, szGPGModuleName, "FirstRun", 0); - DestroyWindow(hwndDlg); - ShowFirstRunDialog(); - } - break; - case IDC_GENERATE_RANDOM: - { - TCHAR tmp[512]; - GetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp, 512); - if(tmp[0]) - { - char *mir_path = new char [MAX_PATH]; - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); - SetCurrentDirectoryA(mir_path); - delete [] mir_path; - if(_waccess(tmp, 0) == -1) - { - if(errno == ENOENT) - { - MessageBox(0, TranslateT("gpg binary does not exists.\nplease choose another location"), TranslateT("Warning"), MB_OK); - break; - } - } - } - else - { - MessageBox(0, TranslateT("please choose gpg binary location"), TranslateT("Warning"), MB_OK); - break; - } - { - bool bad_version = false; - DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); - string out; - DWORD code; - wstring cmd = _T("--version"); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - gpg_valid = true; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - gpg_thread.~thread(); - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - } - gpg_valid = false; - DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath"); - string::size_type p1 = out.find("(GnuPG) "); - if(p1 != string::npos) - { - p1 += strlen("(GnuPG) "); - if(out[p1] != '1') - bad_version = true; - } - else - { - bad_version = false; - MessageBox(0, TranslateT("This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK); - } - if(bad_version) - MessageBox(0, TranslateT("Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK); - } - DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); - GetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp, 512); - while(tmp[_tcslen(tmp)-1] == '\\') - tmp[_tcslen(tmp)-1] = '\0'; - if(!tmp[0]) - { - MessageBox(0, TranslateT("please set keyring's home directory"), TranslateT("Warning"), MB_OK); - break; - } - DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", tmp); - { - TCHAR *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - DWORD dwFileAttr = GetFileAttributes(path); - if (dwFileAttr != INVALID_FILE_ATTRIBUTES) - { - dwFileAttr &=~ FILE_ATTRIBUTE_READONLY; - SetFileAttributes(path, dwFileAttr); - } - mir_free(path); - } - } - { - wstring path; - { //generating key file - TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - path = tmp; - mir_free(tmp); - path.append(_T("\\new_key")); - wfstream f(path.c_str(), std::ios::out); - if(!f.is_open()) - { - MessageBox(0, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK); - break; - } - f<<"Key-Type: RSA"; - f<<"\n"; - f<<"Key-Length: 2048"; - 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; - wstring cmd; - cmd += _T("--batch --yes --gen-key \""); - cmd += path; - cmd += _T("\""); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - gpg_valid = true; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::minutes(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted"; - gpg_valid = false; - break; - } - gpg_valid = false; - if(result == pxNotFound) - break; - DeleteFile(path.c_str()); - 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; - wstring cmd = _T("--batch -a --export "); - cmd += path; - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - gpg_valid = true; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<"GPG execution timed out, aborted\n"; - gpg_valid = false; - break; - } - gpg_valid = false; - if(result == pxNotFound) - break; - string::size_type s = 0; - while((s = out.find("\r", s)) != string::npos) - { - out.erase(s, 1); - } - DBWriteContactSettingString(NULL, szGPGModuleName, "GPGPubKey", out.c_str()); - DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyID", path.c_str()); - extern HWND hwndCurKey_p; - SetWindowText(hwndCurKey_p, path.c_str()); - } - } - bAutoExchange = CheckStateStoreDB(hwndDlg, IDC_AUTO_EXCHANGE, "bAutoExchange"); - gpg_valid = true; - DBWriteContactSettingByte(NULL, szGPGModuleName, "FirstRun", 0); - DestroyWindow(hwndDlg); - break; - default: - break; - } - - break; - } - - case WM_NOTIFY: - { -/* switch (((LPNMHDR)lParam)->code) - { - default: - break; - }*/ - } - break; - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - case WM_DESTROY: - hwndSetDirs = NULL; - break; - - } - return FALSE; -} - -static INT_PTR CALLBACK DlgProcNewKeyDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - extern HANDLE new_key_hcnt; - extern boost::mutex new_key_hcnt_mutex; - static HANDLE hContact = INVALID_HANDLE_VALUE; - void ImportKey(); - TCHAR *tmp = NULL; - switch (msg) - { - case WM_INITDIALOG: - { - hContact = new_key_hcnt; + i++;
+ }
+ }
+ }
+ {
+ SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_ADDSTRING, 0, (LPARAM)Translate("Default"));
+ int count = 0;
+ PROTOACCOUNT **accounts;
+ ProtoEnumAccounts(&count, &accounts);
+ for(int i = 0; i < count; i++)
+ {
+ if(StriStr(accounts[i]->szModuleName, "metacontacts"))
+ continue;
+ if(StriStr(accounts[i]->szModuleName, "weather"))
+ continue;
+ std::string acc = toUTF8(accounts[i]->tszAccountName);
+ acc += "(";
+ acc += accounts[i]->szModuleName;
+ acc += ")";
+ //acc += "_KeyID";
+ SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_ADDSTRING, 0, (LPARAM)acc.c_str());
+ }
+ SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_SELECTSTRING, 0, (LPARAM)Translate("Default"));
+ string keyinfo = Translate("key id");
+ keyinfo += ": ";
+ char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
+ keyinfo += (strlen(keyid) > 0)?keyid:Translate("not set");
+ mir_free(keyid);
+ SetDlgItemTextA(hwndDlg, IDC_KEY_ID, keyinfo.c_str());
+ }
+ return TRUE;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_GENERATE_KEY:
+ void ShowKeyGenDialog();
+ ShowKeyGenDialog();
+ break;
+ case ID_OK:
+ {
+ ListView_GetItemText(hwndList, itemnum, 0, fp, 16);
+ TCHAR *name = new TCHAR [64];
+ ListView_GetItemText(hwndList, itemnum, 2, name, 64);
+ {
+ if(_tcschr(name, _T('(')))
+ {
+ wstring str = name;
+ wstring::size_type p = str.find(_T("("))-1;
+ _tcscpy(name, str.substr(0, p).c_str());
+ }
+ }
+ string out;
+ DWORD code;
+ wstring cmd = _T("--batch -a --export ");
+ cmd += fp;
+// cmd += _T("\"");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ string::size_type s = 0;
+ while((s = out.find("\r", s)) != string::npos)
+ {
+ out.erase(s, 1);
+ }
+ {
+ char buf[64];
+ GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63);
+ if(!strcmp(buf, Translate("Default")))
+ {
+ DBWriteContactSettingString(NULL, szGPGModuleName, "GPGPubKey", out.c_str());
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyMainName", name);
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyID", fp);
+ }
+ else
+ {
+ std::string acc_str = buf;
+ acc_str += "_GPGPubKey";
+ DBWriteContactSettingString(NULL, szGPGModuleName, acc_str.c_str(), out.c_str());
+ acc_str = buf;
+ acc_str += "_KeyMainName";
+ DBWriteContactSettingTString(NULL, szGPGModuleName, acc_str.c_str(), name);
+ acc_str = buf;
+ acc_str += "_KeyID";
+ DBWriteContactSettingTString(NULL, szGPGModuleName, acc_str.c_str(), fp);
+ }
+ if(!strcmp(buf, Translate("Default")))
+ {
+ wstring keyinfo = TranslateT("Default private key id");
+ keyinfo += _T(": ");
+ keyinfo += (fp[0])?fp:_T("not set");
+ extern HWND hwndCurKey_p;
+ SetWindowText(hwndCurKey_p, keyinfo.c_str());
+ }
+ }
+ TCHAR passwd[64];
+ GetDlgItemText(hwndDlg, IDC_KEY_PASSWORD, passwd, 64);
+ if(passwd[0])
+ {
+ string dbsetting = "szKey_";
+ char *keyid = mir_t2a(fp);
+ dbsetting += keyid;
+ mir_free(keyid);
+ dbsetting += "_Password";
+ DBWriteContactSettingTString(NULL, szGPGModuleName, dbsetting.c_str(), passwd);
+ }
+ delete [] name;
+ }
+ bAutoExchange = CheckStateStoreDB(hwndDlg, IDC_AUTO_EXCHANGE, "bAutoExchange");
+ gpg_valid = isGPGValid();
+ gpg_keyexist = isGPGKeyExist();
+ DestroyWindow(hwndDlg);
+ break;
+ case IDC_OTHER:
+ {
+ void ShowLoadPublicKeyDialog();
+ extern map<int, HANDLE> user_data;
+ extern int item_num;
+ item_num = 0; //black magic here
+ user_data[1] = 0;
+ ShowLoadPublicKeyDialog();
+ ListView_DeleteAllItems(hwndList);
+ {
+ int i = 1, iRow = 0;
+ item.mask = LVIF_TEXT;
+ item.iItem = i;
+ item.iSubItem = 0;
+ item.pszText = _T("");
+ {//parse gpg output
+ string out;
+ DWORD code;
+ wstring::size_type p = 0, p2 = 0, stop = 0;
+ {
+ wstring cmd = _T("--batch --list-secret-keys");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ }
+ 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;
+ TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ item.pszText = tmp;
+ iRow = ListView_InsertItem(hwndList, &item);
+ ListView_SetItemText(hwndList, iRow, 4, tmp);
+ mir_free(tmp);
+ p2+=2;
+ p = out.find(" ", p2);
+ tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str());
+ ListView_SetItemText(hwndList, iRow, 0, tmp);
+ mir_free(tmp);
+ p = out.find("uid ", p);
+ p2 = out.find_first_not_of(" ", p+5);
+ p = out.find("<", p2);
+ tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str());
+ ListView_SetItemText(hwndList, iRow, 2, tmp);
+ mir_free(tmp);
+ p++;
+ p2 = out.find(">", p);
+ tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ ListView_SetItemText(hwndList, iRow, 1, tmp);
+ mir_free(tmp);
+ p = out.find("ssb ", 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);
+ ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this
+ ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE);
+ i++;
+ }
+ }
+ }
+ }
+ break;
+ case IDC_DELETE_KEY:
+ ListView_GetItemText(hwndList, itemnum, 0, fp, 16);
+ {
+ string out;
+ DWORD code;
+ wstring cmd = _T("--batch --fingerprint ");
+ cmd += fp;
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread->timed_join(boost::posix_time::seconds(10)))
+ {
+ delete gpg_thread;
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ string::size_type s = out.find("Key fingerprint = ");
+ s += strlen("Key fingerprint = ");
+ string::size_type s2 = out.find("\n", s);
+ TCHAR *fp = NULL;
+ {
+ 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);
+ }
+ fp = mir_a2t(tmp.c_str());
+ }
+ cmd.clear();
+ out.clear();
+ cmd += _T("--batch --delete-secret-and-public-key --fingerprint ");
+ cmd += fp;
+ mir_free(fp);
+ gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread->timed_join(boost::posix_time::seconds(10)))
+ {
+ delete gpg_thread;
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ }
+ {
+ char buf[64];
+ GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63);
+ if(!strcmp(buf, Translate("Default")))
+ {
+ DBDeleteContactSetting(NULL, szGPGModuleName, "GPGPubKey");
+ DBDeleteContactSetting(NULL, szGPGModuleName, "KeyID");
+ DBDeleteContactSetting(NULL, szGPGModuleName, "KeyComment");
+ DBDeleteContactSetting(NULL, szGPGModuleName, "KeyMainName");
+ DBDeleteContactSetting(NULL, szGPGModuleName, "KeyMainEmail");
+ DBDeleteContactSetting(NULL, szGPGModuleName, "KeyType");
+ }
+ else
+ {
+ std::string acc_str = buf;
+ acc_str += "_GPGPubKey";
+ DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyMainName";
+ DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyID";
+ DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyComment";
+ DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyMainEmail";
+ DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str());
+ acc_str = buf;
+ acc_str += "_KeyType";
+ DBDeleteContactSetting(NULL, szGPGModuleName, acc_str.c_str());
+ }
+ }
+ ListView_DeleteItem(hwndList, itemnum);
+ break;
+ case IDC_GENERATE_RANDOM:
+ {
+ wstring path;
+ { //generating key file
+ TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ path = tmp;
+ mir_free(tmp);
+ path.append(_T("\\new_key"));
+ wfstream f(path.c_str(), std::ios::out);
+ if(!f.is_open())
+ {
+ MessageBox(0, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK);
+ break;
+ }
+ 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;
+ wstring cmd;
+ cmd += _T("--batch --yes --gen-key \"");
+ cmd += path;
+ cmd += _T("\"");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_GENERATING_KEY), Translate("Generating new random key, please wait"));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_GENERATE_KEY), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_OTHER), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE_KEY), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_LIST), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_GENERATE_RANDOM), 0);
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::minutes(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+
+ DeleteFile(path.c_str());
+ 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;
+ wstring cmd = _T("--batch -a --export ");
+ cmd += path;
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<"GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ string::size_type s = 0;
+ while((s = out.find("\r", s)) != string::npos)
+ {
+ out.erase(s, 1);
+ }
+ {
+ char buf[64];
+ GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63);
+ if(!strcmp(buf, Translate("Default")))
+ {
+ DBWriteContactSettingString(NULL, szGPGModuleName, "GPGPubKey", out.c_str());
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyID", fp);
+ }
+ else
+ {
+ std::string acc_str = buf;
+ acc_str += "_GPGPubKey";
+ DBWriteContactSettingString(NULL, szGPGModuleName, acc_str.c_str(), out.c_str());
+ acc_str = buf;
+ acc_str += "_KeyID";
+ DBWriteContactSettingTString(NULL, szGPGModuleName, acc_str.c_str(), fp);
+ }
+ }
+ extern HWND hwndCurKey_p;
+ SetWindowText(hwndCurKey_p, path.c_str());
+ }
+ }
+ DestroyWindow(hwndDlg);
+ break;
+ case IDC_ACCOUNT:
+ {
+ char buf[64];
+ GetDlgItemTextA(hwndDlg, IDC_ACCOUNT, buf, 63);
+ if(!strcmp(buf, Translate("Default")))
+ {
+ string keyinfo = Translate("key id");
+ keyinfo += ": ";
+ char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
+ keyinfo += (strlen(keyid) > 0)?keyid:Translate("not set");
+ mir_free(keyid);
+ SetDlgItemTextA(hwndDlg, IDC_KEY_ID, 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 += (strlen(keyid) > 0)?keyid:Translate("not set");
+ mir_free(keyid);
+ SetDlgItemTextA(hwndDlg, IDC_KEY_ID, keyinfo.c_str());
+ }
+ }
+ break;
+
+ }
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ if(hdr && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1))
+ {
+ if(hdr->hdr.code == NM_CLICK)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, ID_OK), 1);
+ itemnum = hdr->iItem;
+ }
+ }
+/* switch(LOWORD(wParam))
+ {
+ default:
+ break;
+ }; */
+/* switch (((LPNMHDR)lParam)->code)
+ {
+ default:
+ break;
+ } */
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ {
+ GetWindowRect(hwndDlg, &firstrun_rect);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowX", firstrun_rect.left);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowY", firstrun_rect.top);
+ }
+ hwndFirstRun = NULL;
+ break;
+
+ }
+
+ return FALSE;
+}
+
+void ShowFirstRunDialog();
+
+static INT_PTR CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ TCHAR *tmp = NULL;
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+ TCHAR *path = new TCHAR [MAX_PATH];
+ bool gpg_exists = false, lang_exists = false;
+ {
+ char *mir_path = new char [MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ SetCurrentDirectoryA(mir_path);
+ tmp = mir_a2t(mir_path);
+ mir_free(mir_path);
+ mir_realloc(path, (_tcslen(path)+128)*sizeof(TCHAR));
+ TCHAR *gpg_path = new TCHAR [MAX_PATH], *gpg_lang_path = new TCHAR [MAX_PATH];
+ _tcscpy(gpg_path, tmp);
+ _tcscat(gpg_path, _T("\\GnuPG\\gpg.exe"));
+ _tcscpy(gpg_lang_path, tmp);
+ _tcscat(gpg_lang_path, _T("\\GnuPG\\gnupg.nls\\en@quot.mo"));
+ mir_free(tmp);
+ if(_waccess(gpg_path, 0) != -1)
+ {
+ gpg_exists = true;
+ _tcscpy(path, _T("GnuPG\\gpg.exe"));
+ }
+ if(_waccess(gpg_lang_path, 0) != -1)
+ lang_exists = true;
+ if(gpg_exists && !lang_exists) //TODO: check gpg version
+ MessageBox(0, TranslateT("gpg binary found in miranda folder, but english locale does not exists.\nit's highly recommended to place \\gnupg.nls\\en@quot.mo in gnupg folder under miranda root.\nwithout this file you may expirense many problem with gpg output on non english systems.\nand plugin may completely do not work.\nyou have beed warned."), TranslateT("Warning"), MB_OK);
+ mir_free(gpg_path);
+ mir_free(gpg_lang_path);
+ }
+ DWORD len = MAX_PATH;
+ if(!gpg_exists)
+ {
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", (SHGetValue(HKEY_CURRENT_USER, _T("Software\\GNU\\GnuPG"), _T("gpgProgram"), 0, path, &len) == ERROR_SUCCESS)?path:_T(""));
+ if(tmp[0])
+ {
+ char *mir_path = new char [MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ SetCurrentDirectoryA(mir_path);
+ delete [] mir_path;
+ if(_waccess(tmp, 0) == -1)
+ {
+ if(errno == ENOENT)
+ MessageBox(0, TranslateT("wrong gpg binary location found in system.\nplease choose another location"), TranslateT("Warning"), MB_OK);
+ }
+ }
+ }
+ else
+ tmp = mir_wstrdup(path);
+ delete [] path;
+ SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp);
+ bool bad_version = false;
+ if(gpg_exists && lang_exists)
+ {
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp);
+ string out;
+ DWORD code;
+ wstring cmd = _T("--version");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ gpg_valid = true;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ }
+ gpg_valid = false;
+ DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath");
+ string::size_type p1 = out.find("(GnuPG) ");
+ if(p1 != string::npos)
+ {
+ p1 += strlen("(GnuPG) ");
+ if(out[p1] != '1')
+ bad_version = true;
+ }
+ else
+ {
+ bad_version = false;
+ MessageBox(0, TranslateT("This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK);
+ }
+ if(bad_version)
+ MessageBox(0, TranslateT("Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK);
+ }
+ mir_free(tmp);
+ if(!gpg_exists)
+ {
+ wstring path_ = _wgetenv(_T("APPDATA"));
+ path_ += _T("\\GnuPG");
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", (TCHAR*)path_.c_str());
+ }
+ SetDlgItemText(hwndDlg, IDC_HOME_DIR, !gpg_exists?tmp:_T("gpg"));
+ mir_free(tmp);
+ if(gpg_exists && lang_exists && !bad_version)
+ MessageBox(0, TranslateT("Your GPG version is supported. The language file was found.\nGPG plugin should work fine.\nPress OK to continue."), TranslateT("Info"), MB_OK);
+ extern bool bIsMiranda09;
+ EnableWindow(GetDlgItem(hwndDlg, IDC_AUTO_EXCHANGE), bIsMiranda09);
+ return TRUE;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_SET_BIN_PATH:
+ {
+ GetFilePath(_T("Choose gpg.exe"), "szGpgBinPath", _T("*.exe"), _T("EXE Executables"));
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("gpg.exe"));
+ SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp);
+ char mir_path[MAX_PATH];
+ char *atmp = mir_t2a(tmp);
+ mir_free(tmp);
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ char* p_path = NULL;
+ if(StriStr(atmp, mir_path))
+ {
+ p_path = atmp + strlen(mir_path);
+ tmp = mir_a2t(p_path);
+ SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp);
+ }
+ }
+ break;
+ case IDC_SET_HOME_DIR:
+ {
+ GetFolderPath(_T("Set home diractory"), "szHomePath");
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ SetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp);
+ char mir_path[MAX_PATH];
+ char *atmp = mir_t2a(tmp);
+ mir_free(tmp);
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ char* p_path = NULL;
+ if(StriStr(atmp, mir_path))
+ {
+ p_path = atmp + strlen(mir_path);
+ tmp = mir_a2t(p_path);
+ SetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp);
+ }
+ }
+ break;
+ case ID_OK:
+ {
+ TCHAR tmp[512];
+ GetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp, 512);
+ if(tmp[0])
+ {
+ char *mir_path = new char [MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ SetCurrentDirectoryA(mir_path);
+ delete [] mir_path;
+ if(_waccess(tmp, 0) == -1)
+ {
+ if(errno == ENOENT)
+ {
+ MessageBox(0, TranslateT("gpg binary does not exists.\nplease choose another location"), TranslateT("Warning"), MB_OK);
+ break;
+ }
+ }
+ }
+ else
+ {
+ MessageBox(0, TranslateT("please choose gpg binary location"), TranslateT("Warning"), MB_OK);
+ break;
+ }
+ {
+ bool bad_version = false;
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp);
+ string out;
+ DWORD code;
+ wstring cmd = _T("--version");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ gpg_valid = true;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ gpg_thread.~thread();
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ }
+ gpg_valid = false;
+ DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath");
+ string::size_type p1 = out.find("(GnuPG) ");
+ if(p1 != string::npos)
+ {
+ p1 += strlen("(GnuPG) ");
+ if(out[p1] != '1')
+ bad_version = true;
+ }
+ else
+ {
+ bad_version = false;
+ MessageBox(0, TranslateT("This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK);
+ }
+ if(bad_version)
+ MessageBox(0, TranslateT("Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK);
+ }
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp);
+ GetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp, 512);
+ while(tmp[_tcslen(tmp)-1] == '\\')
+ tmp[_tcslen(tmp)-1] = '\0';
+ if(!tmp[0])
+ {
+ MessageBox(0, TranslateT("please set keyring's home directory"), TranslateT("Warning"), MB_OK);
+ break;
+ }
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", tmp);
+ {
+ TCHAR *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ DWORD dwFileAttr = GetFileAttributes(path);
+ if (dwFileAttr != INVALID_FILE_ATTRIBUTES)
+ {
+ dwFileAttr &=~ FILE_ATTRIBUTE_READONLY;
+ SetFileAttributes(path, dwFileAttr);
+ }
+ mir_free(path);
+ }
+ gpg_valid = true;
+ DBWriteContactSettingByte(NULL, szGPGModuleName, "FirstRun", 0);
+ DestroyWindow(hwndDlg);
+ ShowFirstRunDialog();
+ }
+ break;
+ case IDC_GENERATE_RANDOM:
+ {
+ TCHAR tmp[512];
+ GetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp, 512);
+ if(tmp[0])
+ {
+ char *mir_path = new char [MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ SetCurrentDirectoryA(mir_path);
+ delete [] mir_path;
+ if(_waccess(tmp, 0) == -1)
+ {
+ if(errno == ENOENT)
+ {
+ MessageBox(0, TranslateT("gpg binary does not exists.\nplease choose another location"), TranslateT("Warning"), MB_OK);
+ break;
+ }
+ }
+ }
+ else
+ {
+ MessageBox(0, TranslateT("please choose gpg binary location"), TranslateT("Warning"), MB_OK);
+ break;
+ }
+ {
+ bool bad_version = false;
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp);
+ string out;
+ DWORD code;
+ wstring cmd = _T("--version");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ gpg_valid = true;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ gpg_thread.~thread();
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ }
+ gpg_valid = false;
+ DBDeleteContactSetting(NULL, szGPGModuleName, "szGpgBinPath");
+ string::size_type p1 = out.find("(GnuPG) ");
+ if(p1 != string::npos)
+ {
+ p1 += strlen("(GnuPG) ");
+ if(out[p1] != '1')
+ bad_version = true;
+ }
+ else
+ {
+ bad_version = false;
+ MessageBox(0, TranslateT("This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK);
+ }
+ if(bad_version)
+ MessageBox(0, TranslateT("Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn."), TranslateT("Warning"), MB_OK);
+ }
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp);
+ GetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp, 512);
+ while(tmp[_tcslen(tmp)-1] == '\\')
+ tmp[_tcslen(tmp)-1] = '\0';
+ if(!tmp[0])
+ {
+ MessageBox(0, TranslateT("please set keyring's home directory"), TranslateT("Warning"), MB_OK);
+ break;
+ }
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", tmp);
+ {
+ TCHAR *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ DWORD dwFileAttr = GetFileAttributes(path);
+ if (dwFileAttr != INVALID_FILE_ATTRIBUTES)
+ {
+ dwFileAttr &=~ FILE_ATTRIBUTE_READONLY;
+ SetFileAttributes(path, dwFileAttr);
+ }
+ mir_free(path);
+ }
+ }
+ {
+ wstring path;
+ { //generating key file
+ TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ path = tmp;
+ mir_free(tmp);
+ path.append(_T("\\new_key"));
+ wfstream f(path.c_str(), std::ios::out);
+ if(!f.is_open())
+ {
+ MessageBox(0, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK);
+ break;
+ }
+ f<<"Key-Type: RSA";
+ f<<"\n";
+ f<<"Key-Length: 2048";
+ 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;
+ wstring cmd;
+ cmd += _T("--batch --yes --gen-key \"");
+ cmd += path;
+ cmd += _T("\"");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ gpg_valid = true;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::minutes(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted";
+ gpg_valid = false;
+ break;
+ }
+ gpg_valid = false;
+ if(result == pxNotFound)
+ break;
+ DeleteFile(path.c_str());
+ 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;
+ wstring cmd = _T("--batch -a --export ");
+ cmd += path;
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ gpg_valid = true;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<"GPG execution timed out, aborted\n";
+ gpg_valid = false;
+ break;
+ }
+ gpg_valid = false;
+ if(result == pxNotFound)
+ break;
+ string::size_type s = 0;
+ while((s = out.find("\r", s)) != string::npos)
+ {
+ out.erase(s, 1);
+ }
+ DBWriteContactSettingString(NULL, szGPGModuleName, "GPGPubKey", out.c_str());
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "KeyID", path.c_str());
+ extern HWND hwndCurKey_p;
+ SetWindowText(hwndCurKey_p, path.c_str());
+ }
+ }
+ bAutoExchange = CheckStateStoreDB(hwndDlg, IDC_AUTO_EXCHANGE, "bAutoExchange");
+ gpg_valid = true;
+ DBWriteContactSettingByte(NULL, szGPGModuleName, "FirstRun", 0);
+ DestroyWindow(hwndDlg);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+/* switch (((LPNMHDR)lParam)->code)
+ {
+ default:
+ break;
+ }*/
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ hwndSetDirs = NULL;
+ break;
+
+ }
+ return FALSE;
+}
+
+static INT_PTR CALLBACK DlgProcNewKeyDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ extern HANDLE new_key_hcnt;
+ extern boost::mutex new_key_hcnt_mutex;
+ static HANDLE hContact = INVALID_HANDLE_VALUE;
+ void ImportKey();
+ TCHAR *tmp = NULL;
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ hContact = new_key_hcnt;
//new_key_hcnt_mutex.unlock();
- SetWindowPos(hwndDlg, 0, new_key_rect.left, new_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); - TranslateDialogDefault(hwndDlg); - TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); - SetDlgItemText(hwndDlg, IDC_MESSAGE, tmp[0]?TranslateT("There is existing key for contact, would you like to replace with new key ?"):TranslateT("New public key was received, do you want to import it?")); - EnableWindow(GetDlgItem(hwndDlg, IDC_IMPORT_AND_USE), DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)?0:1); - SetDlgItemText(hwndDlg, ID_IMPORT, tmp[0]?TranslateT("Replace"):TranslateT("Accept")); - mir_free(tmp); - tmp = new TCHAR [256]; - _tcscpy(tmp, TranslateT("Received key from ")); - _tcscat(tmp, (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_TCHAR)); - SetDlgItemText(hwndDlg, IDC_KEY_FROM, tmp); - delete [] tmp; - return TRUE; - } - - - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case ID_IMPORT: - ImportKey(); - DestroyWindow(hwndDlg); - break; - case IDC_IMPORT_AND_USE: - ImportKey(); - DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); - void setSrmmIcon(HANDLE hContact); - void setClistIcon(HANDLE hContact); - setSrmmIcon(hContact); - setClistIcon(hContact); - DestroyWindow(hwndDlg); - break; - case IDC_IGNORE_KEY: - DestroyWindow(hwndDlg); - break; - default: - break; - } - - break; - } - - case WM_NOTIFY: - { -/* switch (((LPNMHDR)lParam)->code) - { - default: - break; - }*/ - } - break; - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - case WM_DESTROY: - { - GetWindowRect(hwndDlg, &new_key_rect); - DBWriteContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowX", new_key_rect.left); - DBWriteContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowY", new_key_rect.top); - } - hwndNewKey = NULL; - break; - - } - return FALSE; -} -static INT_PTR CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_INITDIALOG: - { - SetWindowPos(hwndDlg, 0, key_gen_rect.left, key_gen_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); - TranslateDialogDefault(hwndDlg); - SetWindowText(hwndDlg, TranslateT("Key Generation dialog")); - ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEY_TYPE), _T("RSA"), 0); - ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEY_TYPE), _T("DSA"), 1); - SendDlgItemMessage(hwndDlg, IDC_KEY_TYPE, CB_SETCURSEL, (WPARAM)1, 0); - SetDlgItemInt(hwndDlg, IDC_KEY_EXPIRE_DATE, 0, 0); - SetDlgItemInt(hwndDlg, IDC_KEY_LENGTH, 4096, 0); - return TRUE; - } - - - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - case IDOK: - { - wstring path; - { //data sanity checks - TCHAR *tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5); - GetDlgItemText(hwndDlg, IDC_KEY_TYPE, tmp, 5); - if(_tcslen(tmp) < 3) - { - mir_free(tmp); tmp = NULL; - MessageBox(0, TranslateT("You must set encryption algorythm first"), TranslateT("Error"), MB_OK); - break; - } - if(tmp) - mir_free(tmp); - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*6); - GetDlgItemText(hwndDlg, IDC_KEY_LENGTH, tmp, 5); - int length = _ttoi(tmp); - mir_free(tmp); - if(length < 1024 || length > 4096) - { - MessageBox(0, TranslateT("Key length must be of length from 1024 to 4096 bits"), TranslateT("Error"), MB_OK); - break; - } - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*12); - GetDlgItemText(hwndDlg, IDC_KEY_EXPIRE_DATE, tmp, 11); - if(_tcslen(tmp) != 10 && tmp[0] != '0') - { - MessageBox(0, TranslateT("Invalid date"), TranslateT("Error"), MB_OK); - mir_free(tmp); - break; - } - mir_free(tmp); - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128); - GetDlgItemText(hwndDlg, IDC_KEY_REAL_NAME, tmp, 127); - if(_tcslen(tmp) < 5) - { - MessageBox(0, TranslateT("Name must contain at least 5 characters"), TranslateT("Error"), MB_OK); - mir_free(tmp); - break; - } - else if (_tcschr(tmp, _T('(')) || _tcschr(tmp, _T(')'))) - { - MessageBox(0, TranslateT("Name cannot contain '(' or ')'"), TranslateT("Error"), MB_OK); - mir_free(tmp); - break; - } - mir_free(tmp); - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128); - GetDlgItemText(hwndDlg, IDC_KEY_EMAIL, tmp, 128); - if((_tcslen(tmp)) < 5 || (!_tcschr(tmp, _T('@'))) || (!_tcschr(tmp, _T('.')))) - { - MessageBox(0, TranslateT("Invalid Email"), TranslateT("Error"), MB_OK); - mir_free(tmp); - break; - } - mir_free(tmp); - } - { //generating key file - TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - char *tmp2;// = mir_t2a(tmp); - path = tmp; - mir_free(tmp); - // mir_free(tmp2); - path.append(_T("\\new_key")); - wfstream f(path.c_str(), std::ios::out); - if(!f.is_open()) - { - MessageBox(0, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK); - break; - } - f<<"Key-Type: "; - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5); - GetDlgItemText(hwndDlg, IDC_KEY_TYPE, tmp, 5); - tmp2 = mir_t2a(tmp); - mir_free(tmp); - char *subkeytype = (char*)mir_alloc(6); - if(strstr(tmp2, "RSA")) - 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 - strcpy(subkeytype, "ELG-E"); - f<<tmp2; - mir_free(tmp2); - f<<"\n"; - f<<"Key-Length: "; - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5); - GetDlgItemText(hwndDlg, IDC_KEY_LENGTH, tmp, 5); - int length = _ttoi(tmp); - mir_free(tmp); - f<<length; - f<<"\n"; - f<<"Subkey-Length: "; - f<<length; - f<<"\n"; - f<<"Subkey-Type: "; - f<<subkeytype; - mir_free(subkeytype); - f<<"\n"; - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*64); //i hope this is enough for password - GetDlgItemText(hwndDlg, IDC_KEY_PASSWD, tmp, 64); - if(tmp[0]) - { - f<<"Passphrase: "; - tmp2 = mir_strdup(toUTF8(tmp).c_str()); - f<<tmp2; - f<<"\n"; - mir_free(tmp2); - } - mir_free(tmp); - f<<"Name-Real: "; - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128); - GetDlgItemText(hwndDlg, IDC_KEY_REAL_NAME, tmp, 128); - tmp2 = mir_strdup(toUTF8(tmp).c_str()); - f<<tmp2; - mir_free(tmp2); - mir_free(tmp); - f<<"\n"; - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*512); - GetDlgItemText(hwndDlg, IDC_KEY_COMMENT, tmp, 512); - if(tmp[0]) - { - tmp2 = mir_strdup(toUTF8(tmp).c_str()); - f<<"Name-Comment: "; - f<<tmp2; - f<<"\n"; - } - mir_free(tmp2); - mir_free(tmp); - f<<"Name-Email: "; - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128); - GetDlgItemText(hwndDlg, IDC_KEY_EMAIL, tmp, 128); - tmp2 = mir_strdup(toUTF8(tmp).c_str()); - f<<tmp2; - mir_free(tmp2); - mir_free(tmp); - f<<"\n"; - f<<"Expire-Date: "; - tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*12); - GetDlgItemText(hwndDlg, IDC_KEY_EXPIRE_DATE, tmp, 12); - tmp2 = mir_strdup(toUTF8(tmp).c_str()); - f<<tmp2; - mir_free(tmp2); - mir_free(tmp); - f<<"\n"; - f.close(); - } - { //gpg execution - DWORD code; - string out; - wstring cmd; - cmd += _T("--batch --yes --gen-key \""); - cmd += path; - cmd += _T("\""); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - SetWindowTextA(GetDlgItem(hwndDlg, IDC_GENERATING_TEXT), Translate("Generating new key, please wait...")); - EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), 0); - EnableWindow(GetDlgItem(hwndDlg, IDOK), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_TYPE), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_LENGTH), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_PASSWD), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_REAL_NAME), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_EMAIL), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_COMMENT), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_EXPIRE_DATE), 0); - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::minutes(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - } - DeleteFile(path.c_str()); - DestroyWindow(hwndDlg); - {//parse gpg output - LVITEM item = {0}; - int i = 1, iRow = 0; - item.mask = LVIF_TEXT; - item.iItem = i; - item.iSubItem = 0; - item.pszText = _T(""); - string out; - DWORD code; - string::size_type p = 0, p2 = 0, stop = 0; - { - wstring cmd = _T("--list-secret-keys"); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - } - ListView_DeleteAllItems(hwndList_g); - 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; - TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - item.pszText = tmp; - iRow = ListView_InsertItem(hwndList_g, &item); - ListView_SetItemText(hwndList_g, iRow, 4, tmp); - mir_free(tmp); - p2+=2; - p = out.find(" ", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str()); - ListView_SetItemText(hwndList_g, iRow, 0, tmp); - mir_free(tmp); - p = out.find("uid ", p); - p2 = out.find_first_not_of(" ", p+5); - p = out.find("<", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str()); - ListView_SetItemText(hwndList_g, iRow, 2, tmp); - mir_free(tmp); - p++; - p2 = out.find(">", p); - tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - ListView_SetItemText(hwndList_g, iRow, 1, tmp); - mir_free(tmp); - p = out.find("ssb ", 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_g, iRow, 3, tmp); - mir_free(tmp); - ListView_SetColumnWidth(hwndList_g, 0, LVSCW_AUTOSIZE);// not sure about this - ListView_SetColumnWidth(hwndList_g, 1, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList_g, 2, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList_g, 3, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList_g, 4, LVSCW_AUTOSIZE); - i++; - } - } - } - break; - default: - break; - } - - break; - } - - case WM_NOTIFY: - { -/* switch (((LPNMHDR)lParam)->code) - { - default: - break; - } */ - } - break; - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - case WM_DESTROY: - { - GetWindowRect(hwndDlg, &key_gen_rect); - DBWriteContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowX", key_gen_rect.left); - DBWriteContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowY", key_gen_rect.top); - } - hwndKeyGen = NULL; - break; - - } - return FALSE; -} - -int itemnum2 = 0; - -static INT_PTR CALLBACK DlgProcLoadExistingKey(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) -{ - HWND hwndList=GetDlgItem(hwndDlg, IDC_EXISTING_KEY_LIST); - hwndList_g = hwndList; - LVCOLUMN col = {0}; - LVITEM item = {0}; - NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; - TCHAR id[16] = {0}; - switch (msg) - { - case WM_INITDIALOG: - { - SetWindowPos(hwndDlg, 0, load_existing_key_rect.left, load_existing_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); - TranslateDialogDefault(hwndDlg); - col.pszText = _T("Key ID"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 50; - ListView_InsertColumn(hwndList, 0, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = _T("Email"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 30; - ListView_InsertColumn(hwndList, 1, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = _T("Name"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 250; - ListView_InsertColumn(hwndList, 2, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = _T("Creation date"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 30; - ListView_InsertColumn(hwndList, 3, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = _T("Expiration date"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 30; - ListView_InsertColumn(hwndList, 4, &col); - ZeroMemory(&col,sizeof(col)); - col.pszText = _T("Key length"); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.fmt = LVCFMT_LEFT; - col.cx = 30; - ListView_InsertColumn(hwndList, 5, &col); - ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_FULLROWSELECT); - int i = 1, iRow = 0; - { - item.mask = LVIF_TEXT; - item.iItem = i; - item.iSubItem = 0; - item.pszText = _T(""); - {//parse gpg output - string out; - DWORD code; - string::size_type p = 0, p2 = 0, stop = 0; - { - wstring cmd = _T("--batch --list-keys"); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - } - 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; - TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - item.pszText = tmp; - iRow = ListView_InsertItem(hwndList, &item); - ListView_SetItemText(hwndList, iRow, 5, tmp); - mir_free(tmp); - p2+=2; - p = out.find(" ", p2); - tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str()); - ListView_SetItemText(hwndList, iRow, 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+=strlen("expires: "); - string::size_type p4 = out.find("]", p3); - tmp = mir_wstrdup(toUTF16(out.substr(p3,p4-p3)).c_str()); - ListView_SetItemText(hwndList, iRow, 4, tmp); - mir_free(tmp); - } - else - p2--; - tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); - ListView_SetItemText(hwndList, iRow, 3, tmp); - mir_free(tmp); - p = out.find("uid ", p); - p+= 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()); - ListView_SetItemText(hwndList, iRow, 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()); - ListView_SetItemText(hwndList, iRow, 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); - ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this - ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); - ListView_SetColumnWidth(hwndList, 5, LVSCW_AUTOSIZE); - i++; - } - } - } - return TRUE; - } - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDOK: - { - ListView_GetItemText(hwndList, itemnum2, 0, id, 16); - extern HWND hPubKeyEdit; - string out; - DWORD code; - wstring cmd = _T("--batch -a --export "); - cmd += id; - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - 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 += strlen("-----END PGP PUBLIC KEY BLOCK-----"); - out = out.substr(p1, p2-p1); - TCHAR *tmp = mir_a2t(out.c_str()); - SetWindowText(hPubKeyEdit, tmp); - mir_free(tmp); - } - else - MessageBox(NULL, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK); - } - else - MessageBox(NULL, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK); -// SetDlgItemText(hPubKeyEdit, IDC_PUBLIC_KEY_EDIT, tmp); - } - DestroyWindow(hwndDlg); - break; - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - } - break; - } - - case WM_NOTIFY: - { - if(hdr && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1)) - { - if(hdr->hdr.code == NM_CLICK) - { - EnableWindow(GetDlgItem(hwndDlg, IDOK), 1); - itemnum2 = hdr->iItem; - } - } - - switch (((LPNMHDR)lParam)->code) - { - - case PSN_APPLY: - { - return TRUE; - } - } - } - break; - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - case WM_DESTROY: - { - GetWindowRect(hwndDlg, &load_existing_key_rect); - DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowX", load_existing_key_rect.left); - DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowY", load_existing_key_rect.top); - } - hwndSelectExistingKey = NULL; - break; - - } - - return FALSE; -} -static INT_PTR CALLBACK DlgProcImportKeyDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - extern HANDLE new_key_hcnt; - extern boost::mutex new_key_hcnt_mutex; - HANDLE hContact = INVALID_HANDLE_VALUE; - switch (msg) - { - case WM_INITDIALOG: - { - hContact = new_key_hcnt; - new_key_hcnt_mutex.unlock(); - SetWindowPos(hwndDlg, 0 , import_key_rect.left, import_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); - TranslateDialogDefault(hwndDlg); - ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEYSERVER), _T("subkeys.pgp.net"), 0); - ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEYSERVER), _T("keys.gnupg.net"), 0); - return TRUE; - } - - - case WM_COMMAND: - { - switch (LOWORD(wParam)) - { - case IDC_IMPORT: - { - string out; - DWORD code; - wstring cmd = _T(" --keyserver \""); - TCHAR *server= new TCHAR [128]; - GetDlgItemText(hwndDlg, IDC_KEYSERVER, server, 128); - cmd += server; - delete [] server; - cmd += _T("\" --recv-keys "); -// char *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID_Prescense", ""); -// TCHAR *tmp2 = mir_a2t(tmp); -// mir_free(tmp); - cmd += toUTF16(hcontact_data[hContact].key_in_prescense); -// mir_free(tmp2); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - } - MessageBoxA(0, out.c_str(), "GPG output", MB_OK); - } - break; - default: - break; - } - break; - } - - case WM_NOTIFY: - { -/* switch (((LPNMHDR)lParam)->code) - { - default: - break; - } */ - } - break; - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - case WM_DESTROY: - { - GetWindowRect(hwndDlg, &import_key_rect); - DBWriteContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowX", import_key_rect.left); - DBWriteContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowY", import_key_rect.top); - } - break; - - } - return FALSE; -} - - -extern HINSTANCE hInst; - - -void ShowFirstRunDialog() -{ - if (hwndFirstRun == NULL) - { - hwndFirstRun = CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIRST_RUN), NULL, DlgProcFirstRun); - } - SetForegroundWindow(hwndFirstRun); -} - - -void ShowSetDirsDialog() -{ - if (hwndSetDirs == NULL) - { - hwndSetDirs = CreateDialog(hInst, MAKEINTRESOURCE(IDD_BIN_PATH), NULL, DlgProcGpgBinOpts); - } - SetForegroundWindow(hwndSetDirs); -} - -void ShowNewKeyDialog() -{ - hwndNewKey = CreateDialog(hInst, MAKEINTRESOURCE(IDD_NEW_KEY), NULL, DlgProcNewKeyDialog); - SetForegroundWindow(hwndNewKey); -} - -void ShowKeyGenDialog() -{ - if (hwndKeyGen == NULL) - { - hwndKeyGen = CreateDialog(hInst, MAKEINTRESOURCE(IDD_KEY_GEN), NULL, DlgProcKeyGenDialog); - } - SetForegroundWindow(hwndKeyGen); -} - -void ShowSelectExistingKeyDialog() -{ - if (hwndSelectExistingKey == NULL) - { - hwndSelectExistingKey = CreateDialog(hInst, MAKEINTRESOURCE(IDD_LOAD_EXISTING_KEY), NULL, DlgProcLoadExistingKey); - } - SetForegroundWindow(hwndSelectExistingKey); -} - -void ShowImportKeyDialog() -{ - CreateDialog(hInst, MAKEINTRESOURCE(IDD_IMPORT_KEY), NULL, DlgProcImportKeyDialog); -} - - - - -void FirstRun() -{ - DWORD pid = 0; - if(!DBGetContactSettingByte(NULL, szGPGModuleName, "FirstRun", 1)) - return; - ShowSetDirsDialog(); -} - -void InitCheck() -{ - {//parse gpg output - gpg_valid = isGPGValid(); - bool home_dir_access = false, temp_access = false; - TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - std::wstring test_path = home_dir; - mir_free(home_dir); - test_path += _T("/"); - test_path += toUTF16(get_random(13)); - wfstream test_file; - test_file.open(test_path, std::ios::trunc | std::ios::out); - if(test_file.is_open() && test_file.good()) - { - test_file<<_T("access_test\n"); - if(test_file.good()) - home_dir_access = true; - test_file.close(); - DeleteFile(test_path.c_str()); - } - home_dir = _tgetenv(_T("TEMP")); - test_path = home_dir; - test_path += _T("/"); - test_path += toUTF16(get_random(13)); - test_file.open(test_path, std::ios::trunc | std::ios::out); - if(test_file.is_open() && test_file.good()) - { - test_file<<_T("access_test\n"); - if(test_file.good()) - temp_access = true; - test_file.close(); - DeleteFile(test_path.c_str()); - } - if(!home_dir_access || !temp_access || !gpg_valid) - { - char buf[4096]; - strcpy(buf, gpg_valid?Translate("GPG binary is set and valid (this is good).\n"):Translate("GPG binary unset or invalid (plugin will not work).\n")); - strcat(buf, home_dir_access?Translate("Home dir write access granted (this is good).\n"):Translate("Home dir have not write access (plugin most probably will not work).\n")); - strcat(buf, temp_access?Translate("Temp dir write access granted (this is good).\n"):Translate("Temp dir have not write access (plugin should work, but may have some problems, filetransfers will not work).")); - if(!gpg_valid) - strcat(buf, Translate("\nGPG will be disabled until you solve this problems")); - MessageBoxA(0, buf, Translate("GPG plugin problems"), MB_OK); - } - if(!gpg_valid) - return; - gpg_keyexist = isGPGKeyExist(); - string out; - DWORD code; - pxResult result; - wstring::size_type p = 0, p2 = 0, stop = 0; - { - gpg_execution_params params; - wstring cmd = _T("--batch --list-secret-keys"); - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return; - } - if(result == pxNotFound) - return; - } - home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - wstring tmp_dir = home_dir; - mir_free(home_dir); - tmp_dir += _T("\\tmp"); - _wmkdir(tmp_dir.c_str()); - string question = Translate("Your secret key whith id: "); - char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); - char *key = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); - void ShowFirstRunDialog(); - if(!DBGetContactSettingByte(NULL, szGPGModuleName, "FirstRun", 1) && (!keyid[0] || !key[0])) - { - question = Translate("You have not set public key for gpg, it's recommended to do it.\nDo you want to do it now ?"); - if(MessageBoxA(0, question.c_str(), Translate("Own public key warning"), MB_YESNO) == IDYES) - ShowFirstRunDialog(); - } - if(out.find(keyid) == string::npos) - { - question += keyid; - question += Translate(" deleted from gpg secret keyring\nDo you want to set another key ?"); - if(MessageBoxA(0, question.c_str(), Translate("Own secret key warning"), MB_YESNO) == IDYES) - ShowFirstRunDialog(); - } - mir_free(keyid); - mir_free(key); - } - { - TCHAR *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - DWORD dwFileAttr = GetFileAttributes(path); - if (dwFileAttr != INVALID_FILE_ATTRIBUTES) - { - dwFileAttr &=~ FILE_ATTRIBUTE_READONLY; - SetFileAttributes(path, dwFileAttr); - } - mir_free(path); - } - extern bool bAutoExchange; - if(bAutoExchange) - { - int count = 0; - PROTOACCOUNT **accounts; - ProtoEnumAccounts(&count, &accounts); - ICQ_CUSTOMCAP cap; - cap.cbSize = sizeof(ICQ_CUSTOMCAP); - cap.hIcon = 0; - strcpy(cap.name, "GPG Key AutoExchange"); - strcpy(cap.caps, "GPG AutoExchange"); - - for(int i = 0; i < count; i++) - { - char svc[64]; - strcpy(svc, accounts[i]->szProtoName); - strcat(svc, PS_ICQ_ADDCAPABILITY); - if(ServiceExists(svc)) - CallService(svc, 0, (LPARAM)&cap); - } - } -} - -void ImportKey() -{ - extern wstring new_key; - extern HANDLE new_key_hcnt; - extern boost::mutex new_key_hcnt_mutex; - HANDLE hContact = new_key_hcnt; - new_key_hcnt_mutex.unlock(); - bool for_all_sub = false; - if(metaIsProtoMetaContacts(hContact)) - if(MessageBox(0, TranslateT("Do you want load key for all subcontacts ?"), TranslateT("Metacontact detected"), MB_YESNO) == IDYES) - for_all_sub = true; - if(metaIsProtoMetaContacts(hContact)) - { - HANDLE hcnt = NULL; - if(for_all_sub) - { - int count = metaGetContactsNum(hContact); - for(int i = 0; i < count; i++) - { - hcnt = metaGetSubcontact(hContact, i); - if(hcnt) - DBWriteContactSettingTString(hcnt, szGPGModuleName, "GPGPubKey", new_key.c_str()); - } - } - else - DBWriteContactSettingTString(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", new_key.c_str()); - } - else - DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", new_key.c_str()); - new_key.clear(); - { //gpg execute block - wstring cmd; - TCHAR tmp2[MAX_PATH] = {0}; - TCHAR *ptmp; - string output; - DWORD exitcode; - { - ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - _tcscpy(tmp2, ptmp); - mir_free(ptmp); - _tcscat(tmp2, _T("\\")); - _tcscat(tmp2, _T("temporary_exported.asc")); - DeleteFile(tmp2); - wfstream f(tmp2, std::ios::out); - if(metaIsProtoMetaContacts(hContact)) - ptmp = UniGetContactSettingUtf(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", _T("")); - else - ptmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); - wstring new_key = ptmp; - mir_free(ptmp); - f<<new_key.c_str(); - f.close(); - cmd += _T(" --batch "); - cmd += _T(" --import \""); - cmd += tmp2; - cmd += _T("\""); - } - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &output; - params.code = &exitcode; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return; - } - if(result == pxNotFound) - return; - { - if(metaIsProtoMetaContacts(hContact)) - { - HANDLE hcnt = NULL; - if(for_all_sub) - { - int count = metaGetContactsNum(hContact); - for(int i = 0; i < count; i++) - { - hcnt = metaGetSubcontact(hContact, i); - if(hcnt) - { - char *tmp = NULL; - string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); - string::size_type s2 = output.find(":", s); - DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); - s = output.find("“", s2); - if(s == string::npos) - { - s = output.find("\"", s2); - s += 1; - } - else - s += 3; - bool uncommon = false; - if((s2 = output.find("(", s)) == string::npos) - { - if((s2 = output.find("<", s)) == string::npos) - { - s2 = output.find("â€", s); - uncommon = true; - } - } - else if(s2 > output.find("<", s)) - s2 = output.find("<", s); - if(s != string::npos && s2 != string::npos) - { - tmp = (char*)mir_alloc(sizeof(char)*(output.substr(s,s2-s-(uncommon?1:0)).length()+1)); - strcpy(tmp, output.substr(s,s2-s-(uncommon?1:0)).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainName", tmp); - mir_free(tmp); - } - - if((s = output.find(")", s2)) == string::npos) - s = output.find(">", s2); - else if(s > output.find(">", s2)) - s = output.find(">", s2); - s2++; - if(s != string::npos && s2 != string::npos) - { - if(output[s] == ')') - { - tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1)); - strcpy(tmp, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyComment", tmp); - mir_free(tmp); - s+=3; - s2 = output.find(">", s); - if(s != string::npos && s2 != string::npos) - { - tmp = (char*) mir_alloc(sizeof(char)*(output.substr(s,s2-s).length()+1)); - strcpy(tmp, output.substr(s,s2-s).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", tmp); - mir_free(tmp); - } - } - else - { - tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1)); - strcpy(tmp, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); - mir_free(tmp); - } - } - DBDeleteContactSetting(hcnt, szGPGModuleName, "bAlwatsTrust"); - } - } - } - else - { - char *tmp = NULL; - string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); - string::size_type s2 = output.find(":", s); - DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); - s = output.find("“", s2); - if(s == string::npos) - { - s = output.find("\"", s2); - s += 1; - } - else - s += 3; - bool uncommon = false; - if((s2 = output.find("(", s)) == string::npos) - { - if((s2 = output.find("<", s)) == string::npos) - { - s2 = output.find("â€", s); - uncommon = true; - } - } - else if(s2 > output.find("<", s)) - s2 = output.find("<", s); - if(s != string::npos && s2 != string::npos) - { - tmp = (char*)mir_alloc(sizeof(char)*(output.substr(s,s2-s-(uncommon?1:0)).length()+1)); - strcpy(tmp, output.substr(s,s2-s-(uncommon?1:0)).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainName", tmp); - mir_free(tmp); - } - if((s = output.find(")", s2)) == string::npos) - s = output.find(">", s2); - else if(s > output.find(">", s2)) - s = output.find(">", s2); - s2++; - if(s != string::npos && s2 != string::npos) - { - if(output[s] == ')') - { - tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1)); - strcpy(tmp, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyComment", tmp); - mir_free(tmp); - s+=3; - s2 = output.find(">", s); - if(s != string::npos && s2 != string::npos) - { - tmp = (char*) mir_alloc(sizeof(char)*(output.substr(s,s2-s).length()+1)); - strcpy(tmp, output.substr(s,s2-s).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", tmp); - mir_free(tmp); - } - } - else - { - tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1)); - strcpy(tmp, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); - mir_free(tmp); - } - } - DBDeleteContactSetting(metaGetMostOnline(hContact), szGPGModuleName, "bAlwatsTrust"); - } - } - else - { - char *tmp = NULL; - string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); - string::size_type s2 = output.find(":", s); - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); - s = output.find("“", s2); - if(s == string::npos) - { - s = output.find("\"", s2); - s += 1; - } - else - s += 3; - bool uncommon = false; - if((s2 = output.find("(", s)) == string::npos) - { - if((s2 = output.find("<", s)) == string::npos) - { - s2 = output.find("â€", s); - uncommon = true; - } - } - else if(s2 > output.find("<", s)) - s2 = output.find("<", s); - if(s != string::npos && s2 != string::npos) - { - tmp = (char*)mir_alloc(sizeof(char)*(output.substr(s,s2-s-(uncommon?1:0)).length()+1)); - strcpy(tmp, output.substr(s,s2-s-(uncommon?1:0)).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", tmp); - mir_free(tmp); - } - if((s = output.find(")", s2)) == string::npos) - s = output.find(">", s2); - else if(s > output.find(">", s2)) - s = output.find(">", s2); - s2++; - if(s != string::npos && s2 != string::npos) - { - if(output[s] == ')') - { - tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1)); - strcpy(tmp, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", tmp); - mir_free(tmp); - s+=3; - s2 = output.find(">", s); - if(s != string::npos && s2 != string::npos) - { - tmp = (char*) mir_alloc(sizeof(char)*(output.substr(s,s2-s).length()+1)); - strcpy(tmp, output.substr(s,s2-s).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", tmp); - mir_free(tmp); - } - } - else - { - tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1)); - strcpy(tmp, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp, 0); - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); - mir_free(tmp); - } - } - DBDeleteContactSetting(hContact, szGPGModuleName, "bAlwatsTrust"); - } - } - ptmp = mir_wstrdup(toUTF16(output).c_str()); - MessageBox(0, ptmp, _T(""), MB_OK); - mir_free(ptmp); - DeleteFile(tmp2); - } + SetWindowPos(hwndDlg, 0, new_key_rect.left, new_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW);
+ TranslateDialogDefault(hwndDlg);
+ TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T(""));
+ SetDlgItemText(hwndDlg, IDC_MESSAGE, tmp[0]?TranslateT("There is existing key for contact, would you like to replace with new key ?"):TranslateT("New public key was received, do you want to import it?"));
+ EnableWindow(GetDlgItem(hwndDlg, IDC_IMPORT_AND_USE), DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)?0:1);
+ SetDlgItemText(hwndDlg, ID_IMPORT, tmp[0]?TranslateT("Replace"):TranslateT("Accept"));
+ mir_free(tmp);
+ tmp = new TCHAR [256];
+ _tcscpy(tmp, TranslateT("Received key from "));
+ _tcscat(tmp, (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_TCHAR));
+ SetDlgItemText(hwndDlg, IDC_KEY_FROM, tmp);
+ delete [] tmp;
+ return TRUE;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case ID_IMPORT:
+ ImportKey();
+ DestroyWindow(hwndDlg);
+ break;
+ case IDC_IMPORT_AND_USE:
+ ImportKey();
+ DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1);
+ void setSrmmIcon(HANDLE hContact);
+ void setClistIcon(HANDLE hContact);
+ setSrmmIcon(hContact);
+ setClistIcon(hContact);
+ DestroyWindow(hwndDlg);
+ break;
+ case IDC_IGNORE_KEY:
+ DestroyWindow(hwndDlg);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+/* switch (((LPNMHDR)lParam)->code)
+ {
+ default:
+ break;
+ }*/
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ {
+ GetWindowRect(hwndDlg, &new_key_rect);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowX", new_key_rect.left);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowY", new_key_rect.top);
+ }
+ hwndNewKey = NULL;
+ break;
+
+ }
+ return FALSE;
+}
+static INT_PTR CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SetWindowPos(hwndDlg, 0, key_gen_rect.left, key_gen_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW);
+ TranslateDialogDefault(hwndDlg);
+ SetWindowText(hwndDlg, TranslateT("Key Generation dialog"));
+ ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEY_TYPE), _T("RSA"), 0);
+ ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEY_TYPE), _T("DSA"), 1);
+ SendDlgItemMessage(hwndDlg, IDC_KEY_TYPE, CB_SETCURSEL, (WPARAM)1, 0);
+ SetDlgItemInt(hwndDlg, IDC_KEY_EXPIRE_DATE, 0, 0);
+ SetDlgItemInt(hwndDlg, IDC_KEY_LENGTH, 4096, 0);
+ return TRUE;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ break;
+ case IDOK:
+ {
+ wstring path;
+ { //data sanity checks
+ TCHAR *tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5);
+ GetDlgItemText(hwndDlg, IDC_KEY_TYPE, tmp, 5);
+ if(_tcslen(tmp) < 3)
+ {
+ mir_free(tmp); tmp = NULL;
+ MessageBox(0, TranslateT("You must set encryption algorythm first"), TranslateT("Error"), MB_OK);
+ break;
+ }
+ if(tmp)
+ mir_free(tmp);
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*6);
+ GetDlgItemText(hwndDlg, IDC_KEY_LENGTH, tmp, 5);
+ int length = _ttoi(tmp);
+ mir_free(tmp);
+ if(length < 1024 || length > 4096)
+ {
+ MessageBox(0, TranslateT("Key length must be of length from 1024 to 4096 bits"), TranslateT("Error"), MB_OK);
+ break;
+ }
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*12);
+ GetDlgItemText(hwndDlg, IDC_KEY_EXPIRE_DATE, tmp, 11);
+ if(_tcslen(tmp) != 10 && tmp[0] != '0')
+ {
+ MessageBox(0, TranslateT("Invalid date"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ break;
+ }
+ mir_free(tmp);
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128);
+ GetDlgItemText(hwndDlg, IDC_KEY_REAL_NAME, tmp, 127);
+ if(_tcslen(tmp) < 5)
+ {
+ MessageBox(0, TranslateT("Name must contain at least 5 characters"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ break;
+ }
+ else if (_tcschr(tmp, _T('(')) || _tcschr(tmp, _T(')')))
+ {
+ MessageBox(0, TranslateT("Name cannot contain '(' or ')'"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ break;
+ }
+ mir_free(tmp);
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128);
+ GetDlgItemText(hwndDlg, IDC_KEY_EMAIL, tmp, 128);
+ if((_tcslen(tmp)) < 5 || (!_tcschr(tmp, _T('@'))) || (!_tcschr(tmp, _T('.'))))
+ {
+ MessageBox(0, TranslateT("Invalid Email"), TranslateT("Error"), MB_OK);
+ mir_free(tmp);
+ break;
+ }
+ mir_free(tmp);
+ }
+ { //generating key file
+ TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ char *tmp2;// = mir_t2a(tmp);
+ path = tmp;
+ mir_free(tmp);
+ // mir_free(tmp2);
+ path.append(_T("\\new_key"));
+ wfstream f(path.c_str(), std::ios::out);
+ if(!f.is_open())
+ {
+ MessageBox(0, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK);
+ break;
+ }
+ f<<"Key-Type: ";
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5);
+ GetDlgItemText(hwndDlg, IDC_KEY_TYPE, tmp, 5);
+ tmp2 = mir_t2a(tmp);
+ mir_free(tmp);
+ char *subkeytype = (char*)mir_alloc(6);
+ if(strstr(tmp2, "RSA"))
+ 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
+ strcpy(subkeytype, "ELG-E");
+ f<<tmp2;
+ mir_free(tmp2);
+ f<<"\n";
+ f<<"Key-Length: ";
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5);
+ GetDlgItemText(hwndDlg, IDC_KEY_LENGTH, tmp, 5);
+ int length = _ttoi(tmp);
+ mir_free(tmp);
+ f<<length;
+ f<<"\n";
+ f<<"Subkey-Length: ";
+ f<<length;
+ f<<"\n";
+ f<<"Subkey-Type: ";
+ f<<subkeytype;
+ mir_free(subkeytype);
+ f<<"\n";
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*64); //i hope this is enough for password
+ GetDlgItemText(hwndDlg, IDC_KEY_PASSWD, tmp, 64);
+ if(tmp[0])
+ {
+ f<<"Passphrase: ";
+ tmp2 = mir_strdup(toUTF8(tmp).c_str());
+ f<<tmp2;
+ f<<"\n";
+ mir_free(tmp2);
+ }
+ mir_free(tmp);
+ f<<"Name-Real: ";
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128);
+ GetDlgItemText(hwndDlg, IDC_KEY_REAL_NAME, tmp, 128);
+ tmp2 = mir_strdup(toUTF8(tmp).c_str());
+ f<<tmp2;
+ mir_free(tmp2);
+ mir_free(tmp);
+ f<<"\n";
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*512);
+ GetDlgItemText(hwndDlg, IDC_KEY_COMMENT, tmp, 512);
+ if(tmp[0])
+ {
+ tmp2 = mir_strdup(toUTF8(tmp).c_str());
+ f<<"Name-Comment: ";
+ f<<tmp2;
+ f<<"\n";
+ }
+ mir_free(tmp2);
+ mir_free(tmp);
+ f<<"Name-Email: ";
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128);
+ GetDlgItemText(hwndDlg, IDC_KEY_EMAIL, tmp, 128);
+ tmp2 = mir_strdup(toUTF8(tmp).c_str());
+ f<<tmp2;
+ mir_free(tmp2);
+ mir_free(tmp);
+ f<<"\n";
+ f<<"Expire-Date: ";
+ tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*12);
+ GetDlgItemText(hwndDlg, IDC_KEY_EXPIRE_DATE, tmp, 12);
+ tmp2 = mir_strdup(toUTF8(tmp).c_str());
+ f<<tmp2;
+ mir_free(tmp2);
+ mir_free(tmp);
+ f<<"\n";
+ f.close();
+ }
+ { //gpg execution
+ DWORD code;
+ string out;
+ wstring cmd;
+ cmd += _T("--batch --yes --gen-key \"");
+ cmd += path;
+ cmd += _T("\"");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ SetWindowTextA(GetDlgItem(hwndDlg, IDC_GENERATING_TEXT), Translate("Generating new key, please wait..."));
+ EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_TYPE), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_LENGTH), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_PASSWD), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_REAL_NAME), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_EMAIL), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_COMMENT), 0);
+ EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_EXPIRE_DATE), 0);
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::minutes(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ }
+ DeleteFile(path.c_str());
+ DestroyWindow(hwndDlg);
+ {//parse gpg output
+ LVITEM item = {0};
+ int i = 1, iRow = 0;
+ item.mask = LVIF_TEXT;
+ item.iItem = i;
+ item.iSubItem = 0;
+ item.pszText = _T("");
+ string out;
+ DWORD code;
+ string::size_type p = 0, p2 = 0, stop = 0;
+ {
+ wstring cmd = _T("--list-secret-keys");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ }
+ ListView_DeleteAllItems(hwndList_g);
+ 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;
+ TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ item.pszText = tmp;
+ iRow = ListView_InsertItem(hwndList_g, &item);
+ ListView_SetItemText(hwndList_g, iRow, 4, tmp);
+ mir_free(tmp);
+ p2+=2;
+ p = out.find(" ", p2);
+ tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str());
+ ListView_SetItemText(hwndList_g, iRow, 0, tmp);
+ mir_free(tmp);
+ p = out.find("uid ", p);
+ p2 = out.find_first_not_of(" ", p+5);
+ p = out.find("<", p2);
+ tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str());
+ ListView_SetItemText(hwndList_g, iRow, 2, tmp);
+ mir_free(tmp);
+ p++;
+ p2 = out.find(">", p);
+ tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ ListView_SetItemText(hwndList_g, iRow, 1, tmp);
+ mir_free(tmp);
+ p = out.find("ssb ", 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_g, iRow, 3, tmp);
+ mir_free(tmp);
+ ListView_SetColumnWidth(hwndList_g, 0, LVSCW_AUTOSIZE);// not sure about this
+ ListView_SetColumnWidth(hwndList_g, 1, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList_g, 2, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList_g, 3, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList_g, 4, LVSCW_AUTOSIZE);
+ i++;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+/* switch (((LPNMHDR)lParam)->code)
+ {
+ default:
+ break;
+ } */
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ {
+ GetWindowRect(hwndDlg, &key_gen_rect);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowX", key_gen_rect.left);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowY", key_gen_rect.top);
+ }
+ hwndKeyGen = NULL;
+ break;
+
+ }
+ return FALSE;
+}
+
+int itemnum2 = 0;
+
+static INT_PTR CALLBACK DlgProcLoadExistingKey(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ HWND hwndList=GetDlgItem(hwndDlg, IDC_EXISTING_KEY_LIST);
+ hwndList_g = hwndList;
+ LVCOLUMN col = {0};
+ LVITEM item = {0};
+ NMLISTVIEW * hdr = (NMLISTVIEW *) lParam;
+ TCHAR id[16] = {0};
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ SetWindowPos(hwndDlg, 0, load_existing_key_rect.left, load_existing_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW);
+ TranslateDialogDefault(hwndDlg);
+ col.pszText = _T("Key ID");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 50;
+ ListView_InsertColumn(hwndList, 0, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = _T("Email");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 30;
+ ListView_InsertColumn(hwndList, 1, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = _T("Name");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 250;
+ ListView_InsertColumn(hwndList, 2, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = _T("Creation date");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 30;
+ ListView_InsertColumn(hwndList, 3, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = _T("Expiration date");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 30;
+ ListView_InsertColumn(hwndList, 4, &col);
+ ZeroMemory(&col,sizeof(col));
+ col.pszText = _T("Key length");
+ col.mask = LVCF_TEXT | LVCF_WIDTH;
+ col.fmt = LVCFMT_LEFT;
+ col.cx = 30;
+ ListView_InsertColumn(hwndList, 5, &col);
+ ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_FULLROWSELECT);
+ int i = 1, iRow = 0;
+ {
+ item.mask = LVIF_TEXT;
+ item.iItem = i;
+ item.iSubItem = 0;
+ item.pszText = _T("");
+ {//parse gpg output
+ string out;
+ DWORD code;
+ string::size_type p = 0, p2 = 0, stop = 0;
+ {
+ wstring cmd = _T("--batch --list-keys");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ }
+ 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;
+ TCHAR *tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ item.pszText = tmp;
+ iRow = ListView_InsertItem(hwndList, &item);
+ ListView_SetItemText(hwndList, iRow, 5, tmp);
+ mir_free(tmp);
+ p2+=2;
+ p = out.find(" ", p2);
+ tmp = mir_wstrdup(toUTF16(out.substr(p2,p-p2)).c_str());
+ ListView_SetItemText(hwndList, iRow, 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+=strlen("expires: ");
+ string::size_type p4 = out.find("]", p3);
+ tmp = mir_wstrdup(toUTF16(out.substr(p3,p4-p3)).c_str());
+ ListView_SetItemText(hwndList, iRow, 4, tmp);
+ mir_free(tmp);
+ }
+ else
+ p2--;
+ tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str());
+ ListView_SetItemText(hwndList, iRow, 3, tmp);
+ mir_free(tmp);
+ p = out.find("uid ", p);
+ p+= 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());
+ ListView_SetItemText(hwndList, iRow, 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());
+ ListView_SetItemText(hwndList, iRow, 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);
+ ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this
+ ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE);
+ ListView_SetColumnWidth(hwndList, 5, LVSCW_AUTOSIZE);
+ i++;
+ }
+ }
+ }
+ return TRUE;
+ }
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ ListView_GetItemText(hwndList, itemnum2, 0, id, 16);
+ extern HWND hPubKeyEdit;
+ string out;
+ DWORD code;
+ wstring cmd = _T("--batch -a --export ");
+ cmd += id;
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ 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 += strlen("-----END PGP PUBLIC KEY BLOCK-----");
+ out = out.substr(p1, p2-p1);
+ TCHAR *tmp = mir_a2t(out.c_str());
+ SetWindowText(hPubKeyEdit, tmp);
+ mir_free(tmp);
+ }
+ else
+ MessageBox(NULL, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK);
+ }
+ else
+ MessageBox(NULL, TranslateT("Failed to export public key."), TranslateT("Error"), MB_OK);
+// SetDlgItemText(hPubKeyEdit, IDC_PUBLIC_KEY_EDIT, tmp);
+ }
+ DestroyWindow(hwndDlg);
+ break;
+ case IDCANCEL:
+ DestroyWindow(hwndDlg);
+ break;
+ }
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ if(hdr && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1))
+ {
+ if(hdr->hdr.code == NM_CLICK)
+ {
+ EnableWindow(GetDlgItem(hwndDlg, IDOK), 1);
+ itemnum2 = hdr->iItem;
+ }
+ }
+
+ switch (((LPNMHDR)lParam)->code)
+ {
+
+ case PSN_APPLY:
+ {
+ return TRUE;
+ }
+ }
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ {
+ GetWindowRect(hwndDlg, &load_existing_key_rect);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowX", load_existing_key_rect.left);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowY", load_existing_key_rect.top);
+ }
+ hwndSelectExistingKey = NULL;
+ break;
+
+ }
+
+ return FALSE;
+}
+static INT_PTR CALLBACK DlgProcImportKeyDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ extern HANDLE new_key_hcnt;
+ extern boost::mutex new_key_hcnt_mutex;
+ HANDLE hContact = INVALID_HANDLE_VALUE;
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ hContact = new_key_hcnt;
+ new_key_hcnt_mutex.unlock();
+ SetWindowPos(hwndDlg, 0 , import_key_rect.left, import_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW);
+ TranslateDialogDefault(hwndDlg);
+ ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEYSERVER), _T("subkeys.pgp.net"), 0);
+ ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEYSERVER), _T("keys.gnupg.net"), 0);
+ return TRUE;
+ }
+
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_IMPORT:
+ {
+ string out;
+ DWORD code;
+ wstring cmd = _T(" --keyserver \"");
+ TCHAR *server= new TCHAR [128];
+ GetDlgItemText(hwndDlg, IDC_KEYSERVER, server, 128);
+ cmd += server;
+ delete [] server;
+ cmd += _T("\" --recv-keys ");
+// char *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID_Prescense", "");
+// TCHAR *tmp2 = mir_a2t(tmp);
+// mir_free(tmp);
+ cmd += toUTF16(hcontact_data[hContact].key_in_prescense);
+// mir_free(tmp2);
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ }
+ MessageBoxA(0, out.c_str(), "GPG output", MB_OK);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+/* switch (((LPNMHDR)lParam)->code)
+ {
+ default:
+ break;
+ } */
+ }
+ break;
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ break;
+ case WM_DESTROY:
+ {
+ GetWindowRect(hwndDlg, &import_key_rect);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowX", import_key_rect.left);
+ DBWriteContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowY", import_key_rect.top);
+ }
+ break;
+
+ }
+ return FALSE;
+}
+
+
+extern HINSTANCE hInst;
+
+
+void ShowFirstRunDialog()
+{
+ if (hwndFirstRun == NULL)
+ {
+ hwndFirstRun = CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIRST_RUN), NULL, DlgProcFirstRun);
+ }
+ SetForegroundWindow(hwndFirstRun);
+}
+
+
+void ShowSetDirsDialog()
+{
+ if (hwndSetDirs == NULL)
+ {
+ hwndSetDirs = CreateDialog(hInst, MAKEINTRESOURCE(IDD_BIN_PATH), NULL, DlgProcGpgBinOpts);
+ }
+ SetForegroundWindow(hwndSetDirs);
+}
+
+void ShowNewKeyDialog()
+{
+ hwndNewKey = CreateDialog(hInst, MAKEINTRESOURCE(IDD_NEW_KEY), NULL, DlgProcNewKeyDialog);
+ SetForegroundWindow(hwndNewKey);
+}
+
+void ShowKeyGenDialog()
+{
+ if (hwndKeyGen == NULL)
+ {
+ hwndKeyGen = CreateDialog(hInst, MAKEINTRESOURCE(IDD_KEY_GEN), NULL, DlgProcKeyGenDialog);
+ }
+ SetForegroundWindow(hwndKeyGen);
+}
+
+void ShowSelectExistingKeyDialog()
+{
+ if (hwndSelectExistingKey == NULL)
+ {
+ hwndSelectExistingKey = CreateDialog(hInst, MAKEINTRESOURCE(IDD_LOAD_EXISTING_KEY), NULL, DlgProcLoadExistingKey);
+ }
+ SetForegroundWindow(hwndSelectExistingKey);
+}
+
+void ShowImportKeyDialog()
+{
+ CreateDialog(hInst, MAKEINTRESOURCE(IDD_IMPORT_KEY), NULL, DlgProcImportKeyDialog);
+}
+
+
+
+
+void FirstRun()
+{
+ DWORD pid = 0;
+ if(!DBGetContactSettingByte(NULL, szGPGModuleName, "FirstRun", 1))
+ return;
+ ShowSetDirsDialog();
+}
+
+void InitCheck()
+{
+ {//parse gpg output
+ gpg_valid = isGPGValid();
+ bool home_dir_access = false, temp_access = false;
+ TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ std::wstring test_path = home_dir;
+ mir_free(home_dir);
+ test_path += _T("/");
+ test_path += toUTF16(get_random(13));
+ wfstream test_file;
+ test_file.open(test_path, std::ios::trunc | std::ios::out);
+ if(test_file.is_open() && test_file.good())
+ {
+ test_file<<_T("access_test\n");
+ if(test_file.good())
+ home_dir_access = true;
+ test_file.close();
+ DeleteFile(test_path.c_str());
+ }
+ home_dir = _tgetenv(_T("TEMP"));
+ test_path = home_dir;
+ test_path += _T("/");
+ test_path += toUTF16(get_random(13));
+ test_file.open(test_path, std::ios::trunc | std::ios::out);
+ if(test_file.is_open() && test_file.good())
+ {
+ test_file<<_T("access_test\n");
+ if(test_file.good())
+ temp_access = true;
+ test_file.close();
+ DeleteFile(test_path.c_str());
+ }
+ if(!home_dir_access || !temp_access || !gpg_valid)
+ {
+ char buf[4096];
+ strcpy(buf, gpg_valid?Translate("GPG binary is set and valid (this is good).\n"):Translate("GPG binary unset or invalid (plugin will not work).\n"));
+ strcat(buf, home_dir_access?Translate("Home dir write access granted (this is good).\n"):Translate("Home dir have not write access (plugin most probably will not work).\n"));
+ strcat(buf, temp_access?Translate("Temp dir write access granted (this is good).\n"):Translate("Temp dir have not write access (plugin should work, but may have some problems, filetransfers will not work)."));
+ if(!gpg_valid)
+ strcat(buf, Translate("\nGPG will be disabled until you solve this problems"));
+ MessageBoxA(0, buf, Translate("GPG plugin problems"), MB_OK);
+ }
+ if(!gpg_valid)
+ return;
+ gpg_keyexist = isGPGKeyExist();
+ string out;
+ DWORD code;
+ pxResult result;
+ wstring::size_type p = 0, p2 = 0, stop = 0;
+ {
+ gpg_execution_params params;
+ wstring cmd = _T("--batch --list-secret-keys");
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ return;
+ }
+ if(result == pxNotFound)
+ return;
+ }
+ home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ wstring tmp_dir = home_dir;
+ mir_free(home_dir);
+ tmp_dir += _T("\\tmp");
+ _wmkdir(tmp_dir.c_str());
+ string question = Translate("Your secret key whith id: ");
+ char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
+ char *key = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", "");
+ void ShowFirstRunDialog();
+ if(!DBGetContactSettingByte(NULL, szGPGModuleName, "FirstRun", 1) && (!keyid[0] || !key[0]))
+ {
+ question = Translate("You have not set public key for gpg, it's recommended to do it.\nDo you want to do it now ?");
+ if(MessageBoxA(0, question.c_str(), Translate("Own public key warning"), MB_YESNO) == IDYES)
+ ShowFirstRunDialog();
+ }
+ if(out.find(keyid) == string::npos)
+ {
+ question += keyid;
+ question += Translate(" deleted from gpg secret keyring\nDo you want to set another key ?");
+ if(MessageBoxA(0, question.c_str(), Translate("Own secret key warning"), MB_YESNO) == IDYES)
+ ShowFirstRunDialog();
+ }
+ mir_free(keyid);
+ mir_free(key);
+ }
+ {
+ TCHAR *path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ DWORD dwFileAttr = GetFileAttributes(path);
+ if (dwFileAttr != INVALID_FILE_ATTRIBUTES)
+ {
+ dwFileAttr &=~ FILE_ATTRIBUTE_READONLY;
+ SetFileAttributes(path, dwFileAttr);
+ }
+ mir_free(path);
+ }
+ extern bool bAutoExchange;
+ if(bAutoExchange)
+ {
+ int count = 0;
+ PROTOACCOUNT **accounts;
+ ProtoEnumAccounts(&count, &accounts);
+ ICQ_CUSTOMCAP cap;
+ cap.cbSize = sizeof(ICQ_CUSTOMCAP);
+ cap.hIcon = 0;
+ strcpy(cap.name, "GPG Key AutoExchange");
+ strcpy(cap.caps, "GPG AutoExchange");
+
+ for(int i = 0; i < count; i++)
+ {
+ char svc[64];
+ strcpy(svc, accounts[i]->szProtoName);
+ strcat(svc, PS_ICQ_ADDCAPABILITY);
+ if(ServiceExists(svc))
+ CallService(svc, 0, (LPARAM)&cap);
+ }
+ }
+}
+
+void ImportKey()
+{
+ extern wstring new_key;
+ extern HANDLE new_key_hcnt;
+ extern boost::mutex new_key_hcnt_mutex;
+ HANDLE hContact = new_key_hcnt;
+ new_key_hcnt_mutex.unlock();
+ bool for_all_sub = false;
+ if(metaIsProtoMetaContacts(hContact))
+ if(MessageBox(0, TranslateT("Do you want load key for all subcontacts ?"), TranslateT("Metacontact detected"), MB_YESNO) == IDYES)
+ for_all_sub = true;
+ if(metaIsProtoMetaContacts(hContact))
+ {
+ HANDLE hcnt = NULL;
+ if(for_all_sub)
+ {
+ int count = metaGetContactsNum(hContact);
+ for(int i = 0; i < count; i++)
+ {
+ hcnt = metaGetSubcontact(hContact, i);
+ if(hcnt)
+ DBWriteContactSettingTString(hcnt, szGPGModuleName, "GPGPubKey", new_key.c_str());
+ }
+ }
+ else
+ DBWriteContactSettingTString(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", new_key.c_str());
+ }
+ else
+ DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", new_key.c_str());
+ new_key.clear();
+ { //gpg execute block
+ wstring cmd;
+ TCHAR tmp2[MAX_PATH] = {0};
+ TCHAR *ptmp;
+ string output;
+ DWORD exitcode;
+ {
+ ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ _tcscpy(tmp2, ptmp);
+ mir_free(ptmp);
+ _tcscat(tmp2, _T("\\"));
+ _tcscat(tmp2, _T("temporary_exported.asc"));
+ DeleteFile(tmp2);
+ wfstream f(tmp2, std::ios::out);
+ if(metaIsProtoMetaContacts(hContact))
+ ptmp = UniGetContactSettingUtf(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", _T(""));
+ else
+ ptmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T(""));
+ wstring new_key = ptmp;
+ mir_free(ptmp);
+ f<<new_key.c_str();
+ f.close();
+ cmd += _T(" --batch ");
+ cmd += _T(" --import \"");
+ cmd += tmp2;
+ cmd += _T("\"");
+ }
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ return;
+ }
+ if(result == pxNotFound)
+ return;
+ {
+ if(metaIsProtoMetaContacts(hContact))
+ {
+ HANDLE hcnt = NULL;
+ if(for_all_sub)
+ {
+ int count = metaGetContactsNum(hContact);
+ for(int i = 0; i < count; i++)
+ {
+ hcnt = metaGetSubcontact(hContact, i);
+ if(hcnt)
+ {
+ char *tmp = NULL;
+ string::size_type s = output.find("gpg: key ") + strlen("gpg: key ");
+ string::size_type s2 = output.find(":", s);
+ DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str());
+ s = output.find("“", s2);
+ if(s == string::npos)
+ {
+ s = output.find("\"", s2);
+ s += 1;
+ }
+ else
+ s += 3;
+ bool uncommon = false;
+ if((s2 = output.find("(", s)) == string::npos)
+ {
+ if((s2 = output.find("<", s)) == string::npos)
+ {
+ s2 = output.find("â€", s);
+ uncommon = true;
+ }
+ }
+ else if(s2 > output.find("<", s))
+ s2 = output.find("<", s);
+ if(s != string::npos && s2 != string::npos)
+ {
+ tmp = (char*)mir_alloc(sizeof(char)*(output.substr(s,s2-s-(uncommon?1:0)).length()+1));
+ strcpy(tmp, output.substr(s,s2-s-(uncommon?1:0)).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainName", tmp);
+ mir_free(tmp);
+ }
+
+ if((s = output.find(")", s2)) == string::npos)
+ s = output.find(">", s2);
+ else if(s > output.find(">", s2))
+ s = output.find(">", s2);
+ s2++;
+ if(s != string::npos && s2 != string::npos)
+ {
+ if(output[s] == ')')
+ {
+ tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1));
+ strcpy(tmp, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyComment", tmp);
+ mir_free(tmp);
+ s+=3;
+ s2 = output.find(">", s);
+ if(s != string::npos && s2 != string::npos)
+ {
+ tmp = (char*) mir_alloc(sizeof(char)*(output.substr(s,s2-s).length()+1));
+ strcpy(tmp, output.substr(s,s2-s).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", tmp);
+ mir_free(tmp);
+ }
+ }
+ else
+ {
+ tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1));
+ strcpy(tmp, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str());
+ mir_free(tmp);
+ }
+ }
+ DBDeleteContactSetting(hcnt, szGPGModuleName, "bAlwatsTrust");
+ }
+ }
+ }
+ else
+ {
+ char *tmp = NULL;
+ string::size_type s = output.find("gpg: key ") + strlen("gpg: key ");
+ string::size_type s2 = output.find(":", s);
+ DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str());
+ s = output.find("“", s2);
+ if(s == string::npos)
+ {
+ s = output.find("\"", s2);
+ s += 1;
+ }
+ else
+ s += 3;
+ bool uncommon = false;
+ if((s2 = output.find("(", s)) == string::npos)
+ {
+ if((s2 = output.find("<", s)) == string::npos)
+ {
+ s2 = output.find("â€", s);
+ uncommon = true;
+ }
+ }
+ else if(s2 > output.find("<", s))
+ s2 = output.find("<", s);
+ if(s != string::npos && s2 != string::npos)
+ {
+ tmp = (char*)mir_alloc(sizeof(char)*(output.substr(s,s2-s-(uncommon?1:0)).length()+1));
+ strcpy(tmp, output.substr(s,s2-s-(uncommon?1:0)).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainName", tmp);
+ mir_free(tmp);
+ }
+ if((s = output.find(")", s2)) == string::npos)
+ s = output.find(">", s2);
+ else if(s > output.find(">", s2))
+ s = output.find(">", s2);
+ s2++;
+ if(s != string::npos && s2 != string::npos)
+ {
+ if(output[s] == ')')
+ {
+ tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1));
+ strcpy(tmp, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyComment", tmp);
+ mir_free(tmp);
+ s+=3;
+ s2 = output.find(">", s);
+ if(s != string::npos && s2 != string::npos)
+ {
+ tmp = (char*) mir_alloc(sizeof(char)*(output.substr(s,s2-s).length()+1));
+ strcpy(tmp, output.substr(s,s2-s).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", tmp);
+ mir_free(tmp);
+ }
+ }
+ else
+ {
+ tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1));
+ strcpy(tmp, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str());
+ mir_free(tmp);
+ }
+ }
+ DBDeleteContactSetting(metaGetMostOnline(hContact), szGPGModuleName, "bAlwatsTrust");
+ }
+ }
+ else
+ {
+ char *tmp = NULL;
+ string::size_type s = output.find("gpg: key ") + strlen("gpg: key ");
+ string::size_type s2 = output.find(":", s);
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str());
+ s = output.find("“", s2);
+ if(s == string::npos)
+ {
+ s = output.find("\"", s2);
+ s += 1;
+ }
+ else
+ s += 3;
+ bool uncommon = false;
+ if((s2 = output.find("(", s)) == string::npos)
+ {
+ if((s2 = output.find("<", s)) == string::npos)
+ {
+ s2 = output.find("â€", s);
+ uncommon = true;
+ }
+ }
+ else if(s2 > output.find("<", s))
+ s2 = output.find("<", s);
+ if(s != string::npos && s2 != string::npos)
+ {
+ tmp = (char*)mir_alloc(sizeof(char)*(output.substr(s,s2-s-(uncommon?1:0)).length()+1));
+ strcpy(tmp, output.substr(s,s2-s-(uncommon?1:0)).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", tmp);
+ mir_free(tmp);
+ }
+ if((s = output.find(")", s2)) == string::npos)
+ s = output.find(">", s2);
+ else if(s > output.find(">", s2))
+ s = output.find(">", s2);
+ s2++;
+ if(s != string::npos && s2 != string::npos)
+ {
+ if(output[s] == ')')
+ {
+ tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1));
+ strcpy(tmp, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", tmp);
+ mir_free(tmp);
+ s+=3;
+ s2 = output.find(">", s);
+ if(s != string::npos && s2 != string::npos)
+ {
+ tmp = (char*) mir_alloc(sizeof(char)*(output.substr(s,s2-s).length()+1));
+ strcpy(tmp, output.substr(s,s2-s).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", tmp);
+ mir_free(tmp);
+ }
+ }
+ else
+ {
+ tmp = (char*)mir_alloc(sizeof(char)* (output.substr(s2,s-s2).length()+1));
+ strcpy(tmp, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp, 0);
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str());
+ mir_free(tmp);
+ }
+ }
+ DBDeleteContactSetting(hContact, szGPGModuleName, "bAlwatsTrust");
+ }
+ }
+ ptmp = mir_wstrdup(toUTF16(output).c_str());
+ MessageBox(0, ptmp, _T(""), MB_OK);
+ mir_free(ptmp);
+ DeleteFile(tmp2);
+ }
}
\ No newline at end of file diff --git a/plugins/New_GPG/src/messages.cpp b/plugins/New_GPG/src/messages.cpp index 292ad1062c..5e3e609037 100755 --- a/plugins/New_GPG/src/messages.cpp +++ b/plugins/New_GPG/src/messages.cpp @@ -333,6 +333,7 @@ void RecvMsgSvc_func(HANDLE hContact, std::wstring str, char *msg, DWORD flags, } else { + fix_line_term(str); if(bAppendTags) { str.insert(0, inopentag); @@ -780,7 +781,10 @@ void SendMsgSvc_func(HANDLE hContact, char *msg, DWORD flags) path.append(_T(".asc")); wfstream f(path.c_str(), std::ios::in | std::ios::ate | std::ios::binary); while(!f.is_open()) + { + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); f.open(path.c_str(), std::ios::in | std::ios::ate | std::ios::binary); + } str.clear(); if(f.is_open()) { @@ -821,6 +825,7 @@ void SendMsgSvc_func(HANDLE hContact, char *msg, DWORD flags) HistoryLog(hContact, db_event((char*)str_event.c_str(), 0,0, dbflags|DBEF_SENT)); if(!(flags & PREF_UTF)) flags |= PREF_UTF; + fix_line_term(str); sent_msgs.push_back((HANDLE)CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)toUTF8(str).c_str())); mir_free(msg); return; diff --git a/plugins/New_GPG/src/utilities.cpp b/plugins/New_GPG/src/utilities.cpp index 5d9e9a2ecd..b71a856eb4 100755 --- a/plugins/New_GPG/src/utilities.cpp +++ b/plugins/New_GPG/src/utilities.cpp @@ -1,1794 +1,1851 @@ -// Copyright © 2010-2012 sss -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - -#include "commonheaders.h" - - -TCHAR* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef) -{ - DBVARIANT dbv = {DBVT_DELETED}; - TCHAR* szRes; - if (DBGetContactSettingTString(hContact, szModule, szSetting, &dbv)) - return mir_tstrdup(szDef); - if(dbv.pszVal) - szRes = mir_tstrdup(dbv.ptszVal); - DBFreeVariant(&dbv); - return szRes; -} - -char* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, char* szDef) -{ - DBVARIANT dbv = {DBVT_DELETED}; - char* szRes; - if (DBGetContactSettingString(hContact, szModule, szSetting, &dbv)) - return mir_strdup(szDef); - if(dbv.pszVal) - szRes = mir_strdup(dbv.pszVal); - DBFreeVariant(&dbv); - return szRes; -} - -void GetFilePath(TCHAR *WindowTittle, char *szSetting, TCHAR *szExt, TCHAR *szExtDesc) -{ - TCHAR str[MAX_PATH+2] = {0}, *tmp; - OPENFILENAME ofn={0}; - TCHAR filter[512], *pfilter; - ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName); - ofn.Flags=OFN_EXPLORER; - ofn.lpstrTitle=TranslateW(WindowTittle); - _tcscpy(filter,TranslateW(szExtDesc)); - pfilter=filter+_tcslen(filter)+1; - _tcscpy(pfilter, szExt); - pfilter[_tcslen(pfilter)+1] = '\0'; - pfilter[_tcslen(pfilter)+2] = '\0'; - ofn.lpstrFilter=filter; - tmp = UniGetContactSettingUtf(0, szGPGModuleName, szSetting, _T("")); - _tcscpy(str, tmp); - mir_free(tmp); - if(_tcslen(str)< 2) - str[0] = '\0'; - ofn.lpstrFile=str; - ofn.nMaxFile=_MAX_PATH; - ofn.nMaxFileTitle=MAX_PATH; - if(!GetOpenFileName(&ofn)) - return; - DBWriteContactSettingTString(0, szGPGModuleName, szSetting, str); -} - -TCHAR *GetFilePath(TCHAR *WindowTittle, TCHAR *szExt, TCHAR *szExtDesc, bool save_file) -{ - TCHAR *str = new TCHAR [MAX_PATH+2]; - OPENFILENAME ofn={0}; - TCHAR filter[512], *pfilter; - ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName); - ofn.Flags=OFN_EXPLORER; - ofn.lpstrTitle=TranslateW(WindowTittle); - _tcscpy(filter,TranslateW(szExtDesc)); - pfilter=filter+_tcslen(filter)+1; - _tcscpy(pfilter, szExt); - pfilter[_tcslen(pfilter)+1] = '\0'; - pfilter[_tcslen(pfilter)+2] = '\0'; - ofn.lpstrFilter=filter; - _tcscpy(str, _T("")); - if(_tcslen(str)< 2) - str[0] = '\0'; - ofn.lpstrFile=str; - ofn.nMaxFile=_MAX_PATH; - ofn.nMaxFileTitle=MAX_PATH; - if(!save_file) - { - if(!GetOpenFileName(&ofn)) - { - delete [] str; - return NULL; - } - } - else - { - if(!GetSaveFileName(&ofn)) - { - delete [] str; - return NULL; - } - } - return str; -} - -void GetFolderPath(TCHAR *WindowTittle, char *szSetting) -{ - BROWSEINFO pbi = {0}; - pbi.lpszTitle = WindowTittle; - pbi.ulFlags = BIF_EDITBOX|BIF_NEWDIALOGSTYLE|BIF_SHAREABLE; - LPITEMIDLIST pidl = SHBrowseForFolder(&pbi); - if (pidl != 0) - { - TCHAR path[MAX_PATH]; - if (SHGetPathFromIDList(pidl, path)) - { - DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", path); - } - IMalloc * imalloc = 0; - if (SUCCEEDED(SHGetMalloc(&imalloc))) - { - imalloc->Free(pidl); - imalloc->Release(); - } - } -} - -INT_PTR LoadKey(WPARAM w, LPARAM l) -{ - void ShowLoadPublicKeyDialog(); - extern map<int, HANDLE> user_data; - user_data[1] = (HANDLE)w; - ShowLoadPublicKeyDialog(); - return 0; -} - -INT_PTR SendKey(WPARAM w, LPARAM l) -{ - HANDLE hContact = (HANDLE)w; - if(metaIsProtoMetaContacts(hContact)) - hContact = metaGetMostOnline(hContact); - char *szMessage; - { - LPSTR proto = GetContactProto(hContact); - PROTOACCOUNT *acc = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)proto); - std::string acc_str; - if(acc) - { - acc_str = toUTF8(acc->tszAccountName); - acc_str += "("; - acc_str += acc->szModuleName; - acc_str += ")" ; - acc_str += "_GPGPubKey"; - } - szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, acc_str.empty()?"GPGPubKey":acc_str.c_str(), ""); - if(!szMessage[0]) - { - mir_free(szMessage); - szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); //try to get default key as fallback in any way - } - } - if(szMessage[0]) - { - BYTE enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); - DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); - CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)szMessage); - HistoryLog(hContact, db_event("Public key sent", 0, 0, DBEF_SENT)); - DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc); - } - mir_free(szMessage); - return 0; -} - -extern HANDLE hLoadPublicKey, hToggleEncryption; - -INT_PTR ToggleEncryption(WPARAM w, LPARAM l) -{ - HANDLE hContact = (HANDLE)w; - BYTE enc = 0; - if(metaIsProtoMetaContacts(hContact)) - enc = DBGetContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0); - else - enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); - if(metaIsProtoMetaContacts(hContact)) - { - HANDLE hcnt = NULL; - if(MessageBox(0, _T("Do you want to toggle encryption for all subcontacts ?"), _T("Metacontact detected"), MB_YESNO) == IDYES) - { - int count = metaGetContactsNum(hContact); - for(int i = 0; i < count; i++) - { - hcnt = metaGetSubcontact(hContact, i); - if(hcnt) - DBWriteContactSettingByte(hcnt, szGPGModuleName, "GPGEncryption", enc?0:1); - } - DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); - } - } - else - DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); - void setSrmmIcon(HANDLE hContact); - void setClistIcon(HANDLE hContact); - setSrmmIcon(hContact); - setClistIcon(hContact); - enc = enc?0:1; - +// Copyright © 2010-2012 sss
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+#include "commonheaders.h"
+
+
+TCHAR* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef)
+{
+ DBVARIANT dbv = {DBVT_DELETED};
+ TCHAR* szRes;
+ if (DBGetContactSettingTString(hContact, szModule, szSetting, &dbv))
+ return mir_tstrdup(szDef);
+ if(dbv.pszVal)
+ szRes = mir_tstrdup(dbv.ptszVal);
+ DBFreeVariant(&dbv);
+ return szRes;
+}
+
+char* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, char* szDef)
+{
+ DBVARIANT dbv = {DBVT_DELETED};
+ char* szRes;
+ if (DBGetContactSettingString(hContact, szModule, szSetting, &dbv))
+ return mir_strdup(szDef);
+ if(dbv.pszVal)
+ szRes = mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ return szRes;
+}
+
+void GetFilePath(TCHAR *WindowTittle, char *szSetting, TCHAR *szExt, TCHAR *szExtDesc)
+{
+ TCHAR str[MAX_PATH+2] = {0}, *tmp;
+ OPENFILENAME ofn={0};
+ TCHAR filter[512], *pfilter;
+ ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName);
+ ofn.Flags=OFN_EXPLORER;
+ ofn.lpstrTitle=TranslateW(WindowTittle);
+ _tcscpy(filter,TranslateW(szExtDesc));
+ pfilter=filter+_tcslen(filter)+1;
+ _tcscpy(pfilter, szExt);
+ pfilter[_tcslen(pfilter)+1] = '\0';
+ pfilter[_tcslen(pfilter)+2] = '\0';
+ ofn.lpstrFilter=filter;
+ tmp = UniGetContactSettingUtf(0, szGPGModuleName, szSetting, _T(""));
+ _tcscpy(str, tmp);
+ mir_free(tmp);
+ if(_tcslen(str)< 2)
+ str[0] = '\0';
+ ofn.lpstrFile=str;
+ ofn.nMaxFile=_MAX_PATH;
+ ofn.nMaxFileTitle=MAX_PATH;
+ if(!GetOpenFileName(&ofn))
+ return;
+ DBWriteContactSettingTString(0, szGPGModuleName, szSetting, str);
+}
+
+TCHAR *GetFilePath(TCHAR *WindowTittle, TCHAR *szExt, TCHAR *szExtDesc, bool save_file)
+{
+ TCHAR *str = new TCHAR [MAX_PATH+2];
+ OPENFILENAME ofn={0};
+ TCHAR filter[512], *pfilter;
+ ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName);
+ ofn.Flags=OFN_EXPLORER;
+ ofn.lpstrTitle=TranslateW(WindowTittle);
+ _tcscpy(filter,TranslateW(szExtDesc));
+ pfilter=filter+_tcslen(filter)+1;
+ _tcscpy(pfilter, szExt);
+ pfilter[_tcslen(pfilter)+1] = '\0';
+ pfilter[_tcslen(pfilter)+2] = '\0';
+ ofn.lpstrFilter=filter;
+ _tcscpy(str, _T(""));
+ if(_tcslen(str)< 2)
+ str[0] = '\0';
+ ofn.lpstrFile=str;
+ ofn.nMaxFile=_MAX_PATH;
+ ofn.nMaxFileTitle=MAX_PATH;
+ if(!save_file)
+ {
+ if(!GetOpenFileName(&ofn))
+ {
+ delete [] str;
+ return NULL;
+ }
+ }
+ else
+ {
+ if(!GetSaveFileName(&ofn))
+ {
+ delete [] str;
+ return NULL;
+ }
+ }
+ return str;
+}
+
+void GetFolderPath(TCHAR *WindowTittle, char *szSetting)
+{
+ BROWSEINFO pbi = {0};
+ pbi.lpszTitle = WindowTittle;
+ pbi.ulFlags = BIF_EDITBOX|BIF_NEWDIALOGSTYLE|BIF_SHAREABLE;
+ LPITEMIDLIST pidl = SHBrowseForFolder(&pbi);
+ if (pidl != 0)
+ {
+ TCHAR path[MAX_PATH];
+ if (SHGetPathFromIDList(pidl, path))
+ {
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", path);
+ }
+ IMalloc * imalloc = 0;
+ if (SUCCEEDED(SHGetMalloc(&imalloc)))
+ {
+ imalloc->Free(pidl);
+ imalloc->Release();
+ }
+ }
+}
+
+INT_PTR LoadKey(WPARAM w, LPARAM l)
+{
+ void ShowLoadPublicKeyDialog();
+ extern map<int, HANDLE> user_data;
+ user_data[1] = (HANDLE)w;
+ ShowLoadPublicKeyDialog();
+ return 0;
+}
+
+INT_PTR SendKey(WPARAM w, LPARAM l)
+{
+ HANDLE hContact = (HANDLE)w;
+ if(metaIsProtoMetaContacts(hContact))
+ hContact = metaGetMostOnline(hContact);
+ char *szMessage;
+ {
+ LPSTR proto = GetContactProto(hContact);
+ PROTOACCOUNT *acc = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)proto);
+ std::string acc_str;
+ if(acc)
+ {
+ acc_str = toUTF8(acc->tszAccountName);
+ acc_str += "(";
+ acc_str += acc->szModuleName;
+ acc_str += ")" ;
+ acc_str += "_GPGPubKey";
+ }
+ szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, acc_str.empty()?"GPGPubKey":acc_str.c_str(), "");
+ if(!szMessage[0])
+ {
+ mir_free(szMessage);
+ szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); //try to get default key as fallback in any way
+ }
+ }
+ if(szMessage[0])
+ {
+ BYTE enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0);
+ DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0);
+ CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)szMessage);
+ HistoryLog(hContact, db_event("Public key sent", 0, 0, DBEF_SENT));
+ DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc);
+ }
+ mir_free(szMessage);
+ return 0;
+}
+
+extern HANDLE hLoadPublicKey, hToggleEncryption;
+
+INT_PTR ToggleEncryption(WPARAM w, LPARAM l)
+{
+ HANDLE hContact = (HANDLE)w;
+ BYTE enc = 0;
+ if(metaIsProtoMetaContacts(hContact))
+ enc = DBGetContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0);
+ else
+ enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0);
+ if(metaIsProtoMetaContacts(hContact))
+ {
+ HANDLE hcnt = NULL;
+ if(MessageBox(0, _T("Do you want to toggle encryption for all subcontacts ?"), _T("Metacontact detected"), MB_YESNO) == IDYES)
+ {
+ int count = metaGetContactsNum(hContact);
+ for(int i = 0; i < count; i++)
+ {
+ hcnt = metaGetSubcontact(hContact, i);
+ if(hcnt)
+ DBWriteContactSettingByte(hcnt, szGPGModuleName, "GPGEncryption", enc?0:1);
+ }
+ DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1);
+ }
+ }
+ else
+ DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1);
+ void setSrmmIcon(HANDLE hContact);
+ void setClistIcon(HANDLE hContact);
+ setSrmmIcon(hContact);
+ setClistIcon(hContact);
+ enc = enc?0:1;
+
CLISTMENUITEM mi = { sizeof(mi) };
- mi.flags = CMIM_NAME; - enc?mi.pszName="Turn off GPG encryption":mi.pszName="Turn on GPG encryption"; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi); - return 0; -} - -int OnPreBuildContactMenu(WPARAM w, LPARAM l) -{ - HANDLE hContact = (HANDLE)w; - if(metaIsProtoMetaContacts(hContact)) - hContact = metaGetMostOnline(hContact); - + mi.flags = CMIM_NAME;
+ enc?mi.pszName="Turn off GPG encryption":mi.pszName="Turn on GPG encryption";
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi);
+ return 0;
+}
+
+int OnPreBuildContactMenu(WPARAM w, LPARAM l)
+{
+ HANDLE hContact = (HANDLE)w;
+ if(metaIsProtoMetaContacts(hContact))
+ hContact = metaGetMostOnline(hContact);
+
CLISTMENUITEM mi = { sizeof(mi) };
- mi.flags = CMIM_NAME; - TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); - if(_tcslen(tmp) < 1) - { - DBDeleteContactSetting(hContact, szGPGModuleName, "GPGEncryption"); - mi.flags += CMIM_FLAGS | CMIF_GRAYED; - } - else - mi.flags = CMIM_NAME | CMIM_FLAGS; - mi.pszName = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)?"Turn off GPG encryption":"Turn on GPG encryption"; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi); - return 0; -} - - -list<wstring> transfers; -extern bool bFileTransfers; - -int onProtoAck(WPARAM w, LPARAM l) -{ - ACKDATA *ack=(ACKDATA*)l; - CCSDATA *ccs=(CCSDATA*)ack->lParam; - - if(ack->type == ACKTYPE_FILE && bFileTransfers) - { - switch(ack->result) - { - case ACKRESULT_DENIED: case ACKRESULT_FAILED: - break; - case ACKRESULT_SUCCESS: - { - PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->hProcess; - TCHAR *filename = NULL; - if(f->flags & PFTS_UNICODE) - { - if(f->tszCurrentFile && f->tszCurrentFile[0]) - filename = mir_wstrdup(f->tszCurrentFile); - if(!filename) - return 0; - } - else - { - if(f->szCurrentFile && f->szCurrentFile[0]) - filename = mir_utf8decodeT(f->szCurrentFile); - if(!filename) - return 0; - } - if(_tcsstr(filename, _T(".gpg"))) //decrypt it - { //process encrypted file + mi.flags = CMIM_NAME;
+ TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T(""));
+ if(_tcslen(tmp) < 1)
+ {
+ DBDeleteContactSetting(hContact, szGPGModuleName, "GPGEncryption");
+ mi.flags += CMIM_FLAGS | CMIF_GRAYED;
+ }
+ else
+ mi.flags = CMIM_NAME | CMIM_FLAGS;
+ mi.pszName = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)?"Turn off GPG encryption":"Turn on GPG encryption";
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi);
+ return 0;
+}
+
+
+list<wstring> transfers;
+extern bool bFileTransfers;
+
+int onProtoAck(WPARAM w, LPARAM l)
+{
+ ACKDATA *ack=(ACKDATA*)l;
+ CCSDATA *ccs=(CCSDATA*)ack->lParam;
+
+ if(ack->type == ACKTYPE_FILE && bFileTransfers)
+ {
+ switch(ack->result)
+ {
+ case ACKRESULT_DENIED: case ACKRESULT_FAILED:
+ break;
+ case ACKRESULT_SUCCESS:
+ {
+ PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->hProcess;
+ TCHAR *filename = NULL;
+ if(f->flags & PFTS_UNICODE)
+ {
+ if(f->tszCurrentFile && f->tszCurrentFile[0])
+ filename = mir_wstrdup(f->tszCurrentFile);
+ if(!filename)
+ return 0;
+ }
+ else
+ {
+ if(f->szCurrentFile && f->szCurrentFile[0])
+ filename = mir_utf8decodeT(f->szCurrentFile);
+ if(!filename)
+ return 0;
+ }
+ if(_tcsstr(filename, _T(".gpg"))) //decrypt it
+ { //process encrypted file
HistoryLog(ack->hContact, db_event("Recieved encrypted file, trying to decrypt", 0,0, 0));
- if(_waccess(f->tszCurrentFile, 0) == -1) - { - if(errno == ENOENT) - return 0; - } - string out; - DWORD code; - pxResult result; - wstring cmd = _T(" -o "); - wstring file = filename; - wstring::size_type p1 = file.rfind(_T(".gpg")); - file.erase(p1, _tcslen(_T(".gpg"))); - if(_waccess(file.c_str(), 0) != -1) - { - if(MessageBox(0, _T("Target file exists, do you want to replace it ?"), _T("Warning"), MB_YESNO) == IDNO) - return 0; - } - DeleteFile(file.c_str()); - file.insert(0, _T("\"")); - file.insert(file.length(), _T("\" ")); - cmd += file; - extern TCHAR *password; - { // password - TCHAR *pass = NULL; - char *keyid = UniGetContactSettingUtf(ack->hContact, szGPGModuleName, "KeyID", ""); - if(strlen(keyid) > 0) - { - string dbsetting = "szKey_"; - dbsetting += keyid; - dbsetting += "_Password"; - pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T("")); - if(_tcslen(pass) > 0) - debuglog<<time_str()<<": info: found password in database for key id: "<<keyid<<", trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with password\n"; - } - else - { - pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T("")); - if(_tcslen(pass) > 0) - debuglog<<time_str()<<": info: found password for all keys in database, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with password\n"; - } - if(_tcslen(pass) > 0) - { - cmd += _T("--passphrase \""); - cmd += pass; - cmd += _T("\" "); - } - else if(password) - { - debuglog<<time_str()<<": info: found password in memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with password\n"; - cmd += _T("--passphrase \""); - cmd += password; - cmd += _T("\" "); - } - else - debuglog<<time_str()<<": info: passwords not found in database or memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with out password\n"; - mir_free(pass); - mir_free(keyid); - } - cmd += _T(" -d \""); - cmd += filename; - cmd += _T("\""); - gpg_execution_params params; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::minutes(15))) - { - delete gpg_thread; - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return 0; - } - while(out.find("public key decryption failed: bad passphrase") != string::npos) - { - extern bool _terminate; - extern HANDLE new_key_hcnt; - extern boost::mutex new_key_hcnt_mutex; - debuglog<<time_str()<<": info: failed to decrypt messaage from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" password needed, trying to get one\n"; - if(_terminate) - break; - { //save inkey id - string::size_type s = out.find(" encrypted with "); - s = out.find(" ID ", s); - s += strlen(" ID "); - string::size_type s2 = out.find(",",s); - if(metaIsProtoMetaContacts(ack->hContact)) - DBWriteContactSettingString(metaGetMostOnline(ack->hContact), szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); - else - DBWriteContactSettingString(ack->hContact, szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); - } - void ShowLoadKeyPasswordWindow(); - new_key_hcnt_mutex.lock(); - new_key_hcnt = ack->hContact; - ShowLoadKeyPasswordWindow(); - wstring cmd2 = cmd; - if(password) - { - debuglog<<time_str()<<": info: found password in memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<"\n"; - wstring tmp = _T("--passphrase \""); - tmp += password; - tmp += _T("\" "); - cmd2.insert(0, tmp); - } - out.clear(); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd2; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - gpg_thread = gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::seconds(15))) - { - delete gpg_thread; - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - DeleteFile(filename); - return 0; - } - if(result == pxNotFound) - { - DeleteFile(filename); - return 0; - } - } - DeleteFile(filename); - mir_free(filename); - } - } - break; - } - } - else if(ack->type == ACKTYPE_MESSAGE) - { - extern std::list<HANDLE> sent_msgs; - if(!sent_msgs.empty()) - { - if(ack->result == ACKRESULT_FAILED) - { - std::list<HANDLE>::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess); - if(it != sent_msgs.end()) - { - HistoryLog(ack->hContact, db_event("Failed to send encrypted message", 0,0, 0)); - - } - } - else if(ack->result == ACKRESULT_SUCCESS) - { - std::list<HANDLE>::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess); - if(it != sent_msgs.end()) - sent_msgs.erase(it); - } - } - } - return 0; -} - -std::wstring encrypt_file(HANDLE hContact, TCHAR *filename) -{ - string out; - DWORD code; - pxResult result; - HANDLE hcnt = metaIsProtoMetaContacts(hContact)?metaGetMostOnline(hContact):hContact; - wstring cmd = _T("--batch --yes -r "); - char *keyid = UniGetContactSettingUtf(hcnt, szGPGModuleName, "KeyID", ""); - TCHAR *szKeyid = mir_a2t(keyid); - TCHAR *name = _tcsrchr(filename,_T('\\')); - if( !name ) - name = filename; - else - name++; - TCHAR *file_out = new TCHAR [_tcslen(filename)+4]; - mir_sntprintf(file_out, _tcslen(name)+7, _T("%s.gpg"), name); - cmd += szKeyid; - if(DBGetContactSettingByte(hcnt, szGPGModuleName, "bAlwaysTrust", 0)) - cmd += _T(" --trust-model always "); - mir_free(szKeyid); - mir_free(keyid); - cmd += _T(" -o \""); - TCHAR *temp = _tgetenv(_T("TEMP")); - cmd += temp; - cmd += _T("\\"); - cmd += file_out; - wstring path_out = temp; - path_out += _T("\\"); - path_out += file_out; - DeleteFile(path_out.c_str()); - cmd += _T("\" "); - mir_free(temp); - cmd += _T(" -e \""); - cmd += filename; - cmd += _T("\" "); - gpg_execution_params params; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - mir_free(keyid); - delete [] file_out; - boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::seconds(180))) - { - delete gpg_thread; - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return 0; - } - if(out.find("There is no assurance this key belongs to the named user") != string::npos) - { - out.clear(); - if(MessageBox(0, _T("We trying to encrypt with untrusted key, do you want to trust this key permanently ?"), _T("Warning"), MB_YESNO) == IDYES) - { - DBWriteContactSettingByte(hcnt, szGPGModuleName, "bAlwaysTrust", 1); - cmd.insert(0, _T("--trust-model always ")); - gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread->timed_join(boost::posix_time::seconds(180))) - { - delete gpg_thread; - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return 0; - } - } - else - return 0; - } - return path_out; -} - -//from secureim partially -int onSendFile(WPARAM w, LPARAM l) -{ - if(!bFileTransfers) - return CallService(MS_PROTO_CHAINSEND, w, l); - CCSDATA *ccs=(CCSDATA*)l; - if(isContactSecured(ccs->hContact)) - { + if(_waccess(f->tszCurrentFile, 0) == -1)
+ {
+ if(errno == ENOENT)
+ return 0;
+ }
+ string out;
+ DWORD code;
+ pxResult result;
+ wstring cmd = _T(" -o ");
+ wstring file = filename;
+ wstring::size_type p1 = file.rfind(_T(".gpg"));
+ file.erase(p1, _tcslen(_T(".gpg")));
+ if(_waccess(file.c_str(), 0) != -1)
+ {
+ if(MessageBox(0, _T("Target file exists, do you want to replace it ?"), _T("Warning"), MB_YESNO) == IDNO)
+ return 0;
+ }
+ DeleteFile(file.c_str());
+ file.insert(0, _T("\""));
+ file.insert(file.length(), _T("\" "));
+ cmd += file;
+ extern TCHAR *password;
+ { // password
+ TCHAR *pass = NULL;
+ char *keyid = UniGetContactSettingUtf(ack->hContact, szGPGModuleName, "KeyID", "");
+ if(strlen(keyid) > 0)
+ {
+ string dbsetting = "szKey_";
+ dbsetting += keyid;
+ dbsetting += "_Password";
+ pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T(""));
+ if(_tcslen(pass) > 0)
+ debuglog<<time_str()<<": info: found password in database for key id: "<<keyid<<", trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with password\n";
+ }
+ else
+ {
+ pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T(""));
+ if(_tcslen(pass) > 0)
+ debuglog<<time_str()<<": info: found password for all keys in database, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with password\n";
+ }
+ if(_tcslen(pass) > 0)
+ {
+ cmd += _T("--passphrase \"");
+ cmd += pass;
+ cmd += _T("\" ");
+ }
+ else if(password)
+ {
+ debuglog<<time_str()<<": info: found password in memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with password\n";
+ cmd += _T("--passphrase \"");
+ cmd += password;
+ cmd += _T("\" ");
+ }
+ else
+ debuglog<<time_str()<<": info: passwords not found in database or memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" with out password\n";
+ mir_free(pass);
+ mir_free(keyid);
+ }
+ cmd += _T(" -d \"");
+ cmd += filename;
+ cmd += _T("\"");
+ gpg_execution_params params;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread->timed_join(boost::posix_time::minutes(15)))
+ {
+ delete gpg_thread;
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ return 0;
+ }
+ while(out.find("public key decryption failed: bad passphrase") != string::npos)
+ {
+ extern bool _terminate;
+ extern HANDLE new_key_hcnt;
+ extern boost::mutex new_key_hcnt_mutex;
+ debuglog<<time_str()<<": info: failed to decrypt messaage from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<" password needed, trying to get one\n";
+ if(_terminate)
+ break;
+ { //save inkey id
+ string::size_type s = out.find(" encrypted with ");
+ s = out.find(" ID ", s);
+ s += strlen(" ID ");
+ string::size_type s2 = out.find(",",s);
+ if(metaIsProtoMetaContacts(ack->hContact))
+ DBWriteContactSettingString(metaGetMostOnline(ack->hContact), szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str());
+ else
+ DBWriteContactSettingString(ack->hContact, szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str());
+ }
+ void ShowLoadKeyPasswordWindow();
+ new_key_hcnt_mutex.lock();
+ new_key_hcnt = ack->hContact;
+ ShowLoadKeyPasswordWindow();
+ wstring cmd2 = cmd;
+ if(password)
+ {
+ debuglog<<time_str()<<": info: found password in memory, trying to decrypt message from "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ack->hContact, GCDNF_TCHAR)<<"\n";
+ wstring tmp = _T("--passphrase \"");
+ tmp += password;
+ tmp += _T("\" ");
+ cmd2.insert(0, tmp);
+ }
+ out.clear();
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd2;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ gpg_thread = gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread->timed_join(boost::posix_time::seconds(15)))
+ {
+ delete gpg_thread;
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ DeleteFile(filename);
+ return 0;
+ }
+ if(result == pxNotFound)
+ {
+ DeleteFile(filename);
+ return 0;
+ }
+ }
+ DeleteFile(filename);
+ mir_free(filename);
+ }
+ }
+ break;
+ }
+ }
+ else if(ack->type == ACKTYPE_MESSAGE)
+ {
+ extern std::list<HANDLE> sent_msgs;
+ if(!sent_msgs.empty())
+ {
+ if(ack->result == ACKRESULT_FAILED)
+ {
+ std::list<HANDLE>::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess);
+ if(it != sent_msgs.end())
+ {
+ HistoryLog(ack->hContact, db_event("Failed to send encrypted message", 0,0, 0));
+
+ }
+ }
+ else if(ack->result == ACKRESULT_SUCCESS)
+ {
+ std::list<HANDLE>::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess);
+ if(it != sent_msgs.end())
+ sent_msgs.erase(it);
+ }
+ }
+ }
+ return 0;
+}
+
+std::wstring encrypt_file(HANDLE hContact, TCHAR *filename)
+{
+ string out;
+ DWORD code;
+ pxResult result;
+ HANDLE hcnt = metaIsProtoMetaContacts(hContact)?metaGetMostOnline(hContact):hContact;
+ wstring cmd = _T("--batch --yes -r ");
+ char *keyid = UniGetContactSettingUtf(hcnt, szGPGModuleName, "KeyID", "");
+ TCHAR *szKeyid = mir_a2t(keyid);
+ TCHAR *name = _tcsrchr(filename,_T('\\'));
+ if( !name )
+ name = filename;
+ else
+ name++;
+ TCHAR *file_out = new TCHAR [_tcslen(filename)+4];
+ mir_sntprintf(file_out, _tcslen(name)+7, _T("%s.gpg"), name);
+ cmd += szKeyid;
+ if(DBGetContactSettingByte(hcnt, szGPGModuleName, "bAlwaysTrust", 0))
+ cmd += _T(" --trust-model always ");
+ mir_free(szKeyid);
+ mir_free(keyid);
+ cmd += _T(" -o \"");
+ TCHAR *temp = _tgetenv(_T("TEMP"));
+ cmd += temp;
+ cmd += _T("\\");
+ cmd += file_out;
+ wstring path_out = temp;
+ path_out += _T("\\");
+ path_out += file_out;
+ DeleteFile(path_out.c_str());
+ cmd += _T("\" ");
+ mir_free(temp);
+ cmd += _T(" -e \"");
+ cmd += filename;
+ cmd += _T("\" ");
+ gpg_execution_params params;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ mir_free(keyid);
+ delete [] file_out;
+ boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread->timed_join(boost::posix_time::seconds(180)))
+ {
+ delete gpg_thread;
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ return 0;
+ }
+ if(out.find("There is no assurance this key belongs to the named user") != string::npos)
+ {
+ out.clear();
+ if(MessageBox(0, _T("We trying to encrypt with untrusted key, do you want to trust this key permanently ?"), _T("Warning"), MB_YESNO) == IDYES)
+ {
+ DBWriteContactSettingByte(hcnt, szGPGModuleName, "bAlwaysTrust", 1);
+ cmd.insert(0, _T("--trust-model always "));
+ gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread->timed_join(boost::posix_time::seconds(180)))
+ {
+ delete gpg_thread;
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ return 0;
+ }
+ }
+ else
+ return 0;
+ }
+ return path_out;
+}
+
+//from secureim partially
+int onSendFile(WPARAM w, LPARAM l)
+{
+ if(!bFileTransfers)
+ return CallService(MS_PROTO_CHAINSEND, w, l);
+ CCSDATA *ccs=(CCSDATA*)l;
+ if(isContactSecured(ccs->hContact))
+ {
HistoryLog(ccs->hContact, db_event(Translate("encrypting file for transfer"), 0, 0, DBEF_SENT));
- DWORD flags = (DWORD)ccs->wParam; //check for PFTS_UNICODE here - int i; -// if(flags & PFTS_UNICODE) //this does not work .... - if(StriStr(ccs->szProtoService, "/sendfilew")) - { - TCHAR **file=(TCHAR **)ccs->lParam; - for(i = 0; file[i]; i++) - { - if(_waccess(file[i], 0) == -1) - if(errno == ENOENT) - return 0; //we do not want to send file unencrypted (sometimes ack have wrong info) - if (_tcsstr(file[i],_T(".gpg"))) - continue; - std::wstring path_out = encrypt_file(ccs->hContact, file[i]); - mir_free(file[i]); - file[i] = mir_tstrdup(path_out.c_str()); - transfers.push_back(path_out); - } - } - else - { - char **file = (char**) ccs->lParam; - for(i = 0; file[i]; i++) - { - if(_access(file[i], 0) == -1) - if(errno == ENOENT) - return 0; //we do not want to send file unencrypted (sometimes ack have wrong info) - if (strstr(file[i],".gpg")) - continue; - TCHAR *tmp = mir_utf8decodeT(file[i]); - std::wstring path_out = encrypt_file(ccs->hContact, tmp); - mir_free(tmp); - char* tmp2 = mir_utf8encodeW(path_out.c_str()); - mir_free(file[i]); - file[i] = tmp2; - transfers.push_back(path_out); - - } - } - } - return CallService(MS_PROTO_CHAINSEND, w, l); -} - -void storeOutput(HANDLE ahandle, string *output) + DWORD flags = (DWORD)ccs->wParam; //check for PFTS_UNICODE here
+ int i;
+// if(flags & PFTS_UNICODE) //this does not work ....
+ if(StriStr(ccs->szProtoService, "/sendfilew"))
+ {
+ TCHAR **file=(TCHAR **)ccs->lParam;
+ for(i = 0; file[i]; i++)
+ {
+ if(_waccess(file[i], 0) == -1)
+ if(errno == ENOENT)
+ return 0; //we do not want to send file unencrypted (sometimes ack have wrong info)
+ if (_tcsstr(file[i],_T(".gpg")))
+ continue;
+ std::wstring path_out = encrypt_file(ccs->hContact, file[i]);
+ mir_free(file[i]);
+ file[i] = mir_tstrdup(path_out.c_str());
+ transfers.push_back(path_out);
+ }
+ }
+ else
+ {
+ char **file = (char**) ccs->lParam;
+ for(i = 0; file[i]; i++)
+ {
+ if(_access(file[i], 0) == -1)
+ if(errno == ENOENT)
+ return 0; //we do not want to send file unencrypted (sometimes ack have wrong info)
+ if (strstr(file[i],".gpg"))
+ continue;
+ TCHAR *tmp = mir_utf8decodeT(file[i]);
+ std::wstring path_out = encrypt_file(ccs->hContact, tmp);
+ mir_free(tmp);
+ char* tmp2 = mir_utf8encodeW(path_out.c_str());
+ mir_free(file[i]);
+ file[i] = tmp2;
+ transfers.push_back(path_out);
+
+ }
+ }
+ }
+ return CallService(MS_PROTO_CHAINSEND, w, l);
+}
+
+void storeOutput(HANDLE ahandle, string *output)
+{
+ BOOL success;
+ char *readbuffer = NULL;
+ unsigned long transfered, available;
+
+ do {
+ PeekNamedPipe(ahandle,NULL,0,NULL,&available,NULL);
+ if (!available)
+ continue;
+ readbuffer = (char*)mir_alloc(available);
+ success=ReadFile(ahandle,readbuffer,available,&transfered,NULL);
+ if (success && transfered)
+ output->append(readbuffer, available);
+ mir_free(readbuffer);
+ } while (available>0);
+}
+
+void HistoryLog(HANDLE hContact, db_event evt)
+{
+ DBEVENTINFO Event = {0};
+ Event.cbSize = sizeof(Event);
+ Event.szModule = szGPGModuleName;
+ Event.eventType = evt.eventType;
+ Event.flags = evt.flags;
+ if(!evt.timestamp)
+ Event.timestamp = (DWORD)time(NULL);
+ else
+ Event.timestamp = evt.timestamp;
+ Event.cbBlob = strlen((char*)evt.pBlob)+1;
+ Event.pBlob = (PBYTE)_strdup((char*)evt.pBlob);
+ CallService(MS_DB_EVENT_ADD, (WPARAM)(HANDLE)hContact,(LPARAM)&Event);
+}
+
+static int ControlAddStringUtf(HWND ctrl, DWORD msg, const TCHAR *szString)
+{
+ int item = -1;
+ item = SendMessage(ctrl, msg, 0, (LPARAM)szString);
+ return item;
+}
+
+int ComboBoxAddStringUtf(HWND hCombo, const TCHAR *szString, DWORD data)
+{
+ int item = ControlAddStringUtf(hCombo, CB_ADDSTRING, szString);
+ SendMessage(hCombo, CB_SETITEMDATA, item, data);
+
+ return item;
+}
+
+
+int GetJabberInterface(WPARAM w, LPARAM l) //get interface for all jabber accounts, options later
+{
+ extern list <JabberAccount*> Accounts;
+ void AddHandlers();
+ int count = 0;
+ PROTOACCOUNT **accounts;
+ ProtoEnumAccounts(&count, &accounts);
+ list <JabberAccount*>::iterator p;
+ Accounts.clear();
+ Accounts.push_back(new JabberAccount);
+ p = Accounts.begin();
+ (*p)->setAccountNumber(0);
+ for(int i = 0; i < count; i++) //get only jabber accounts from all accounts
+ {
+ IJabberInterface *JIftmp = getJabberApi(accounts[i]->szModuleName);
+ int a = 0;
+ if(JIftmp)
+ {
+ (*p)->setJabberInterface(JIftmp);
+ if(accounts[i]->tszAccountName)
+ {
+ TCHAR* tmp = mir_tstrdup(accounts[i]->tszAccountName);
+ (*p)->setAccountName(tmp);
+ }
+ else
+ {
+ TCHAR *tmp = mir_a2t(accounts[i]->szModuleName);
+ (*p)->setAccountName(tmp);
+ }
+ (*p)->setAccountNumber(a);
+ a++;
+ Accounts.push_back(new JabberAccount);
+ p++;
+ }
+ }
+ Accounts.pop_back();
+ AddHandlers();
+ return 0;
+}
+
+static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pUserData)
+{
+ HXML local_node = node;
+ for(int n = 0; n <= xi.getChildCount(node); n++)
+ {
+ LPCTSTR str = xi.getText(local_node);
+ LPCTSTR nodename = xi.getName(local_node);
+ LPCTSTR attr = xi.getAttrValue(local_node, _T("to"));
+ if(attr)
+ {
+ HANDLE hContact = ji->Sys()->ContactFromJID(attr);
+ if(hContact)
+ if(!isContactSecured(hContact))
+ return FALSE;
+ }
+ if(str)
+ {
+ if(_tcsstr(str, _T("-----BEGIN PGP MESSAGE-----")) && _tcsstr(str, _T("-----END PGP MESSAGE-----")))
+ {
+ wstring data = str;
+ xi.setText(local_node, _T("This message is encrypted."));
+ wstring::size_type p1 = data.find(_T("-----BEGIN PGP MESSAGE-----")) + _tcslen(_T("-----BEGIN PGP MESSAGE-----"));
+ while(data.find(_T("Version: "), p1) != wstring::npos)
+ {
+ p1 = data.find(_T("Version: "), p1);
+ p1 = data.find(_T("\n"), p1);
+ }
+ while(data.find(_T("Comment: "), p1) != wstring::npos)
+ {
+ p1 = data.find(_T("Comment: "), p1);
+ p1 = data.find(_T("\n"), p1);
+ }
+ while(data.find(_T("Encoding: "), p1) != wstring::npos)
+ {
+ p1 = data.find(_T("Encoding: "), p1);
+ p1 = data.find(_T("\n"), p1);
+ }
+ p1+=3;
+ wstring::size_type p2 = data.find(_T("-----END PGP MESSAGE-----"));
+ wstring data2 = data.substr(p1, p2-p1-2);
+ strip_line_term(data2);
+ HXML encrypted_data = xi.addChild(node, _T("x"), data2.c_str());
+ xi.addAttr(encrypted_data, _T("xmlns"), _T("jabber:x:encrypted"));
+ return FALSE;
+ }
+ }
+ if(bPresenceSigning && nodename)
+ {
+ if(_tcsstr(nodename, _T("status")))
+ {
+ TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ wstring path_out = path_c;
+ wstring file = toUTF16(get_random(10));
+ mir_free(path_c);
+ path_out += _T("\\tmp\\");
+ path_out += file;
+ DeleteFile(path_out.c_str());
+ wfstream f(path_out.c_str(), std::ios::out);
+ f<<toUTF8(str).c_str();
+ f.close();
+ if(_waccess(path_out.c_str(), 0) == -1)
+ {
+ if(errno == ENOENT)
+ {
+ debuglog<<time_str()<<": info: Failed to write prescense in file\n";
+ return FALSE;
+ }
+ }
+ {
+ extern TCHAR *password;
+ string out;
+ DWORD code;
+ wstring cmd;
+ {
+ char *inkeyid;
+ {
+ char *proto = ji->Sys()->GetModuleName();
+ char setting[64];
+ strcpy(setting, proto);
+ strcat(setting, "_KeyID");
+ inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, setting, "");
+ if(!inkeyid[0])
+ {
+ mir_free(inkeyid);
+ inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", "");
+ }
+ }
+ TCHAR *pass = NULL;
+ if(inkeyid[0])
+ {
+ string dbsetting = "szKey_";
+ dbsetting += inkeyid;
+ dbsetting += "_Password";
+ pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T(""));
+ if(pass[0])
+ debuglog<<time_str()<<": info: found password in database for key id: "<<inkeyid<<", trying to encrypt message from self with password\n";
+ }
+ else
+ {
+ pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T(""));
+ if(pass[0])
+ debuglog<<time_str()<<": info: found password for all keys in database, trying to encrypt message from self with password\n";
+ }
+ if(pass[0])
+ {
+ cmd += _T("--passphrase \"");
+ cmd += pass;
+ cmd += _T("\" ");
+ }
+ else if(password)
+ {
+ debuglog<<time_str()<<": info: found password in memory, trying to encrypt message from self with password\n";
+ cmd += _T("--passphrase \"");
+ cmd += password;
+ cmd += _T("\" ");
+ }
+ else
+ debuglog<<time_str()<<": info: passwords not found in database or memory, trying to encrypt message from self with out password\n";
+ mir_free(pass);
+ mir_free(inkeyid);
+ }
+ cmd += _T("--local-user ");
+ path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", _T(""));
+ cmd += path_c;
+ cmd += _T(" --default-key ");
+ cmd += path_c;
+ mir_free(path_c);
+ cmd += _T(" --batch --yes -a -b -s \"");
+ cmd += path_out;
+ cmd += _T("\" ");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(15)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<"GPG execution timed out, aborted\n";
+ }
+ DeleteFile(path_out.c_str());
+ path_out += _T(".asc");
+ f.open(path_out.c_str(), std::ios::in | std::ios::ate | std::ios::binary);
+ wstring data;
+ if(f.is_open())
+ {
+ std::wifstream::pos_type size = f.tellg();
+ TCHAR *tmp = new TCHAR [(std::ifstream::pos_type)size+(std::ifstream::pos_type)1];
+ f.seekg(0, std::ios::beg);
+ f.read(tmp, size);
+ tmp[size]= '\0';
+ data.append(tmp);
+ delete [] tmp;
+ f.close();
+ DeleteFile(path_out.c_str());
+ }
+ if(data.empty())
+ {
+ debuglog<<time_str()<<": info: Failed to read prescense sign from file\n";
+ return FALSE;
+ }
+ if(data.find(_T("-----BEGIN PGP SIGNATURE-----")) != wstring::npos && data.find(_T("-----END PGP SIGNATURE-----")) != wstring::npos)
+ {
+ wstring::size_type p1 = data.find(_T("-----BEGIN PGP SIGNATURE-----")) + _tcslen(_T("-----BEGIN PGP SIGNATURE-----"));
+ if(data.find(_T("Version: "), p1) != wstring::npos)
+ {
+ p1 = data.find(_T("Version: "), p1);
+ p1 = data.find(_T("\n"), p1);
+ if(data.find(_T("Version: "), p1) != wstring::npos)
+ {
+ p1 = data.find(_T("Version: "), p1);
+ p1 = data.find(_T("\n"), p1)+1;
+ }
+ else
+ p1 += 1;
+ }
+ if(data.find(_T("Comment: "), p1) != wstring::npos)
+ {
+ p1 = data.find(_T("Comment: "), p1);
+ p1 = data.find(_T("\n"), p1);
+ if(data.find(_T("Comment: "), p1) != wstring::npos)
+ {
+ p1 = data.find(_T("Comment: "), p1);
+ p1 = data.find(_T("\n"), p1)+1;
+ }
+ else
+ p1 += 1;
+ }
+ else
+ p1+=1;
+ p1++;
+ wstring::size_type p2 = data.find(_T("-----END PGP SIGNATURE-----"));
+ {
+ std::wstring tmp = data.substr(p1, p2-p1);
+ strip_line_term(tmp);
+ HXML encrypted_data = xi.addChild(node, _T("x"), tmp.c_str());
+ xi.addAttr(encrypted_data, _T("xmlns"), _T("jabber:x:signed"));
+ }
+ }
+ return FALSE;
+ }
+ }
+ }
+ local_node = xi.getChild(node, n);
+ }
+ return FALSE;
+}
+
+//boost::mutex sign_file_mutex;
+
+static JABBER_HANDLER_FUNC PrescenseHandler(IJabberInterface *ji, HXML node, void *pUserData)
+{
+ HXML local_node = node;
+ for(int n = 0; n <= xi.getChildCount(node); n++)
+ {
+ LPCTSTR str = xi.getText(local_node);
+ LPCTSTR nodename = xi.getName(local_node);
+ if(nodename)
+ {
+ if(_tcsstr(nodename, _T("x")))
+ {
+ for(int n = 0; n < xi.getAttrCount(local_node); n++)
+ {
+ LPCTSTR name = xi.getAttrName(local_node, n);
+ LPCTSTR value = xi.getAttrValue(local_node, name);
+ if(_tcsstr(value, _T("jabber:x:signed")))
+ {
+ std::wstring status_str;
+ HXML local_node2 = node;
+ for(int n = 0; n <= xi.getChildCount(node); n++)
+ {
+ LPCTSTR nodename2 = xi.getName(local_node2);
+ if(_tcsstr(nodename2, _T("status")))
+ {
+ LPCTSTR status = xi.getText(local_node2);
+ status_str = status;
+ break;
+ }
+ local_node2 = xi.getChild(node, n);
+ }
+ LPCTSTR data = xi.getText(local_node);
+ wstring sign = _T("-----BEGIN PGP SIGNATURE-----\n\n");
+ wstring file = toUTF16(get_random(10)), status_file = toUTF16(get_random(10));
+ sign += data;
+ sign += _T("\n-----END PGP SIGNATURE-----\n");
+ TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ wstring path_out = path_c, status_file_out = path_c;
+ mir_free(path_c);
+ path_out += L"\\tmp\\";
+ path_out += file;
+ path_out += L".sig";
+ status_file_out += L"\\tmp\\";
+ status_file_out += status_file;
+ status_file_out += L".status";
+// sign_file_mutex.lock();
+ DeleteFile(path_out.c_str());
+ DeleteFile(status_file_out.c_str());
+ wfstream f(path_out.c_str(), std::ios::out);
+ while(!f.is_open())
+ f.open(path_out.c_str(), std::ios::out);
+ f<<toUTF8(sign).c_str();
+ f.close();
+ f.open(status_file_out.c_str(), std::ios::out);
+ while(!f.is_open())
+ f.open(status_file_out.c_str(), std::ios::out);
+ f<<toUTF8(status_str).c_str();
+ f.close();
+ if(_waccess(path_out.c_str(), 0) == -1)
+ {
+ if(errno == ENOENT)
+ {
+// sign_file_mutex.unlock();
+ debuglog<<time_str()<<": info: Failed to write sign in file\n";
+ return FALSE;
+ }
+ }
+ { //gpg
+ string out;
+ DWORD code;
+ wstring cmd = L" --verify -a \"";
+ cmd += path_out;
+ cmd += L"\"";
+ cmd += L" \"";
+ cmd += status_file_out;
+ cmd += L"\"";
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(15)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ return FALSE;
+ }
+ if(result == pxNotFound)
+ {
+ return FALSE;
+ }
+ DeleteFile(path_out.c_str());
+ DeleteFile(status_file_out.c_str());
+ if(out.find("key ID ") != string::npos)
+ {
+ //need to get hcontact here, i can get jid from hxml, and get handle from jid, maybe exists better way ?
+ string::size_type p1 = out.find("key ID ") + strlen("key ID ");
+ string::size_type p2 = out.find("\n", p1);
+ if(p1 != string::npos && p2 != string::npos)
+ {
+ HANDLE hContact = NULL;
+ {
+ extern list <JabberAccount*> Accounts;
+ list <JabberAccount*>::iterator p = Accounts.begin();
+ for(unsigned int i = 0; i < Accounts.size(); i++, p++)
+ {
+ if(!(*p))
+ break;
+ hContact = (*p)->getJabberInterface()->Sys()->ContactFromJID(xi.getAttrValue(node, _T("from")));
+ if(hContact)
+ hcontact_data[hContact].key_in_prescense = out.substr(p1, p2-p1-1).c_str();
+ }
+ }
+ }
+ }
+ }
+ return FALSE;
+ }
+ }
+ }
+ }
+ local_node = xi.getChild(node, n);
+ }
+ return FALSE;
+}
+
+static JABBER_HANDLER_FUNC MessageHandler(IJabberInterface *ji, HXML node, void *pUserData)
+{
+ return FALSE;
+}
+
+
+
+
+void AddHandlers()
+{
+ extern list<JabberAccount*> Accounts;
+ list<JabberAccount*>::iterator end = Accounts.end();
+ for(list<JabberAccount*>::iterator p = Accounts.begin(); p != end; p++)
+ {
+ if(!(*p))
+ break;
+ if((*p)->getSendHandler() == INVALID_HANDLE_VALUE)
+ (*p)->setSendHandler((*p)->getJabberInterface()->Net()->AddSendHandler((JABBER_HANDLER_FUNC)SendHandler));
+ if((*p)->getPrescenseHandler() == INVALID_HANDLE_VALUE)
+ (*p)->setPrescenseHandler((*p)->getJabberInterface()->Net()->AddPresenceHandler((JABBER_HANDLER_FUNC)PrescenseHandler));
+// if((*p)->getMessageHandler() == INVALID_HANDLE_VALUE)
+// (*p)->setMessageHandler((*p)->getJabberInterface()->Net()->AddMessageHandler((JABBER_HANDLER_FUNC)MessageHandler, JABBER_MESSAGE_TYPE_ANY ,NULL,NULL));
+ if(bAutoExchange)
+ {
+ (*p)->getJabberInterface()->Net()->RegisterFeature(_T("GPG_Key_Auto_Exchange:0"), _T("Indicates that gpg installed and configured to public key auto exchange (currently implemented in new_gpg Miranda IM plugin)"));
+ (*p)->getJabberInterface()->Net()->AddFeatures(_T("GPG_Key_Auto_Exchange:0\0\0"));
+ }
+ }
+}
+
+bool isContactSecured(HANDLE hContact)
+{
+ BYTE gpg_enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0);
+ if(!gpg_enc)
+ {
+ debuglog<<time_str()<<": encryption is turned off for "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n";
+ return false;
+ }
+ if(!metaIsProtoMetaContacts(hContact))
+ {
+ TCHAR *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T(""));
+ if(!key[0])
+ {
+ mir_free(key);
+ debuglog<<time_str()<<": encryption is turned off for "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n";
+ return false;
+ }
+ mir_free(key);
+ }
+ debuglog<<time_str()<<": encryption is turned on for "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n";
+ return true;
+}
+
+bool isContactHaveKey(HANDLE hContact)
+{
+ TCHAR *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T(""));
+ if(_tcslen(key) > 0)
+ {
+ mir_free(key);
+ return true;
+ }
+ mir_free(key);
+ return false;
+}
+
+bool isGPGKeyExist()
+{
+ TCHAR *id = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", _T(""));
+ char *key = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", "");
+ if(id[0] && key[0])
+ {
+ mir_free(id);
+ mir_free(key);
+ return true;
+ }
+ mir_free(id);
+ mir_free(key);
+ return false;
+}
+bool isGPGValid()
+{
+ TCHAR *tmp;
+ bool gpg_exists = false, is_valid = true;
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T(""));
+ if(_waccess(tmp, 0) != -1)
+ gpg_exists = true;
+ else
+ {
+ mir_free(tmp);
+ TCHAR *path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH);
+ char *mir_path = (char*)mir_alloc(MAX_PATH);
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path);
+ SetCurrentDirectoryA(mir_path);
+ tmp = mir_a2t(mir_path);
+ mir_free(mir_path);
+ //mir_realloc(path, (_tcslen(path)+64)*sizeof(TCHAR));
+ TCHAR *gpg_path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH);
+ _tcscpy(gpg_path, tmp);
+ _tcscat(gpg_path, _T("\\GnuPG\\gpg.exe"));
+ mir_free(tmp);
+ if(_waccess(gpg_path, 0) != -1)
+ {
+ gpg_exists = true;
+ _tcscpy(path, _T("GnuPG\\gpg.exe"));
+ }
+ mir_free(gpg_path);
+ tmp = mir_tstrdup(path);
+ mir_free(path);
+ }
+ DWORD len = MAX_PATH;
+ if(gpg_exists)
+ {
+ DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp);
+ string out;
+ DWORD code;
+ wstring cmd = _T("--version");
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &out;
+ params.code = &code;
+ params.result = &result;
+ gpg_valid = true;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ }
+ gpg_valid = false;
+ string::size_type p1 = out.find("(GnuPG) ");
+ if(p1 == string::npos)
+ is_valid = false;
+ }
+ mir_free(tmp); tmp = NULL;
+ if(!gpg_exists)
+ {
+ wstring path_ = _wgetenv(_T("APPDATA"));
+ path_ += _T("\\GnuPG");
+ tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", (TCHAR*)path_.c_str());
+ }
+ if(tmp)
+ mir_free(tmp);
+ return is_valid;
+}
+
+#define NEWTSTR_MALLOC(A) (A==NULL)?NULL:strcpy((char*)mir_alloc(sizeof(char)*(strlen(A)+1)),A)
+
+const bool StriStr(const char *str, const char *substr)
+{
+ bool i = false;
+ char *str_up = NEWTSTR_MALLOC(str);
+ char *substr_up = NEWTSTR_MALLOC(substr);
+
+ CharUpperBuffA(str_up, strlen(str_up));
+ CharUpperBuffA(substr_up, strlen(substr_up));
+
+ if(strstr (str_up, substr_up))
+ i = true;
+
+ mir_free(str_up);
+ mir_free(substr_up);
+
+ return i;
+}
+
+bool IsOnline(HANDLE hContact)
+{
+ if(DBGetContactSettingByte(hContact, szGPGModuleName, "Status", 0) == ID_STATUS_OFFLINE)
+ return false;
+ return true;
+}
+
+//from secureim
+#include <process.h>
+
+struct TFakeAckParams {
+ inline TFakeAckParams( HANDLE p1, HANDLE p2, LONG p3, LPCSTR p4 ) :
+ hEvent( p1 ),
+ hContact( p2 ),
+ id( p3 ),
+ msg( p4 )
+ {}
+
+ HANDLE hEvent;
+ HANDLE hContact;
+ LONG id;
+ LPCSTR msg;
+};
+
+int SendBroadcast( HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam ) {
+ ACKDATA ack;
+ memset(&ack,0,sizeof(ack));
+ ack.cbSize = sizeof( ACKDATA );
+ ack.szModule = szGPGModuleName;// GetContactProto(hContact);
+ ack.hContact = hContact;
+ ack.type = type;
+ ack.result = result;
+ ack.hProcess = hProcess;
+ ack.lParam = lParam;
+ return CallService( MS_PROTO_BROADCASTACK, 0, ( LPARAM )&ack );
+}
+
+
+
+unsigned __stdcall sttFakeAck( LPVOID param ) {
+
+ TFakeAckParams* tParam = ( TFakeAckParams* )param;
+ WaitForSingleObject( tParam->hEvent, INFINITE );
+
+ Sleep( 100 );
+ if ( tParam->msg == NULL )
+ SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, ( HANDLE )tParam->id, 0 );
+ else
+ SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, ( HANDLE )tParam->id, LPARAM( tParam->msg ));
+
+ CloseHandle( tParam->hEvent );
+ delete tParam;
+
+ return 0;
+}
+
+
+int returnNoError(HANDLE hContact) {
+ HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
+ unsigned int tID;
+ CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttFakeAck, new TFakeAckParams(hEvent,hContact,777,0), 0, &tID) );
+ SetEvent( hEvent );
+ return 777;
+}
+// end from secureim
+
+
+
+string toUTF8(wstring str)
+{
+ string ustr;
+ try{
+ utf8::utf16to8(str.begin(), str.end(), back_inserter(ustr));
+ }
+ catch(const utf8::exception& e)
+ {
+ debuglog<<std::string("utf8cpp encoding exception: ")+(char*)e.what();
+ //TODO
+ }
+ return ustr;
+}
+
+
+
+wstring toUTF16(string str) //convert as much as possible
+{
+ wstring ustr;
+ string tmpstr;
+ try{
+ utf8::replace_invalid(str.begin(), str.end(), back_inserter(tmpstr));
+ utf8::utf8to16(tmpstr.begin(), tmpstr.end(), back_inserter(ustr));
+ }
+ catch(const utf8::exception& e)
+ {
+ debuglog<<std::string("utf8cpp decoding exception: ")+(char*)e.what();
+ //TODO
+ }
+ return ustr;
+}
+
+string get_random(int length)
+{
+ string chars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890");
+ string data;
+ boost::random_device rng;
+ boost::variate_generator<boost::random_device&, boost::uniform_int<>> gen(rng, boost::uniform_int<>(0, chars.length()-1));
+ for(int i = 0; i < length; ++i)
+ data += chars[gen()];
+ return data;
+}
+
+void send_encrypted_msgs_thread(HANDLE hContact)
+{
+ while(true)
+ {
+ char *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", "");
+ while(!isContactSecured(hContact))
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ if(!hcontact_data[hContact].msgs_to_send.empty())
+ {
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ list<string>::iterator end = hcontact_data[hContact].msgs_to_send.end();
+ extern std::list<HANDLE> sent_msgs;
+ for(list<string>::iterator p = hcontact_data[hContact].msgs_to_send.begin(); p != end; ++p)
+ {
+ sent_msgs.push_back((HANDLE)CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)p->c_str()));
+ HistoryLog(hContact, db_event((char*)p->c_str(),0,0, DBEF_SENT));
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ }
+ hcontact_data[hContact].msgs_to_send.clear();
+ return;
+ }
+ else
+ return;
+ }
+}
+
+string time_str()
+{
+ boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+ return (string)boost::posix_time::to_simple_string(now);
+}
+
+int handleEnum(const char *szSetting, LPARAM lParam)
+{
+ if(!*(bool*)lParam && szSetting[0] && StriStr(szSetting, "tabsrmm"))
+ {
+ bool f = false, *found = (bool*)lParam;
+ f = !DBGetContactSettingByte(NULL, "PluginDisable", szSetting, 0);
+ if(f)
+ *found = f;
+ }
+ return 0;
+}
+
+bool isTabsrmmUsed()
+{
+ DBCONTACTENUMSETTINGS enm = {0};
+ bool found = false;
+ enm.lParam = (LPARAM)&found;
+ enm.pfnEnumProc = (DBSETTINGENUMPROC)&handleEnum;
+ enm.szModule = "PluginDisable";
+ if(CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&enm) == -1)
+ return false;
+
+ return found;
+}
+
+
+INT_PTR ExportGpGKeys(WPARAM w, LPARAM l)
+{
+ TCHAR *p = GetFilePath(_T("Choose file to export public keys"), _T("*"), _T("Any file"), true);
+ if(!p || !p[0])
+ {
+ delete [] p;
+ //TODO: handle error
+ return 1;
+ }
+ char *path = mir_t2a(p);
+ delete [] p;
+ std::ofstream file;
+ file.open(path, std::ios::trunc | std::ios::out);
+ mir_free(path);
+ int exported_keys = 0;
+ if(!file.is_open())
+ return 1; //TODO: handle error
+ for(HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact))
+ {
+ char *k = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", "");
+ if(!k[0])
+ {
+ mir_free(k);
+ continue;
+ }
+ std::string key = k;
+ mir_free(k);
+
+ const char* proto = (const char*)GetContactProto(hContact);
+ std::string id = "Comment: login ";
+ const char * uid = (const char*)CallProtoService(proto, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0);
+ DBVARIANT dbv = {0};
+ DBCONTACTGETSETTING dbcgs = {0};
+ dbcgs.pValue = &dbv;
+ dbcgs.szModule = proto;
+ dbcgs.szSetting = uid;
+ CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs);
+ switch(dbcgs.pValue->type)
+ {
+ case DBVT_DELETED:
+ continue;
+ break;
+ case DBVT_BYTE:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal);
+ id += _id;
+ }
+ break;
+ case DBVT_WORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal);
+ id += _id;
+ }
+ break;
+ case DBVT_DWORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal);
+ id += _id;
+ }
+ break;
+ case DBVT_ASCIIZ:
+ {
+ id += dbcgs.pValue->pszVal;
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ }
+ break;
+ case DBVT_UTF8:
+ {
+ char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal);
+ if(tmp[0])
+ id += tmp;
+ mir_free(tmp);
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ }
+ break;
+ case DBVT_BLOB:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ case DBVT_WCHAR:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ }
+ id += " contact_id ";
+ ZeroMemory(&dbv, sizeof(dbv));
+ ZeroMemory(&dbcgs, sizeof(dbcgs));
+ dbcgs.pValue = &dbv;
+ dbcgs.szModule = proto;
+ dbcgs.szSetting = uid;
+ CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs);
+ switch(dbcgs.pValue->type)
+ {
+ case DBVT_DELETED:
+ continue;
+ break;
+ case DBVT_BYTE:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal);
+ id += _id;
+ }
+ break;
+ case DBVT_WORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal);
+ id += _id;
+ }
+ break;
+ case DBVT_DWORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal);
+ id += _id;
+ }
+ break;
+ case DBVT_ASCIIZ:
+ {
+ id += dbcgs.pValue->pszVal;
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ }
+ break;
+ case DBVT_UTF8:
+ {
+ char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal);
+ if(tmp[0])
+ id += tmp;
+ mir_free(tmp);
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ }
+ break;
+ case DBVT_BLOB:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ case DBVT_WCHAR:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ }
+ std::string::size_type p1 = key.find("-----BEGIN PGP PUBLIC KEY BLOCK-----");
+ if(p1 == std::string::npos)
+ continue;
+ p1 += strlen("-----BEGIN PGP PUBLIC KEY BLOCK-----");
+ p1 ++;
+ id += '\n';
+ key.insert(p1, id);
+ file<<key;
+ file<<std::endl;
+ exported_keys++;
+ }
+ if(file.is_open())
+ file.close();
+ char msg[512];
+ mir_snprintf(msg, 511, "we have succesfully exported %d keys", exported_keys);
+ MessageBoxA(NULL, msg, Translate("Keys export result"), MB_OK);
+ return 0;
+}
+
+INT_PTR ImportGpGKeys(WPARAM w, LPARAM l)
+{
+ TCHAR *p = GetFilePath(_T("Choose file to import keys from"), _T("*"), _T("Any file"));
+ if(!p || !p[0])
+ {
+ delete [] p;
+ //TODO: handle error
+ return 1;
+ }
+ char *path = mir_t2a(p);
+ delete [] p;
+ std::ifstream file;
+ file.open(path, std::ios::in);
+ mir_free(path);
+ if(!file.is_open())
+ return 1; //TODO: handle error
+ PROTOACCOUNT **accs;
+ int acc_count = 0, processed_keys = 0;
+ ProtoEnumAccounts(&acc_count, &accs);
+ char line[256];
+ file.getline(line, 255);
+ if(!strstr(line, "-----BEGIN PGP PUBLIC KEY BLOCK-----"))
+ return 1; //TODO: handle error
+ std::string key, login, contact_id;
+ key += line;
+ key += '\n';
+ while(file.is_open() && !file.eof())
+ {
+ file.getline(line, 255);
+ key += line;
+ key += '\n';
+ if(strstr(line, "-----END PGP PUBLIC KEY BLOCK-----"))
+ { //TODO: parse key
+ std::string::size_type p1 = 0, p2 = 0;
+ p1 = key.find("Comment: login ");
+ p1 += strlen("Comment: login ");
+ p2 = key.find(" contact_id ");
+ login = key.substr(p1, p2-p1);
+ p2 += strlen(" contact_id ");
+ p1 = key.find("\n", p2);
+ contact_id = key.substr(p2, p1-p2);
+ p1 = key.find("Comment: login ");
+ p2 = key.find("\n", p1);
+ p2++;
+ key.erase(p1, p2-p1);
+ std::string acc;
+ for(int i = 0; i < acc_count; i++)
+ {
+ if(acc.length())
+ break;
+ const char * uid = (const char*)CallProtoService(accs[i]->szModuleName, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0);
+ DBVARIANT dbv = {0};
+ DBCONTACTGETSETTING dbcgs = {0};
+ dbcgs.pValue = &dbv;
+ dbcgs.szModule = accs[i]->szModuleName;
+ dbcgs.szSetting = uid;
+ CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs);
+ std::string id;
+ switch(dbcgs.pValue->type)
+ {
+ case DBVT_DELETED:
+ continue;
+ break;
+ case DBVT_BYTE:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal);
+ id += _id;
+ if(id == login)
+ acc = accs[i]->szModuleName;
+ }
+ break;
+ case DBVT_WORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal);
+ id += _id;
+ if(id == login)
+ acc = accs[i]->szModuleName;
+ }
+ break;
+ case DBVT_DWORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal);
+ id += _id;
+ if(id == login)
+ acc = accs[i]->szModuleName;
+ }
+ break;
+ case DBVT_ASCIIZ:
+ {
+ id += dbcgs.pValue->pszVal;
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ if(id == login)
+ acc = accs[i]->szModuleName;
+ }
+ break;
+ case DBVT_UTF8:
+ {
+ char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal);
+ if(tmp[0])
+ id += tmp;
+ mir_free(tmp);
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ if(id == login)
+ acc = accs[i]->szModuleName;
+ }
+ break;
+ case DBVT_BLOB:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ case DBVT_WCHAR:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ }
+ }
+ if(acc.length())
+ {
+ const char * uid = (const char*)CallProtoService(acc.c_str(), PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0);
+ for(HANDLE hContact = db_find_first(acc.c_str()); hContact; hContact = db_find_next(hContact, acc.c_str()))
+ {
+ DBVARIANT dbv = {0};
+ DBCONTACTGETSETTING dbcgs = {0};
+ dbcgs.pValue = &dbv;
+ dbcgs.szModule = acc.c_str();
+ dbcgs.szSetting = uid;
+ CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs);
+ std::string id;
+ bool found = false;
+ switch(dbcgs.pValue->type)
+ {
+ case DBVT_DELETED:
+ continue;
+ break;
+ case DBVT_BYTE:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal);
+ id += _id;
+ if(id == contact_id)
+ found = true;
+ }
+ break;
+ case DBVT_WORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal);
+ id += _id;
+ if(id == contact_id)
+ found = true;
+ }
+ break;
+ case DBVT_DWORD:
+ {
+ char _id[64];
+ mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal);
+ id += _id;
+ if(id == contact_id)
+ found = true;
+ }
+ break;
+ case DBVT_ASCIIZ:
+ {
+ id += dbcgs.pValue->pszVal;
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ if(id == contact_id)
+ found = true;
+ }
+ break;
+ case DBVT_UTF8:
+ {
+ char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal);
+ if(tmp[0])
+ id += tmp;
+ mir_free(tmp);
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ if(id == contact_id)
+ found = true;
+ }
+ break;
+ case DBVT_BLOB:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ case DBVT_WCHAR:
+ //TODO
+ CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv);
+ break;
+ }
+ if(found)
+ {
+ wstring cmd;
+ TCHAR tmp2[MAX_PATH] = {0};
+ TCHAR *ptmp;
+ string output;
+ DWORD exitcode;
+ {
+ HANDLE hcnt = hContact;
+ ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T(""));
+ _tcscpy(tmp2, ptmp);
+ mir_free(ptmp);
+ _tcscat(tmp2, _T("\\"));
+ _tcscat(tmp2, _T("temporary_exported.asc"));
+ DeleteFile(tmp2);
+ wfstream f(tmp2, std::ios::out);
+ f<<toUTF16(key).c_str();
+ f.close();
+ cmd += _T(" --batch ");
+ cmd += _T(" --import \"");
+ cmd += tmp2;
+ cmd += _T("\"");
+ }
+ gpg_execution_params params;
+ pxResult result;
+ params.cmd = &cmd;
+ params.useless = "";
+ params.out = &output;
+ params.code = &exitcode;
+ params.result = &result;
+ boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms));
+ if(!gpg_thread.timed_join(boost::posix_time::seconds(10)))
+ {
+ gpg_thread.~thread();
+ TerminateProcess(params.hProcess, 1);
+ params.hProcess = NULL;
+ debuglog<<time_str()<<": GPG execution timed out, aborted\n";
+ break;
+ }
+ if(result == pxNotFound)
+ break;
+ if(result == pxSuccess)
+ processed_keys++;
+ {
+ if(output.find("already in secret keyring") != string::npos)
+ {
+ MessageBox(0, _T("Key already in scret key ring."), _T("Info"), MB_OK);
+ DeleteFile(tmp2);
+ break;
+ }
+ char *tmp2;
+ string::size_type s = output.find("gpg: key ") + strlen("gpg: key ");
+ string::size_type s2 = output.find(":", s);
+ tmp2 = new char [output.substr(s,s2-s).length()+1];
+ strcpy(tmp2, output.substr(s,s2-s).c_str());
+ mir_utf8decode(tmp2, 0);
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID", tmp2);
+ mir_free(tmp2);
+ s = output.find("“", s2);
+ if(s == string::npos)
+ {
+ s = output.find("\"", s2);
+ s += 1;
+ }
+ else
+ s += 3;
+ if((s2 = output.find("(", s)) == string::npos)
+ s2 = output.find("<", s);
+ else if(s2 > output.find("<", s))
+ s2 = output.find("<", s);
+ if(s2 != string::npos)
+ {
+ tmp2 = new char [output.substr(s,s2-s-1).length()+1];
+ strcpy(tmp2, output.substr(s,s2-s-1).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ {
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str());
+ }
+ mir_free(tmp2);
+ if((s = output.find(")", s2)) == string::npos)
+ s = output.find(">", s2);
+ else if(s > output.find(">", s2))
+ s = output.find(">", s2);
+ s2++;
+ if(output[s] == ')')
+ {
+ tmp2 = new char [output.substr(s2,s-s2).length()+1];
+ strcpy(tmp2, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str());
+ mir_free(tmp2);
+ s+=3;
+ s2 = output.find(">", s);
+ tmp2 = new char [output.substr(s,s2-s).length()+1];
+ strcpy(tmp2, output.substr(s,s2-s).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str());
+ mir_free(tmp2);
+ }
+ else
+ {
+ tmp2 = new char [output.substr(s2,s-s2).length()+1];
+ strcpy(tmp2, output.substr(s2,s-s2).c_str());
+ mir_utf8decode(tmp2, 0);
+ if(hContact)
+ DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str());
+ mir_free(tmp2);
+ }
+ }
+ DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1);
+ DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", toUTF16(key).c_str());
+ }
+ DeleteFile(tmp2);
+ break;
+ }
+ }
+ }
+ key.clear();
+ }
+ }
+ if(file.is_open())
+ file.close();
+ char msg[512];
+ mir_snprintf(msg, 511, "we have succesfully processed %d keys", processed_keys);
+ MessageBoxA(NULL, msg, Translate("Keys import result"), MB_OK);
+ return 0;
+}
+
+void fix_line_term(std::string &s)
{ - BOOL success; - char *readbuffer = NULL; - unsigned long transfered, available; - - do { - PeekNamedPipe(ahandle,NULL,0,NULL,&available,NULL); - if (!available) - continue; - readbuffer = (char*)mir_alloc(available); - success=ReadFile(ahandle,readbuffer,available,&transfered,NULL); - if (success && transfered) - output->append(readbuffer, available); - mir_free(readbuffer); - } while (available>0); + for(std::string::size_type s1 = s.find("\r\r", 0); s1 != string::npos; s1 = s.find("\r\r", s1)) + s.erase(s1, 1); } -void HistoryLog(HANDLE hContact, db_event evt) +void fix_line_term(std::wstring &s) { - DBEVENTINFO Event = {0}; - Event.cbSize = sizeof(Event); - Event.szModule = szGPGModuleName; - Event.eventType = evt.eventType; - Event.flags = evt.flags; - if(!evt.timestamp) - Event.timestamp = (DWORD)time(NULL); - else - Event.timestamp = evt.timestamp; - Event.cbBlob = strlen((char*)evt.pBlob)+1; - Event.pBlob = (PBYTE)_strdup((char*)evt.pBlob); - CallService(MS_DB_EVENT_ADD, (WPARAM)(HANDLE)hContact,(LPARAM)&Event); + for(std::wstring::size_type s1 = s.find(_T("\r\r"), 0); s1 != wstring::npos; s1 = s.find(_T("\r\r"), s1)) + s.erase(s1, 1); } -static int ControlAddStringUtf(HWND ctrl, DWORD msg, const TCHAR *szString) -{ - int item = -1; - item = SendMessage(ctrl, msg, 0, (LPARAM)szString); - return item; -} - -int ComboBoxAddStringUtf(HWND hCombo, const TCHAR *szString, DWORD data) -{ - int item = ControlAddStringUtf(hCombo, CB_ADDSTRING, szString); - SendMessage(hCombo, CB_SETITEMDATA, item, data); - - return item; -} - - -int GetJabberInterface(WPARAM w, LPARAM l) //get interface for all jabber accounts, options later -{ - extern list <JabberAccount*> Accounts; - void AddHandlers(); - int count = 0; - PROTOACCOUNT **accounts; - ProtoEnumAccounts(&count, &accounts); - list <JabberAccount*>::iterator p; - Accounts.clear(); - Accounts.push_back(new JabberAccount); - p = Accounts.begin(); - (*p)->setAccountNumber(0); - for(int i = 0; i < count; i++) //get only jabber accounts from all accounts - { - IJabberInterface *JIftmp = getJabberApi(accounts[i]->szModuleName); - int a = 0; - if(JIftmp) - { - (*p)->setJabberInterface(JIftmp); - if(accounts[i]->tszAccountName) - { - TCHAR* tmp = mir_tstrdup(accounts[i]->tszAccountName); - (*p)->setAccountName(tmp); - } - else - { - TCHAR *tmp = mir_a2t(accounts[i]->szModuleName); - (*p)->setAccountName(tmp); - } - (*p)->setAccountNumber(a); - a++; - Accounts.push_back(new JabberAccount); - p++; - } - } - Accounts.pop_back(); - AddHandlers(); - return 0; -} - -static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pUserData) -{ - HXML local_node = node; - for(int n = 0; n <= xi.getChildCount(node); n++) - { - LPCTSTR str = xi.getText(local_node); - LPCTSTR nodename = xi.getName(local_node); - LPCTSTR attr = xi.getAttrValue(local_node, _T("to")); - if(attr) - { - HANDLE hContact = ji->Sys()->ContactFromJID(attr); - if(hContact) - if(!isContactSecured(hContact)) - return FALSE; - } - if(str) - { - if(_tcsstr(str, _T("-----BEGIN PGP MESSAGE-----")) && _tcsstr(str, _T("-----END PGP MESSAGE-----"))) - { - wstring data = str; - xi.setText(local_node, _T("This message is encrypted.")); - wstring::size_type p1 = data.find(_T("-----BEGIN PGP MESSAGE-----")) + _tcslen(_T("-----BEGIN PGP MESSAGE-----")); - while(data.find(_T("Version: "), p1) != wstring::npos) - { - p1 = data.find(_T("Version: "), p1); - p1 = data.find(_T("\n"), p1); - } - while(data.find(_T("Comment: "), p1) != wstring::npos) - { - p1 = data.find(_T("Comment: "), p1); - p1 = data.find(_T("\n"), p1); - } - while(data.find(_T("Encoding: "), p1) != wstring::npos) - { - p1 = data.find(_T("Encoding: "), p1); - p1 = data.find(_T("\n"), p1); - } - p1+=2; - wstring::size_type p2 = data.find(_T("-----END PGP MESSAGE-----")); - wstring data2 = data.substr(p1, p2-p1); - for(std::wstring::size_type i = data2.find(_T("\r")); i != std::wstring::npos; i = data2.find(_T("\r"), i+1)) - data2.erase(i, 1); - for(std::wstring::size_type i = data2.find(_T("\n")); i != std::wstring::npos; i = data2.find(_T("\n"), i+1)) - data2.erase(i, 1); - HXML encrypted_data = xi.addChild(node, _T("x"), data2.c_str()); - xi.addAttr(encrypted_data, _T("xmlns"), _T("jabber:x:encrypted")); - return FALSE; - } - } - if(bPresenceSigning && nodename) - { - if(_tcsstr(nodename, _T("status"))) - { - TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - wstring path_out = path_c; - wstring file = toUTF16(get_random(10)); - mir_free(path_c); - path_out += _T("\\tmp\\"); - path_out += file; - DeleteFile(path_out.c_str()); - wfstream f(path_out.c_str(), std::ios::out); - f<<toUTF8(str).c_str(); - f.close(); - if(_waccess(path_out.c_str(), 0) == -1) - { - if(errno == ENOENT) - { - debuglog<<time_str()<<": info: Failed to write prescense in file\n"; - return FALSE; - } - } - { - extern TCHAR *password; - string out; - DWORD code; - wstring cmd; - { - char *inkeyid; - { - char *proto = ji->Sys()->GetModuleName(); - char setting[64]; - strcpy(setting, proto); - strcat(setting, "_KeyID"); - inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, setting, ""); - if(!inkeyid[0]) - { - mir_free(inkeyid); - inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); - } - } - TCHAR *pass = NULL; - if(inkeyid[0]) - { - string dbsetting = "szKey_"; - dbsetting += inkeyid; - dbsetting += "_Password"; - pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T("")); - if(pass[0]) - debuglog<<time_str()<<": info: found password in database for key id: "<<inkeyid<<", trying to encrypt message from self with password\n"; - } - else - { - pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T("")); - if(pass[0]) - debuglog<<time_str()<<": info: found password for all keys in database, trying to encrypt message from self with password\n"; - } - if(pass[0]) - { - cmd += _T("--passphrase \""); - cmd += pass; - cmd += _T("\" "); - } - else if(password) - { - debuglog<<time_str()<<": info: found password in memory, trying to encrypt message from self with password\n"; - cmd += _T("--passphrase \""); - cmd += password; - cmd += _T("\" "); - } - else - debuglog<<time_str()<<": info: passwords not found in database or memory, trying to encrypt message from self with out password\n"; - mir_free(pass); - mir_free(inkeyid); - } - cmd += _T("--local-user "); - path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", _T("")); - cmd += path_c; - cmd += _T(" --default-key "); - cmd += path_c; - mir_free(path_c); - cmd += _T(" --batch --yes -a -s \""); - cmd += path_out; - cmd += _T("\" "); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(15))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<"GPG execution timed out, aborted\n"; - } - DeleteFile(path_out.c_str()); - path_out += _T(".asc"); - f.open(path_out.c_str(), std::ios::in | std::ios::ate | std::ios::binary); - wstring data; - if(f.is_open()) - { - std::wifstream::pos_type size = f.tellg(); - TCHAR *tmp = new TCHAR [(std::ifstream::pos_type)size+(std::ifstream::pos_type)1]; - f.seekg(0, std::ios::beg); - f.read(tmp, size); - tmp[size]= '\0'; - data.append(tmp); - delete [] tmp; - f.close(); - DeleteFile(path_out.c_str()); - } - if(data.empty()) - { - debuglog<<time_str()<<": info: Failed to read prescense sign from file\n"; - return FALSE; - } - if(data.find(_T("-----BEGIN PGP MESSAGE-----")) != wstring::npos && data.find(_T("-----END PGP MESSAGE-----")) != wstring::npos) - { - wstring::size_type p1 = data.find(_T("-----BEGIN PGP MESSAGE-----")) + _tcslen(_T("-----BEGIN PGP MESSAGE-----")); - if(data.find(_T("Version: "), p1) != wstring::npos) - { - p1 = data.find(_T("Version: "), p1); - p1 = data.find(_T("\n"), p1); - if(data.find(_T("Version: "), p1) != wstring::npos) - { - p1 = data.find(_T("Version: "), p1); - p1 = data.find(_T("\n"), p1)+1; - } - else - p1 += 1; - } - if(data.find(_T("Comment: "), p1) != wstring::npos) - { - p1 = data.find(_T("Comment: "), p1); - p1 = data.find(_T("\n"), p1); - if(data.find(_T("Comment: "), p1) != wstring::npos) - { - p1 = data.find(_T("Comment: "), p1); - p1 = data.find(_T("\n"), p1)+1; - } - else - p1 += 1; - } - else - p1+=1; - wstring::size_type p2 = data.find(_T("-----END PGP MESSAGE-----")); - HXML encrypted_data = xi.addChild(node, _T("x"), data.substr(p1, p2-p1).c_str()); - xi.addAttr(encrypted_data, _T("xmlns"), _T("jabber:x:signed")); - } - return FALSE; - } - } - } - local_node = xi.getChild(node, n); - } - return FALSE; -} - -//boost::mutex sign_file_mutex; - -static JABBER_HANDLER_FUNC PrescenseHandler(IJabberInterface *ji, HXML node, void *pUserData) -{ - HXML local_node = node; - for(int n = 0; n <= xi.getChildCount(node); n++) - { - LPCTSTR str = xi.getText(local_node); - LPCTSTR nodename = xi.getName(local_node); - if(nodename) - { - if(_tcsstr(nodename, _T("x"))) - { - for(int n = 0; n < xi.getAttrCount(local_node); n++) - { - LPCTSTR name = xi.getAttrName(local_node, n); - LPCTSTR value = xi.getAttrValue(local_node, name); - if(_tcsstr(value, _T("jabber:x:signed"))) - { - LPCTSTR data = xi.getText(local_node); - wstring sign = _T("-----BEGIN PGP MESSAGE-----\n\n"); - wstring file = toUTF16(get_random(10)); - sign += data; - sign += _T("\n-----END PGP MESSAGE-----\n"); - TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - wstring path_out = path_c; - mir_free(path_c); - path_out += _T("\\tmp\\"); - path_out += file; -// sign_file_mutex.lock(); - DeleteFile(path_out.c_str()); - wfstream f(path_out.c_str(), std::ios::out); - while(!f.is_open()) - f.open(path_out.c_str(), std::ios::out); - f<<toUTF8(sign).c_str(); - f.close(); - if(_waccess(path_out.c_str(), 0) == -1) - { - if(errno == ENOENT) - { -// sign_file_mutex.unlock(); - debuglog<<time_str()<<": info: Failed to write sign in file\n"; - return FALSE; - } - } - { //gpg - string out; - DWORD code; - wstring cmd = _T(" --verify -a \""); - cmd += path_out; - cmd += _T("\""); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(15))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - return FALSE; - } - if(result == pxNotFound) - { - return FALSE; - } - DeleteFile(path_out.c_str()); - if(out.find("key ID ") != string::npos) - { - //need to get hcontact here, i can get jid from hxml, and get handle from jid, maybe exists better way ? - string::size_type p1 = out.find("key ID ") + strlen("key ID "); - string::size_type p2 = out.find("\n", p1); - if(p1 != string::npos && p2 != string::npos) - { - HANDLE hContact = NULL; - { - extern list <JabberAccount*> Accounts; - list <JabberAccount*>::iterator p = Accounts.begin(); - for(unsigned int i = 0; i < Accounts.size(); i++, p++) - { - if(!(*p)) - break; - hContact = (*p)->getJabberInterface()->Sys()->ContactFromJID(xi.getAttrValue(node, _T("from"))); - if(hContact) - hcontact_data[hContact].key_in_prescense = out.substr(p1, p2-p1-1).c_str(); - } - } - } - } - } - return FALSE; - } - } - } - } - local_node = xi.getChild(node, n); - } - return FALSE; -} - -static JABBER_HANDLER_FUNC MessageHandler(IJabberInterface *ji, HXML node, void *pUserData) -{ - return FALSE; -} - - - - -void AddHandlers() -{ - extern list<JabberAccount*> Accounts; - list<JabberAccount*>::iterator end = Accounts.end(); - for(list<JabberAccount*>::iterator p = Accounts.begin(); p != end; p++) - { - if(!(*p)) - break; - if((*p)->getSendHandler() == INVALID_HANDLE_VALUE) - (*p)->setSendHandler((*p)->getJabberInterface()->Net()->AddSendHandler((JABBER_HANDLER_FUNC)SendHandler)); - if((*p)->getPrescenseHandler() == INVALID_HANDLE_VALUE) - (*p)->setPrescenseHandler((*p)->getJabberInterface()->Net()->AddPresenceHandler((JABBER_HANDLER_FUNC)PrescenseHandler)); -// if((*p)->getMessageHandler() == INVALID_HANDLE_VALUE) -// (*p)->setMessageHandler((*p)->getJabberInterface()->Net()->AddMessageHandler((JABBER_HANDLER_FUNC)MessageHandler, JABBER_MESSAGE_TYPE_ANY ,NULL,NULL)); - if(bAutoExchange) - { - (*p)->getJabberInterface()->Net()->RegisterFeature(_T("GPG_Key_Auto_Exchange:0"), _T("Indicates that gpg installed and configured to public key auto exchange (currently implemented in new_gpg Miranda IM plugin)")); - (*p)->getJabberInterface()->Net()->AddFeatures(_T("GPG_Key_Auto_Exchange:0\0\0")); - } - } -} - -bool isContactSecured(HANDLE hContact) -{ - BYTE gpg_enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); - if(!gpg_enc) - { - debuglog<<time_str()<<": encryption is turned off for "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n"; - return false; - } - if(!metaIsProtoMetaContacts(hContact)) - { - TCHAR *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); - if(!key[0]) - { - mir_free(key); - debuglog<<time_str()<<": encryption is turned off for "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n"; - return false; - } - mir_free(key); - } - debuglog<<time_str()<<": encryption is turned on for "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<"\n"; - return true; -} - -bool isContactHaveKey(HANDLE hContact) -{ - TCHAR *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); - if(_tcslen(key) > 0) - { - mir_free(key); - return true; - } - mir_free(key); - return false; -} - -bool isGPGKeyExist() -{ - TCHAR *id = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", _T("")); - char *key = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); - if(id[0] && key[0]) - { - mir_free(id); - mir_free(key); - return true; - } - mir_free(id); - mir_free(key); - return false; -} -bool isGPGValid() -{ - TCHAR *tmp; - bool gpg_exists = false, is_valid = true; - tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("")); - if(_waccess(tmp, 0) != -1) - gpg_exists = true; - else - { - mir_free(tmp); - TCHAR *path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH); - char *mir_path = (char*)mir_alloc(MAX_PATH); - CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); - SetCurrentDirectoryA(mir_path); - tmp = mir_a2t(mir_path); - mir_free(mir_path); - //mir_realloc(path, (_tcslen(path)+64)*sizeof(TCHAR)); - TCHAR *gpg_path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH); - _tcscpy(gpg_path, tmp); - _tcscat(gpg_path, _T("\\GnuPG\\gpg.exe")); - mir_free(tmp); - if(_waccess(gpg_path, 0) != -1) - { - gpg_exists = true; - _tcscpy(path, _T("GnuPG\\gpg.exe")); - } - mir_free(gpg_path); - tmp = mir_tstrdup(path); - mir_free(path); - } - DWORD len = MAX_PATH; - if(gpg_exists) - { - DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); - string out; - DWORD code; - wstring cmd = _T("--version"); - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &out; - params.code = &code; - params.result = &result; - gpg_valid = true; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - } - gpg_valid = false; - string::size_type p1 = out.find("(GnuPG) "); - if(p1 == string::npos) - is_valid = false; - } - mir_free(tmp); tmp = NULL; - if(!gpg_exists) - { - wstring path_ = _wgetenv(_T("APPDATA")); - path_ += _T("\\GnuPG"); - tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", (TCHAR*)path_.c_str()); - } - if(tmp) - mir_free(tmp); - return is_valid; -} - -#define NEWTSTR_MALLOC(A) (A==NULL)?NULL:strcpy((char*)mir_alloc(sizeof(char)*(strlen(A)+1)),A) - -const bool StriStr(const char *str, const char *substr) -{ - bool i = false; - char *str_up = NEWTSTR_MALLOC(str); - char *substr_up = NEWTSTR_MALLOC(substr); - - CharUpperBuffA(str_up, strlen(str_up)); - CharUpperBuffA(substr_up, strlen(substr_up)); - - if(strstr (str_up, substr_up)) - i = true; - - mir_free(str_up); - mir_free(substr_up); - - return i; -} - -bool IsOnline(HANDLE hContact) -{ - if(DBGetContactSettingByte(hContact, szGPGModuleName, "Status", 0) == ID_STATUS_OFFLINE) - return false; - return true; -} - -//from secureim -#include <process.h> - -struct TFakeAckParams { - inline TFakeAckParams( HANDLE p1, HANDLE p2, LONG p3, LPCSTR p4 ) : - hEvent( p1 ), - hContact( p2 ), - id( p3 ), - msg( p4 ) - {} - - HANDLE hEvent; - HANDLE hContact; - LONG id; - LPCSTR msg; -}; - -int SendBroadcast( HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam ) { - ACKDATA ack; - memset(&ack,0,sizeof(ack)); - ack.cbSize = sizeof( ACKDATA ); - ack.szModule = szGPGModuleName;// GetContactProto(hContact); - ack.hContact = hContact; - ack.type = type; - ack.result = result; - ack.hProcess = hProcess; - ack.lParam = lParam; - return CallService( MS_PROTO_BROADCASTACK, 0, ( LPARAM )&ack ); -} - - - -unsigned __stdcall sttFakeAck( LPVOID param ) { - - TFakeAckParams* tParam = ( TFakeAckParams* )param; - WaitForSingleObject( tParam->hEvent, INFINITE ); - - Sleep( 100 ); - if ( tParam->msg == NULL ) - SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, ( HANDLE )tParam->id, 0 ); - else - SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, ( HANDLE )tParam->id, LPARAM( tParam->msg )); - - CloseHandle( tParam->hEvent ); - delete tParam; - - return 0; -} - - -int returnNoError(HANDLE hContact) { - HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); - unsigned int tID; - CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttFakeAck, new TFakeAckParams(hEvent,hContact,777,0), 0, &tID) ); - SetEvent( hEvent ); - return 777; -} -// end from secureim - - - -string toUTF8(wstring str) -{ - string ustr; - try{ - utf8::utf16to8(str.begin(), str.end(), back_inserter(ustr)); - } - catch(const utf8::exception& e) - { - debuglog<<std::string("utf8cpp encoding exception: ")+(char*)e.what(); - //TODO - } - return ustr; -} - - - -wstring toUTF16(string str) //convert as much as possible -{ - wstring ustr; - string tmpstr; - try{ - utf8::replace_invalid(str.begin(), str.end(), back_inserter(tmpstr)); - utf8::utf8to16(tmpstr.begin(), tmpstr.end(), back_inserter(ustr)); - } - catch(const utf8::exception& e) - { - debuglog<<std::string("utf8cpp decoding exception: ")+(char*)e.what(); - //TODO - } - return ustr; -} - -string get_random(int length) -{ - string chars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"); - string data; - boost::random_device rng; - boost::variate_generator<boost::random_device&, boost::uniform_int<>> gen(rng, boost::uniform_int<>(0, chars.length()-1)); - for(int i = 0; i < length; ++i) - data += chars[gen()]; - return data; -} - -void send_encrypted_msgs_thread(HANDLE hContact) -{ - while(true) - { - char *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); - while(!isContactSecured(hContact)) - boost::this_thread::sleep(boost::posix_time::seconds(1)); - if(!hcontact_data[hContact].msgs_to_send.empty()) - { - boost::this_thread::sleep(boost::posix_time::seconds(1)); - list<string>::iterator end = hcontact_data[hContact].msgs_to_send.end(); - extern std::list<HANDLE> sent_msgs; - for(list<string>::iterator p = hcontact_data[hContact].msgs_to_send.begin(); p != end; ++p) - { - sent_msgs.push_back((HANDLE)CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)p->c_str())); - HistoryLog(hContact, db_event((char*)p->c_str(),0,0, DBEF_SENT)); - boost::this_thread::sleep(boost::posix_time::seconds(1)); - } - hcontact_data[hContact].msgs_to_send.clear(); - return; - } - else - return; - } -} - -string time_str() -{ - boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - return (string)boost::posix_time::to_simple_string(now); -} - -int handleEnum(const char *szSetting, LPARAM lParam) -{ - if(!*(bool*)lParam && szSetting[0] && StriStr(szSetting, "tabsrmm")) - { - bool f = false, *found = (bool*)lParam; - f = !DBGetContactSettingByte(NULL, "PluginDisable", szSetting, 0); - if(f) - *found = f; - } - return 0; -} - -bool isTabsrmmUsed() -{ - DBCONTACTENUMSETTINGS enm = {0}; - bool found = false; - enm.lParam = (LPARAM)&found; - enm.pfnEnumProc = (DBSETTINGENUMPROC)&handleEnum; - enm.szModule = "PluginDisable"; - if(CallService(MS_DB_CONTACT_ENUMSETTINGS, 0, (LPARAM)&enm) == -1) - return false; - - return found; -} - - -INT_PTR ExportGpGKeys(WPARAM w, LPARAM l) -{ - TCHAR *p = GetFilePath(_T("Choose file to export public keys"), _T("*"), _T("Any file"), true); - if(!p || !p[0]) - { - delete [] p; - //TODO: handle error - return 1; - } - char *path = mir_t2a(p); - delete [] p; - std::ofstream file; - file.open(path, std::ios::trunc | std::ios::out); - mir_free(path); - int exported_keys = 0; - if(!file.is_open()) - return 1; //TODO: handle error - for(HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) - { - char *k = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); - if(!k[0]) - { - mir_free(k); - continue; - } - std::string key = k; - mir_free(k); - - const char* proto = (const char*)GetContactProto(hContact); - std::string id = "Comment: login "; - const char * uid = (const char*)CallProtoService(proto, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); - DBVARIANT dbv = {0}; - DBCONTACTGETSETTING dbcgs = {0}; - dbcgs.pValue = &dbv; - dbcgs.szModule = proto; - dbcgs.szSetting = uid; - CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs); - switch(dbcgs.pValue->type) - { - case DBVT_DELETED: - continue; - break; - case DBVT_BYTE: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); - id += _id; - } - break; - case DBVT_WORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); - id += _id; - } - break; - case DBVT_DWORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); - id += _id; - } - break; - case DBVT_ASCIIZ: - { - id += dbcgs.pValue->pszVal; - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - } - break; - case DBVT_UTF8: - { - char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); - if(tmp[0]) - id += tmp; - mir_free(tmp); - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - } - break; - case DBVT_BLOB: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - case DBVT_WCHAR: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - } - id += " contact_id "; - ZeroMemory(&dbv, sizeof(dbv)); - ZeroMemory(&dbcgs, sizeof(dbcgs)); - dbcgs.pValue = &dbv; - dbcgs.szModule = proto; - dbcgs.szSetting = uid; - CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); - switch(dbcgs.pValue->type) - { - case DBVT_DELETED: - continue; - break; - case DBVT_BYTE: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); - id += _id; - } - break; - case DBVT_WORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); - id += _id; - } - break; - case DBVT_DWORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); - id += _id; - } - break; - case DBVT_ASCIIZ: - { - id += dbcgs.pValue->pszVal; - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - } - break; - case DBVT_UTF8: - { - char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); - if(tmp[0]) - id += tmp; - mir_free(tmp); - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - } - break; - case DBVT_BLOB: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - case DBVT_WCHAR: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - } - std::string::size_type p1 = key.find("-----BEGIN PGP PUBLIC KEY BLOCK-----"); - if(p1 == std::string::npos) - continue; - p1 += strlen("-----BEGIN PGP PUBLIC KEY BLOCK-----"); - p1 ++; - id += '\n'; - key.insert(p1, id); - file<<key; - file<<std::endl; - exported_keys++; - } - if(file.is_open()) - file.close(); - char msg[512]; - mir_snprintf(msg, 511, "we have succesfully exported %d keys", exported_keys); - MessageBoxA(NULL, msg, Translate("Keys export result"), MB_OK); - return 0; -} - -INT_PTR ImportGpGKeys(WPARAM w, LPARAM l) -{ - TCHAR *p = GetFilePath(_T("Choose file to import keys from"), _T("*"), _T("Any file")); - if(!p || !p[0]) - { - delete [] p; - //TODO: handle error - return 1; - } - char *path = mir_t2a(p); - delete [] p; - std::ifstream file; - file.open(path, std::ios::in); - mir_free(path); - if(!file.is_open()) - return 1; //TODO: handle error - PROTOACCOUNT **accs; - int acc_count = 0, processed_keys = 0; - ProtoEnumAccounts(&acc_count, &accs); - char line[256]; - file.getline(line, 255); - if(!strstr(line, "-----BEGIN PGP PUBLIC KEY BLOCK-----")) - return 1; //TODO: handle error - std::string key, login, contact_id; - key += line; - key += '\n'; - while(file.is_open() && !file.eof()) - { - file.getline(line, 255); - key += line; - key += '\n'; - if(strstr(line, "-----END PGP PUBLIC KEY BLOCK-----")) - { //TODO: parse key - std::string::size_type p1 = 0, p2 = 0; - p1 = key.find("Comment: login "); - p1 += strlen("Comment: login "); - p2 = key.find(" contact_id "); - login = key.substr(p1, p2-p1); - p2 += strlen(" contact_id "); - p1 = key.find("\n", p2); - contact_id = key.substr(p2, p1-p2); - p1 = key.find("Comment: login "); - p2 = key.find("\n", p1); - p2++; - key.erase(p1, p2-p1); - std::string acc; - for(int i = 0; i < acc_count; i++) - { - if(acc.length()) - break; - const char * uid = (const char*)CallProtoService(accs[i]->szModuleName, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); - DBVARIANT dbv = {0}; - DBCONTACTGETSETTING dbcgs = {0}; - dbcgs.pValue = &dbv; - dbcgs.szModule = accs[i]->szModuleName; - dbcgs.szSetting = uid; - CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs); - std::string id; - switch(dbcgs.pValue->type) - { - case DBVT_DELETED: - continue; - break; - case DBVT_BYTE: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); - id += _id; - if(id == login) - acc = accs[i]->szModuleName; - } - break; - case DBVT_WORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); - id += _id; - if(id == login) - acc = accs[i]->szModuleName; - } - break; - case DBVT_DWORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); - id += _id; - if(id == login) - acc = accs[i]->szModuleName; - } - break; - case DBVT_ASCIIZ: - { - id += dbcgs.pValue->pszVal; - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - if(id == login) - acc = accs[i]->szModuleName; - } - break; - case DBVT_UTF8: - { - char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); - if(tmp[0]) - id += tmp; - mir_free(tmp); - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - if(id == login) - acc = accs[i]->szModuleName; - } - break; - case DBVT_BLOB: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - case DBVT_WCHAR: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - } - } - if(acc.length()) - { - const char * uid = (const char*)CallProtoService(acc.c_str(), PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); - for(HANDLE hContact = db_find_first(acc.c_str()); hContact; hContact = db_find_next(hContact, acc.c_str())) - { - DBVARIANT dbv = {0}; - DBCONTACTGETSETTING dbcgs = {0}; - dbcgs.pValue = &dbv; - dbcgs.szModule = acc.c_str(); - dbcgs.szSetting = uid; - CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); - std::string id; - bool found = false; - switch(dbcgs.pValue->type) - { - case DBVT_DELETED: - continue; - break; - case DBVT_BYTE: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); - id += _id; - if(id == contact_id) - found = true; - } - break; - case DBVT_WORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); - id += _id; - if(id == contact_id) - found = true; - } - break; - case DBVT_DWORD: - { - char _id[64]; - mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); - id += _id; - if(id == contact_id) - found = true; - } - break; - case DBVT_ASCIIZ: - { - id += dbcgs.pValue->pszVal; - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - if(id == contact_id) - found = true; - } - break; - case DBVT_UTF8: - { - char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); - if(tmp[0]) - id += tmp; - mir_free(tmp); - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - if(id == contact_id) - found = true; - } - break; - case DBVT_BLOB: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - case DBVT_WCHAR: - //TODO - CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); - break; - } - if(found) - { - wstring cmd; - TCHAR tmp2[MAX_PATH] = {0}; - TCHAR *ptmp; - string output; - DWORD exitcode; - { - HANDLE hcnt = hContact; - ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); - _tcscpy(tmp2, ptmp); - mir_free(ptmp); - _tcscat(tmp2, _T("\\")); - _tcscat(tmp2, _T("temporary_exported.asc")); - DeleteFile(tmp2); - wfstream f(tmp2, std::ios::out); - f<<toUTF16(key).c_str(); - f.close(); - cmd += _T(" --batch "); - cmd += _T(" --import \""); - cmd += tmp2; - cmd += _T("\""); - } - gpg_execution_params params; - pxResult result; - params.cmd = &cmd; - params.useless = ""; - params.out = &output; - params.code = &exitcode; - params.result = &result; - boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); - if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) - { - gpg_thread.~thread(); - TerminateProcess(params.hProcess, 1); - params.hProcess = NULL; - debuglog<<time_str()<<": GPG execution timed out, aborted\n"; - break; - } - if(result == pxNotFound) - break; - if(result == pxSuccess) - processed_keys++; - { - if(output.find("already in secret keyring") != string::npos) - { - MessageBox(0, _T("Key already in scret key ring."), _T("Info"), MB_OK); - DeleteFile(tmp2); - break; - } - char *tmp2; - string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); - string::size_type s2 = output.find(":", s); - tmp2 = new char [output.substr(s,s2-s).length()+1]; - strcpy(tmp2, output.substr(s,s2-s).c_str()); - mir_utf8decode(tmp2, 0); - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID", tmp2); - mir_free(tmp2); - s = output.find("“", s2); - if(s == string::npos) - { - s = output.find("\"", s2); - s += 1; - } - else - s += 3; - if((s2 = output.find("(", s)) == string::npos) - s2 = output.find("<", s); - else if(s2 > output.find("<", s)) - s2 = output.find("<", s); - if(s2 != string::npos) - { - tmp2 = new char [output.substr(s,s2-s-1).length()+1]; - strcpy(tmp2, output.substr(s,s2-s-1).c_str()); - mir_utf8decode(tmp2, 0); - if(hContact) - { - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str()); - } - mir_free(tmp2); - if((s = output.find(")", s2)) == string::npos) - s = output.find(">", s2); - else if(s > output.find(">", s2)) - s = output.find(">", s2); - s2++; - if(output[s] == ')') - { - tmp2 = new char [output.substr(s2,s-s2).length()+1]; - strcpy(tmp2, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp2, 0); - if(hContact) - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str()); - mir_free(tmp2); - s+=3; - s2 = output.find(">", s); - tmp2 = new char [output.substr(s,s2-s).length()+1]; - strcpy(tmp2, output.substr(s,s2-s).c_str()); - mir_utf8decode(tmp2, 0); - if(hContact) - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str()); - mir_free(tmp2); - } - else - { - tmp2 = new char [output.substr(s2,s-s2).length()+1]; - strcpy(tmp2, output.substr(s2,s-s2).c_str()); - mir_utf8decode(tmp2, 0); - if(hContact) - DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); - mir_free(tmp2); - } - } - DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); - DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", toUTF16(key).c_str()); - } - DeleteFile(tmp2); - break; - } - } - } - key.clear(); - } - } - if(file.is_open()) - file.close(); - char msg[512]; - mir_snprintf(msg, 511, "we have succesfully processed %d keys", processed_keys); - MessageBoxA(NULL, msg, Translate("Keys import result"), MB_OK); - return 0; -}
\ No newline at end of file +void strip_line_term(std::wstring &s) +{
+ for(std::wstring::size_type i = s.find(_T("\r")); i != std::wstring::npos; i = s.find(_T("\r"), i+1))
+ s.erase(i, 1);
+ for(std::wstring::size_type i = s.find(_T("\n")); i != std::wstring::npos; i = s.find(_T("\n"), i+1))
+ s.erase(i, 1);
+}
+
+void strip_line_term(std::string &s) +{
+ for(std::string::size_type i = s.find("\r"); i != std::string::npos; i = s.find("\r", i+1))
+ s.erase(i, 1);
+ for(std::string::size_type i = s.find("\n"); i != std::string::npos; i = s.find("\n", i+1))
+ s.erase(i, 1);
+}
diff --git a/plugins/New_GPG/src/utilities.h b/plugins/New_GPG/src/utilities.h index 30e9f68bb2..739495a48a 100755 --- a/plugins/New_GPG/src/utilities.h +++ b/plugins/New_GPG/src/utilities.h @@ -100,5 +100,9 @@ public: }
};
void HistoryLog(HANDLE, db_event);
+void fix_line_term(std::string &s);
+void fix_line_term(std::wstring &s);
+void strip_line_term(std::wstring &s);
+void strip_line_term(std::string &s);
#endif
|