From 8f3e583fffeba6606cf4442008c65e6902308080 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 8 Jan 2021 17:55:06 +0300 Subject: encryption code unification, part 2: initialization & data storage --- include/m_db_int.h | 24 +++- libs/win32/mir_app.lib | Bin 215052 -> 217150 bytes libs/win64/mir_app.lib | Bin 210806 -> 212944 bytes plugins/Db3x_mmap/res/db3x_mmap.rc | 18 --- plugins/Db3x_mmap/src/dbcrypt.cpp | 176 +++++++---------------------- plugins/Db3x_mmap/src/dbintf.cpp | 1 + plugins/Db3x_mmap/src/dbintf.h | 11 +- plugins/Db3x_mmap/src/resource.h | 1 - plugins/Db3x_mmap/src/ui.cpp | 117 ++----------------- plugins/Dbx_mdbx/res/dbx_mdbx.rc | 14 --- plugins/Dbx_mdbx/src/dbcrypt.cpp | 185 +++++++------------------------ plugins/Dbx_mdbx/src/dbintf.cpp | 1 + plugins/Dbx_mdbx/src/dbintf.h | 12 +- plugins/Dbx_mdbx/src/resource.h | 1 - plugins/Dbx_mdbx/src/ui.cpp | 4 +- plugins/Dbx_sqlite/res/dbx_sqlite.rc | 14 --- plugins/Dbx_sqlite/src/dbcrypt.cpp | 58 ++++++++++ plugins/Dbx_sqlite/src/dbintf.cpp | 5 + plugins/Dbx_sqlite/src/dbintf.h | 8 +- plugins/Dbx_sqlite/src/resource.h | 1 - plugins/Import/src/dbrw/dbintf.h | 4 +- plugins/Import/src/dbrw/dbsettings.cpp | 10 -- src/mir_app/res/database.ico | Bin 0 -> 5430 bytes src/mir_app/res/resource.rc | 15 +++ src/mir_app/src/MDatabaseCommonCrypt.cpp | 130 +++++++++++++++++++++- src/mir_app/src/MDatabaseReadonly.cpp | 27 +++++ src/mir_app/src/ei_services.cpp | 9 +- src/mir_app/src/mir_app.def | 8 +- src/mir_app/src/mir_app64.def | 8 +- src/mir_app/src/resource.h | 6 +- 30 files changed, 393 insertions(+), 475 deletions(-) create mode 100644 src/mir_app/res/database.ico diff --git a/include/m_db_int.h b/include/m_db_int.h index 45440ff981..b4fef07719 100644 --- a/include/m_db_int.h +++ b/include/m_db_int.h @@ -175,7 +175,7 @@ class MIR_APP_EXPORT MDatabaseCommon : public MIDatabase, public MNonCopyable HANDLE m_hLock = nullptr; protected: - bool m_bEncrypted = false; + bool m_bEncrypted = false, m_bUsesPassword = false; int m_codePage; mir_cs m_csDbAccess; @@ -184,13 +184,24 @@ protected: MICryptoEngine *m_crypto; protected: + int CheckProto(DBCachedContact *cc, const char *proto); void FillContactSettings(); bool LockName(const wchar_t *pwszProfileName); - int CheckProto(DBCachedContact *cc, const char *proto); void UnlockName(); + //////////////////////////////////////////////////////////////////////////////////////// + // encryption support + + int InitCrypt(); + CRYPTO_PROVIDER* SelectProvider(); - STDMETHOD_(BOOL, StoreProvider)(CRYPTO_PROVIDER*); + STDMETHOD_(CRYPTO_PROVIDER*, ReadProvider)() PURE; + STDMETHOD_(BOOL, StoreProvider)(CRYPTO_PROVIDER*) PURE; + + STDMETHOD_(BOOL, ReadCryptoKey)(MBinBuffer&) PURE; + STDMETHOD_(BOOL, StoreCryptoKey)() PURE; + + STDMETHOD_(BOOL, ReadEncryption)() PURE; STDMETHOD_(BOOL, GetContactSettingWorker)(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic); STDMETHOD_(BOOL, WriteContactSettingWorker)(MCONTACT contactID, DBCONTACTWRITESETTING &dbcws) PURE; @@ -202,6 +213,7 @@ public: __forceinline bool isEncrypted() const { return m_bEncrypted; } __forceinline MICryptoEngine* getCrypt() const { return m_crypto; } __forceinline MIDatabaseCache* getCache() const { return m_cache; } + __forceinline bool usesPassword() const { return m_bUsesPassword; } STDMETHODIMP_(BOOL) DeleteModule(MCONTACT contactID, LPCSTR szModule) override; @@ -247,6 +259,12 @@ public: STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC, void*) override; + STDMETHODIMP_(CRYPTO_PROVIDER*) ReadProvider() override; + STDMETHODIMP_(BOOL) StoreProvider(CRYPTO_PROVIDER*) override; + STDMETHODIMP_(BOOL) ReadCryptoKey(MBinBuffer&) override; + STDMETHODIMP_(BOOL) StoreCryptoKey() override; + STDMETHODIMP_(BOOL) ReadEncryption() override; + //////////////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_(MCONTACT) AddContact(void) override; STDMETHODIMP_(LONG) DeleteContact(MCONTACT) override; diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib index 5e57edf393..1cc19b3133 100644 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index 6d5ddf644f..58bc02d3d9 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib differ diff --git a/plugins/Db3x_mmap/res/db3x_mmap.rc b/plugins/Db3x_mmap/res/db3x_mmap.rc index a2a65076cc..464f7aa8fb 100644 --- a/plugins/Db3x_mmap/res/db3x_mmap.rc +++ b/plugins/Db3x_mmap/res/db3x_mmap.rc @@ -23,20 +23,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_LOGIN DIALOGEX 0, 0, 190, 86 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW -CAPTION "Login to Miranda NG" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,190,26 - CTEXT "",IDC_LANG,158,34,13,13,SS_CENTERIMAGE | NOT WS_GROUP - EDITTEXT IDC_USERPASS,21,34,128,14,ES_PASSWORD | ES_AUTOHSCROLL | WS_GROUP - DEFPUSHBUTTON "OK",IDOK,36,64,50,14 - PUSHBUTTON "Cancel",IDCANCEL,102,64,50,14 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,0,55,190,1 -END - IDD_NEWPASS DIALOGEX 0, 0, 190, 102 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW @@ -94,10 +80,6 @@ END #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN - IDD_LOGIN, DIALOG - BEGIN - END - IDD_CHANGEPASS, DIALOG BEGIN END diff --git a/plugins/Db3x_mmap/src/dbcrypt.cpp b/plugins/Db3x_mmap/src/dbcrypt.cpp index 340464eed8..42a0cc57db 100644 --- a/plugins/Db3x_mmap/src/dbcrypt.cpp +++ b/plugins/Db3x_mmap/src/dbcrypt.cpp @@ -25,20 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ///////////////////////////////////////////////////////////////////////////////////////// -//VERY VERY VERY BASIC ENCRYPTION FUNCTION - -static void Encrypt(char *msg, BOOL up) -{ - int jump = (up) ? 5 : -5; - for (int i = 0; msg[i]; i++) - msg[i] = msg[i] + jump; -} - -__forceinline void DecodeString(LPSTR buf) -{ - Encrypt(buf, FALSE); -} - struct VarDescr { VarDescr(LPCSTR var, LPCSTR value) : @@ -63,138 +49,29 @@ struct VarDescr int iLen; }; -struct SettingUgraderParam -{ - CDb3Mmap *db; - LPCSTR szModule; - MCONTACT contactID; - OBJLIST* pList; -}; - -int sttSettingUgrader(const char *szSetting, void *lParam) -{ - SettingUgraderParam *param = (SettingUgraderParam*)lParam; - if (param->db->IsSettingEncrypted(param->szModule, szSetting)) { - DBVARIANT dbv = { DBVT_UTF8 }; - if (!param->db->GetContactSettingStr(param->contactID, param->szModule, szSetting, &dbv)) { - if (dbv.type == DBVT_UTF8) { - DecodeString(dbv.pszVal); - param->pList->insert(new VarDescr(szSetting, (LPCSTR)dbv.pszVal)); - } - param->db->FreeVariant(&dbv); - } - } - return 0; -} - -void sttContactEnum(MCONTACT contactID, const char *szModule, CDb3Mmap *db) -{ - OBJLIST arSettings(1); - SettingUgraderParam param = { db, szModule, contactID, &arSettings }; - db->EnumContactSettings(0, sttSettingUgrader, szModule, ¶m); - - for (auto &p : arSettings) { - size_t len; - BYTE *pResult = db->getCrypt()->encodeString(p->szValue, &len); - if (pResult != nullptr) { - DBCONTACTWRITESETTING dbcws = { szModule, p->szVar }; - dbcws.value.type = DBVT_ENCRYPTED; - dbcws.value.pbVal = pResult; - dbcws.value.cpbVal = (WORD)len; - db->WriteContactSetting(contactID, &dbcws); - - mir_free(pResult); - } - } -} - -int sttModuleEnum(const char *szModule, void *lParam) -{ - CDb3Mmap *db = (CDb3Mmap*)lParam; - sttContactEnum(0, szModule, db); - - for (MCONTACT contactID = db->FindFirstContact(); contactID; contactID = db->FindNextContact(contactID)) - sttContactEnum(contactID, szModule, db); - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - int CDb3Mmap::InitCrypt() { if (m_dbHeader.version == DB_OLD_VERSION) return 0; - CRYPTO_PROVIDER *pProvider; - bool bMissingKey = false; - - DBVARIANT dbv = { 0 }; - dbv.type = DBVT_BLOB; - if (GetContactSetting(0, "CryptoEngine", "Provider", &dbv)) { -LBL_CreateProvider: - pProvider = SelectProvider(); - if (pProvider == nullptr) - return 1; - } - else { - if (dbv.type != DBVT_BLOB) { // old version, clean it up - bMissingKey = true; - goto LBL_CreateProvider; - } - - pProvider = Crypto_GetProvider(LPCSTR(dbv.pbVal)); - FreeVariant(&dbv); - if (pProvider == nullptr) - goto LBL_CreateProvider; - } + return MDatabaseCommon::InitCrypt(); +} - if ((m_crypto = pProvider->pFactory()) == nullptr) - return 3; +///////////////////////////////////////////////////////////////////////////////////////// +// Saving encryption key in a database +STDMETHODIMP_(BOOL) CDb3Mmap::ReadCryptoKey(MBinBuffer &buf) +{ + DBVARIANT dbv = {}; dbv.type = DBVT_BLOB; - if (GetContactSetting(0, "CryptoEngine", "StoredKey", &dbv)) { - bMissingKey = true; - - LBL_SetNewKey: - m_crypto->generateKey(); // unencrypted key - StoreKey(); - } - else { - size_t iKeyLength = m_crypto->getKeyLength(); - if (dbv.cpbVal != (WORD)iKeyLength) - goto LBL_SetNewKey; - - if (!m_crypto->setKey(dbv.pbVal, iKeyLength)) { - if (memcmp(m_dbHeader.signature, &dbSignatureE, sizeof(m_dbHeader.signature))) - goto LBL_SetNewKey; - - if (!EnterPassword(dbv.pbVal, iKeyLength)) { // password protected? - if (m_dbHeader.version >= DB_094_VERSION) - return 4; - - // one of the early used version of mmap was replaced then by mmap_sa - // simply remove old badly generated key - bMissingKey = true; - goto LBL_SetNewKey; - } - } - - FreeVariant(&dbv); - } - - if (bMissingKey) - EnumModuleNames(sttModuleEnum, this); + if (GetContactSetting(0, "CryptoEngine", "StoredKey", &dbv)) + return FALSE; - dbv.type = DBVT_BYTE; - if (!GetContactSetting(0, "CryptoEngine", "DatabaseEncryption", &dbv)) - m_bEncrypted = dbv.bVal != 0; - - InitDialogs(); - return 0; + buf.append(dbv.pbVal, dbv.cpbVal); + return TRUE; } -void CDb3Mmap::StoreKey() +STDMETHODIMP_(BOOL) CDb3Mmap::StoreCryptoKey() { size_t iKeyLength = m_crypto->getKeyLength(); BYTE *pKey = (BYTE*)_alloca(iKeyLength); @@ -207,6 +84,35 @@ void CDb3Mmap::StoreKey() WriteContactSetting(0, &dbcws); SecureZeroMemory(pKey, iKeyLength); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Saving encryption flag + +STDMETHODIMP_(BOOL) CDb3Mmap::ReadEncryption() +{ + DBVARIANT dbv = {}; + dbv.type = DBVT_BYTE; + return (GetContactSetting(0, "CryptoEngine", "DatabaseEncryption", &dbv)) ? false : dbv.bVal != 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Saving provider in a database + +STDMETHODIMP_(CRYPTO_PROVIDER *) CDb3Mmap::ReadProvider() +{ + DBVARIANT dbv = {}; + dbv.type = DBVT_BLOB; + if (GetContactSetting(0, "CryptoEngine", "Provider", &dbv)) + return nullptr; + + if (dbv.type != DBVT_BLOB) + return nullptr; + + auto *pProvider = Crypto_GetProvider(LPCSTR(dbv.pbVal)); + FreeVariant(&dbv); + return pProvider; } STDMETHODIMP_(BOOL) CDb3Mmap::StoreProvider(CRYPTO_PROVIDER *pProvider) diff --git a/plugins/Db3x_mmap/src/dbintf.cpp b/plugins/Db3x_mmap/src/dbintf.cpp index cee46868a9..121d5a3d72 100644 --- a/plugins/Db3x_mmap/src/dbintf.cpp +++ b/plugins/Db3x_mmap/src/dbintf.cpp @@ -116,6 +116,7 @@ int CDb3Mmap::Load(bool bSkipInit) if (InitMap()) return 1; if (InitModuleNames()) return 1; if (InitCrypt()) return EGROKPRF_CANTREAD; + InitDialogs(); // everything is ok, go on if (!m_bReadOnly) { diff --git a/plugins/Db3x_mmap/src/dbintf.h b/plugins/Db3x_mmap/src/dbintf.h index ea3a99c364..81aca25423 100644 --- a/plugins/Db3x_mmap/src/dbintf.h +++ b/plugins/Db3x_mmap/src/dbintf.h @@ -193,7 +193,6 @@ struct CDb3Mmap : public MDatabaseCommon, public MZeroedObject int CheckDbHeaders(bool bInteractive); void ToggleEncryption(void); - void StoreKey(void); void SetPassword(const wchar_t *ptszPassword); void UpdateMenuItem(void); @@ -203,7 +202,6 @@ struct CDb3Mmap : public MDatabaseCommon, public MZeroedObject void WriteSignature(DBSignature&); __forceinline HANDLE getFile() const { return m_hDbFile; } - __forceinline bool usesPassword() const { return m_bUsesPassword; } public: STDMETHODIMP_(BOOL) IsRelational(void) override { return FALSE; } @@ -231,6 +229,12 @@ public: STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) override; + STDMETHODIMP_(BOOL) ReadCryptoKey(MBinBuffer&); + STDMETHODIMP_(BOOL) StoreCryptoKey(void); + + STDMETHODIMP_(BOOL) ReadEncryption(void); + + STDMETHODIMP_(CRYPTO_PROVIDER*) ReadProvider(); STDMETHODIMP_(BOOL) StoreProvider(CRYPTO_PROVIDER*); STDMETHODIMP_(BOOL) GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic) override; @@ -265,7 +269,7 @@ protected: HANDLE m_hDbFile; DBHeader m_dbHeader; DWORD m_ChunkSize; - bool m_safetyMode, m_bReadOnly, m_bShared, m_bUsesPassword; + bool m_safetyMode, m_bReadOnly, m_bShared; //////////////////////////////////////////////////////////////////////////// // database stuff @@ -322,5 +326,4 @@ protected: void ToggleSettingsEncryption(MCONTACT contactID); void InitDialogs(); - bool EnterPassword(const BYTE *pKey, const size_t keyLen); }; diff --git a/plugins/Db3x_mmap/src/resource.h b/plugins/Db3x_mmap/src/resource.h index f0734b5662..0f3113cc29 100644 --- a/plugins/Db3x_mmap/src/resource.h +++ b/plugins/Db3x_mmap/src/resource.h @@ -4,7 +4,6 @@ // #define IDREMOVE 3 #define IDI_LOGO 101 -#define IDD_LOGIN 102 #define IDD_NEWPASS 103 #define IDD_CHANGEPASS 104 #define IDD_OPTIONS 105 diff --git a/plugins/Db3x_mmap/src/ui.cpp b/plugins/Db3x_mmap/src/ui.cpp index 19e8a1c4f2..10c428b9fd 100644 --- a/plugins/Db3x_mmap/src/ui.cpp +++ b/plugins/Db3x_mmap/src/ui.cpp @@ -23,13 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" -struct DlgChangePassParam -{ - CDb3Mmap *db; - wchar_t newPass[100]; - int wrongPass; -}; - #define MS_DB_CHANGEPASSWORD "DB/UI/ChangePassword" static IconItem iconList[] = @@ -55,105 +48,6 @@ void LanguageChanged(HWND hwndDlg) ///////////////////////////////////////////////////////////////////////////////////////// -static INT_PTR CALLBACK sttEnterPassword(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - DlgChangePassParam *param = (DlgChangePassParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - - switch (uMsg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - SendDlgItemMessage(hwndDlg, IDC_HEADERBAR, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(iconList[0].defIconID))); - - param = (DlgChangePassParam*)lParam; - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - - if (param->wrongPass) { - if (param->wrongPass > 2) { - HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_USERPASS); - EnableWindow(hwndCtrl, FALSE); - hwndCtrl = GetDlgItem(hwndDlg, IDOK); - EnableWindow(hwndCtrl, FALSE); - SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Too many errors!")); - } - else SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Password is not correct!")); - } - else SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Please type in your password")); - - oldLangID = 0; - SetTimer(hwndDlg, 1, 200, nullptr); - LanguageChanged(hwndDlg); - return TRUE; - - case WM_CTLCOLORSTATIC: - if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_LANG)) { - SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkMode((HDC)wParam, TRANSPARENT); - return (INT_PTR)GetSysColorBrush(COLOR_HIGHLIGHT); - } - return FALSE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCANCEL: - EndDialog(hwndDlg, IDCANCEL); - break; - - case IDOK: - GetDlgItemText(hwndDlg, IDC_USERPASS, param->newPass, _countof(param->newPass)); - - if (Profile_GetSettingInt(L"Database/RememberPassword")) { - CREDENTIAL cred = { 0 }; - cred.Type = CRED_TYPE_GENERIC; - cred.TargetName = L"Miranda NG/Database"; - cred.CredentialBlobSize = DWORD(mir_wstrlen(param->newPass) * sizeof(wchar_t) + sizeof(wchar_t)); - cred.CredentialBlob = (LPBYTE)param->newPass; - cred.Persist = CRED_PERSIST_LOCAL_MACHINE; - CredWrite(&cred, 0); - } - - EndDialog(hwndDlg, IDOK); - } - break; - - case WM_TIMER: - LanguageChanged(hwndDlg); - return FALSE; - - case WM_DESTROY: - KillTimer(hwndDlg, 1); - DestroyIcon((HICON)SendMessage(hwndDlg, WM_GETICON, ICON_SMALL, 0)); - } - - return FALSE; -} - -bool CDb3Mmap::EnterPassword(const BYTE *pKey, const size_t keyLen) -{ - DlgChangePassParam param = { this }; - while (true) { - PCREDENTIAL pCred; - if (param.wrongPass == 0 && CredRead(L"Miranda NG/Dbx_mmap", CRED_TYPE_GENERIC, 0, &pCred)) { - m_crypto->setPassword(T2Utf((wchar_t*)pCred->CredentialBlob)); - CredFree(pCred); - } - else { - if (IDOK != DialogBoxParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_LOGIN), nullptr, sttEnterPassword, (LPARAM)¶m)) - return false; - m_crypto->setPassword(T2Utf(param.newPass)); - } - - if (m_crypto->setKey(pKey, keyLen)) { - m_bUsesPassword = true; - SecureZeroMemory(¶m, sizeof(param)); - return true; - } - - param.wrongPass++; - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - static bool CheckOldPassword(HWND hwndDlg, CDb3Mmap *db) { if (db->usesPassword()) { @@ -167,6 +61,13 @@ static bool CheckOldPassword(HWND hwndDlg, CDb3Mmap *db) return true; } +struct DlgChangePassParam +{ + CDb3Mmap *db; + wchar_t newPass[100]; + int wrongPass; +}; + static INT_PTR CALLBACK sttChangePassword(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { DlgChangePassParam *param = (DlgChangePassParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); @@ -209,7 +110,7 @@ static INT_PTR CALLBACK sttChangePassword(HWND hwndDlg, UINT uMsg, WPARAM wParam else { param->db->WriteSignature(dbSignatureU); param->db->SetPassword(nullptr); - param->db->StoreKey(); + param->db->StoreCryptoKey(); EndDialog(hwndDlg, IDREMOVE); } break; @@ -233,7 +134,7 @@ static INT_PTR CALLBACK sttChangePassword(HWND hwndDlg, UINT uMsg, WPARAM wParam param->db->WriteSignature(dbSignatureE); param->db->SetPassword(buf2); - param->db->StoreKey(); + param->db->StoreCryptoKey(); SecureZeroMemory(buf2, sizeof(buf2)); EndDialog(hwndDlg, IDOK); } diff --git a/plugins/Dbx_mdbx/res/dbx_mdbx.rc b/plugins/Dbx_mdbx/res/dbx_mdbx.rc index 61530296f2..83b1661322 100644 --- a/plugins/Dbx_mdbx/res/dbx_mdbx.rc +++ b/plugins/Dbx_mdbx/res/dbx_mdbx.rc @@ -23,20 +23,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_LOGIN DIALOGEX 0, 0, 190, 86 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW -CAPTION "Login to Miranda NG" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,190,26 - CTEXT "",IDC_LANG,158,34,13,13,SS_CENTERIMAGE | NOT WS_GROUP - EDITTEXT IDC_USERPASS,21,34,128,14,ES_PASSWORD | ES_AUTOHSCROLL | WS_GROUP - DEFPUSHBUTTON "OK",IDOK,36,64,50,14 - PUSHBUTTON "Cancel",IDCANCEL,102,64,50,14 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,0,55,190,1 -END - IDD_NEWPASS DIALOGEX 0, 0, 190, 102 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW diff --git a/plugins/Dbx_mdbx/src/dbcrypt.cpp b/plugins/Dbx_mdbx/src/dbcrypt.cpp index d20315b773..3ee4ce9fc6 100644 --- a/plugins/Dbx_mdbx/src/dbcrypt.cpp +++ b/plugins/Dbx_mdbx/src/dbcrypt.cpp @@ -27,155 +27,21 @@ char DBKey_Crypto_Provider[] = "Provider"; char DBKey_Crypto_Key[] = "Key"; char DBKey_Crypto_IsEncrypted[] = "EncryptedDB"; -STDMETHODIMP_(BOOL) CDbxMDBX::StoreProvider(CRYPTO_PROVIDER *pProv) -{ - txn_ptr trnlck(this); - MDBX_val key = { DBKey_Crypto_Provider, sizeof(DBKey_Crypto_Provider) }, value = { pProv->pszName, mir_strlen(pProv->pszName) + 1 }; - if (mdbx_put(trnlck, m_dbCrypto, &key, &value, MDBX_UPSERT) != MDBX_SUCCESS) - return FALSE; - - DBFlush(); - return TRUE; -} - ///////////////////////////////////////////////////////////////////////////////////////// +// Saving encryption key in a database -class CEnterPasswordDialog : public CDlgBase +STDMETHODIMP_(BOOL) CDbxMDBX::ReadCryptoKey(MBinBuffer &buf) { - friend class CDbxMDBX; - - CTimer m_timer; - CCtrlData m_header; - CCtrlData m_language; - CCtrlEdit m_passwordEdit; - - int m_wrongPass = 0; - wchar_t m_newPass[100]; - CDbxMDBX *m_db; - - void OnTimer(CTimer*) - { - UINT_PTR LangID = (UINT_PTR)GetKeyboardLayout(0); - char Lang[3] = { 0 }; - GetLocaleInfoA(MAKELCID((LangID & 0xffffffff), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, Lang, 2); - Lang[0] = toupper(Lang[0]); - Lang[1] = tolower(Lang[1]); - m_language.SetTextA(Lang); - } - - INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override - { - if (msg == WM_CTLCOLORSTATIC) { - if ((HWND)lParam == m_language.GetHwnd()) { - SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkMode((HDC)wParam, TRANSPARENT); - return (INT_PTR)GetSysColorBrush(COLOR_HIGHLIGHT); - } - } - return CDlgBase::DlgProc(msg, wParam, lParam); - } - -public: - CEnterPasswordDialog(CDbxMDBX *db) : - CDlgBase(g_plugin, IDD_LOGIN), - m_timer(this, 1), - m_header(this, IDC_HEADERBAR), - m_language(this, IDC_LANG), - m_passwordEdit(this, IDC_USERPASS), - m_db(db) - { - m_newPass[0] = 0; - m_timer.OnEvent = Callback(this, &CEnterPasswordDialog::OnTimer); - } - - bool OnInitDialog() override - { - m_header.SendMsg(WM_SETICON, ICON_SMALL, (LPARAM)g_plugin.getIcon(IDI_LOGO, true)); - - if (m_wrongPass) { - if (m_wrongPass > 2) { - m_passwordEdit.Disable(); - EnableWindow(GetDlgItem(m_hwnd, IDOK), false); - m_header.SetText(TranslateT("Too many errors!")); - } - else m_header.SetText(TranslateT("Password is not correct!")); - } - else m_header.SetText(TranslateT("Please type in your password")); - - m_timer.Start(200); - return true; - } - - bool OnApply() override - { - m_passwordEdit.GetText(m_newPass, _countof(m_newPass)); - return true; - } - - void OnDestroy() override - { - Window_FreeIcon_IcoLib(m_header.GetHwnd()); - } -}; - -int CDbxMDBX::InitCrypt() -{ - if (m_crypto != nullptr) - return 0; - - CRYPTO_PROVIDER *pProvider; - MDBX_val key = { DBKey_Crypto_Provider, sizeof(DBKey_Crypto_Provider) }, value; - + MDBX_val key = { DBKey_Crypto_Key, sizeof(DBKey_Crypto_Key) }, value; int rc = mdbx_get(StartTran(), m_dbCrypto, &key, &value); - if (rc == MDBX_SUCCESS) { - pProvider = Crypto_GetProvider((const char*)value.iov_base); - if (pProvider == nullptr) - pProvider = SelectProvider(); - } - else pProvider = SelectProvider(); - - if (pProvider == nullptr) - return 1; - - if ((m_crypto = pProvider->pFactory()) == nullptr) - return 3; - - key.iov_len = sizeof(DBKey_Crypto_Key); key.iov_base = DBKey_Crypto_Key; - rc = mdbx_get(StartTran(), m_dbCrypto, &key, &value); - if (rc == MDBX_SUCCESS && (value.iov_len == m_crypto->getKeyLength())) { - if (!m_crypto->setKey((const BYTE*)value.iov_base, value.iov_len)) { - CEnterPasswordDialog dlg(this); - while (true) { - if (!dlg.DoModal()) - return 4; - - m_crypto->setPassword(pass_ptrA(mir_utf8encodeW(dlg.m_newPass))); - if (m_crypto->setKey((const BYTE*)value.iov_base, value.iov_len)) { - m_bUsesPassword = true; - SecureZeroMemory(&dlg.m_newPass, sizeof(dlg.m_newPass)); - break; - } - dlg.m_wrongPass++; - } - } - } - else { - if (!m_crypto->generateKey()) - return 6; - StoreKey(); - } - - key.iov_len = sizeof(DBKey_Crypto_IsEncrypted); key.iov_base = DBKey_Crypto_IsEncrypted; - if (mdbx_get(StartTran(), m_dbCrypto, &key, &value) == MDBX_SUCCESS) - m_bEncrypted = *(const bool *)value.iov_base; - else - m_bEncrypted = false; + if (rc != MDBX_SUCCESS) + return FALSE; - InitDialogs(); - return 0; + buf.append(value.iov_base, value.iov_len); + return TRUE; } -void CDbxMDBX::StoreKey() +STDMETHODIMP_(BOOL) CDbxMDBX::StoreCryptoKey() { size_t iKeyLength = m_crypto->getKeyLength(); BYTE *pKey = (BYTE*)_alloca(iKeyLength); @@ -191,8 +57,43 @@ void CDbxMDBX::StoreKey() SecureZeroMemory(pKey, iKeyLength); DBFlush(); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Saving encryption flag + +STDMETHODIMP_(BOOL) CDbxMDBX::ReadEncryption() +{ + MDBX_val key = { DBKey_Crypto_IsEncrypted, sizeof(DBKey_Crypto_IsEncrypted) }, value; + if (mdbx_get(StartTran(), m_dbCrypto, &key, &value) == MDBX_SUCCESS) + return *(const bool *)value.iov_base; + return false; } +///////////////////////////////////////////////////////////////////////////////////////// +// Saving provider in a database + +STDMETHODIMP_(CRYPTO_PROVIDER *) CDbxMDBX::ReadProvider() +{ + MDBX_val key = { DBKey_Crypto_Provider, sizeof(DBKey_Crypto_Provider) }, value; + int rc = mdbx_get(StartTran(), m_dbCrypto, &key, &value); + return (rc == MDBX_SUCCESS) ? Crypto_GetProvider((const char *)value.iov_base) : nullptr; +} + +STDMETHODIMP_(BOOL) CDbxMDBX::StoreProvider(CRYPTO_PROVIDER *pProv) +{ + txn_ptr trnlck(this); + MDBX_val key = { DBKey_Crypto_Provider, sizeof(DBKey_Crypto_Provider) }, value = { pProv->pszName, mir_strlen(pProv->pszName) + 1 }; + if (mdbx_put(trnlck, m_dbCrypto, &key, &value, MDBX_UPSERT) != MDBX_SUCCESS) + return FALSE; + + DBFlush(); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////////////////// + void CDbxMDBX::SetPassword(const wchar_t *ptszPassword) { if (ptszPassword == nullptr || *ptszPassword == 0) { diff --git a/plugins/Dbx_mdbx/src/dbintf.cpp b/plugins/Dbx_mdbx/src/dbintf.cpp index a9d57566c2..69c09f265a 100644 --- a/plugins/Dbx_mdbx/src/dbintf.cpp +++ b/plugins/Dbx_mdbx/src/dbintf.cpp @@ -221,6 +221,7 @@ int CDbxMDBX::Load() if (InitModules()) return EGROKPRF_DAMAGED; if (InitCrypt()) return EGROKPRF_DAMAGED; + InitDialogs(); FillContacts(); FillSettings(); diff --git a/plugins/Dbx_mdbx/src/dbintf.h b/plugins/Dbx_mdbx/src/dbintf.h index 1003c31c7c..e4d542ae07 100644 --- a/plugins/Dbx_mdbx/src/dbintf.h +++ b/plugins/Dbx_mdbx/src/dbintf.h @@ -171,7 +171,7 @@ class CDbxMDBX : public MDatabaseCommon, public MIDatabaseChecker, public MZeroe // database stuff ptrW m_pwszProfileName; - bool m_safetyMode = true, m_bReadOnly, m_bUsesPassword; + bool m_safetyMode = true, m_bReadOnly; MDBX_env *m_env; MDBX_txn *m_pWriteTran; @@ -224,7 +224,6 @@ class CDbxMDBX : public MDatabaseCommon, public MIDatabaseChecker, public MZeroe MDBX_dbi m_dbCrypto; - int InitCrypt(void); void InitDialogs(); public: @@ -236,7 +235,6 @@ public: int EnableEncryption(bool bEnable); int Load(); int Map(); - void StoreKey(void); void SetPassword(const wchar_t *ptszPassword); int CheckEvents1(void); @@ -245,8 +243,6 @@ public: __forceinline LPSTR GetMenuTitle() const { return m_bUsesPassword ? (char*)LPGEN("Change/remove password") : (char*)LPGEN("Set password"); } - __forceinline bool usesPassword() const { return m_bUsesPassword; } - public: STDMETHODIMP_(BOOL) IsRelational(void) override { return TRUE; } STDMETHODIMP_(void) SetCacheSafetyMode(BOOL) override; @@ -281,8 +277,14 @@ public: STDMETHODIMP_(BOOL) MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) override; STDMETHODIMP_(BOOL) MetaRemoveSubHistory(DBCachedContact *ccSub) override; + STDMETHODIMP_(CRYPTO_PROVIDER*) ReadProvider(void); STDMETHODIMP_(BOOL) StoreProvider(CRYPTO_PROVIDER*); + STDMETHODIMP_(BOOL) ReadEncryption(void); + + STDMETHODIMP_(BOOL) ReadCryptoKey(MBinBuffer&); + STDMETHODIMP_(BOOL) StoreCryptoKey(void); + STDMETHODIMP_(BOOL) Compact(); STDMETHODIMP_(BOOL) Backup(const wchar_t*); diff --git a/plugins/Dbx_mdbx/src/resource.h b/plugins/Dbx_mdbx/src/resource.h index a6c8f8644e..c705e3ad15 100644 --- a/plugins/Dbx_mdbx/src/resource.h +++ b/plugins/Dbx_mdbx/src/resource.h @@ -4,7 +4,6 @@ // #define IDREMOVE 3 #define IDI_LOGO 101 -#define IDD_LOGIN 102 #define IDD_NEWPASS 103 #define IDD_CHANGEPASS 104 #define IDD_OPTIONS 105 diff --git a/plugins/Dbx_mdbx/src/ui.cpp b/plugins/Dbx_mdbx/src/ui.cpp index 6b7ce1fe83..f538d99c51 100644 --- a/plugins/Dbx_mdbx/src/ui.cpp +++ b/plugins/Dbx_mdbx/src/ui.cpp @@ -104,7 +104,7 @@ static INT_PTR CALLBACK sttChangePassword(HWND hwndDlg, UINT uMsg, WPARAM wParam else { // param->db->WriteSignature(dbSignatureU); param->db->SetPassword(nullptr); - param->db->StoreKey(); + param->db->StoreCryptoKey(); EndDialog(hwndDlg, IDREMOVE); } break; @@ -128,7 +128,7 @@ static INT_PTR CALLBACK sttChangePassword(HWND hwndDlg, UINT uMsg, WPARAM wParam // param->db->WriteSignature(dbSignatureE); param->db->SetPassword(buf2); - param->db->StoreKey(); + param->db->StoreCryptoKey(); SecureZeroMemory(buf2, sizeof(buf2)); EndDialog(hwndDlg, IDOK); } diff --git a/plugins/Dbx_sqlite/res/dbx_sqlite.rc b/plugins/Dbx_sqlite/res/dbx_sqlite.rc index 141e211876..7f2c2b022e 100644 --- a/plugins/Dbx_sqlite/res/dbx_sqlite.rc +++ b/plugins/Dbx_sqlite/res/dbx_sqlite.rc @@ -23,20 +23,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Dialog // -IDD_LOGIN DIALOGEX 0, 0, 190, 86 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW -CAPTION "Login to Miranda NG" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,190,26 - CTEXT "",IDC_LANG,158,34,13,13,SS_CENTERIMAGE | NOT WS_GROUP - EDITTEXT IDC_USERPASS,21,34,128,14,ES_PASSWORD | ES_AUTOHSCROLL | WS_GROUP - DEFPUSHBUTTON "OK",IDOK,36,64,50,14 - PUSHBUTTON "Cancel",IDCANCEL,102,64,50,14 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,0,55,190,1 -END - IDD_NEWPASS DIALOGEX 0, 0, 190, 102 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW diff --git a/plugins/Dbx_sqlite/src/dbcrypt.cpp b/plugins/Dbx_sqlite/src/dbcrypt.cpp index f0dca5a0bc..af4aa22682 100644 --- a/plugins/Dbx_sqlite/src/dbcrypt.cpp +++ b/plugins/Dbx_sqlite/src/dbcrypt.cpp @@ -1,5 +1,63 @@ #include "stdafx.h" +///////////////////////////////////////////////////////////////////////////////////////// +// Saving encryption key in a database + +STDMETHODIMP_(BOOL) CDbxSQLite::ReadCryptoKey(MBinBuffer &buf) +{ + DBVARIANT dbv = {}; + dbv.type = DBVT_BLOB; + if (GetContactSetting(0, "CryptoEngine", "StoredKey", &dbv)) + return FALSE; + + buf.append(dbv.pbVal, dbv.cpbVal); + return TRUE; +} + +STDMETHODIMP_(BOOL) CDbxSQLite::StoreCryptoKey() +{ + size_t iKeyLength = m_crypto->getKeyLength(); + BYTE *pKey = (BYTE*)_alloca(iKeyLength); + m_crypto->getKey(pKey, iKeyLength); + + DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "StoredKey" }; + dbcws.value.type = DBVT_BLOB; + dbcws.value.cpbVal = (WORD)iKeyLength; + dbcws.value.pbVal = pKey; + WriteContactSetting(0, &dbcws); + + SecureZeroMemory(pKey, iKeyLength); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Saving encryption flag + +STDMETHODIMP_(BOOL) CDbxSQLite::ReadEncryption() +{ + DBVARIANT dbv = {}; + dbv.type = DBVT_BYTE; + return (GetContactSetting(0, "CryptoEngine", "DatabaseEncryption", &dbv)) ? false : dbv.bVal != 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Saving provider in a database + +STDMETHODIMP_(CRYPTO_PROVIDER*) CDbxSQLite::ReadProvider() +{ + DBVARIANT dbv = {}; + dbv.type = DBVT_BLOB; + if (GetContactSetting(0, "CryptoEngine", "Provider", &dbv)) + return nullptr; + + if (dbv.type != DBVT_BLOB) + return nullptr; + + auto *pProvider = Crypto_GetProvider(LPCSTR(dbv.pbVal)); + FreeVariant(&dbv); + return pProvider; +} + STDMETHODIMP_(BOOL) CDbxSQLite::StoreProvider(CRYPTO_PROVIDER *pProvider) { DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "Provider" }; diff --git a/plugins/Dbx_sqlite/src/dbintf.cpp b/plugins/Dbx_sqlite/src/dbintf.cpp index 862ecdae75..9cc637103d 100755 --- a/plugins/Dbx_sqlite/src/dbintf.cpp +++ b/plugins/Dbx_sqlite/src/dbintf.cpp @@ -142,6 +142,11 @@ MDatabaseCommon* CDbxSQLite::Load(const wchar_t *profile, int readonly) CDbxSQLite *db = new CDbxSQLite(database); + if (!db->InitCrypt()) { + delete db; + return nullptr; + } + db->InitContacts(); db->InitSettings(); db->InitEvents(); diff --git a/plugins/Dbx_sqlite/src/dbintf.h b/plugins/Dbx_sqlite/src/dbintf.h index ca220289c0..88638623a5 100755 --- a/plugins/Dbx_sqlite/src/dbintf.h +++ b/plugins/Dbx_sqlite/src/dbintf.h @@ -91,7 +91,13 @@ public: STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) override; - STDMETHODIMP_(BOOL) StoreProvider(CRYPTO_PROVIDER*); + STDMETHODIMP_(BOOL) ReadCryptoKey(MBinBuffer&) override; + STDMETHODIMP_(BOOL) StoreCryptoKey() override; + + STDMETHODIMP_(CRYPTO_PROVIDER*) ReadProvider() override; + STDMETHODIMP_(BOOL) StoreProvider(CRYPTO_PROVIDER*) override; + + STDMETHODIMP_(BOOL) ReadEncryption() override; STDMETHODIMP_(BOOL) WriteContactSettingWorker(MCONTACT contactID, DBCONTACTWRITESETTING &dbcws) override; STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting) override; diff --git a/plugins/Dbx_sqlite/src/resource.h b/plugins/Dbx_sqlite/src/resource.h index 135f6899d0..9e2976c927 100644 --- a/plugins/Dbx_sqlite/src/resource.h +++ b/plugins/Dbx_sqlite/src/resource.h @@ -5,7 +5,6 @@ #define IDREMOVE 3 #define IDI_ICONPASS 100 #define IDI_LOGO 101 -#define IDD_LOGIN 102 #define IDD_NEWPASS 103 #define IDD_CHANGEPASS 104 #define IDD_OPTIONS 105 diff --git a/plugins/Import/src/dbrw/dbintf.h b/plugins/Import/src/dbrw/dbintf.h index 4749e8146d..cca3998246 100644 --- a/plugins/Import/src/dbrw/dbintf.h +++ b/plugins/Import/src/dbrw/dbintf.h @@ -90,7 +90,7 @@ struct TSqlMessage { HANDLE hDoneEvent; }; -struct CDbxSQLite : public MDatabaseCommon, public MZeroedObject +struct CDbxSQLite : public MDatabaseReadonly, public MZeroedObject { private: sqlite3 *m_sqlite; @@ -148,8 +148,6 @@ public: STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam) override; STDMETHODIMP_(BOOL) GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic) override; - STDMETHODIMP_(BOOL) WriteContactSettingWorker(MCONTACT contactID, DBCONTACTWRITESETTING &dbcws) override; - STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting) override; STDMETHODIMP_(BOOL) EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param) override; STDMETHODIMP_(BOOL) MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub) override; diff --git a/plugins/Import/src/dbrw/dbsettings.cpp b/plugins/Import/src/dbrw/dbsettings.cpp index b09f1675b6..615415dec6 100644 --- a/plugins/Import/src/dbrw/dbsettings.cpp +++ b/plugins/Import/src/dbrw/dbsettings.cpp @@ -148,16 +148,6 @@ STDMETHODIMP_(BOOL) CDbxSQLite::GetContactSettingWorker(MCONTACT contactID, LPCS return 0; } -STDMETHODIMP_(BOOL) CDbxSQLite::WriteContactSettingWorker(MCONTACT, DBCONTACTWRITESETTING&) -{ - return 1; -} - -STDMETHODIMP_(BOOL) CDbxSQLite::DeleteContactSetting(MCONTACT, LPCSTR, LPCSTR) -{ - return 1; -} - STDMETHODIMP_(BOOL) CDbxSQLite::EnumContactSettings(MCONTACT hContact, DBSETTINGENUMPROC pfnEnumProc, const char *szModule, void *param) { if (szModule == nullptr) diff --git a/src/mir_app/res/database.ico b/src/mir_app/res/database.ico new file mode 100644 index 0000000000..f49bbe83d6 Binary files /dev/null and b/src/mir_app/res/database.ico differ diff --git a/src/mir_app/res/resource.rc b/src/mir_app/res/resource.rc index 30b353082e..895593352c 100644 --- a/src/mir_app/res/resource.rc +++ b/src/mir_app/res/resource.rc @@ -890,6 +890,20 @@ BEGIN LTEXT "",IDC_CRYPTOPROVIDER_DESCR,17,29,197,14,NOT WS_GROUP END +IDD_LOGIN DIALOGEX 0, 0, 190, 86 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW +CAPTION "Login to Miranda NG" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,190,26 + CTEXT "",IDC_LANG,158,34,13,13,SS_CENTERIMAGE | NOT WS_GROUP + EDITTEXT IDC_USERPASS,21,34,128,14,ES_PASSWORD | ES_AUTOHSCROLL | WS_GROUP + DEFPUSHBUTTON "OK",IDOK,36,64,50,14 + PUSHBUTTON "Cancel",IDCANCEL,102,64,50,14 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,0,55,190,1 +END + ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO @@ -1338,6 +1352,7 @@ IDI_PASSWORD ICON "icon_password.ico" IDI_SOUND ICON "sound.ico" +IDI_DATABASE ICON "database.ico" ///////////////////////////////////////////////////////////////////////////// // diff --git a/src/mir_app/src/MDatabaseCommonCrypt.cpp b/src/mir_app/src/MDatabaseCommonCrypt.cpp index 0b3a135e46..10a3e21881 100644 --- a/src/mir_app/src/MDatabaseCommonCrypt.cpp +++ b/src/mir_app/src/MDatabaseCommonCrypt.cpp @@ -90,16 +90,11 @@ CRYPTO_PROVIDER* MDatabaseCommon::SelectProvider() return (StoreProvider(pProv)) ? pProv : nullptr; } -STDMETHODIMP_(BOOL) MDatabaseCommon::StoreProvider(CRYPTO_PROVIDER *) -{ - return FALSE; -} - ///////////////////////////////////////////////////////////////////////////////////////// BOOL MDatabaseCommon::IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting) { - if (!_strnicmp(szSetting, "password", 8)) return true; + if (!_strnicmp(szSetting, "password", 8)) return true; if (!mir_strcmp(szSetting, "NLProxyAuthPassword")) return true; if (!mir_strcmp(szSetting, "LNPassword")) return true; if (!mir_strcmp(szSetting, "FileProxyPassword")) return true; @@ -111,3 +106,126 @@ BOOL MDatabaseCommon::IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting) } return false; } + +///////////////////////////////////////////////////////////////////////////////////////// + +class CEnterPasswordDialog : public CDlgBase +{ + friend class MDatabaseCommon; + + CTimer m_timer; + CCtrlData m_header; + CCtrlData m_language; + CCtrlEdit m_passwordEdit; + + int m_wrongPass = 0; + wchar_t m_newPass[100]; + MDatabaseCommon *m_db; + + void OnTimer(CTimer*) + { + UINT_PTR LangID = (UINT_PTR)GetKeyboardLayout(0); + char Lang[3] = { 0 }; + GetLocaleInfoA(MAKELCID((LangID & 0xffffffff), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, Lang, 2); + Lang[0] = toupper(Lang[0]); + Lang[1] = tolower(Lang[1]); + m_language.SetTextA(Lang); + } + + INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override + { + if (msg == WM_CTLCOLORSTATIC) { + if ((HWND)lParam == m_language.GetHwnd()) { + SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode((HDC)wParam, TRANSPARENT); + return (INT_PTR)GetSysColorBrush(COLOR_HIGHLIGHT); + } + } + return CDlgBase::DlgProc(msg, wParam, lParam); + } + +public: + CEnterPasswordDialog(MDatabaseCommon *db) : + CDlgBase(g_plugin, IDD_LOGIN), + m_timer(this, 1), + m_header(this, IDC_HEADERBAR), + m_language(this, IDC_LANG), + m_passwordEdit(this, IDC_USERPASS), + m_db(db) + { + m_newPass[0] = 0; + m_timer.OnEvent = Callback(this, &CEnterPasswordDialog::OnTimer); + } + + bool OnInitDialog() override + { + m_header.SendMsg(WM_SETICON, ICON_SMALL, (LPARAM)g_plugin.getIcon(IDI_DATABASE, true)); + + if (m_wrongPass) { + if (m_wrongPass > 2) { + m_passwordEdit.Disable(); + EnableWindow(GetDlgItem(m_hwnd, IDOK), false); + m_header.SetText(TranslateT("Too many errors!")); + } + else m_header.SetText(TranslateT("Password is not correct!")); + } + else m_header.SetText(TranslateT("Please type in your password")); + + m_timer.Start(200); + return true; + } + + bool OnApply() override + { + m_passwordEdit.GetText(m_newPass, _countof(m_newPass)); + return true; + } + + void OnDestroy() override + { + Window_FreeIcon_IcoLib(m_header.GetHwnd()); + } +}; + +int MDatabaseCommon::InitCrypt() +{ + if (m_crypto != nullptr) + return 0; + + CRYPTO_PROVIDER *pProvider = ReadProvider(); + if (pProvider == nullptr) + pProvider = SelectProvider(); + if (pProvider == nullptr) + return 1; + + if ((m_crypto = pProvider->pFactory()) == nullptr) + return 3; + + MBinBuffer key; + BOOL bSuccess = ReadCryptoKey(key); + if (bSuccess && (key.length() == m_crypto->getKeyLength())) { + if (!m_crypto->setKey((const BYTE*)key.data(), key.length())) { + CEnterPasswordDialog dlg(this); + while (true) { + if (!dlg.DoModal()) + return 4; + + m_crypto->setPassword(pass_ptrA(mir_utf8encodeW(dlg.m_newPass))); + if (m_crypto->setKey((const BYTE*)key.data(), key.length())) { + m_bUsesPassword = true; + SecureZeroMemory(&dlg.m_newPass, sizeof(dlg.m_newPass)); + break; + } + dlg.m_wrongPass++; + } + } + } + else { + if (!m_crypto->generateKey()) + return 6; + StoreCryptoKey(); + } + + m_bEncrypted = ReadEncryption(); + return 0; +} diff --git a/src/mir_app/src/MDatabaseReadonly.cpp b/src/mir_app/src/MDatabaseReadonly.cpp index 7490eff643..a1fef48769 100644 --- a/src/mir_app/src/MDatabaseReadonly.cpp +++ b/src/mir_app/src/MDatabaseReadonly.cpp @@ -44,6 +44,33 @@ BOOL MDatabaseReadonly::EnumModuleNames(DBMODULEENUMPROC, void*) ///////////////////////////////////////////////////////////////////////////////////////// +STDMETHODIMP_(BOOL) MDatabaseReadonly::ReadCryptoKey(MBinBuffer&) +{ + return FALSE; +} + +STDMETHODIMP_(BOOL) MDatabaseReadonly::StoreCryptoKey() +{ + return FALSE; +} + +STDMETHODIMP_(CRYPTO_PROVIDER*) MDatabaseReadonly::ReadProvider() +{ + return nullptr; +} + +STDMETHODIMP_(BOOL) MDatabaseReadonly::StoreProvider(CRYPTO_PROVIDER *) +{ + return FALSE; +} + +STDMETHODIMP_(BOOL) MDatabaseReadonly::ReadEncryption() +{ + return FALSE; +} + +///////////////////////////////////////////////////////////////////////////////////////// + MCONTACT MDatabaseReadonly::AddContact(void) { return 0; diff --git a/src/mir_app/src/ei_services.cpp b/src/mir_app/src/ei_services.cpp index d44a310d09..c891ef3f7a 100644 --- a/src/mir_app/src/ei_services.cpp +++ b/src/mir_app/src/ei_services.cpp @@ -465,10 +465,11 @@ MIR_APP_DLL(int) ExtraIcon_Clear(HANDLE hExtraIcon, MCONTACT hContact) static IconItem iconList[] = { - { LPGEN("Chat activity"), "ChatActivity", IDI_CHAT }, - { LPGEN("Mute chat"), "ChatMute", IDI_OFF }, - { LPGEN("Male"), "gender_male", IDI_MALE }, - { LPGEN("Female"), "gender_female", IDI_FEMALE } + { LPGEN("Chat activity"), "ChatActivity", IDI_CHAT }, + { LPGEN("Mute chat"), "ChatMute", IDI_OFF }, + { LPGEN("Male"), "gender_male", IDI_MALE }, + { LPGEN("Female"), "gender_female", IDI_FEMALE }, + { LPGEN("Database"), "database", IDI_DATABASE }, }; void LoadExtraIconsModule() diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 70dc5372b8..8e4c4994c5 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -757,7 +757,13 @@ _Netlib_GetTlsUnique@8 @831 NONAME ?getCrypt@MDatabaseCommon@@QBEPAUMICryptoEngine@@XZ @845 NONAME ?isEncrypted@MDatabaseCommon@@QBE_NXZ @846 NONAME ?SelectProvider@MDatabaseCommon@@IAEPAUCRYPTO_PROVIDER@@XZ @847 NONAME -?StoreProvider@MDatabaseCommon@@MAGHPAUCRYPTO_PROVIDER@@@Z @848 NONAME +?StoreProvider@MDatabaseReadonly@@UAGHPAUCRYPTO_PROVIDER@@@Z @848 NONAME ?Crypto_GetProvider@@YGPAUCRYPTO_PROVIDER@@PBD@Z @849 NONAME ?Crypto_ListProviders@@YGXPAHPAPAPAUCRYPTO_PROVIDER@@@Z @850 NONAME ?Crypto_RegisterEngine@@YGXPBUCRYPTO_PROVIDER@@@Z @851 NONAME +?InitCrypt@MDatabaseCommon@@IAEHXZ @852 NONAME +?ReadCryptoKey@MDatabaseReadonly@@UAGHAAVMBinBuffer@@@Z @853 NONAME +?ReadEncryption@MDatabaseReadonly@@UAGHXZ @854 NONAME +?ReadProvider@MDatabaseReadonly@@UAGPAUCRYPTO_PROVIDER@@XZ @855 NONAME +?StoreCryptoKey@MDatabaseReadonly@@UAGHXZ @856 NONAME +?usesPassword@MDatabaseCommon@@QBE_NXZ @857 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 804cbf7c55..f9f3d0e791 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -757,7 +757,13 @@ Netlib_GetTlsUnique @831 NONAME ?getCrypt@MDatabaseCommon@@QEBAPEAUMICryptoEngine@@XZ @845 NONAME ?isEncrypted@MDatabaseCommon@@QEBA_NXZ @846 NONAME ?SelectProvider@MDatabaseCommon@@IEAAPEAUCRYPTO_PROVIDER@@XZ @847 NONAME -?StoreProvider@MDatabaseCommon@@MEAAHPEAUCRYPTO_PROVIDER@@@Z @848 NONAME +?StoreProvider@MDatabaseReadonly@@UEAAHPEAUCRYPTO_PROVIDER@@@Z @848 NONAME ?Crypto_GetProvider@@YAPEAUCRYPTO_PROVIDER@@PEBD@Z @849 NONAME ?Crypto_ListProviders@@YAXPEAHPEAPEAPEAUCRYPTO_PROVIDER@@@Z @850 NONAME ?Crypto_RegisterEngine@@YAXPEBUCRYPTO_PROVIDER@@@Z @851 NONAME +?InitCrypt@MDatabaseCommon@@IEAAHXZ @852 NONAME +?ReadCryptoKey@MDatabaseReadonly@@UEAAHAEAVMBinBuffer@@@Z @853 NONAME +?ReadEncryption@MDatabaseReadonly@@UEAAHXZ @854 NONAME +?ReadProvider@MDatabaseReadonly@@UEAAPEAUCRYPTO_PROVIDER@@XZ @855 NONAME +?StoreCryptoKey@MDatabaseReadonly@@UEAAHXZ @856 NONAME +?usesPassword@MDatabaseCommon@@QEBA_NXZ @857 NONAME diff --git a/src/mir_app/src/resource.h b/src/mir_app/src/resource.h index 9784e98b46..c4fb0e3a94 100644 --- a/src/mir_app/src/resource.h +++ b/src/mir_app/src/resource.h @@ -29,6 +29,8 @@ #define IDD_OPT_CHAT_EVENTS 120 #define IDD_AUTHREQ 121 #define IDD_SELECT_CRYPTOPROVIDER 122 +#define IDD_LOGIN 123 +#define IDI_DATABASE 124 #define IDD_DETAILS 125 #define IDD_HISTORY 127 #define IDI_AWAY 128 @@ -351,8 +353,10 @@ #define IDC_USESPECIFIC 1212 #define IDC_FILEDIR 1213 #define IDC_TRANSFERCOMPLETED 1214 +#define IDC_LANG 1215 +#define IDC_USERPASS 1216 #define IDC_ALLFILESPROGRESS 1217 -#define IDC_WHITERECT 1221 +#define IDC_WHITERECT 1220 #define IDC_ALLSPEED 1221 #define IDC_FIRSTNAME 1224 #define IDC_LASTNAME 1225 -- cgit v1.2.3