From 7e0c7c426f9c8a453deef09c3d6679824af5f3d5 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 29 Dec 2013 19:55:04 +0000 Subject: preparing mmap_sa, that it finally compatible with new mmap git-svn-id: http://svn.miranda-ng.org/main/trunk@7415 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_mmap_SA/src/commonheaders.h | 111 +++++++ plugins/Dbx_mmap_SA/src/dbintf_sa.cpp | 256 ++++++++++++++++ plugins/Dbx_mmap_SA/src/dbintf_sa.h | 76 +++++ plugins/Dbx_mmap_SA/src/dialogs.cpp | 526 ++++++++++++++++++++++++++++++++ plugins/Dbx_mmap_SA/src/init.cpp | 152 +++++++++ plugins/Dbx_mmap_SA/src/options.h | 38 +++ plugins/Dbx_mmap_SA/src/resource.h | 54 ++++ plugins/Dbx_mmap_SA/src/security.cpp | 358 ++++++++++++++++++++++ plugins/Dbx_mmap_SA/src/stdafx.cpp | 18 ++ plugins/Dbx_mmap_SA/src/version.h | 14 + 10 files changed, 1603 insertions(+) create mode 100644 plugins/Dbx_mmap_SA/src/commonheaders.h create mode 100644 plugins/Dbx_mmap_SA/src/dbintf_sa.cpp create mode 100644 plugins/Dbx_mmap_SA/src/dbintf_sa.h create mode 100644 plugins/Dbx_mmap_SA/src/dialogs.cpp create mode 100644 plugins/Dbx_mmap_SA/src/init.cpp create mode 100644 plugins/Dbx_mmap_SA/src/options.h create mode 100644 plugins/Dbx_mmap_SA/src/resource.h create mode 100644 plugins/Dbx_mmap_SA/src/security.cpp create mode 100644 plugins/Dbx_mmap_SA/src/stdafx.cpp create mode 100644 plugins/Dbx_mmap_SA/src/version.h (limited to 'plugins/Dbx_mmap_SA/src') diff --git a/plugins/Dbx_mmap_SA/src/commonheaders.h b/plugins/Dbx_mmap_SA/src/commonheaders.h new file mode 100644 index 0000000000..f95ac242d8 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/commonheaders.h @@ -0,0 +1,111 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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. +*/ + +#define _CRT_SECURE_NO_WARNINGS + +#define _WIN32_WINNT 0x0501 + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +//own headers +#include "dbintf_sa.h" +#include "..\Db3x_mmap\src\database.h" +#include "resource.h" +#include "version.h" + +extern HINSTANCE g_hInst; +extern HGENMENU hSetPwdMenu; + +#ifdef __GNUC__ +#define mir_i64(x) (x##LL) +#else +#define mir_i64(x) (x##i64) +#endif + +//global procedures + +struct DlgStdInProcParam +{ + CDbxMmapSA *p_Db; + const TCHAR *pStr; +}; +INT_PTR CALLBACK DlgStdInProc(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam); + +struct DlgChangePassParam +{ + CDbxMmapSA *p_Db; + char *pszNewPass; +}; +INT_PTR CALLBACK DlgChangePass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam); + +INT_PTR CALLBACK DlgStdNewPass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +void xModifyMenu(HGENMENU hMenu,long flags,const TCHAR* name, HICON hIcon); + +extern DBSignature dbSignatureSecured, dbSignatureNonSecured; +extern DBSignature dbSignatureU, dbSignatureE, dbSignatureIM, dbSignatureSA; + +extern LIST g_Dbs; + +typedef struct{ + void* (__stdcall *GenerateKey)(char* pwd); + void (__stdcall *FreeKey)(void* key); + void (__stdcall *EncryptMem)(BYTE* data, int size, void* key); + void (__stdcall *DecryptMem)(BYTE* data, int size, void* key); + + char* Name; + char* Info; + char* Author; + char* Site; + char* Email; + + DWORD Version; + + WORD uid; +} Cryptor; + +typedef struct{ + TCHAR dllname[MAX_PATH]; + HMODULE hLib; + Cryptor* cryptor; +} CryptoModule; + +extern Cryptor* CryptoEngine; +extern void* key; diff --git a/plugins/Dbx_mmap_SA/src/dbintf_sa.cpp b/plugins/Dbx_mmap_SA/src/dbintf_sa.cpp new file mode 100644 index 0000000000..a06af08da7 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/dbintf_sa.cpp @@ -0,0 +1,256 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012-13 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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" + +#define NeedBytes(n) if(bytesRemaining<(n)) pBlob=(PBYTE)DBRead(ofsBlobPtr,(n),&bytesRemaining) +#define MoveAlong(n) {int x=n; pBlob+=(x); ofsBlobPtr+=(x); bytesRemaining-=(x);} +#define VLT(n) ((n==DBVT_UTF8)?DBVT_ASCIIZ:n) + +DBSignature dbSignatureSecured = { "Miranda ICQ SD", 0x1A }; +DBSignature dbSignatureNonSecured = { "Miranda ICQ SA", 0x1A }; + +CDbxMmapSA::CDbxMmapSA(const TCHAR* tszFileName) : + CDb3Base(tszFileName) +{ +} + +int CDbxMmapSA::Load(bool bSkipInit) +{ + if (CDb3Base::Load(bSkipInit) != ERROR_SUCCESS) + return 1; + + if (CheckDbHeaders()) + return 1; + + if (!bSkipInit) { + TCHAR* p = _tcsrchr(m_tszProfileName, '\\'); + if (!p) + return 1; + + if (m_bEncoding && !CheckPassword(LOWORD(m_dbHeader.version), p + 1)) + return 1; + + InitDialogs(); + } + + return 0; +} + +int CDbxMmapSA::CheckDbHeaders() +{ + if (memcmp(m_dbHeader.signature, &dbSignatureSecured, sizeof(m_dbHeader.signature)) == 0) + m_bEncoding = true; + else if (memcmp(m_dbHeader.signature, &dbSignatureNonSecured, sizeof(m_dbHeader.signature)) == 0) + m_bEncoding = false; + else { + m_bEncoding = false; + if (memcmp(m_dbHeader.signature, &dbSignatureIM, sizeof(m_dbHeader.signature))) + return EGROKPRF_UNKHEADER; + if (LOWORD(m_dbHeader.version) != 0x0700) + return EGROKPRF_VERNEWER; + } + if (m_dbHeader.ofsUser == 0) + return EGROKPRF_DAMAGED; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +static DWORD __inline GetSettingValueLength(PBYTE pSetting) +{ + if (pSetting[0] & DBVTF_VARIABLELENGTH) return 2 + *(PWORD)(pSetting + 1); + return pSetting[0]; +} + +void CDbxMmapSA::EncodeContactSettings(HANDLE hContact) +{ + if (!hContact) + hContact = (HANDLE)m_dbHeader.ofsUser; + + DBContact *contact = (DBContact *)DBRead((DWORD)hContact, sizeof(DBContact), NULL); + if (contact->ofsFirstSettings) { + DBContactSettings *setting = (struct DBContactSettings *)DBRead(contact->ofsFirstSettings, sizeof(struct DBContactSettings), NULL); + DWORD offset = contact->ofsFirstSettings; + while (true) { + DWORD ofsBlobPtr; + PBYTE pBlob; + int bytesRemaining; + DWORD len; + + ofsBlobPtr = offset + offsetof(struct DBContactSettings, blob); + pBlob = (PBYTE)DBRead(ofsBlobPtr, 1, &bytesRemaining); + while (pBlob[0]) { + NeedBytes(1); + NeedBytes(1 + pBlob[0]); + MoveAlong(1 + pBlob[0]); + + NeedBytes(5); + + switch (pBlob[0]) { + case DBVT_DELETED: break; + case DBVT_BYTE: break; + case DBVT_WORD: + CryptoEngine->EncryptMem(pBlob + 1, 2, key); + break; + + case DBVT_DWORD: + CryptoEngine->EncryptMem(pBlob + 1, 4, key); + break; + + case DBVT_UTF8: + case DBVT_ASCIIZ: + case DBVT_BLOB: + NeedBytes(3 + *(PWORD)(pBlob + 1)); + len = *(PWORD)(pBlob + 1); + + CryptoEngine->EncryptMem(pBlob + 3, len, key); + break; + } + NeedBytes(3); + MoveAlong(1 + GetSettingValueLength(pBlob)); + NeedBytes(1); + } + + if (!setting->ofsNext) + break; + + offset = setting->ofsNext; + setting = (struct DBContactSettings *)DBRead(setting->ofsNext, sizeof(struct DBContactSettings), NULL); + } + } +} + +void CDbxMmapSA::DecodeContactSettings(HANDLE hContact) +{ + if (!hContact) + hContact = (HANDLE)m_dbHeader.ofsUser; + + DBContact *contact = (DBContact *)DBRead((DWORD)hContact, sizeof(DBContact), NULL); + if (contact->ofsFirstSettings) { + DBContactSettings *setting = (struct DBContactSettings *)DBRead(contact->ofsFirstSettings, sizeof(struct DBContactSettings), NULL); + DWORD offset = contact->ofsFirstSettings; + while (true) { + DWORD ofsBlobPtr; + PBYTE pBlob; + int bytesRemaining; + DWORD len; + ofsBlobPtr = offset + offsetof(struct DBContactSettings, blob); + pBlob = (PBYTE)DBRead(ofsBlobPtr, 1, &bytesRemaining); + while (pBlob[0]) { + NeedBytes(1); + NeedBytes(1 + pBlob[0]); + MoveAlong(1 + pBlob[0]); + + NeedBytes(5); + + switch (pBlob[0]) { + case DBVT_DELETED: break; + case DBVT_BYTE: break; + case DBVT_WORD: + CryptoEngine->DecryptMem(pBlob + 1, 2, key); + break; + + case DBVT_DWORD: + CryptoEngine->DecryptMem(pBlob + 1, 4, key); + break; + + case DBVT_UTF8: + case DBVT_ASCIIZ: + case DBVT_BLOB: + NeedBytes(3 + *(PWORD)(pBlob + 1)); + len = *(PWORD)(pBlob + 1); + + CryptoEngine->DecryptMem(pBlob + 3, len, key); + break; + } + NeedBytes(3); + MoveAlong(1 + GetSettingValueLength(pBlob)); + NeedBytes(1); + } + + if (!setting->ofsNext) + break; + + offset = setting->ofsNext; + setting = (struct DBContactSettings *)DBRead(setting->ofsNext, sizeof(struct DBContactSettings), NULL); + } + } +} + +void CDbxMmapSA::EncodeEvent(HANDLE hEvent) +{ + DBEvent *dbe = (DBEvent*)DBRead((DWORD)hEvent, sizeof(DBEvent), NULL); + if (dbe->signature = DBEVENT_SIGNATURE) + CryptoEngine->EncryptMem(DBRead((DWORD)hEvent + offsetof(DBEvent, blob), dbe->cbBlob, NULL), dbe->cbBlob, key); +} + +void CDbxMmapSA::DecodeEvent(HANDLE hEvent) +{ + DBEvent *dbe = (DBEvent*)DBRead((DWORD)hEvent, sizeof(DBEvent), NULL); + if (dbe->signature = DBEVENT_SIGNATURE) + CryptoEngine->DecryptMem(DBRead((DWORD)hEvent + offsetof(DBEvent, blob), dbe->cbBlob, NULL), dbe->cbBlob, key); +} + +void CDbxMmapSA::EncodeContactEvents(HANDLE hContact) +{ + HANDLE hEvent = FindFirstEvent(hContact); + while (hEvent != 0) { + EncodeEvent(hEvent); + hEvent = FindNextEvent(hEvent); + } +} + +void CDbxMmapSA::DecodeContactEvents(HANDLE hContact) +{ + HANDLE hEvent = FindFirstEvent(hContact); + while (hEvent != 0) { + DecodeEvent(hEvent); + hEvent = FindNextEvent(hEvent); + } +} + +int CDbxMmapSA::WorkInitialCheckHeaders(void) +{ + if (m_bEncoding) { + cb->pfnAddLogMessage(STATUS_SUCCESS, TranslateT("Database is Secured MMAP database")); + + TCHAR* p = _tcsrchr(m_tszProfileName, '\\'); + if (!p) + return ERROR_BAD_FORMAT; + + if (!CheckPassword(LOWORD(m_dbHeader.version), p + 1)) { + cb->pfnAddLogMessage(STATUS_FATAL, TranslateT("You are not authorized for access to Database")); + return ERROR_BAD_FORMAT; + } + + cb->pfnAddLogMessage(STATUS_SUCCESS, TranslateT("Secured MMAP: authorization successful")); + } + + if (LOWORD(m_dbHeader.version) != 0x0700 && !m_bEncoding) { + cb->pfnAddLogMessage(STATUS_FATAL, TranslateT("Database is marked as belonging to an unknown version of Miranda")); + return ERROR_BAD_FORMAT; + } + + return ERROR_SUCCESS; +} diff --git a/plugins/Dbx_mmap_SA/src/dbintf_sa.h b/plugins/Dbx_mmap_SA/src/dbintf_sa.h new file mode 100644 index 0000000000..519e5c50bb --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/dbintf_sa.h @@ -0,0 +1,76 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012-13 Miranda NG project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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 + +#include "..\Db3x_mmap\src\dbintf.h" + +struct CDbxMmapSA : public CDb3Base +{ + CDbxMmapSA(const TCHAR* tszFileName); + + int CheckPassword(WORD checkWord, TCHAR *szDBName); + int CheckDbHeaders(void); + + void ChangePwd(); + void EncryptDB(); + void DecryptDB(); + void RecryptDB(); + + int Load(bool bSkipInit); + + bool m_bEncoding, bEncProcess; + +protected: + virtual void EncodeCopyMemory(void *dst, void *src, size_t size); + virtual void DecodeCopyMemory(void *dst, void *src, size_t size); + virtual void EncodeDBWrite(DWORD ofs, void *src, int size); + virtual void DecodeDBWrite(DWORD ofs, void *src, int size); + + virtual int WorkInitialCheckHeaders(void); + +protected: + int CheckProto(HANDLE hContact, const char *proto); + + void EncoderInit(); + void EncodeContactEvents(HANDLE hContact); + void EncodeEvent(HANDLE hEvent); + void DecodeEvent(HANDLE hEvent); + void DecodeContactEvents(HANDLE hContact); + + void DecodeContactSettings(HANDLE hContact); + void EncodeContactSettings(HANDLE hContact); + + void WritePlainHeader(); + void WriteCryptHeader(); + + void EncodeAll(); + void DecodeAll(); + +public: + char encryptKey[255]; + size_t encryptKeyLength; + +private: + void InitDialogs(void); +}; diff --git a/plugins/Dbx_mmap_SA/src/dialogs.cpp b/plugins/Dbx_mmap_SA/src/dialogs.cpp new file mode 100644 index 0000000000..b210f30628 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/dialogs.cpp @@ -0,0 +1,526 @@ +#include "commonheaders.h" +#include +#include +#include +#include + +#define MS_DB_CHANGEPASSWORD "DB/ChangePassword" + +extern LIST arCryptors; + +HGENMENU hSetPwdMenu; + +BOOL ShowDlgItem(HWND hwndDlg, int iIDCtrl, BOOL bShow) +{ + HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); + if (!hwndCtrl) return FALSE; + + // Avoid flickering + if (bShow && IsWindowVisible(hwndCtrl)) + return TRUE; + + return ShowWindow(hwndCtrl, (bShow ? SW_SHOW : SW_HIDE)); +} + +BOOL EnableDlgItem(HWND hwndDlg, int iIDCtrl, BOOL bEnable) +{ + HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); + if (!hwndCtrl) return FALSE; + + // Avoid flickering + if (IsWindowEnabled(hwndCtrl) == bEnable) + return (bEnable == FALSE); + + return EnableWindow(hwndCtrl, bEnable); +} + +BOOL IsDlgItemEnabled(HWND hwndDlg, int iIDCtrl) +{ + HWND hwndCtrl = GetDlgItem(hwndDlg, iIDCtrl); + if (!hwndCtrl) return FALSE; + return IsWindowEnabled(hwndCtrl); +} + +static int OptionsInit(void *obj, WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.position = -790000000; + odp.hInstance = g_hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.ptszTitle = LPGENT("Database Features"); + odp.ptszGroup = LPGENT("Database"); + odp.pfnDlgProc = DlgProcOptions; + odp.dwInitParam = (LPARAM)obj; + Options_AddPage(wParam, &odp); + return 0; +} + +INT_PTR ChangePassword(void* obj, LPARAM wParam, LPARAM lParam) +{ + CDbxMmapSA *p = (CDbxMmapSA*)obj; + + if (p->m_bEncoding) + p->ChangePwd(); + else + p->EncryptDB(); + + return 0; +} + +void xModifyMenu(HGENMENU hMenu, long flags, const TCHAR *name, HICON hIcon) +{ + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_FLAGS | CMIF_TCHAR; + mi.flags |= name ? CMIM_NAME : 0; + mi.flags |= hIcon ? CMIM_ICON : 0; + mi.flags |= flags; + mi.ptszName = (TCHAR*)name; + mi.hIcon = hIcon; + Menu_ModifyItem(hMenu, &mi); +} + +static IconItem iconList[] = +{ + { LPGEN("Database"), "database", IDI_ICON2 }, + { LPGEN("Change Password"), "password", IDI_ICON3 } +}; + +int InitMenus(void *obj, WPARAM, LPARAM) +{ + CDbxMmapSA *p = (CDbxMmapSA*)obj; + + HookEventObj(ME_OPT_INITIALISE, OptionsInit, obj); + + Icon_Register(g_hInst, LPGEN("Database"), iconList, SIZEOF(iconList)); + + // main menu item + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIM_ALL | CMIF_TCHAR; + mi.icolibItem = iconList[1].hIcolib; + mi.ptszName = (p->m_bEncoding) ? LPGENT("Change password") : LPGENT("Set password"); + mi.ptszPopupName = LPGENT("Database"); + mi.pszService = MS_DB_CHANGEPASSWORD; + mi.position = 500000000; + hSetPwdMenu = Menu_AddMainMenuItem(&mi); + return 0; +} + +void CDbxMmapSA::InitDialogs() +{ + HookEventObj(ME_SYSTEM_MODULESLOADED, InitMenus, this); + CreateServiceFunctionObj(MS_DB_CHANGEPASSWORD, ChangePassword, this); +} + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwndList = GetDlgItem(hwndDlg, IDC_MODULES); + CDbxMmapSA *p_Db = (CDbxMmapSA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + LVITEM item; + int i, iRow, iIndex; + NMLISTVIEW * hdr = (NMLISTVIEW *)lParam; + WORD uid; + + switch (msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + p_Db = (CDbxMmapSA*)lParam; + { + HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 0); + ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_OTHER_LOADED)); + ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_OTHER_NOTLOADED)); + ListView_SetImageList(hwndList, hIml, LVSIL_SMALL); + + LVCOLUMN col; + col.pszText = NULL; + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 50; + ListView_InsertColumn(hwndList, 1, &col); + + col.pszText = TranslateT("Dll"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 1000; + ListView_InsertColumn(hwndList, 2, &col); + + col.pszText = TranslateT("Name"); + col.cx = 1000; + ListView_InsertColumn(hwndList, 3, &col); + + col.pszText = TranslateT("Version"); + col.cx = 1000; + ListView_InsertColumn(hwndList, 4, &col); + } + + ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES); + + uid = db_get_w(NULL, "SecureMMAP", "CryptoModule", 0); + + for (i = 0; i < arCryptors.getCount(); i++) { + TCHAR buf[100]; + + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = NULL; + iRow = ListView_InsertItem(hwndList, &item); + + ListView_SetItemText(hwndList, iRow, 1, arCryptors[i]->dllname); + _tcsncpy(buf, _A2T(arCryptors[i]->cryptor->Name), SIZEOF(buf)); + ListView_SetItemText(hwndList, iRow, 2, buf); + mir_sntprintf(buf, SIZEOF(buf), _T("%d.%d.%d.%d"), HIBYTE(HIWORD(arCryptors[i]->cryptor->Version)), LOBYTE(HIWORD(arCryptors[i]->cryptor->Version)), HIBYTE(LOWORD(arCryptors[i]->cryptor->Version)), LOBYTE(LOWORD(arCryptors[i]->cryptor->Version))); + ListView_SetItemText(hwndList, iRow, 3, buf); + + if (uid == arCryptors[i]->cryptor->uid && p_Db->m_bEncoding) + ListView_SetCheckState(hwndList, i, 1); + + item.mask = LVIF_IMAGE; + item.iItem = iRow; + item.iSubItem = 0; + item.iImage = (CryptoEngine == arCryptors[i]->cryptor && p_Db->m_bEncoding) ? 0 : 1; + ListView_SetItem(hwndList, &item); + } + + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); + return TRUE; + + case WM_COMMAND: + if (HIWORD(wParam) == STN_CLICKED) { + switch (LOWORD(wParam)) { + case IDC_EMAIL: + case IDC_SITE: + char buf[512]; + char *p = &buf[7]; + lstrcpyA(buf, "mailto:"); + if (GetWindowTextA(GetDlgItem(hwndDlg, LOWORD(wParam)), p, SIZEOF(buf) - 7)) + CallService(MS_UTILS_OPENURL, 0, (LPARAM)(LOWORD(wParam) == IDC_EMAIL ? buf : p)); + break; + } + } + break; + + case WM_NOTIFY: + if (hdr && hdr->hdr.code == LVN_ITEMCHANGED && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1)) { + iIndex = hdr->iItem; + if (hdr->uNewState & 0x2000) { + for (i = 0; i < arCryptors.getCount(); i++) + if (i != iIndex) + ListView_SetCheckState(hwndList, i, 0); + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + if (hdr->uNewState & 0x1000) { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + if (hdr->uNewState & LVIS_SELECTED) { + SetDlgItemTextA(hwndDlg, IDC_AUTHOR, arCryptors[iIndex]->cryptor->Author); + { + TCHAR *info_t = mir_a2t((char*)(arCryptors[iIndex]->cryptor->Info)); + SetDlgItemText(hwndDlg, IDC_INFO, TranslateTS(info_t)); + mir_free(info_t); + } + SetDlgItemTextA(hwndDlg, IDC_SITE, arCryptors[iIndex]->cryptor->Site); + SetDlgItemTextA(hwndDlg, IDC_EMAIL, arCryptors[iIndex]->cryptor->Email); + SetDlgItemTextA(hwndDlg, IDC_ENC, arCryptors[iIndex]->cryptor->Name); + SetDlgItemInt(hwndDlg, IDC_UID, arCryptors[iIndex]->cryptor->uid, 0); + } + else { + SetDlgItemTextA(hwndDlg, IDC_AUTHOR, ""); + SetDlgItemTextA(hwndDlg, IDC_INFO, ""); + SetDlgItemTextA(hwndDlg, IDC_SITE, ""); + SetDlgItemTextA(hwndDlg, IDC_EMAIL, ""); + SetDlgItemTextA(hwndDlg, IDC_ENC, ""); + SetDlgItemTextA(hwndDlg, IDC_UID, ""); + } + + break; + } + if (((LPNMHDR)lParam)->code == PSN_APPLY) { + int alg = -1; + for (i = 0; i < arCryptors.getCount(); i++) { + if (ListView_GetCheckState(hwndList, i)) { + alg = i; + break; + } + } + + if (alg > -1) { + if (!p_Db->m_bEncoding) { + db_set_w(NULL, "SecureMMAP", "CryptoModule", arCryptors[alg]->cryptor->uid); + p_Db->EncryptDB(); + } + else { + if (arCryptors[alg]->cryptor->uid != db_get_w(NULL, "SecureMMAP", "CryptoModule", -1)) { + db_set_w(NULL, "SecureMMAP", "CryptoModule", arCryptors[alg]->cryptor->uid); + p_Db->RecryptDB(); + } + } + } + else if (p_Db->m_bEncoding) + p_Db->DecryptDB(); + + uid = db_get_w(NULL, "SecureMMAP", "CryptoModule", 0); + + for (i = 0; i < arCryptors.getCount(); i++) { + if (uid == arCryptors[i]->cryptor->uid && p_Db->m_bEncoding) + ListView_SetCheckState(hwndList, i, 1); + + item.mask = LVIF_IMAGE; + item.iItem = i; + item.iSubItem = 0; + item.iImage = (CryptoEngine == arCryptors[i]->cryptor && p_Db->m_bEncoding) ? 0 : 1; + + ListView_SetItem(hwndList, &item); + } + + return TRUE; + + } + break; + } + + return FALSE; +} + +UINT oldLangID = 0; +void LanguageChanged(HWND hDlg) +{ + UINT LangID = (UINT)GetKeyboardLayout(0); + char Lang[3] = { 0 }; + if (LangID != oldLangID) { + oldLangID = LangID; + GetLocaleInfoA(MAKELCID((LangID & 0xffffffff), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, Lang, 2); + Lang[0] = toupper(Lang[0]); + Lang[1] = tolower(Lang[1]); + SetDlgItemTextA(hDlg, IDC_LANG, Lang); + } +} + +extern BOOL wrongPass; + +INT_PTR CALLBACK DlgStdInProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + TCHAR tszHeaderTxt[256]; + + switch (uMsg) { + case WM_INITDIALOG: + TranslateDialogDefault(hDlg); + { + HICON hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, ICON_SMALL, (LPARAM)hIcon); + + DlgStdInProcParam *param = (DlgStdInProcParam*)lParam; + SetWindowLongPtr(hDlg, GWLP_USERDATA, (LPARAM)param->p_Db); + + if (!wrongPass) { + mir_sntprintf(tszHeaderTxt, SIZEOF(tszHeaderTxt), _T("%s\n%s"), TranslateT("Please type in your password for"), param->pStr); + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), tszHeaderTxt); + } + else { + if (wrongPass > 2) { + HWND hwndCtrl = GetDlgItem(hDlg, IDC_USERPASS); + EnableWindow(hwndCtrl, FALSE); + hwndCtrl = GetDlgItem(hDlg, IDOK); + EnableWindow(hwndCtrl, FALSE); + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Too many errors!")); + } + else SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is not correct!")); + } + } + oldLangID = 0; + SetTimer(hDlg, 1, 200, NULL); + LanguageChanged(hDlg); + return TRUE; + + case WM_CTLCOLORSTATIC: + if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) { + SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode((HDC)wParam, TRANSPARENT); + return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); + } + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + + case IDOK: + CDbxMmapSA *p_Db = (CDbxMmapSA*)GetWindowLongPtr(hDlg, GWLP_USERDATA); + p_Db->encryptKeyLength = GetDlgItemTextA(hDlg, IDC_USERPASS, p_Db->encryptKey, 254); + EndDialog(hDlg, IDOK); + } + break; + + case WM_TIMER: + LanguageChanged(hDlg); + return FALSE; + + case WM_DESTROY: + KillTimer(hDlg, 1); + DestroyIcon((HICON)SendMessage(hDlg, WM_GETICON, ICON_SMALL, 0)); + } + + return FALSE; +} + +INT_PTR CALLBACK DlgStdNewPass(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) { + case WM_INITDIALOG: + TranslateDialogDefault(hDlg); + SetWindowLongPtr(hDlg, GWLP_USERDATA, (LPARAM)lParam); + + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2))); + + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Please enter your new password")); + + oldLangID = 0; + SetTimer(hDlg, 1, 200, NULL); + LanguageChanged(hDlg); + return TRUE; + + case WM_CTLCOLORSTATIC: + if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) { + SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode((HDC)wParam, TRANSPARENT); + return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); + } + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + + case IDOK: + CDbxMmapSA *p_Db = (CDbxMmapSA*)GetWindowLongPtr(hDlg, GWLP_USERDATA); + char pass1[255], pass2[255]; + if (GetDlgItemTextA(hDlg, IDC_USERPASS1, pass1, 254) < 3) { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is too short!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + SetDlgItemTextA(hDlg, IDC_USERPASS1, ""); + SetDlgItemTextA(hDlg, IDC_USERPASS2, ""); + } + else { + GetDlgItemTextA(hDlg, IDC_USERPASS2, pass2, 254); + if (!strcmp(pass1, pass2)) { + p_Db->encryptKeyLength = strlen(pass1); + strcpy(p_Db->encryptKey, pass1); + EndDialog(hDlg, IDOK); + } + else { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Passwords do not match!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + SetDlgItemTextA(hDlg, IDC_USERPASS1, ""); + SetDlgItemTextA(hDlg, IDC_USERPASS2, ""); + } + } + } + break; + + case WM_TIMER: + LanguageChanged(hDlg); + return FALSE; + + case WM_DESTROY: + KillTimer(hDlg, 1); + DestroyIcon((HICON)SendMessage(hDlg, WM_GETICON, ICON_SMALL, 0)); + return FALSE; + } + return FALSE; +} + +INT_PTR CALLBACK DlgChangePass(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static char* newPass; + CDbxMmapSA *p_Db = (CDbxMmapSA*)GetWindowLongPtr(hDlg, GWLP_USERDATA); + + switch (uMsg) { + case WM_INITDIALOG: + TranslateDialogDefault(hDlg); + + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2))); + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Change password")); + { + DlgChangePassParam *param = (DlgChangePassParam*)lParam; + newPass = param->pszNewPass; + SetWindowLongPtr(hDlg, GWLP_USERDATA, (LPARAM)param->p_Db); + } + oldLangID = 0; + SetTimer(hDlg, 1, 200, NULL); + LanguageChanged(hDlg); + return TRUE; + + case WM_CTLCOLORSTATIC: + if ((HWND)lParam == GetDlgItem(hDlg, IDC_LANG)) { + SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode((HDC)wParam, TRANSPARENT); + return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT); + } + + return FALSE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + char pass1[255], pass2[255], oldpass[255]; + case IDOK: + GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); + if (strcmp(oldpass, p_Db->encryptKey)) { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Wrong password!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + break; + } + + if (GetDlgItemTextA(hDlg, IDC_NEWPASS1, pass1, 254) < 3) { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Password is too short!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + } + else { + GetDlgItemTextA(hDlg, IDC_NEWPASS2, pass2, 254); + if (!strcmp(pass1, pass2)) { + strcpy(newPass, pass1); + EndDialog(hDlg, IDOK); + } + else { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Passwords do not match!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + } + } + break; + + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + + case IDREMOVE: + GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); + if (strcmp(oldpass, p_Db->encryptKey)) { + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Wrong password!")); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_NCPAINT, 0, 0); + break; + } + EndDialog(hDlg, IDREMOVE); + } + break; + + case WM_TIMER: + LanguageChanged(hDlg); + return FALSE; + + case WM_DESTROY: + KillTimer(hDlg, 1); + DestroyIcon((HICON)SendMessage(hDlg, WM_GETICON, ICON_SMALL, 0)); + return FALSE; + } + return FALSE; +} diff --git a/plugins/Dbx_mmap_SA/src/init.cpp b/plugins/Dbx_mmap_SA/src/init.cpp new file mode 100644 index 0000000000..fffb7dd314 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/init.cpp @@ -0,0 +1,152 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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" + +void InitSecurity(void); +void UnloadSecurity(void); + +int hLangpack; + +HINSTANCE g_hInst = NULL; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE | STATIC_PLUGIN, + // {28FF9B91-3E4D-4F1C-B47C-C641B037FF40} + {0x28ff9b91, 0x3e4d, 0x4f1c, {0xb4, 0x7c, 0xc6, 0x41, 0xb0, 0x37, 0xff, 0x40}} +}; + +LIST g_Dbs(1, HandleKeySortT); + +///////////////////////////////////////////////////////////////////////////////////////// + +// returns 0 if the profile is created, EMKPRF* +static int makeDatabase(const TCHAR *profile) +{ + std::auto_ptr db(new CDbxMmapSA(profile)); + if (db->Create() == ERROR_SUCCESS) { + db->CreateDbHeaders(dbSignatureNonSecured); + return 0; + } + + return EMKPRF_CREATEFAILED; +} + +// returns 0 if the given profile has a valid header +static int grokHeader(const TCHAR *profile) +{ + std::auto_ptr db(new CDbxMmapSA(profile)); + if (db->Load(true) != ERROR_SUCCESS) + return EGROKPRF_CANTREAD; + + return db->CheckDbHeaders(); +} + +// returns 0 if all the APIs are injected otherwise, 1 +static MIDatabase* LoadDatabase(const TCHAR *profile) +{ + // set the memory, lists & UTF8 manager + mir_getLP(&pluginInfo); + + std::auto_ptr db(new CDbxMmapSA(profile)); + if (db->Load(false) != ERROR_SUCCESS) + return NULL; + + g_Dbs.insert(db.get()); + return db.release(); +} + +static int UnloadDatabase(MIDatabase* db) +{ + g_Dbs.remove((CDbxMmapSA*)db); + delete (CDbxMmapSA*)db; + return 0; +} + +MIDatabaseChecker* CheckDb(const TCHAR* profile, int *error) +{ + std::auto_ptr db(new CDbxMmapSA(profile)); + if (db->Load(true) != ERROR_SUCCESS) { + *error = EGROKPRF_CANTREAD; + return NULL; + } + + int chk = db->CheckDbHeaders(); + if (chk != ERROR_SUCCESS) { + *error = chk; + return NULL; + } + + *error = 0; + return db.release(); +} + +static DATABASELINK dblink = +{ + sizeof(DATABASELINK), + "dbx_mmap_sa", + _T("dbx secure mmap driver"), + makeDatabase, + grokHeader, + LoadDatabase, + UnloadDatabase, + CheckDb +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_DATABASE, MIID_LAST }; + +extern "C" __declspec(dllexport) int Load(void) +{ + InitSecurity(); + + RegisterDatabasePlugin(&dblink); + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + g_Dbs.destroy(); + UnloadSecurity(); + return 0; +} + +BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved) +{ + g_hInst = hInstDLL; + return TRUE; +} diff --git a/plugins/Dbx_mmap_SA/src/options.h b/plugins/Dbx_mmap_SA/src/options.h new file mode 100644 index 0000000000..efabf3eba5 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/options.h @@ -0,0 +1,38 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2003 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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 +#include +#include "resource.h" + +typedef enum { BT_DISABLED = 0, BT_START = 1, BT_EXIT = 2, BT_PERIODIC = 4} BackupType; +typedef enum { PT_DAYS, PT_HOURS, PT_MINUTES} PeriodType; + +typedef struct Options_tag { + int backup_types; + unsigned int period; + PeriodType period_type; + char folder[MAX_PATH]; + unsigned int num_backups; + BOOL disable_progress; +} Options; \ No newline at end of file diff --git a/plugins/Dbx_mmap_SA/src/resource.h b/plugins/Dbx_mmap_SA/src/resource.h new file mode 100644 index 0000000000..7b13f6957d --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/resource.h @@ -0,0 +1,54 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by db3x_mmap.rc +// +#define IDC_NOTOALL 3 +#define IDREMOVE 3 +#define IDD_OPTIONS 101 +#define IDD_INSTALLINI 235 +#define IDD_WARNINICHANGE 236 +#define IDD_INIIMPORTDONE 237 +#define IDD_LOGIN 269 +#define IDD_NEWPASS 270 +#define IDI_ICON2 271 +#define IDI_ICON3 272 +#define IDC_LANG 274 +#define IDD_CHANGEPASS 275 +#define IDC_ININAME 1333 +#define IDC_VIEWINI 1334 +#define IDC_SECURITYINFO 1335 +#define IDC_SETTINGNAME 1336 +#define IDC_NEWVALUE 1337 +#define IDC_WARNNOMORE 1338 +#define IDC_DELETE 1339 +#define IDC_RECYCLE 1340 +#define IDC_NEWNAME 1341 +#define IDC_MOVE 1342 +#define IDC_LEAVE 1343 +#define IDC_HEADERBAR 1657 +#define IDC_USERPASS 1658 +#define IDC_ENC 1659 +#define IDC_USERPASS1 1659 +#define IDC_OLDPASS 1660 +#define IDC_USERPASS2 1661 +#define IDC_NEWPASSINFO 1679 +#define IDC_MODULES 1680 +#define IDC_NEWPASSINFO2 1680 +#define IDC_INFO 1682 +#define IDC_AUTHOR 1683 +#define IDC_NEWPASS1 1683 +#define IDC_SITE 1684 +#define IDC_NEWPASS2 1684 +#define IDC_EMAIL 1685 +#define IDC_UID 1686 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 276 +#define _APS_NEXT_COMMAND_VALUE 40018 +#define _APS_NEXT_CONTROL_VALUE 1685 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/Dbx_mmap_SA/src/security.cpp b/plugins/Dbx_mmap_SA/src/security.cpp new file mode 100644 index 0000000000..eb997e1eb8 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/security.cpp @@ -0,0 +1,358 @@ +// (C) Artem Shpynov aka FYR and Igonin Vitaliy aka chaos.persei, 2007 - 2008 + +#include "commonheaders.h" + +int wrongPass = 0; +void* key; + +Cryptor* CryptoEngine = NULL; + +LIST arCryptors(1); + +void zero_fill(BYTE * pBuf, size_t bufSize) +{ + size_t i; + for (i = 0; i < bufSize; i++) + pBuf[i] = 0; +} + +void InitSecurity() +{ + Cryptor* (__stdcall *GetCryptor)(); + + TCHAR tszPath[MAX_PATH]; + GetModuleFileName(g_hInst, tszPath, SIZEOF(tszPath)); + TCHAR *p = _tcsrchr(tszPath, '\\')+1; _tcscpy(p, _T("cryptors\\*.dll")); + + WIN32_FIND_DATA fd; + HANDLE hFile = FindFirstFile(tszPath, &fd); + while (hFile != INVALID_HANDLE_VALUE) { + mir_sntprintf(p, MAX_PATH - (p-tszPath), _T("cryptors\\%s"), fd.cFileName); + HMODULE hLib = LoadLibrary(tszPath); + if (hLib) { + GetCryptor = (Cryptor* (__stdcall *)()) GetProcAddress(hLib, "GetCryptor"); + if (GetCryptor) { + CryptoModule* newItem = (CryptoModule*) malloc(sizeof(CryptoModule)); + newItem->cryptor = GetCryptor(); + _tcsncpy(newItem->dllname, fd.cFileName, MAX_PATH); + newItem->hLib = hLib; + arCryptors.insert(newItem); + } + else FreeLibrary(hLib); + } + if (!FindNextFile(hFile, &fd)) + break; + } +} + +void UnloadSecurity() +{ + if (CryptoEngine) + CryptoEngine->FreeKey(key); + + for (int i = 0; i < arCryptors.getCount(); i++) { + FreeLibrary(arCryptors[i]->hLib); + free(arCryptors[i]); + } + arCryptors.destroy(); +} + +void CDbxMmapSA::EncoderInit() +{ + if (!m_bEncoding) return; + + encryptKey[encryptKeyLength] = 0; + key = CryptoEngine->GenerateKey(encryptKey); +} + +void CDbxMmapSA::EncodeCopyMemory(void * dst, void * src, size_t size) +{ + memcpy(dst, src, size); + + if (m_bEncoding) + CryptoEngine->EncryptMem((BYTE *)dst, (int)size, key); +} + +void CDbxMmapSA::DecodeCopyMemory(void * dst, void * src, size_t size) +{ + memcpy(dst, src, size); + + if (m_bEncoding) + CryptoEngine->DecryptMem((BYTE *)dst, (int)size, key); +} + +void CDbxMmapSA::EncodeDBWrite(DWORD ofs, void *src, int size) +{ + if (m_bEncoding) { + BYTE *buf = (BYTE*)GlobalAlloc(GPTR, sizeof(BYTE)*size); + EncodeCopyMemory(buf, src, size); + DBWrite(ofs, buf, (int)size); + GlobalFree(buf); + } + else DBWrite(ofs, src, (int)size); +} + +void CDbxMmapSA::DecodeDBWrite(DWORD ofs, void *src, int size) +{ + if (m_bEncoding) { + BYTE *buf = (BYTE*)GlobalAlloc(GPTR, sizeof(BYTE)*size); + DecodeCopyMemory(buf, src, size); + DBWrite(ofs, buf, (int)size); + GlobalFree(buf); + } + else DBWrite(ofs, src, (int)size); +} + +int bCheckingPass = 0; + +int CDbxMmapSA::CheckPassword(WORD checkWord, TCHAR *szDBName) +{ + if (bCheckingPass) + return 0; + + bCheckingPass = 1; + + int Found = 0; + for (int i = 0; i < arCryptors.getCount(); i++) { + if (HIWORD(m_dbHeader.version) == arCryptors[i]->cryptor->uid) { + CryptoEngine = arCryptors[i]->cryptor; + Found = 1; + break; + } + } + if (!Found) { + MessageBox(0, TranslateT("Sorry, but your database encrypted with unknown module"), TranslateT("Error"), MB_OK | MB_ICONERROR); + bCheckingPass = 0; + return 0; + } + + while (1) { + DlgStdInProcParam param = { this, szDBName }; + int res = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_LOGIN), NULL, DlgStdInProc, (LPARAM)¶m); + if (res == IDCANCEL) { + wrongPass = 0; + bCheckingPass = 0; + return 0; + } + if (encryptKeyLength < 1) + continue; + + EncoderInit(); + + WORD ver; + DecodeCopyMemory(&ver, &checkWord, sizeof(checkWord)); + if (ver == 0x5195) { + wrongPass = 0; + bCheckingPass = 0; + return 1; + } + wrongPass++; + } + + bCheckingPass = 0; +} + +int SelectEncoder() +{ + if (arCryptors.getCount() == 0) { + MessageBox(0, TranslateT("Crypto modules not found"), TranslateT("Error"), MB_OK | MB_ICONERROR); + return 1; + } + + WORD uid = db_get_w(NULL, "SecureMMAP", "CryptoModule", 0); + if (uid != 0) { + for (int i = 0; i < arCryptors.getCount(); i++) { + if (arCryptors[i]->cryptor->uid == uid) { + CryptoEngine = arCryptors[i]->cryptor; + return 0; + } + } + } + + db_set_w(NULL, "SecureMMAP", "CryptoModule", arCryptors[0]->cryptor->uid); + CryptoEngine = arCryptors[0]->cryptor; + return 0; +} + +void CDbxMmapSA::EncodeAll() +{ + for (HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + EncodeContactEvents(hContact); + EncodeContactSettings(hContact); + } + + EncodeContactEvents(NULL); + EncodeContactSettings(NULL); +} + +void CDbxMmapSA::DecodeAll() +{ + for (HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + DecodeContactEvents(hContact); + DecodeContactSettings(hContact); + } + DecodeContactEvents(NULL); + DecodeContactSettings(NULL); +} + +void CDbxMmapSA::WritePlainHeader() +{ + DWORD bytesWritten; + + memcpy(m_dbHeader.signature, &dbSignatureNonSecured, sizeof(m_dbHeader.signature)); + SetFilePointer(m_hDbFile, 0, NULL, FILE_BEGIN); + WriteFile(m_hDbFile, m_dbHeader.signature, sizeof(m_dbHeader.signature), &bytesWritten, NULL); + + m_dbHeader.version = MAKELONG(0x0700, 0x0000); //no encryption + WriteFile(m_hDbFile, &m_dbHeader.version, sizeof(m_dbHeader.version), &bytesWritten, NULL); +} + +void CDbxMmapSA::WriteCryptHeader() +{ + DWORD bytesWritten; + + memcpy(m_dbHeader.signature, &dbSignatureSecured, sizeof(m_dbHeader.signature)); + SetFilePointer(m_hDbFile, 0, NULL, FILE_BEGIN); + WriteFile(m_hDbFile, m_dbHeader.signature, sizeof(m_dbHeader.signature), &bytesWritten, NULL); + + WORD checkWord = 0x5195, cryptWord; + EncodeCopyMemory(&cryptWord, &checkWord, sizeof(checkWord)); + m_dbHeader.version = MAKELONG(cryptWord, CryptoEngine->uid); + WriteFile(m_hDbFile, &m_dbHeader.version, sizeof(m_dbHeader.version), &bytesWritten, NULL); +} + +void CDbxMmapSA::EncryptDB() +{ + int action = 0; + if (bEncProcess) + return; + + if (memcmp(m_dbHeader.signature, &dbSignatureSecured, sizeof(m_dbHeader.signature)) == 0) { + MessageBox(0, TranslateT("DB is already secured!"), TranslateT("Error"), MB_OK | MB_ICONERROR); + return; + } + + if (SelectEncoder()) + return; + + bEncProcess = 1; + + action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_NEWPASS), NULL, DlgStdNewPass, (LPARAM)this); + if (action != IDOK || !strlen(encryptKey)) { + bEncProcess = 0; + db_set_b(NULL, "SecureMMAP", "CryptoModule", 0); + return; + } + + EnterCriticalSection(&m_csDbAccess); + + m_bEncoding = 1; + EncoderInit(); + + EncodeAll(); + + LeaveCriticalSection(&m_csDbAccess); + + WriteCryptHeader(); + + xModifyMenu(hSetPwdMenu, 0, LPGENT("Change Password"), 0); + + bEncProcess = 0; +} + +void CDbxMmapSA::DecryptDB() +{ + char oldKey[255]; + strcpy(oldKey, encryptKey); + + if (!CheckPassword(LOWORD(m_dbHeader.version), TranslateT("current database"))) { + strcpy(encryptKey, oldKey); + encryptKeyLength = strlen(oldKey); + return; + } + + WritePlainHeader(); + + EnterCriticalSection(&m_csDbAccess); + DecodeAll(); + LeaveCriticalSection(&m_csDbAccess); + + m_bEncoding = 0; + + zero_fill((BYTE *)encryptKey, sizeof encryptKey); + + xModifyMenu(hSetPwdMenu, 0, LPGENT("Set Password"), 0); + + db_set_w(NULL, "SecureMMAP", "CryptoModule", 0); + + CryptoEngine->FreeKey(key); + + CryptoEngine = NULL; +} + +void CDbxMmapSA::RecryptDB() +{ + EnterCriticalSection(&m_csDbAccess); + + DecodeAll(); + + CryptoEngine->FreeKey(key); + + SelectEncoder(); + + m_bEncoding = 1; + + EncoderInit(); + + EncodeAll(); + + WriteCryptHeader(); + + LeaveCriticalSection(&m_csDbAccess); +} + +void CDbxMmapSA::ChangePwd() +{ + char newpass[255] = { 0 }; + + DlgChangePassParam param = { this, newpass }; + int action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHANGEPASS), NULL, DlgChangePass, (LPARAM)¶m); + + if (action == IDCANCEL || (action == IDOK && !strlen(newpass))) + return; + + EnterCriticalSection(&m_csDbAccess); + + DecodeAll(); + + CryptoEngine->FreeKey(key); + + if (action == IDREMOVE) { + WritePlainHeader(); + + m_bEncoding = 0; + CryptoEngine = NULL; + db_set_w(NULL, "SecureMMAP", "CryptoModule", 0); + + zero_fill((BYTE *)encryptKey, sizeof encryptKey); + + xModifyMenu(hSetPwdMenu, 0, LPGENT("Set Password"), 0); + } + + if (action == IDOK) { + strcpy(encryptKey, newpass); + encryptKeyLength = strlen(newpass); + + m_bEncoding = 1; + + EncoderInit(); + + EncodeAll(); + + WriteCryptHeader(); + } + + zero_fill((BYTE *)newpass, sizeof newpass); + + LeaveCriticalSection(&m_csDbAccess); +} diff --git a/plugins/Dbx_mmap_SA/src/stdafx.cpp b/plugins/Dbx_mmap_SA/src/stdafx.cpp new file mode 100644 index 0000000000..e7e41dae3c --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/stdafx.cpp @@ -0,0 +1,18 @@ +/* +Copyright (C) 2012-13 Miranda NG Project (http://miranda-ng.org) + +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 version 2 +of the License. + +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, see . +*/ + +#include "commonheaders.h" \ No newline at end of file diff --git a/plugins/Dbx_mmap_SA/src/version.h b/plugins/Dbx_mmap_SA/src/version.h new file mode 100644 index 0000000000..c77ad2d7ed --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/version.h @@ -0,0 +1,14 @@ +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 7 +#define __RELEASE_NUM 5 +#define __BUILD_NUM 4 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM + +#define __PLUGIN_NAME "Miranda NG mmap secure database driver" +#define __FILENAME "Dbx_mmap_SA.dll" +#define __DESCRIPTION "Provides Miranda database support: global settings, contacts, history, settings per contact. Enhanced modification with Encryption support." +#define __AUTHOR "Miranda-IM project, modification by FYR and chaos.persei, nullbie, Billy_Bons" +#define __AUTHOREMAIL "chaos.persei@gmail.com; ashpynov@gmail.com; bio@msx.ru; ghazan@miranda.im" +#define __AUTHORWEB "http://miranda-ng.org/p/Dbx_mmap_SA/" +#define __COPYRIGHT "© 2000-2011 Miranda IM project, 2012 Miranda NG project FYR, chaos.persei, induction, nullbie" -- cgit v1.2.3