From d828acae837c71992f6a5f9dd688ba7afd944e56 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 23 Jul 2012 07:10:03 +0000 Subject: Dbx_mmap_SA, Import_SA, Dbtool_SA: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1108 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dbx_mmap_SA/src/commonheaders.h | 119 +++++++ plugins/Dbx_mmap_SA/src/dbintf_sa.cpp | 234 ++++++++++++++ plugins/Dbx_mmap_SA/src/dbintf_sa.h | 71 +++++ plugins/Dbx_mmap_SA/src/dbpreset.cpp | 296 +++++++++++++++++ plugins/Dbx_mmap_SA/src/dialogs.cpp | 543 ++++++++++++++++++++++++++++++++ plugins/Dbx_mmap_SA/src/init.cpp | 168 ++++++++++ plugins/Dbx_mmap_SA/src/options.h | 38 +++ plugins/Dbx_mmap_SA/src/resource.h | 54 ++++ plugins/Dbx_mmap_SA/src/security.cpp | 392 +++++++++++++++++++++++ plugins/Dbx_mmap_SA/src/version.h | 6 + 10 files changed, 1921 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/dbpreset.cpp 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/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..27c7036adf --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/commonheaders.h @@ -0,0 +1,119 @@ +/* + +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 MIRANDA_VER 0x0A00 + +#define _WIN32_WINNT 0x0501 +#include "m_stdhdr.h" + +//windows headers + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//miranda headers +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//non-official miranda-plugins sdk +#include "m_folders.h" + +//own headers +#include "dbintf_sa.h" +#include "..\Db3x_mmap\src\database.h" +#include "resource.h" +#include "version.h" + +extern HINSTANCE g_hInst; +extern HANDLE hSetPwdMenu; + +#ifdef __GNUC__ +#define mir_i64(x) (x##LL) +#else +#define mir_i64(x) (x##i64) +#endif + +//global procedures +//int InitSkin(); +void EncodeCopyMemory(void * dst, void * src, size_t size ); +void DecodeCopyMemory(void * dst, void * src, size_t size ); +void EncodeDBWrite(DWORD ofs, void * src, size_t size); +void DecodeDBWrite(DWORD ofs, void * src, size_t size); + +BOOL CALLBACK DlgStdInProc(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam); +BOOL CALLBACK DlgStdNewPass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam); +BOOL CALLBACK DlgChangePass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam); +void xModifyMenu(HANDLE hMenu,long flags,const TCHAR* name, HICON hIcon); + +extern DBSignature dbSignature, dbSignatureSecured; + +extern LIST g_Dbs; + +int InitPreset(); +void UninitPreset(); + +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..b85b3481cb --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/dbintf_sa.cpp @@ -0,0 +1,234 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 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) + +extern CDdxMmapSA* g_Db; + +int InitDialogs(void); + +DBSignature dbSignatureSecured = {"Miranda ICQ SD",0x1A}; + +CDdxMmapSA::CDdxMmapSA(const TCHAR* tszFileName) : + CDdxMmap(tszFileName) +{ +} + +int CDdxMmapSA::Load(bool bSkipInit) +{ + if ( CDdxMmap::Load(bSkipInit) != ERROR_SUCCESS) + return 1; + + if ( CheckDbHeaders()) + return 1; + + if (!bSkipInit) { + TCHAR* p = _tcsrchr(m_tszProfileName, '\\'); + if (!p) + return 1; + + g_Db = this; + if (m_bEncoding && !CheckPassword( LOWORD(m_dbHeader.version), p+1)) + return 1; + + InitDialogs(); + } + + return 0; +} + +int CDdxMmapSA::CheckDbHeaders() +{ + if ( memcmp(m_dbHeader.signature, &dbSignatureSecured, sizeof(m_dbHeader.signature)) == 0) + m_bEncoding = true; + else { + m_bEncoding = false; + if ( memcmp(m_dbHeader.signature,&dbSignature,sizeof(m_dbHeader.signature))) + return 1; + if ( LOWORD(m_dbHeader.version) != 0x0700) + return 2; + } + if (m_dbHeader.ofsUser == 0) + return 3; + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +static DWORD __inline GetSettingValueLength(PBYTE pSetting) +{ + if(pSetting[0]&DBVTF_VARIABLELENGTH) return 2+*(PWORD)(pSetting+1); + return pSetting[0]; +} + +void CDdxMmapSA::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 CDdxMmapSA::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]); + //CopyMemory(szSetting,pBlob+1,pBlob[0]); szSetting[pBlob[0]] = 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 CDdxMmapSA::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 CDdxMmapSA::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 CDdxMmapSA::EncodeContactEvents(HANDLE hContact) +{ + HANDLE hEvent = FindFirstEvent(hContact); + while (hEvent != 0) { + EncodeEvent(hEvent); + hEvent = FindNextEvent(hEvent); + } +} + +void CDdxMmapSA::DecodeContactEvents(HANDLE hContact) +{ + HANDLE hEvent = FindFirstEvent(hContact); + while (hEvent != 0) { + DecodeEvent(hEvent); + hEvent = FindNextEvent(hEvent); + } +} 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..8c6c9c04dc --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/dbintf_sa.h @@ -0,0 +1,71 @@ +/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright 2012 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 CDdxMmapSA : public CDdxMmap +{ + CDdxMmapSA(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); + +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; +}; diff --git a/plugins/Dbx_mmap_SA/src/dbpreset.cpp b/plugins/Dbx_mmap_SA/src/dbpreset.cpp new file mode 100644 index 0000000000..564bbf3c40 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/dbpreset.cpp @@ -0,0 +1,296 @@ +/* + +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. +*/ +// Miranda Memory-Mapped Secured DataBase +// (C) Artem Shpynov aka FYR, Igonin Vitaliy aka chaos.persei, Victor Pavlychko aka nullbie, 2007 - 2008 + +#include "commonheaders.h" + +/* Public API */ +int DBPreset_QuerySetting (const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic); +int DBPreset_CompareSetting (const char *szModule, const char *szSetting, DBVARIANT *dbv); + +/* Preset cache item */ +typedef struct +{ + DWORD dwHash; + char *szModule; + char *szSetting; + DBVARIANT dbv; +} DBPresetItem; + +static DBPresetItem * DBPresetItem_Create (char *szModule, char *szSetting, BYTE bType); +static void DBPresetItem_Destroy (DBPresetItem *item); +static void DBPresetItem_Hash (DBPresetItem *item); +static int DBPresetItem_Cmp (DBPresetItem *item1, DBPresetItem *item2); + +SortedList *lstPresets = NULL; + +int InitPreset() +{ + char szIniPath[MAX_PATH]; + char szLine[2048]; + int lineLength; + char szSection[128]; + FILE *fp; + + GetModuleFileNameA(GetModuleHandle(NULL), szIniPath, SIZEOF(szIniPath)); + strcpy(strrchr(szIniPath, '\\')+1, "dbpreset.ini"); + + fp = fopen(szIniPath,"rt"); + + // no preset + if (!fp) return 0; + + lstPresets = List_Create(0, 50); + lstPresets->sortFunc = (FSortFunc)DBPresetItem_Cmp; + + while(!feof(fp)) + { + if (fgets(szLine,sizeof(szLine),fp) == NULL) break; + lineLength = lstrlenA(szLine); + while(lineLength && (BYTE)(szLine[lineLength-1]) <= ' ') szLine[--lineLength] = '\0'; + if (szLine[0] == ';' || szLine[0] <= ' ') continue; + if (szLine[0] == '[') + { + char *szEnd = strchr(szLine+1,']'); + if (szEnd == NULL) continue; + if (szLine[1] == '!') + szSection[0] = '\0'; + else + lstrcpynA(szSection, szLine+1, (int)min(sizeof(szSection), szEnd-szLine)); + } else + { + char *szValue; + char szName[128]; + DBPresetItem *item; + + if (szSection[0] == '\0') continue; + szValue = strchr(szLine,' = '); + if (szValue == NULL) continue; + lstrcpynA(szName, szLine, (int)min(sizeof(szName), szValue-szLine+1)); + szValue++; + + switch(szValue[0]) + { + case 'b': + case 'B': + item = DBPresetItem_Create(szSection, szName, DBVT_BYTE); + item->dbv.bVal = (BYTE)strtol(szValue+1,NULL,0); + List_InsertPtr(lstPresets, item); + break; + case 'w': + case 'W': + item = DBPresetItem_Create(szSection, szName, DBVT_WORD); + item->dbv.wVal = (WORD)strtol(szValue+1,NULL,0); + List_InsertPtr(lstPresets, item); + break; + case 'd': + case 'D': + item = DBPresetItem_Create(szSection, szName, DBVT_DWORD); + item->dbv.dVal = (DWORD)strtoul(szValue+1,NULL,0); + List_InsertPtr(lstPresets, item); + break; + case 's': + case 'S': + item = DBPresetItem_Create(szSection, szName, DBVT_ASCIIZ); + item->dbv.pszVal = mir_strdup(szValue+1); + List_InsertPtr(lstPresets, item); + break; + case 'u': + case 'U': + item = DBPresetItem_Create(szSection, szName, DBVT_UTF8); + item->dbv.pszVal = mir_strdup(szValue+1); + List_InsertPtr(lstPresets, item); + break; + case 'n': + case 'N': + { + PBYTE buf; + int len; + char *pszValue,*pszEnd; + + buf = (PBYTE)mir_alloc(lstrlenA(szValue+1)); + for (len = 0,pszValue = szValue+1;;len++) { + buf[len] = (BYTE)strtol(pszValue,&pszEnd,0x10); + if (pszValue == pszEnd) break; + pszValue = pszEnd; + } + + item = DBPresetItem_Create(szSection, szName, DBVT_BLOB); + item->dbv.pbVal = buf; + item->dbv.cpbVal = len; + List_InsertPtr(lstPresets, item); + break; + } + } + } + } + fclose(fp); + + return 0; +} + +void UninitPreset() +{ + int i; + if (!lstPresets) return; + for (i = 0; i < lstPresets->realCount; ++i) + DBPresetItem_Destroy((DBPresetItem *)lstPresets->items[i]); + List_Destroy(lstPresets); +} + +int DBPreset_QuerySetting(const char *szModule, const char *szSetting, DBVARIANT *dbv, BOOL isStatic) +{ + DBPresetItem *item; + DBPresetItem search = {0}; + + if (!lstPresets) return FALSE; + + search.szModule = (char *)szModule; + search.szSetting = (char *)szSetting; + DBPresetItem_Hash(&search); + item = (DBPresetItem *)List_Find(lstPresets, &search); + + if (!item) return FALSE; + + dbv->type = item->dbv.type; + switch (item->dbv.type) + { + case DBVT_BYTE: dbv->bVal = item->dbv.bVal; return TRUE; + case DBVT_WORD: dbv->wVal = item->dbv.wVal; return TRUE; + case DBVT_DWORD: dbv->dVal = item->dbv.dVal; return TRUE; + + case DBVT_UTF8: + case DBVT_ASCIIZ: + if (isStatic && dbv->pszVal) + lstrcpynA(dbv->pszVal, item->dbv.pszVal, dbv->cchVal); + else if (!isStatic) + dbv->pszVal = mir_strdup(item->dbv.pszVal); + return TRUE; + + default: + return FALSE; + } + + return FALSE; +} + +int DBPreset_CompareSetting(const char *szModule, const char *szSetting, DBVARIANT *dbv) +{ + DBPresetItem *item; + DBPresetItem search = {0}; + + if (!lstPresets) return FALSE; + + search.szModule = (char *)szModule; + search.szSetting = (char *)szSetting; + DBPresetItem_Hash(&search); + item = (DBPresetItem *)List_Find(lstPresets, &search); + + if (!item) return FALSE; + if (item->dbv.type != item->dbv.type) return FALSE; + switch (item->dbv.type) + { + case DBVT_BYTE: return dbv->bVal == item->dbv.bVal ? TRUE : FALSE; + case DBVT_WORD: return dbv->wVal == item->dbv.wVal ? TRUE : FALSE; + case DBVT_DWORD: return dbv->dVal == item->dbv.dVal ? TRUE : FALSE; + case DBVT_UTF8: + case DBVT_ASCIIZ: return strcmp(dbv->pszVal, item->dbv.pszVal) ? FALSE : TRUE; + } + + return FALSE; +} + +static DBPresetItem *DBPresetItem_Create(char *szModule, char *szSetting, BYTE bType) +{ + DBPresetItem *item = (DBPresetItem *)mir_alloc(sizeof(DBPresetItem)); + item->szModule = mir_strdup(szModule); + item->szSetting = mir_strdup(szSetting); + DBPresetItem_Hash(item); + item->dbv.type = bType; + return item; +} + +static void DBPresetItem_Destroy(DBPresetItem *item) +{ + if (!item) return; + if (item->szModule) + { + mir_free(item->szModule); + item->szModule = NULL; + } + if (item->szSetting) + { + mir_free(item->szSetting); + item->szSetting = NULL; + } + + switch (item->dbv.type) + { + case DBVT_ASCIIZ: + case DBVT_UTF8: + case DBVT_WCHAR: + { + if (item->dbv.pszVal) + mir_free(item->dbv.pszVal); + item->dbv.pszVal = 0; + break; + } + case DBVT_BLOB: + { + if (item->dbv.pbVal) + mir_free(item->dbv.pbVal); + item->dbv.pbVal = 0; + break; + } + } + item->dbv.type = 0; +} + +static void DBPresetItem_Hash(DBPresetItem *item) +{ + int i; + int shift = 0; + item->dwHash = 0; + for (i = 0;item->szModule[i];i++) + { + item->dwHash ^= item->szModule[i]<24) item->dwHash ^= (item->szModule[i]>>(32-shift))&0x7F; + shift = (shift+5)&0x1F; + } + for (i = 0;item->szSetting[i];i++) + { + item->dwHash ^= item->szSetting[i]<24) item->dwHash ^= (item->szSetting[i]>>(32-shift))&0x7F; + shift = (shift+5)&0x1F; + } +} + +static int DBPresetItem_Cmp(DBPresetItem *item1, DBPresetItem *item2) +{ + int cmp; + if (item1->dwHash < item2->dwHash) return -1; + if (item1->dwHash > item2->dwHash) return 1; + if (cmp = strcmp(item1->szModule, item2->szModule)) return cmp; + return strcmp(item1->szSetting, item2->szSetting); +} diff --git a/plugins/Dbx_mmap_SA/src/dialogs.cpp b/plugins/Dbx_mmap_SA/src/dialogs.cpp new file mode 100644 index 0000000000..8445b69ef7 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/dialogs.cpp @@ -0,0 +1,543 @@ +#include "commonheaders.h" +#include +#include +#include +#include + +#define MS_DB_CHANGEPASSWORD "DB/ChangePassword" + +extern LIST arCryptors; + +CDdxMmapSA* g_Db; +HANDLE hSetPwdMenu; + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +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(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = 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("Services"); + odp.pfnDlgProc = DlgProcOptions; + Options_AddPage(wParam, &odp); + return 0; +} + +INT_PTR ChangePassword(WPARAM wParam, LPARAM lParam) +{ + if (g_Db->m_bEncoding) + g_Db->ChangePwd(); + else + g_Db->EncryptDB(); + + return 0; +} + +void xModifyMenu(HANDLE hMenu,long flags,const TCHAR* name, HICON hIcon) +{ + CLISTMENUITEM menu; + ZeroMemory(&menu,sizeof(menu)); + menu.cbSize = sizeof(menu); + menu.flags = CMIM_FLAGS | CMIF_TCHAR; + menu.flags |= name ? CMIM_NAME : 0; + menu.flags |= hIcon ? CMIM_ICON : 0; + menu.flags |= flags; + menu.ptszName = (TCHAR*)name; + menu.hIcon = hIcon; + + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMenu,(LPARAM)&menu); +} + +int InitMenus(WPARAM, LPARAM) +{ + HookEvent(ME_OPT_INITIALISE, OptionsInit); + + TCHAR szFile[MAX_PATH]; + GetModuleFileName(g_hInst, szFile, MAX_PATH); + + SKINICONDESC sid = {0}; + sid.cbSize = sizeof(sid); + sid.ptszDefaultFile = szFile; + sid.flags = SIDF_ALL_TCHAR; + sid.ptszSection = LPGENT("Database"); + sid.ptszDescription = LPGENT("Database"); + sid.pszName = "database"; + sid.iDefaultIndex = -IDI_ICON2; + Skin_AddIcon(&sid); + + sid.ptszDescription = LPGENT("Change Password"); + sid.pszName = "password"; + sid.iDefaultIndex = -IDI_ICON3; + HANDLE hIcon = Skin_AddIcon(&sid); + + // main menu item + CLISTMENUITEM menu = {0}; + menu.cbSize = sizeof(menu); + menu.flags = CMIM_ALL | CMIF_TCHAR | CMIF_ICONFROMICOLIB; + menu.icolibItem = hIcon; + menu.ptszName = (g_Db->m_bEncoding) ? LPGENT("Change password") : LPGENT("Set password"); + menu.ptszPopupName = LPGENT("Database"); + menu.pszService = MS_DB_CHANGEPASSWORD; + menu.position = 500100000; + hSetPwdMenu = Menu_AddMainMenuItem(&menu); + return 0; +} + +int InitDialogs() +{ + HookEvent(ME_SYSTEM_MODULESLOADED, InitMenus); + CreateServiceFunction(MS_DB_CHANGEPASSWORD, ChangePassword); + return 0; +} + +int ImageList_AddIcon_IconLibLoaded(HIMAGELIST hIml, char* name) +{ + HICON hIcon = (HICON)CallService(MS_SKIN2_GETICON, (WPARAM)NULL, (LPARAM)name); + int res = ImageList_AddIcon(hIml, hIcon); + return res; +} + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwndList = GetDlgItem(hwndDlg, IDC_MODULES); + LVCOLUMN col; + LVITEM item; + int i, iRow, iIndex; + NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; + WORD uid; + HIMAGELIST hIml; + + switch ( msg ) { + case WM_INITDIALOG: + hIml = ImageList_Create(16, 16, ILC_MASK | (IsWinVerXPPlus()? ILC_COLOR32 : ILC_COLOR16), 2, 0); + TranslateDialogDefault( hwndDlg ); + + ImageList_AddIcon_IconLibLoaded( hIml, "core_main_29" ); + ImageList_AddIcon_IconLibLoaded( hIml, "core_main_30" ); + ListView_SetImageList( hwndList, hIml, LVSIL_SMALL ); + + 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 = DBGetContactSettingWord(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 && g_Db->m_bEncoding) + ListView_SetCheckState(hwndList, i, 1); + + item.mask = LVIF_IMAGE; + item.iItem = iRow; + item.iSubItem = 0; + item.iImage = ( CryptoEngine == arCryptors[i]->cryptor && g_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 (!g_Db->m_bEncoding){ + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", arCryptors[alg]->cryptor->uid); + g_Db->EncryptDB(); + } + else { + if (arCryptors[alg]->cryptor->uid != DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", -1)) { + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", arCryptors[alg]->cryptor->uid); + g_Db->RecryptDB(); + } + } + } + else if (g_Db->m_bEncoding) + g_Db->DecryptDB(); + + uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + for (i = 0; i < arCryptors.getCount(); i++) { + if (uid == arCryptors[i]->cryptor->uid && g_Db->m_bEncoding) + ListView_SetCheckState(hwndList, i, 1); + + item.mask = LVIF_IMAGE; + item.iItem = i; + item.iSubItem = 0; + item.iImage = ( CryptoEngine == arCryptors[i]->cryptor && g_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; + +BOOL CALLBACK DlgStdInProc(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + HICON hIcon = 0; + TCHAR tszHeaderTxt[256]; + + switch(uMsg) { + case WM_INITDIALOG: + TranslateDialogDefault(hDlg); + + hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); + + if (!wrongPass) { + mir_sntprintf(tszHeaderTxt, SIZEOF(tszHeaderTxt), _T("%s\n%s"), TranslateT("Please type in your password for"), (TCHAR*)lParam); + 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 IDOK: + if (!GetWindowLongPtr(hDlg,GWLP_USERDATA)) { + g_Db->encryptKeyLength = GetDlgItemTextA(hDlg, IDC_USERPASS, g_Db->encryptKey, 254); + EndDialog(hDlg,IDOK); + } + break; + + case IDCANCEL: + EndDialog(hDlg,IDCANCEL); + } + break; + + case WM_TIMER: + LanguageChanged(hDlg); + return FALSE; + + case WM_DESTROY: + KillTimer(hDlg, 1); + DestroyIcon(hIcon); + } + + return FALSE; +} + +BOOL CALLBACK DlgStdNewPass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + HICON hIcon = 0; + + switch(uMsg) { + case WM_INITDIALOG: + TranslateDialogDefault(hDlg); + + hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); + + 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: + { + UINT uid = LOWORD(wParam); + if (uid == IDOK) { + if (!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)) { + g_Db->encryptKeyLength = strlen(pass1); + strcpy(g_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,""); + } + } + } + } + else if (uid == IDCANCEL) + EndDialog(hDlg,IDCANCEL); + } + break; + + case WM_TIMER: + LanguageChanged(hDlg); + return FALSE; + + case WM_DESTROY: + KillTimer(hDlg, 1); + DestroyIcon(hIcon); + return FALSE; + } + return FALSE; +} + +char* newPass; + +BOOL CALLBACK DlgChangePass(HWND hDlg, UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + HICON hIcon = 0; + + switch(uMsg) { + case WM_INITDIALOG: + TranslateDialogDefault(hDlg); + + hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_ICON2)); + SendMessage(GetDlgItem(hDlg, IDC_HEADERBAR), WM_SETICON, 0, (LPARAM)hIcon); + SetWindowText(GetDlgItem(hDlg, IDC_HEADERBAR), TranslateT("Change password")); + + newPass = (char*)lParam; + 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: + { + UINT uid = LOWORD(wParam); + if (uid == IDOK) { + char pass1[255], pass2[255], oldpass[255]; + GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); + if (strcmp(oldpass, g_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); + } + } + } + else if (uid == IDCANCEL) + EndDialog(hDlg,IDCANCEL); + else if (uid == IDREMOVE) { + char oldpass[255]; + GetDlgItemTextA(hDlg, IDC_OLDPASS, oldpass, 254); + if (strcmp(oldpass, g_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); + 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..2566e14471 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/init.cpp @@ -0,0 +1,168 @@ +/* + +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, + __VERSION_DWORD, + "Provides Miranda database support: global settings, contacts, history, settings per contact. Enhanced modification with Encryption support.", + "Miranda-IM project, modification by FYR and chaos.persei, nullbie, Billy_Bons", + "chaos.persei@gmail.com; ashpynov@gmail.com; bio@msx.ru; ghazan@miranda.im", + "Copyright 2000-2011 Miranda IM project, FYR, chaos.persei, induction, nullbie", + "http://dbmmapmod.googlecode.com/", + UNICODE_AWARE, + // {28FF9B91-3E4D-4f1c-B47C-C641B037FF40} + { 0x28ff9b91, 0x3e4d, 0x4f1c, { 0xb4, 0x7c, 0xc6, 0x41, 0xb0, 0x37, 0xff, 0x40 } } +}; + +LIST g_Dbs(1, (LIST::FTSortFunc)HandleKeySort); + +///////////////////////////////////////////////////////////////////////////////////////// + +// returns 0 if the profile is created, EMKPRF* +static int makeDatabase(const TCHAR *profile, int *error) +{ + CDdxMmapSA *tmp = new CDdxMmapSA(profile); + if (tmp->Create() == ERROR_SUCCESS) { + tmp->CreateDbHeaders(); + delete tmp; + return 0; + } + delete tmp; + if (error != NULL) *error = EMKPRF_CREATEFAILED; + return 1; +} + +// returns 0 if the given profile has a valid header +static int grokHeader(const TCHAR *profile, int *error) +{ + CDdxMmapSA *tmp = new CDdxMmapSA(profile); + if (tmp->Load(true) != ERROR_SUCCESS) { + delete tmp; + if (error != NULL) *error = EGROKPRF_CANTREAD; + return 1; + } + + int chk = tmp->CheckDbHeaders(); + delete tmp; + if ( chk == 0 ) { + // all the internal tests passed, hurrah + if (error != NULL) *error = 0; + return 0; + } + + // didn't pass at all, or some did. + switch ( chk ) { + case 1: + // "Miranda ICQ DB" wasn't present + if (error != NULL) *error = EGROKPRF_UNKHEADER; + break; + + case 2: + // header was present, but version information newer + if (error != NULL) *error = EGROKPRF_VERNEWER; + break; + + case 3: + // header/version OK, internal data missing + if (error != NULL) *error = EGROKPRF_DAMAGED; + break; + } + + return 1; +} + +// 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 ); + + CDdxMmapSA* db = new CDdxMmapSA(profile); + if (db->Load(false) != ERROR_SUCCESS) { + delete db; + return NULL; + } + + g_Dbs.insert(db); + return db; +} + +static int UnloadDatabase(MIDatabase* db) +{ + g_Dbs.remove((CDdxMmapSA*)db); + delete (CDdxMmapSA*)db; + return 0; +} + +static DATABASELINK dblink = +{ + sizeof(DATABASELINK), + "db3x secure mmap driver", + _T("db3x secure mmap database support"), + makeDatabase, + grokHeader, + LoadDatabase, + UnloadDatabase +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +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(); + InitPreset(); + + RegisterDatabasePlugin(&dblink); + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + g_Dbs.destroy(); + UnloadSecurity(); + UninitPreset(); + 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..4ecf5f745b --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/security.cpp @@ -0,0 +1,392 @@ +// (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 CDdxMmapSA::EncoderInit() +{ + if (!m_bEncoding) return; + + encryptKey[encryptKeyLength] = 0; + key = CryptoEngine->GenerateKey(encryptKey); +} + +void CDdxMmapSA::EncodeCopyMemory(void * dst, void * src, size_t size ) +{ + memcpy(dst, src, size); + + if (!m_bEncoding) + return; + + CryptoEngine->EncryptMem((BYTE *)dst, (int)size, key); +} + +void CDdxMmapSA::DecodeCopyMemory(void * dst, void * src, size_t size ) +{ + memcpy(dst, src, size); + + if (!m_bEncoding) + return; + + CryptoEngine->DecryptMem((BYTE *)dst, (int)size, key); +} + +void CDdxMmapSA::EncodeDBWrite(DWORD ofs, void *src, int size) +{ + if (m_bEncoding) + { + BYTE * buf; + + 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 CDdxMmapSA::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 CDdxMmapSA::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){ + MessageBoxA(0, "Sorry, but your database encrypted with unknown module", "Error", MB_OK); + bCheckingPass = 0; + return 0; + } + + while(1) { + int res = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_LOGIN), NULL, (DLGPROC)DlgStdInProc, (LPARAM)szDBName); + 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() +{ + WORD uid; + int i; + + if (arCryptors.getCount() == 0){ + MessageBox(0, TranslateT("Crypto modules not found"), TranslateT("Error"), MB_OK); + return 1; + } + + uid = DBGetContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + if (uid == 0){ + MessageBox(0, TranslateT("Crypto module hasn't been chosen, using first one found"), TranslateT("Notice"), MB_OK); + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", arCryptors[0]->cryptor->uid); + CryptoEngine = arCryptors[0]->cryptor; + } + else{ + int Found = 0; + for (i = 0; i < arCryptors.getCount(); i++) { + if (arCryptors[i]->cryptor->uid == uid){ + CryptoEngine = arCryptors[i]->cryptor; + Found = 1; + break; + } + } + if (!Found){ + MessageBox(0, TranslateT("Crypto module hasn't been chosen, using first one found"), TranslateT("Notice"), MB_OK); + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", arCryptors[0]->cryptor->uid); + CryptoEngine = arCryptors[0]->cryptor; + } + } + + return 0; +} + +void CDdxMmapSA::EncodeAll() +{ + HANDLE hContact; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + if (hContact){ + do { + EncodeContactEvents(hContact); + EncodeContactSettings(hContact); + } + while(hContact = FindNextContact(hContact)); + } + + EncodeContactEvents(NULL); + EncodeContactSettings(NULL); +} + +void CDdxMmapSA::DecodeAll() +{ + HANDLE hContact; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + if (hContact){ + do{ + DecodeContactEvents(hContact); + DecodeContactSettings(hContact); + }while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); + } + DecodeContactEvents(NULL); + DecodeContactSettings(NULL); +} + +void CDdxMmapSA::WritePlainHeader() +{ + DWORD bytesWritten; + + memcpy(m_dbHeader.signature, &dbSignature, 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 CDdxMmapSA::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 CDdxMmapSA::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); + return; + } + + if (SelectEncoder()) { + return; + } + + bEncProcess = 1; + + action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_NEWPASS), NULL, (DLGPROC)DlgStdNewPass, (LPARAM)NULL); + 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 CDdxMmapSA::DecryptDB() +{ + char oldKey[255]; + strcpy(oldKey, encryptKey); + + if ( !CheckPassword( HIWORD(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); + + DBWriteContactSettingWord(NULL, "SecureMMAP", "CryptoModule", 0); + + CryptoEngine->FreeKey(key); + + CryptoEngine = NULL; +} + +void CDdxMmapSA::RecryptDB() +{ + EnterCriticalSection(&m_csDbAccess); + + DecodeAll(); + + CryptoEngine->FreeKey(key); + + SelectEncoder(); + + m_bEncoding = 1; + + EncoderInit(); + + EncodeAll(); + + WriteCryptHeader(); + + LeaveCriticalSection(&m_csDbAccess); +} + +void CDdxMmapSA::ChangePwd() +{ + char newpass[255] = {0}; + + int action = DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_CHANGEPASS), NULL, (DLGPROC)DlgChangePass, (LPARAM)newpass); + + if (action == IDCANCEL || (action == IDOK && !strlen(newpass))) + return; + + EnterCriticalSection(&m_csDbAccess); + + DecodeAll(); + + CryptoEngine->FreeKey(key); + + if (action == IDREMOVE){ + WritePlainHeader(); + + m_bEncoding = 0; + CryptoEngine = NULL; + DBWriteContactSettingWord(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); +} \ 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..57928c3905 --- /dev/null +++ b/plugins/Dbx_mmap_SA/src/version.h @@ -0,0 +1,6 @@ +#include "m_version.h" + +#define __FILEVERSION_STRING MIRANDA_VERSION_FILEVERSION +#define __VERSION_STRING MIRANDA_VERSION_STRING +#define __VERSION_DWORD MIRANDA_VERSION_DWORD +#define __PLUGIN_NAME "Miranda NG secure database driver" -- cgit v1.2.3