From b81bd804e435e76592f9f281b717c696c3618fa2 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 15 Mar 2015 15:30:03 +0000 Subject: initial release git-svn-id: http://svn.miranda-ng.org/main/trunk@12409 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_kv/src/dbcrypt.cpp | 263 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 plugins/Dbx_kv/src/dbcrypt.cpp (limited to 'plugins/Dbx_kv/src/dbcrypt.cpp') diff --git a/plugins/Dbx_kv/src/dbcrypt.cpp b/plugins/Dbx_kv/src/dbcrypt.cpp new file mode 100644 index 0000000000..b79639fa61 --- /dev/null +++ b/plugins/Dbx_kv/src/dbcrypt.cpp @@ -0,0 +1,263 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org) +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" + +///////////////////////////////////////////////////////////////////////////////////////// + +//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) : + szVar(mir_strdup(var)), + szValue(mir_strdup(value)) + {} + + VarDescr(LPCSTR var, LPSTR value) : + szVar(mir_strdup(var)), + szValue(value) + {} + + VarDescr(LPCSTR var, PBYTE value, int len) : + szVar(mir_strdup(var)), + szValue((char*)memcpy(mir_alloc(len), value, len)), + iLen(len) + {} + + ptrA szVar, szValue; + int iLen; +}; + +struct SettingUgraderParam +{ + CDbxKV *db; + LPCSTR szModule; + MCONTACT contactID; + OBJLIST* pList; +}; + +int sttSettingUgrader(const char *szSetting, LPARAM 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, CDbxKV *db) +{ + OBJLIST arSettings(1); + SettingUgraderParam param = { db, szModule, contactID, &arSettings }; + + DBCONTACTENUMSETTINGS dbces = { 0 }; + dbces.pfnEnumProc = sttSettingUgrader; + dbces.szModule = szModule; + dbces.lParam = (LPARAM)¶m; + db->EnumContactSettings(NULL, &dbces); + + for (int i = 0; i < arSettings.getCount(); i++) { + VarDescr &p = arSettings[i]; + + size_t len; + BYTE *pResult = db->m_crypto->encodeString(p.szValue, &len); + if (pResult != NULL) { + 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, DWORD, LPARAM lParam) +{ + CDbxKV *db = (CDbxKV*)lParam; + sttContactEnum(NULL, szModule, db); + + for (MCONTACT contactID = db->FindFirstContact(); contactID; contactID = db->FindNextContact(contactID)) + sttContactEnum(contactID, szModule, db); + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int CDbxKV::InitCrypt() +{ + CRYPTO_PROVIDER *pProvider; + bool bMissingKey = false; + + DBVARIANT dbv = { 0 }; + dbv.type = DBVT_BLOB; + if (GetContactSetting(NULL, "CryptoEngine", "Provider", &dbv)) { + LBL_CreateProvider: + CRYPTO_PROVIDER **ppProvs; + int iNumProvs; + Crypto_EnumProviders(&iNumProvs, &ppProvs); + if (iNumProvs == 0) + return 1; + + pProvider = ppProvs[0]; //!!!!!!!!!!!!!!!!!! + + DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "Provider" }; + dbcws.value.type = DBVT_BLOB; + dbcws.value.pbVal = (PBYTE)pProvider->pszName; + dbcws.value.cpbVal = (int)strlen(pProvider->pszName) + 1; + WriteContactSetting(NULL, &dbcws); + } + 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 == NULL) + goto LBL_CreateProvider; + } + + if ((m_crypto = pProvider->pFactory()) == NULL) + return 3; + + dbv.type = DBVT_BLOB; + if (GetContactSetting(NULL, "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 (!EnterPassword(dbv.pbVal, iKeyLength)) // password protected? + return 4; + + FreeVariant(&dbv); + } + + if (bMissingKey) + EnumModuleNames(sttModuleEnum, this); + + dbv.type = DBVT_BYTE; + if (!GetContactSetting(NULL, "CryptoEngine", "DatabaseEncryption", &dbv)) + m_bEncrypted = dbv.bVal != 0; + + InitDialogs(); + return 0; +} + +void CDbxKV::StoreKey() +{ + 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(NULL, &dbcws); + + SecureZeroMemory(pKey, iKeyLength); +} + +void CDbxKV::SetPassword(LPCTSTR ptszPassword) +{ + if (ptszPassword == NULL || *ptszPassword == 0) { + m_bUsesPassword = false; + m_crypto->setPassword(NULL); + } + else { + m_bUsesPassword = true; + m_crypto->setPassword(ptrA(mir_utf8encodeT(ptszPassword))); + } + UpdateMenuItem(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CDbxKV::ToggleEncryption() +{ + HANDLE hSave1 = hSettingChangeEvent; hSettingChangeEvent = NULL; + HANDLE hSave2 = hEventAddedEvent; hEventAddedEvent = NULL; + HANDLE hSave3 = hEventDeletedEvent; hEventDeletedEvent = NULL; + HANDLE hSave4 = hEventFilterAddedEvent; hEventFilterAddedEvent = NULL; + + mir_cslock lck(m_csDbAccess); + ToggleSettingsEncryption(NULL); + ToggleEventsEncryption(NULL); + + for (MCONTACT contactID = FindFirstContact(); contactID; contactID = FindNextContact(contactID)) { + ToggleSettingsEncryption(contactID); + ToggleEventsEncryption(contactID); + } + + m_bEncrypted = !m_bEncrypted; + + DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "DatabaseEncryption" }; + dbcws.value.type = DBVT_BYTE; + dbcws.value.bVal = m_bEncrypted; + WriteContactSetting(NULL, &dbcws); + + hSettingChangeEvent = hSave1; + hEventAddedEvent = hSave2; + hEventDeletedEvent = hSave3; + hEventFilterAddedEvent = hSave4; +} + +void CDbxKV::ToggleSettingsEncryption(MCONTACT contactID) +{ +} + +void CDbxKV::ToggleEventsEncryption(MCONTACT contactID) +{ +} -- cgit v1.2.3