From a9580df150d799246eaecbf3c1fb5cecf9f8ab49 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Mon, 23 Jul 2012 13:49:28 +0000 Subject: SecureIM, SeenPlugin, SendSS, Sessions: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1122 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/SecureIM/src/commonheaders.cpp | 197 +++ plugins/SecureIM/src/commonheaders.h | 192 +++ plugins/SecureIM/src/crypt.h | 183 +++ plugins/SecureIM/src/crypt_check.cpp | 267 ++++ plugins/SecureIM/src/crypt_dll.cpp | 236 ++++ plugins/SecureIM/src/crypt_icons.cpp | 151 +++ plugins/SecureIM/src/crypt_lists.cpp | 327 +++++ plugins/SecureIM/src/crypt_metacontacts.cpp | 60 + plugins/SecureIM/src/crypt_misc.cpp | 139 ++ plugins/SecureIM/src/crypt_popups.cpp | 153 +++ plugins/SecureIM/src/cryptopp.h | 73 + plugins/SecureIM/src/dbevent.cpp | 21 + plugins/SecureIM/src/dbevent.h | 8 + plugins/SecureIM/src/gettime.cpp | 29 + plugins/SecureIM/src/gettime.h | 8 + plugins/SecureIM/src/images.cpp | 358 +++++ plugins/SecureIM/src/images.h | 8 + plugins/SecureIM/src/language.cpp | 104 ++ plugins/SecureIM/src/language.h | 100 ++ plugins/SecureIM/src/loadicons.cpp | 96 ++ plugins/SecureIM/src/loadicons.h | 7 + plugins/SecureIM/src/loadlib.cpp | 76 ++ plugins/SecureIM/src/loadlib.h | 188 +++ plugins/SecureIM/src/main.cpp | 534 ++++++++ plugins/SecureIM/src/mmi.cpp | 155 +++ plugins/SecureIM/src/mmi.h | 27 + plugins/SecureIM/src/options.cpp | 1928 +++++++++++++++++++++++++++ plugins/SecureIM/src/options.h | 40 + plugins/SecureIM/src/popupOptions.cpp | 239 ++++ plugins/SecureIM/src/popupOptions.h | 8 + plugins/SecureIM/src/resource.h | 160 +++ plugins/SecureIM/src/rtfconv.cpp | 46 + plugins/SecureIM/src/rtfconv.h | 23 + plugins/SecureIM/src/secureim.h | 172 +++ plugins/SecureIM/src/splitmsg.cpp | 124 ++ plugins/SecureIM/src/splitmsg.h | 9 + plugins/SecureIM/src/svcs_clist.cpp | 224 ++++ plugins/SecureIM/src/svcs_clist.h | 13 + plugins/SecureIM/src/svcs_menu.cpp | 232 ++++ plugins/SecureIM/src/svcs_menu.h | 26 + plugins/SecureIM/src/svcs_popup.cpp | 115 ++ plugins/SecureIM/src/svcs_proto.cpp | 1130 ++++++++++++++++ plugins/SecureIM/src/svcs_proto.h | 14 + plugins/SecureIM/src/svcs_rsa.cpp | 226 ++++ plugins/SecureIM/src/svcs_rsa.h | 20 + plugins/SecureIM/src/svcs_srmm.cpp | 37 + plugins/SecureIM/src/svcs_srmm.h | 9 + plugins/SecureIM/src/version.h | 16 + 48 files changed, 8508 insertions(+) create mode 100644 plugins/SecureIM/src/commonheaders.cpp create mode 100644 plugins/SecureIM/src/commonheaders.h create mode 100644 plugins/SecureIM/src/crypt.h create mode 100644 plugins/SecureIM/src/crypt_check.cpp create mode 100644 plugins/SecureIM/src/crypt_dll.cpp create mode 100644 plugins/SecureIM/src/crypt_icons.cpp create mode 100644 plugins/SecureIM/src/crypt_lists.cpp create mode 100644 plugins/SecureIM/src/crypt_metacontacts.cpp create mode 100644 plugins/SecureIM/src/crypt_misc.cpp create mode 100644 plugins/SecureIM/src/crypt_popups.cpp create mode 100644 plugins/SecureIM/src/cryptopp.h create mode 100644 plugins/SecureIM/src/dbevent.cpp create mode 100644 plugins/SecureIM/src/dbevent.h create mode 100644 plugins/SecureIM/src/gettime.cpp create mode 100644 plugins/SecureIM/src/gettime.h create mode 100644 plugins/SecureIM/src/images.cpp create mode 100644 plugins/SecureIM/src/images.h create mode 100644 plugins/SecureIM/src/language.cpp create mode 100644 plugins/SecureIM/src/language.h create mode 100644 plugins/SecureIM/src/loadicons.cpp create mode 100644 plugins/SecureIM/src/loadicons.h create mode 100644 plugins/SecureIM/src/loadlib.cpp create mode 100644 plugins/SecureIM/src/loadlib.h create mode 100644 plugins/SecureIM/src/main.cpp create mode 100644 plugins/SecureIM/src/mmi.cpp create mode 100644 plugins/SecureIM/src/mmi.h create mode 100644 plugins/SecureIM/src/options.cpp create mode 100644 plugins/SecureIM/src/options.h create mode 100644 plugins/SecureIM/src/popupOptions.cpp create mode 100644 plugins/SecureIM/src/popupOptions.h create mode 100644 plugins/SecureIM/src/resource.h create mode 100644 plugins/SecureIM/src/rtfconv.cpp create mode 100644 plugins/SecureIM/src/rtfconv.h create mode 100644 plugins/SecureIM/src/secureim.h create mode 100644 plugins/SecureIM/src/splitmsg.cpp create mode 100644 plugins/SecureIM/src/splitmsg.h create mode 100644 plugins/SecureIM/src/svcs_clist.cpp create mode 100644 plugins/SecureIM/src/svcs_clist.h create mode 100644 plugins/SecureIM/src/svcs_menu.cpp create mode 100644 plugins/SecureIM/src/svcs_menu.h create mode 100644 plugins/SecureIM/src/svcs_popup.cpp create mode 100644 plugins/SecureIM/src/svcs_proto.cpp create mode 100644 plugins/SecureIM/src/svcs_proto.h create mode 100644 plugins/SecureIM/src/svcs_rsa.cpp create mode 100644 plugins/SecureIM/src/svcs_rsa.h create mode 100644 plugins/SecureIM/src/svcs_srmm.cpp create mode 100644 plugins/SecureIM/src/svcs_srmm.h create mode 100644 plugins/SecureIM/src/version.h (limited to 'plugins/SecureIM/src') diff --git a/plugins/SecureIM/src/commonheaders.cpp b/plugins/SecureIM/src/commonheaders.cpp new file mode 100644 index 0000000000..3697abea6e --- /dev/null +++ b/plugins/SecureIM/src/commonheaders.cpp @@ -0,0 +1,197 @@ +#include "commonheaders.h" + +HINSTANCE g_hInst, g_hIconInst; + +LPCSTR szModuleName = MODULENAME; +LPCSTR szVersionStr = MODULENAME" DLL ("__VERSION_STRING")"; +char TEMP[MAX_PATH]; +int TEMP_SIZE = 0; + +HANDLE g_hEvent[2], g_hMenu[15], g_hCLIcon=0, g_hFolders=0; +HANDLE *g_hService=NULL; +HANDLE *g_hHook=NULL; +int iService=0; +int iHook=0; + +HICON g_hICO[ICO_CNT], g_hPOP[POP_CNT], g_hIEC[1+IEC_CNT*MODE_CNT] = {0}; +IconExtraColumn g_IEC[1+IEC_CNT*MODE_CNT]; + +int iBmpDepth; +BOOL bCoreUnicode = false, bMetaContacts = false, bPopupExists = false, bPopupUnicode = false; +BOOL bPGPloaded = false, bPGPkeyrings = false, bUseKeyrings = false, bPGPprivkey = false; +BOOL bGPGloaded = false, bGPGkeyrings = false, bSavePass = false; +BOOL bSFT, bSOM, bASI, bMCD, bSCM, bDGP, bAIP, bNOL, bAAK, bMCM; +BYTE bADV, bPGP, bGPG; +DWORD iCoreVersion = 0; +CRITICAL_SECTION localQueueMutex; + +PLUGININFOEX pluginInfoEx = { + sizeof(PLUGININFOEX), + MODULENAME, + __VERSION_DWORD, + MODULENAME" plugin for Miranda IM ("__DATE__")", + "Johell, Ghost, Nightwish, __alex, Baloo", + "Johell@ifrance.com, baloo@bk.ru", + "© 2003 Johell, © 2005-09 Baloo", + "http://nightly.miranda.im/", + 0, + MIID_SECUREIM +}; + +LPSTR myDBGetString(HANDLE hContact,const char *szModule,const char *szSetting) { + char *val=NULL; + DBVARIANT dbv; + dbv.type = DBVT_ASCIIZ; + DBGetContactSetting(hContact,szModule,szSetting,&dbv); + if ( dbv.pszVal && (dbv.type==DBVT_ASCIIZ || dbv.type==DBVT_UTF8 || dbv.type==DBVT_WCHAR)) + val = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + return val; +} + + +LPSTR myDBGetStringDecode(HANDLE hContact,const char *szModule,const char *szSetting) { + char *val = myDBGetString(hContact,szModule,szSetting); + if (!val) return NULL; + size_t len = strlen(val)+64; + char *buf = (LPSTR)mir_alloc(len); + strncpy(buf,val,len); mir_free(val); + CallService(MS_DB_CRYPT_DECODESTRING,(WPARAM)len,(LPARAM)buf); + return buf; +} + + +int myDBWriteStringEncode(HANDLE hContact,const char *szModule,const char *szSetting,const char *val) { + int len = (int)strlen(val)+64; + char *buf = (LPSTR)alloca(len); + strncpy(buf,val,len); + CallService(MS_DB_CRYPT_ENCODESTRING,(WPARAM)len,(LPARAM)buf); + int ret = DBWriteContactSettingString(hContact,szModule,szSetting,buf); + return ret; +} + +void GetFlags() { + bSFT = DBGetContactSettingByte(0,szModuleName,"sft",0); + bSOM = DBGetContactSettingByte(0,szModuleName,"som",0); + bASI = DBGetContactSettingByte(0,szModuleName,"asi",0); + bMCD = DBGetContactSettingByte(0,szModuleName,"mcd",0); + bSCM = DBGetContactSettingByte(0,szModuleName,"scm",0); + bDGP = DBGetContactSettingByte(0,szModuleName,"dgp",0); + bAIP = DBGetContactSettingByte(0,szModuleName,"aip",0); + bADV = DBGetContactSettingByte(0,szModuleName,"adv",0); + bNOL = DBGetContactSettingByte(0,szModuleName,"nol",0); + bAAK = DBGetContactSettingByte(0,szModuleName,"aak",0); + bMCM = DBGetContactSettingByte(0,szModuleName,"mcm",0); +} + + +void SetFlags() { + DBWriteContactSettingByte(0,szModuleName,"sft",bSFT); + DBWriteContactSettingByte(0,szModuleName,"som",bSOM); + DBWriteContactSettingByte(0,szModuleName,"asi",bASI); + DBWriteContactSettingByte(0,szModuleName,"mcd",bMCD); + DBWriteContactSettingByte(0,szModuleName,"scm",bSCM); + DBWriteContactSettingByte(0,szModuleName,"dgp",bDGP); + DBWriteContactSettingByte(0,szModuleName,"aip",bAIP); + DBWriteContactSettingByte(0,szModuleName,"adv",bADV); + DBWriteContactSettingByte(0,szModuleName,"nol",bNOL); + DBWriteContactSettingByte(0,szModuleName,"aak",bAAK); + DBWriteContactSettingByte(0,szModuleName,"mcm",bMCM); +} + +struct A2U { + LPSTR a; + LPSTR u; +}; +typedef A2U* pA2U; + +pA2U pa2u; +int ca2u=0; + +LPSTR TranslateU( LPCSTR lpText ) { + int i; + for(i=0;iutf8encode(lpwTran)); + } + else { + LPSTR lpTran = Translate(lpText); + LPWSTR lpwTran = mir_a2u(lpTran); + lpTran = exp->utf8encode(lpwTran); + mir_free(lpwTran); + pa2u[i].u = mir_strdup(lpTran); + } + return pa2u[i].u; +} + +int msgbox( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { + if ( bCoreUnicode ) { + LPWSTR lpwText = mir_a2u(lpText); + LPWSTR lpwCaption = mir_a2u(lpCaption); + int r = MessageBoxW(hWnd,TranslateW(lpwText),TranslateW(lpwCaption),uType); + mir_free(lpwCaption); + mir_free(lpwText); + return r; + } + return MessageBoxA(hWnd,Translate(lpText),Translate(lpCaption),uType); +} + +void CopyToClipboard(HWND hwnd,LPSTR msg) +{ + HGLOBAL hglbCopy; + LPSTR lpstrCopy; + + hglbCopy = GlobalAlloc(GMEM_MOVEABLE, lstrlenA(msg)+1); + lpstrCopy = (LPSTR)GlobalLock(hglbCopy); + lstrcpyA(lpstrCopy, msg); + GlobalUnlock(hglbCopy); + + OpenClipboard(NULL); + EmptyClipboard(); + SetClipboardData(CF_TEXT, hglbCopy); + CloseClipboard(); +} + +#if defined(_DEBUG) || defined(NETLIB_LOG) +HANDLE hNetlibUser; + +void InitNetlib() { + NETLIBUSER nl_user; + memset(&nl_user,0,sizeof(nl_user)); + nl_user.cbSize = sizeof(nl_user); + nl_user.szSettingsModule = (LPSTR)szModuleName; + nl_user.szDescriptiveName = (LPSTR)szModuleName; + nl_user.flags = NUF_NOOPTIONS; + + hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nl_user); +} + +void DeinitNetlib() { + if(hNetlibUser) + CallService(MS_NETLIB_CLOSEHANDLE, (WPARAM)hNetlibUser, 0); +} + +int Sent_NetLog(const char *fmt,...) +{ + va_list va; + char szText[1024]; + + va_start(va,fmt); + mir_vsnprintf(szText,sizeof(szText),fmt,va); + va_end(va); + return CallService(MS_NETLIB_LOG,(WPARAM)hNetlibUser,(LPARAM)szText); +} +#endif + + +// EOF diff --git a/plugins/SecureIM/src/commonheaders.h b/plugins/SecureIM/src/commonheaders.h new file mode 100644 index 0000000000..c848d43484 --- /dev/null +++ b/plugins/SecureIM/src/commonheaders.h @@ -0,0 +1,192 @@ +// Windows API + +#define WIN32_LEAN_AND_MEAN +#define NETLIB_LOG + +#ifdef _MSC_VER +#pragma once +#define _CRT_SECURE_NO_WARNINGS +// _MSC_VER: 1200=6.0 1300=7.0(2003) 1400=8.0(2005) 1500=9.0(2008) +#if _MSC_VER >= 1300 +// MSVC 7.0 and above +#define mir_itoa _itoa +#define mir_unlink _unlink +#else +// MSVC 6.0 and below +#ifndef _DEBUG +#pragma optimize("gsy", on) +#endif +#endif +#endif + +#ifndef mir_itoa +#define mir_itoa itoa +#endif + +#ifndef mir_unlink +#define mir_unlink unlink +#endif + +#ifndef WINVER +#define WINVER 0x0501 +#endif + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0501 +#endif + +#ifndef M_SIM_COMMONHEADERS_H +#define M_SIM_COMMONHEADERS_H + +#define MIRANDA_VER 0x0A00 +#include + +// Windows API +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MODULENAME "SecureIM" + +#ifndef ListView_SetCheckState +#define ListView_SetCheckState(hwndLV, i, fCheck) \ + ListView_SetItemState(hwndLV, i, INDEXTOSTATEIMAGEMASK((fCheck)?2:1), LVIS_STATEIMAGEMASK) +#endif + +#ifndef SIZEOF +#define SIZEOF(X) (sizeof(X)/sizeof(X[0])) +#endif + +#ifndef M_API_H__ +#define M_API_H__ + +// Miranda API +#include "newpluginapi.h" +#include "m_stdhdr.h" +#include "m_system.h" +#include "m_database.h" +#include "m_protomod.h" +#include "m_protosvc.h" +#include "m_langpack.h" +#include "m_options.h" +#include "m_clist.h" +#include "m_clc.h" +#include "m_clui.h" +#include "m_cluiframes.h" +#include "m_utils.h" +#include "m_skin.h" +#include "m_popup.h" +#include "m_genmenu.h" +#include "m_icolib.h" +#include "m_message.h" +#include "m_netlib.h" +#include "m_metacontacts.h" +#include "m_extraicons.h" +#include "m_folders.h" + +#endif + +// my libs +#include "secureim.h" +#include "version.h" +#include "resource.h" +#include "language.h" +#include "loadlib.h" +#include "mmi.h" +#include "crypt.h" +#include "gettime.h" +#include "language.h" +#include "options.h" +#include "popupoptions.h" +#include "loadicons.h" +#include "rtfconv.h" +#include "cryptopp.h" +#include "images.h" +#include "dbevent.h" +#include "splitmsg.h" +#include "svcs_proto.h" +#include "svcs_clist.h" +#include "svcs_menu.h" +#include "svcs_srmm.h" +#include "svcs_rsa.h" + +extern LPCSTR szModuleName; +extern LPCSTR szVersionStr; +extern char TEMP[MAX_PATH]; +extern int TEMP_SIZE; + +// shared vars +extern HINSTANCE g_hInst, g_hIconInst; +extern PLUGININFOEX pluginInfoEx; + +#define MIID_SECUREIM {0x1B2A39E5, 0xE2F6, 0x494D, { 0x95, 0x8D, 0x18, 0x08, 0xFD, 0x11, 0x0D, 0xD5 }} //1B2A39E5-E2F6-494D-958D-1808FD110DD5 + +#define PREF_METANODB 0x2000 //!< Flag to indicate message should not be added to db by filter when sending +#define PREF_SIMNOMETA 0x4000 //!< Flag to indicate message should not be inspected by filter on metacontact + +extern HANDLE g_hEvent[2], g_hMenu[15], g_hCLIcon, g_hFolders; +extern HANDLE *g_hService; +extern HANDLE *g_hHook; +extern int iService, iHook; +extern HICON g_hICO[ICO_CNT], g_hIEC[1+IEC_CNT*MODE_CNT], g_hPOP[POP_CNT]; +extern IconExtraColumn g_IEC[1+IEC_CNT*MODE_CNT]; +extern int iBmpDepth; +extern BOOL bCoreUnicode, bMetaContacts, bPopupExists, bPopupUnicode; +extern BOOL bPGPloaded, bPGPkeyrings, bUseKeyrings, bPGPprivkey; +extern BOOL bGPGloaded, bGPGkeyrings, bSavePass; +extern BOOL bSFT, bSOM, bASI, bMCD, bSCM, bDGP, bAIP, bNOL, bAAK, bMCM; +extern BYTE bADV, bPGP, bGPG; +extern DWORD iCoreVersion; +extern CRITICAL_SECTION localQueueMutex; + +int onModulesLoaded(WPARAM,LPARAM); +int onSystemOKToExit(WPARAM,LPARAM); + +void AddServiceFunction(LPCSTR,MIRANDASERVICE); +void AddProtoServiceFunction(LPCSTR,MIRANDASERVICE); +void AddHookFunction(LPCSTR,MIRANDAHOOK); + +LPSTR myDBGetString(HANDLE,const char *,const char *); +LPSTR myDBGetStringDecode(HANDLE,const char *,const char *); +int myDBWriteStringEncode(HANDLE,const char *,const char *,const char *); + +#if defined(_DEBUG) || defined(NETLIB_LOG) +extern HANDLE hNetlibUser; +void InitNetlib(); +void DeinitNetlib(); +int Sent_NetLog(const char *,...); +#endif +/* +int DBWriteString(HANDLE,const char *,const char *,const char *); +int DBGetByte(HANDLE,const char *,const char *,int); +int DBWriteByte(HANDLE,const char *,const char *,BYTE); +int DBGetWord(HANDLE,const char *,const char *,int); +int DBWriteWord(HANDLE,const char *,const char *,WORD); +*/ +void GetFlags(); +void SetFlags(); +/* +LPSTR u2a( LPCWSTR src ); +LPWSTR a2u( LPCSTR src ); +*/ +LPSTR TranslateU( LPCSTR lpText ); +int msgbox( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ); +void CopyToClipboard(HWND hwnd,LPSTR msg); +#define msgbox0(a,b,c,d) msgbox(a,b,c,d) +#define msgbox1(a,b,c,d) msgbox(a,b,c,d) + +#endif + +// EOF diff --git a/plugins/SecureIM/src/crypt.h b/plugins/SecureIM/src/crypt.h new file mode 100644 index 0000000000..e626570f9e --- /dev/null +++ b/plugins/SecureIM/src/crypt.h @@ -0,0 +1,183 @@ +#ifndef __CRYPT_H__ +#define __CRYPT_H__ + +#include "secureim.h" +#include "cryptopp.h" +#include "gettime.h" + +#define KEYSIZE 256 +#define NAMSIZE 512 +#define DEFMSGS 4096 + +#define KEY_A_SIG 0x000000 +#define KEY_B_SIG 0x010000 + +// struct to store all supported protocols +struct SupPro { + LPSTR name; + BOOL inspecting; + int split_on,tsplit_on; + int split_off,tsplit_off; +}; +typedef SupPro *pSupPro; + +// struct to store wainting messages +struct waitingMessage { + LPSTR Message; + WPARAM wParam; + waitingMessage *nextMessage; +}; +typedef waitingMessage* pWM; + +struct partitionMessage { + int id; + LPSTR *message; // array of message parts + partitionMessage *nextMessage; +}; +typedef partitionMessage* pPM; + +#define HEADER 0xABCD1234 +#define FOOTER 0x9876FEDC +#define EMPTYH 0xF1E2D3C4 + +// memory struct for keys +struct UinKey { + u_int header; // HEADER + HANDLE hContact; // handle of contact + pSupPro proto; // proto struct + BYTE mode,tmode; // mode: Native,PGP,GPG,RSA/AES,RSA [0..4] + BYTE status,tstatus; // status: Disabled,Enabled,AlwaysTry [0..2] for Native mode + LPSTR msgSplitted; // message to combine + pPM msgPart; // parts of message + pWM msgQueue; // last messages not sended or to resend; + BOOL sendQueue; // идет отсылка очереди - не обрабатываются сообщения + BOOL offlineKey; + char waitForExchange; // 0 - сбросить очередь + // 1 - ожидаем + // 2 - дослать с шифрованием + // 3 - дослать без шифрования с вопросом + BOOL decoded; // false on decode error + short features; + HANDLE cntx; // crypto context + BYTE keyLoaded; // ( 1-PGP, 2-GPG ) | 1-RSA + BYTE gpgMode,tgpgMode; // 0-UTF8, 1-ANSI + char *lastFileRecv; + char *lastFileSend; + char **fileSend; + BOOL finFileRecv; + BOOL finFileSend; + LPSTR tmp; // tmp text string + u_int footer; // FOOTER +}; +typedef UinKey* pUinKey; + +struct TFakeAckParams { + inline TFakeAckParams( HANDLE p1, HANDLE p2, LONG p3, LPCSTR p4 ) : + hEvent( p1 ), + hContact( p2 ), + id( p3 ), + msg( p4 ) + {} + + HANDLE hEvent; + HANDLE hContact; + LONG id; + LPCSTR msg; +}; + +struct TWaitForExchange { + inline TWaitForExchange( HANDLE p1, HANDLE p2 ) : + hEvent( p1 ), + hContact( p2 ) + {} + + HANDLE hEvent; + HANDLE hContact; +}; + +extern char szUIN[NAMSIZE]; +extern char szName[NAMSIZE]; +extern pSupPro proto; +extern pUinKey clist; +extern int proto_cnt; +extern int clist_cnt; + +// crypt_lists.cpp +void loadContactList(); +void freeContactList(); +pUinKey addContact(HANDLE); +void delContact(HANDLE); +pSupPro getSupPro(HANDLE); +pUinKey getUinKey(HANDLE); +pUinKey getUinCtx(HANDLE); +void addMsg2Queue(pUinKey,WPARAM,LPSTR); + +void getContactName(HANDLE hContact, LPSTR szName); +void getContactNameA(HANDLE hContact, LPSTR szName); +void getContactUin(HANDLE hContact, LPSTR szUIN); +void getContactUinA(HANDLE hContact, LPSTR szUIN); + +// crypt_check.cpp +int getContactStatus(HANDLE); + +BOOL isSecureProtocol(HANDLE); +BYTE isContactSecured(HANDLE); +BOOL isClientMiranda(pUinKey ptr, BOOL emptyMirverAsMiranda=FALSE); +BOOL isClientMiranda(HANDLE hContact, BOOL emptyMirverAsMiranda=FALSE); +BOOL isProtoSmallPackets(HANDLE); +BOOL isContactInvisible(HANDLE); +BOOL isNotOnList(HANDLE); +BOOL isContactNewPG(HANDLE); +BOOL isContactPGP(HANDLE); +BOOL isContactGPG(HANDLE); +BOOL isContactRSAAES(HANDLE); +BOOL isContactRSA(HANDLE); +BOOL isChatRoom(HANDLE); +BOOL isFileExist(LPCSTR); +BOOL isSecureIM(pUinKey ptr, BOOL emptyMirverAsSecureIM=FALSE); +BOOL isSecureIM(HANDLE hContact, BOOL emptyMirverAsSecureIM=FALSE); + +// crypt_icons.cpp +HICON mode2icon(int,int); +HICON mode2icon2(int,int); // создает КОПИЮ иконки, которую надо разрушить +IconExtraColumn mode2iec(int); +void RefreshContactListIcons(void); +void ShowStatusIcon(HANDLE,UINT); +void ShowStatusIcon(HANDLE); +void ShowStatusIconNotify(HANDLE); + +// crypt_popups.cpp +//static int CALLBACK PopupDlgProc(HWND,UINT,WPARAM,LPARAM); +void showPopUp(LPCSTR,HANDLE,HICON,UINT); +void showPopUpEC(HANDLE); +void showPopUpDCmsg(HANDLE,LPCSTR); +void showPopUpDC(HANDLE); +void showPopUpKS(HANDLE); +void showPopUpKRmsg(HANDLE,LPCSTR); +void showPopUpKR(HANDLE); +void showPopUpSM(HANDLE); +void showPopUpRM(HANDLE); + +// crypt_meta.cpp +BOOL isProtoMetaContacts(HANDLE); +BOOL isDefaultSubContact(HANDLE); +HANDLE getMetaContact(HANDLE); +HANDLE getMostOnline(HANDLE); +void DeinitMetaContact(HANDLE); + +// crypt_dll.cpp +LPSTR InitKeyA(pUinKey,int); +int InitKeyB(pUinKey,LPCSTR); +void InitKeyX(pUinKey,BYTE*); +BOOL CalculateKeyX(pUinKey,HANDLE); +LPSTR encodeMsg(pUinKey,LPARAM); +LPSTR decodeMsg(pUinKey,LPARAM,LPSTR); +BOOL LoadKeyPGP(pUinKey); +BOOL LoadKeyGPG(pUinKey); + +// crypt_misc.cpp +unsigned __stdcall sttFakeAck(LPVOID); +unsigned __stdcall sttWaitForExchange(LPVOID); +void waitForExchange(pUinKey ptr, int flag = 1); + +#endif diff --git a/plugins/SecureIM/src/crypt_check.cpp b/plugins/SecureIM/src/crypt_check.cpp new file mode 100644 index 0000000000..3a4a0e0c30 --- /dev/null +++ b/plugins/SecureIM/src/crypt_check.cpp @@ -0,0 +1,267 @@ +#include "commonheaders.h" + + +int getContactStatus(HANDLE hContact) { + + pSupPro ptr = getSupPro(hContact); + if (ptr) + return DBGetContactSettingWord(hContact, ptr->name, "Status", ID_STATUS_OFFLINE); + + return -1; +} + + +BOOL isSecureProtocol(HANDLE hContact) { + + pSupPro ptr = getSupPro(hContact); + if (!ptr) return false; + + return ptr->inspecting; +} + + +BYTE isContactSecured(HANDLE hContact) { + // нужна проверка на Offline и в этом случае другие статусы + if (!clist_cnt) return 0; + + BYTE r=0; + if ( isProtoMetaContacts(hContact)) + hContact = getMostOnline(hContact); // возьмем тот, через который пойдет сообщение + + for(int j=0;jinspecting ) break; + DBVARIANT dbv; + r=clist[j].mode; + switch(r) { + case MODE_NATIVE: + if(cpp_keyx(clist[j].cntx)!=0) r|=SECURED; + break; + case MODE_PGP: + DBGetContactSetting(hContact,szModuleName,"pgp",&dbv); + if ( dbv.type!=0 ) r|=SECURED; + DBFreeVariant(&dbv); + break; + case MODE_GPG: + DBGetContactSetting(hContact,szModuleName,"gpg",&dbv); + if ( dbv.type!=0 ) r|=SECURED; + DBFreeVariant(&dbv); + break; + case MODE_RSAAES: + if(exp->rsa_get_state(clist[j].cntx)==7) r|=SECURED; + break; + case MODE_RSA: + if(clist[j].cntx) r|=SECURED; + break; + } + break; + } + } + return r; // (mode&SECURED) - проверка на EST/DIS +} + + +BOOL isClientMiranda(pUinKey ptr, BOOL emptyMirverAsMiranda) { + + if ( !bMCD ) return true; + if ( !ptr->proto->inspecting ) return false; + + BOOL isMiranda = true; + LPSTR mirver = myDBGetString(ptr->hContact,ptr->proto->name,"MirVer"); + if ( mirver ) { + isMiranda = (emptyMirverAsMiranda && !*mirver) || (strstr(mirver,"Miranda")!=NULL); + mir_free(mirver); + } + return isMiranda; +} + + +BOOL isClientMiranda(HANDLE hContact, BOOL emptyMirverAsMiranda) { + + if ( !bMCD ) return true; + if ( !clist_cnt ) return false; + + for(int j=0;jinspecting ) break; + return strstr(clist[j].proto->name,"IRC")!=NULL || + strstr(clist[j].proto->name,"WinPopup")!=NULL || + strstr(clist[j].proto->name,"VyChat")!=NULL; + } + } + return false; +} + + +BOOL isContactInvisible(HANDLE hContact) { + + if ( !DBGetContactSettingByte(hContact,"CList","Hidden",0)) { + if ( !clist_cnt ) return false; + for(int j=0;jinspecting ) return false; + if ( clist[j].waitForExchange ) return false; + switch( (int)DBGetContactSettingWord(hContact,clist[j].proto->name,"ApparentMode",0)) { + case 0: + return (CallProtoService(clist[j].proto->name,PS_GETSTATUS,0,0)==ID_STATUS_INVISIBLE); + case ID_STATUS_ONLINE: + return false; + case ID_STATUS_OFFLINE: + return true; + } //switch + break; + } + }// for + } + return true; +} + + +BOOL isNotOnList(HANDLE hContact) { + return DBGetContactSettingByte(hContact, "CList", "NotOnList", 0); +} + + +BOOL isContactNewPG(HANDLE hContact) { + + if (!clist_cnt) return false; + for(int j=0;jinspecting ) break; + if ( !clist[j].cntx ) break; + return (clist[j].features & CPP_FEATURES_NEWPG) != 0; + } + } + return false; +} + + +BOOL isContactPGP(HANDLE hContact) { + + if (!bPGPloaded || (!bPGPkeyrings && !bPGPprivkey)) return false; + if (!clist_cnt) return false; + for(int j=0;jinspecting ) break; + if ( clist[j].mode!=MODE_PGP ) break; + DBVARIANT dbv; + DBGetContactSetting(hContact,szModuleName,"pgp",&dbv); + BOOL r=(dbv.type!=0); + DBFreeVariant(&dbv); + return r; + } + } + return false; +} + + +BOOL isContactGPG(HANDLE hContact) { + + if (!bGPGloaded || !bGPGkeyrings) return false; + if (!clist_cnt) return false; + for(int j=0;jinspecting ) break; + if ( clist[j].mode!=MODE_GPG ) break; + DBVARIANT dbv; + DBGetContactSetting(hContact,szModuleName,"gpg",&dbv); + BOOL r=(dbv.type!=0); + DBFreeVariant(&dbv); + return r; + } + } + return false; +} + + +BOOL isContactRSAAES(HANDLE hContact) { + + if (!clist_cnt) return false; + for(int j=0;jinspecting ) break; + if ( clist[j].mode!=MODE_RSAAES ) break; + return true; + } + } + return false; +} + + +BOOL isContactRSA(HANDLE hContact) { + + if (!clist_cnt) return false; + for(int j=0;jinspecting ) break; + if ( clist[j].mode!=MODE_RSA ) break; + return true; + } + } + return false; +} + + +BOOL isChatRoom(HANDLE hContact) { + + if (!clist_cnt) return false; + for(int j=0;jinspecting ) break; + return (DBGetContactSettingByte(hContact,clist[j].proto->name,"ChatRoom",0)!=0); + } + } + return false; +} + + +BOOL isFileExist(LPCSTR filename) { + return (GetFileAttributes(filename)!=(UINT)-1); +} + + +BOOL isSecureIM(pUinKey ptr, BOOL emptyMirverAsSecureIM) { + + if ( !bAIP ) return false; + if ( !ptr->proto->inspecting ) return false; + + BOOL isSecureIM = false; + if ( bNOL && DBGetContactSettingByte(ptr->hContact,"CList","NotOnList",0)) { + return false; + } + LPSTR mirver = myDBGetString(ptr->hContact,ptr->proto->name,"MirVer"); + if ( mirver ) { + isSecureIM = (emptyMirverAsSecureIM && !*mirver) || (strstr(mirver,"SecureIM")!=NULL) || (strstr(mirver,"secureim")!=NULL); + mir_free(mirver); + } + return isSecureIM; +} + + +BOOL isSecureIM(HANDLE hContact, BOOL emptyMirverAsSecureIM) { + + if ( !bAIP ) return false; + if ( !clist_cnt ) return false; + + for(int j=0;jcntx ) + ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0); + + char *tmp = myDBGetString(ptr->hContact,szModuleName,"PSK"); + if(tmp) { + cpp_init_keyp(ptr->cntx,tmp); // make pre-shared key from password + mir_free(tmp); + } + + LPSTR pub_text = cpp_init_keya(ptr->cntx,features); // calculate public and private key & fill KeyA + + LPSTR keysig; + if(features&CPP_FEATURES_NEWPG) { + if(features&KEY_B_SIG) + keysig = (LPSTR)SIG_KEYB; + else + keysig = (LPSTR)SIG_KEYA; + } + else + if(isProtoSmallPackets(ptr->hContact)) + keysig = (LPSTR)SIG_KEY4; + else + keysig = (LPSTR)SIG_KEY3; + + int slen = (int)strlen(keysig); + int tlen = (int)strlen(pub_text); + + LPSTR keyToSend = (LPSTR) mir_alloc(slen+tlen+1); + + memcpy(keyToSend,keysig,slen); + memcpy(keyToSend+slen,pub_text,tlen+1); + + return keyToSend; +} + +// store KeyB into context +int InitKeyB(pUinKey ptr,LPCSTR key) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("InitKeyB: %s", key); +#endif + if (!ptr->cntx) + ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0); + + if (!cpp_keyp(ptr->cntx)) { + char *tmp = myDBGetString(ptr->hContact,szModuleName,"PSK"); + if(tmp) { + cpp_init_keyp(ptr->cntx,tmp); // make pre-shared key from password + mir_free(tmp); + } + } + + cpp_init_keyb(ptr->cntx,key); + ptr->features = cpp_get_features(ptr->cntx); + + return cpp_get_error(ptr->cntx); +} + + +// store KeyX into context +void InitKeyX(pUinKey ptr,BYTE *key) { + + if (!ptr->cntx) + ptr->cntx = cpp_create_context(isProtoSmallPackets(ptr->hContact)?CPP_MODE_BASE64:0); + + cpp_set_keyx(ptr->cntx,key); +} + + +// calculate secret key +BOOL CalculateKeyX(pUinKey ptr,HANDLE hContact) { + + int agr = cpp_calc_keyx(ptr->cntx); + if ( agr ) { + // do this only if key exchanged is ok + // we use a 192bit key + int keysize = cpp_size_keyx(); + PBYTE buffer = (PBYTE) alloca(keysize); // buffer for hash + + // store key + cpp_get_keyx(ptr->cntx,buffer); + + DBCONTACTWRITESETTING cws; + cws.szModule = szModuleName; + + // store key in database + cws.szSetting = "offlineKey"; + cws.value.type = DBVT_BLOB; + cws.value.cpbVal = keysize; + cws.value.pbVal = buffer; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); + + // store timeout of key in database (2 days) + cws.szSetting = "offlineKeyTimeout"; + cws.value.type = DBVT_DWORD; + cws.value.dVal = gettime()+(60*60*24*DBGetContactSettingWord(0,szModuleName,"okt",2)); + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); + + // key exchange is finished + showPopUpEC(ptr->hContact); + } + else { + // agree value problem + showPopUp(sim002,hContact,g_hPOP[POP_PU_DIS],0); + } + return agr!=0; +} + + +// encrypt message +LPSTR encrypt(pUinKey ptr, LPCSTR szEncMsg) { + + LPSTR szSig = (LPSTR) (ptr->offlineKey?SIG_ENOF:SIG_ENON); + + int slen = (int)strlen(szSig); + int clen = (int)strlen(szEncMsg); + + LPSTR szMsg = (LPSTR) mir_alloc(clen+slen+1); + memcpy(szMsg, szSig, slen); + memcpy(szMsg+slen, szEncMsg, clen+1); + + return szMsg; +} + + +// encode message +LPSTR encodeMsg(pUinKey ptr, LPARAM lParam) { + + CCSDATA *pccsd = (CCSDATA *)lParam; + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = (LPSTR) pccsd->lParam; + + if ( pccsd->wParam & PREF_UTF ) + szNewMsg = encrypt(ptr,cpp_encodeU(ptr->cntx,szOldMsg)); + else + if ( pccsd->wParam & PREF_UNICODE ) + szNewMsg = encrypt(ptr,cpp_encodeW(ptr->cntx,(LPWSTR)(szOldMsg+strlen(szOldMsg)+1))); + else + szNewMsg = encrypt(ptr,cpp_encodeA(ptr->cntx,szOldMsg)); + +// pccsd->wParam &= ~(PREF_UNICODE|PREF_UTF); + pccsd->wParam &= ~PREF_UNICODE; + + return szNewMsg; +} + + +// decode message +LPSTR decodeMsg(pUinKey ptr, LPARAM lParam, LPSTR szEncMsg) { + + CCSDATA *pccsd = (CCSDATA *)lParam; + PROTORECVEVENT *ppre = (PROTORECVEVENT *)pccsd->lParam; + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = (ppre->flags&PREF_UTF)?cpp_decodeU(ptr->cntx,szEncMsg):cpp_decode(ptr->cntx,szEncMsg); + + if(szOldMsg == NULL) { + ptr->decoded=false; + switch(cpp_get_error(ptr->cntx)) { + case CPP_ERROR_BAD_LEN: + szNewMsg = mir_strdup(Translate(sim102)); + break; + case CPP_ERROR_BAD_CRC: + szNewMsg = mir_strdup(Translate(sim103)); + break; + default: { + ptr->decoded=true; + szNewMsg = mir_strdup(Translate(sim101)); + } + break; + } + ppre->flags &= ~(PREF_UNICODE|PREF_UTF); + pccsd->wParam &= ~(PREF_UNICODE|PREF_UTF); + } + else { + ptr->decoded=true; + if ( ppre->flags & PREF_UTF ) { // Ґб«Ё Їа®в®Є®« Ї®¤¤Ґа¦Ёў Ґв utf8 - в®Ј¤  ®вЇа ў«пҐ¬ ў utf8 + int olen = (int)strlen(szOldMsg)+1; + szNewMsg = (LPSTR) mir_alloc(olen); + memcpy(szNewMsg,szOldMsg,olen); + } + else { + int olen = ((int)strlen(szOldMsg)+1)*(sizeof(WCHAR)+1); + szNewMsg = (LPSTR) mir_alloc(olen); + memcpy(szNewMsg,szOldMsg,olen); + ppre->flags |= PREF_UNICODE; + pccsd->wParam |= PREF_UNICODE; + } + } + ppre->szMessage = szNewMsg; + return szNewMsg; +} + + +BOOL LoadKeyPGP(pUinKey ptr) { + int mode = DBGetContactSettingByte(ptr->hContact,szModuleName,"pgp_mode",255); + if(mode==0) { + DBVARIANT dbv; + DBGetContactSetting(ptr->hContact,szModuleName,"pgp",&dbv); + BOOL r=(dbv.type==DBVT_BLOB); + if(r) pgp_set_keyid(ptr->cntx,(PVOID)dbv.pbVal); + DBFreeVariant(&dbv); + return r; + } + else + if(mode==1) { + LPSTR key = myDBGetStringDecode(ptr->hContact,szModuleName,"pgp"); + if ( key ) { + pgp_set_key(ptr->cntx,key); + mir_free(key); + return 1; + } + } + return 0; +} + + +BOOL LoadKeyGPG(pUinKey ptr) { + + LPSTR key = myDBGetString(ptr->hContact,szModuleName,"gpg"); + if ( key ) { + gpg_set_keyid(ptr->cntx,key); + mir_free(key); + return 2; + } + return 0; +} + +// EOF diff --git a/plugins/SecureIM/src/crypt_icons.cpp b/plugins/SecureIM/src/crypt_icons.cpp new file mode 100644 index 0000000000..6c5984c345 --- /dev/null +++ b/plugins/SecureIM/src/crypt_icons.cpp @@ -0,0 +1,151 @@ +#include "commonheaders.h" + + +typedef struct { + HICON icon; + SHORT mode; +} ICON_CACHE; + + +ICON_CACHE *ICONS_CACHE = NULL; +int icons_cache = 0; + + +// преобразует mode в HICON который НЕ НУЖНО разрушать в конце +HICON mode2icon(int mode,int type) { + + int m=mode&0x0f,s=(mode&SECURED)>>4,i; // разобрали на части - режим и состояние + HICON icon; + + if ( icons_cache ) { + for(i=0;i>4; // разобрали на части - режим и состояние + + if ( mode==-1 || (!s && !bASI && m!=MODE_PGP && m!=MODE_GPG)) { + return g_IEC[0]; // вернем пустое место + } + + int i=1+m*IEC_CNT+IEC_CL_DIS+s; + if ( g_IEC[i].hImage==(HANDLE)-1 ) { +/* g_hIEC[i] = mode2icon(mode,1); + g_IEC[i].hImage = (HANDLE) CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)g_hIEC[i], (LPARAM)0);*/ + HICON icon = mode2icon(mode,1); + g_IEC[i].hImage = (HANDLE) CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)icon, (LPARAM)0); + } + return g_IEC[i]; +} + + +// обновляет иконки в clist и в messagew +void ShowStatusIcon(HANDLE hContact,int mode) { + + HANDLE hMC = getMetaContact(hContact); + if ( bADV || g_hCLIcon ) { // обновить иконки в clist + if ( mode!= -1 ) { + IconExtraColumn iec=mode2iec(mode); + if ( g_hCLIcon ) { + ExtraIcon_SetIcon(g_hCLIcon, hContact, iec.hImage); + if ( hMC ) + ExtraIcon_SetIcon(g_hCLIcon, hMC, iec.hImage); + } + else { + CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)hContact, (LPARAM)&iec); + if ( hMC ) + CallService(MS_CLIST_EXTRA_SET_ICON, (WPARAM)hMC, (LPARAM)&iec); + } + } + } + if ( ServiceExists(MS_MSG_MODIFYICON)) { // обновить иконки в srmm + StatusIconData sid; + memset(&sid,0,sizeof(sid)); + sid.cbSize = sizeof(sid); + sid.szModule = (char*)szModuleName; + for(int i=MODE_NATIVE; itype == PROTOTYPE_PROTOCOL && protos[i]->szName && (CallProtoService(protos[i]->szName,PS_GETCAPS,PFLAGNUM_2,0)||strcmp(protos[i]->szName,"MetaContacts")==0)) { + if (protos[i]->type == PROTOTYPE_PROTOCOL && protos[i]->szName && CallProtoService(protos[i]->szName,PS_GETCAPS,PFLAGNUM_2,0)) { + int j = proto_cnt; proto_cnt++; + proto = (pSupPro) mir_realloc(proto,sizeof(SupPro)*proto_cnt); + memset(&proto[j],0,sizeof(SupPro)); + proto[j].name = mir_strdup(protos[i]->szName); + if ( szNames ) { + if ( proto[j].name ) { + char tmp[128]; strcpy(tmp,proto[j].name); strcat(tmp,":"); + LPSTR szName = strstr(szNames,tmp); + if ( szName ) { + szName = strchr(szName,':'); + if ( szName ) { + proto[j].inspecting = (*++szName == '1'); + szName = strchr(szName,':'); + if ( szName ) { + proto[j].split_on = atoi(++szName); proto[j].tsplit_on = proto[j].split_on; + szName = strchr(szName,':'); + if ( szName ) { + proto[j].split_off = atoi(++szName); proto[j].tsplit_off = proto[j].split_off; + } + } + } + } + } + } + else { + proto[j].inspecting = true; + } + } + } + SAFE_FREE(szNames); +} + + +void freeSupportedProtocols() { + for (int j=0;jmsgQueue==NULL){ + // create new + ptr->msgQueue = (pWM) mir_alloc(sizeof(struct waitingMessage)); + ptrMessage = ptr->msgQueue; + } + else { + // add to list + ptrMessage = ptr->msgQueue; + while (ptrMessage->nextMessage) { + ptrMessage = ptrMessage->nextMessage; + } + ptrMessage->nextMessage = (pWM) mir_alloc(sizeof(struct waitingMessage)); + ptrMessage = ptrMessage->nextMessage; + } + + ptrMessage->wParam = wParam; + ptrMessage->nextMessage = NULL; + + if(wParam & PREF_UNICODE) { + int slen = (int)strlen(szMsg)+1; + int wlen = (int)wcslen((wchar_t *)(szMsg+slen))+1; + ptrMessage->Message = (LPSTR) mir_alloc(slen+wlen*sizeof(WCHAR)); + memcpy(ptrMessage->Message,szMsg,slen+wlen*sizeof(WCHAR)); + } + else{ + ptrMessage->Message = mir_strdup(szMsg); + } + + LeaveCriticalSection(&localQueueMutex); +} + + +void getContactNameA(HANDLE hContact, LPSTR szName) { + strcpy(szName,(LPCSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0)); +} + + +void getContactName(HANDLE hContact, LPSTR szName) { + if ( bCoreUnicode ) wcscpy((LPWSTR)szName,(LPWSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GSMDF_UNICODE)); + else getContactNameA(hContact, szName); +} + + +void getContactUinA(HANDLE hContact, LPSTR szUIN) { + + *szUIN = 0; + + pSupPro ptr = getSupPro(hContact); + if (!ptr) return; + + DBVARIANT dbv_uniqueid; + LPSTR uID = (LPSTR) CallProtoService(ptr->name, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + if ( uID==(LPSTR)CALLSERVICE_NOTFOUND ) uID = 0; // Billy_Bons + if ( uID && DBGetContactSetting(hContact, ptr->name, uID, &dbv_uniqueid)==0 ) { + if (dbv_uniqueid.type == DBVT_WORD) + sprintf(szUIN, "%u [%s]", dbv_uniqueid.wVal, ptr->name); + else + if (dbv_uniqueid.type == DBVT_DWORD) + sprintf(szUIN, "%u [%s]", (UINT)dbv_uniqueid.dVal, ptr->name); + else + if (dbv_uniqueid.type == DBVT_BLOB) + sprintf(szUIN, "%s [%s]", dbv_uniqueid.pbVal, ptr->name); + else + sprintf(szUIN, "%s [%s]", dbv_uniqueid.pszVal, ptr->name); + } + else { + strcpy(szUIN, "=== unknown ==="); + } + DBFreeVariant(&dbv_uniqueid); +} + + +void getContactUin(HANDLE hContact, LPSTR szUIN) { + getContactUinA(hContact, szUIN); + if ( bCoreUnicode && *szUIN ) { + LPWSTR tmp = mir_a2u(szUIN); + wcscpy((LPWSTR)szUIN, tmp); + mir_free(tmp); + } +} + + +// EOF diff --git a/plugins/SecureIM/src/crypt_metacontacts.cpp b/plugins/SecureIM/src/crypt_metacontacts.cpp new file mode 100644 index 0000000000..f36c7e4dd3 --- /dev/null +++ b/plugins/SecureIM/src/crypt_metacontacts.cpp @@ -0,0 +1,60 @@ +#include "commonheaders.h" + + +BOOL isProtoMetaContacts(HANDLE hContact) { + if(bMetaContacts) { + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if ( proto && strcmp(proto,"MetaContacts")==0 ) { + return true; + } + } +// for(int j=0;jinspecting) +// return strstr(clist[j].proto->name,"MetaContacts")!=NULL; + return false; +} + + +BOOL isDefaultSubContact(HANDLE hContact) { + + if(bMetaContacts) { + return (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT,(WPARAM)CallService(MS_MC_GETMETACONTACT,(WPARAM)hContact,0),0)==hContact; + } + return false; +} + + +HANDLE getMetaContact(HANDLE hContact) { + + if(bMetaContacts) { + return (HANDLE)CallService(MS_MC_GETMETACONTACT,(WPARAM)hContact,0); + } + return 0; +} + + +HANDLE getMostOnline(HANDLE hContact) { + + if(bMetaContacts) { + return (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(WPARAM)hContact,0); + } + return 0; +} + + +// remove all secureim connections on subcontacts +void DeinitMetaContact(HANDLE hContact) { + + HANDLE hMetaContact = isProtoMetaContacts(hContact) ? hContact : getMetaContact(hContact); + + if ( hMetaContact ) { + for(int i=0;ihEvent, INFINITE ); + + Sleep( 100 ); + if ( tParam->msg == NULL ) + SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, ( HANDLE )tParam->id, 0 ); + else + SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, ( HANDLE )tParam->id, LPARAM( tParam->msg )); + + CloseHandle( tParam->hEvent ); + delete tParam; + + return 0; +} + + +unsigned __stdcall sttWaitForExchange( LPVOID param ) { + + TWaitForExchange* tParam = ( TWaitForExchange* )param; + WaitForSingleObject( tParam->hEvent, INFINITE ); + + pUinKey ptr = getUinKey(tParam->hContact); + delete tParam; + + if ( !ptr ) return 0; + + for(int i=0;iwaitForExchange != 1 ) break; + } // for + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("sttWaitForExchange: %d",ptr->waitForExchange); +#endif + // if keyexchange failed or timeout + if ( ptr->waitForExchange==1 || ptr->waitForExchange==3 ) { // Їа®вге«® - ®вЇа ў«пҐ¬ ­Ґ§ иЁда®ў ­­®, Ґб«Ё ­ ¤® + if ( ptr->msgQueue && msgbox1(0,sim104,szModuleName,MB_YESNO|MB_ICONQUESTION)==IDYES ) { + EnterCriticalSection(&localQueueMutex); + ptr->sendQueue = true; + pWM ptrMessage = ptr->msgQueue; + while( ptrMessage ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("Sent (unencrypted) message from queue: %s",ptrMessage->Message); +#endif + // send unencrypted messages + CallContactService(ptr->hContact,PSS_MESSAGE,(WPARAM)ptrMessage->wParam|PREF_METANODB,(LPARAM)ptrMessage->Message); + mir_free(ptrMessage->Message); + pWM tmp = ptrMessage; + ptrMessage = ptrMessage->nextMessage; + mir_free(tmp); + } + ptr->msgQueue = NULL; + ptr->sendQueue = false; + LeaveCriticalSection(&localQueueMutex); + } + ptr->waitForExchange = 0; + ShowStatusIconNotify(ptr->hContact); + } + else + if ( ptr->waitForExchange==2 ) { // ¤®б« вм ®зҐаҐ¤м зҐаҐ§ гбв ­®ў«Ґ­­®Ґ ᮥ¤Ё­Ґ­ЁҐ + EnterCriticalSection(&localQueueMutex); + // we need to resend last send back message with new crypto Key + pWM ptrMessage = ptr->msgQueue; + while (ptrMessage) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("Sent (encrypted) message from queue: %s",ptrMessage->Message); +#endif + // send unencrypted messages + CallContactService(ptr->hContact,PSS_MESSAGE,(WPARAM)ptrMessage->wParam|PREF_METANODB,(LPARAM)ptrMessage->Message); + mir_free(ptrMessage->Message); + pWM tmp = ptrMessage; + ptrMessage = ptrMessage->nextMessage; + mir_free(tmp); + } + ptr->msgQueue = NULL; + ptr->waitForExchange = 0; + LeaveCriticalSection(&localQueueMutex); + } + else + if ( ptr->waitForExchange==0 ) { // ®зЁбвЁвм ®зҐаҐ¤м + EnterCriticalSection(&localQueueMutex); + // we need to resend last send back message with new crypto Key + pWM ptrMessage = ptr->msgQueue; + while (ptrMessage) { + mir_free(ptrMessage->Message); + pWM tmp = ptrMessage; + ptrMessage = ptrMessage->nextMessage; + mir_free(tmp); + } + ptr->msgQueue = NULL; + LeaveCriticalSection(&localQueueMutex); + } + return 0; +} + + +// set wait flag and run thread +void waitForExchange(pUinKey ptr, int flag) { + switch( flag ) { + case 0: // бЎа®бЁвм + case 2: // ¤®б« вм иЁда®ў ­® + case 3: // ¤®б« вм ­ҐиЁда®ў ­® + if ( ptr->waitForExchange ) + ptr->waitForExchange = flag; + break; + case 1: // § ЇгбвЁвм + if ( ptr->waitForExchange ) + break; + ptr->waitForExchange = 1; + // § ЇгбЄ Ґ¬ ван¤ + HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + unsigned int tID; + CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttWaitForExchange, new TWaitForExchange(hEvent,ptr->hContact), 0, &tID)); + SetEvent( hEvent ); + break; + } +} + + +// EOF diff --git a/plugins/SecureIM/src/crypt_popups.cpp b/plugins/SecureIM/src/crypt_popups.cpp new file mode 100644 index 0000000000..836a68efc1 --- /dev/null +++ b/plugins/SecureIM/src/crypt_popups.cpp @@ -0,0 +1,153 @@ +#include "commonheaders.h" + +/* +static int CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + switch(message) { + case WM_COMMAND: + if (wParam == STN_CLICKED) { // It was a click on the Popup. + PUDeletePopUp(hWnd); + return TRUE; + } + break; + case UM_FREEPLUGINDATA: { + return TRUE; //TRUE or FALSE is the same, it gets ignored. + } + default: + break; + } + return DefWindowProc(hWnd, message, wParam, lParam); +} +*/ + +void showPopUp(LPCSTR lpzText,HANDLE hContact,HICON hIcon, UINT type) { + //type=0 key colors + //type=1 session colors + //type=2 SR colors + + if (!bPopupExists) return; + + //hContact = A_VALID_HANDLE_YOU_GOT_FROM_SOMEWHERE; + COLORREF colorBackKey = RGB(230,230,255); + COLORREF colorTextKey = RGB(0,0,0); + COLORREF colorBackSec = RGB(255,255,200); + COLORREF colorTextSec = RGB(0,0,0); + COLORREF colorBackSR = RGB(200,255,200); + COLORREF colorTextSR = RGB(0,0,0); + COLORREF colorBack = 0; + COLORREF colorText = 0; + int timeout=0; + int res; + + DBVARIANT dbv_timeout; + + if (type==0) { + colorBack=DBGetContactSettingDword(0,szModuleName,"colorKeyb",(UINT)-1); + colorText=DBGetContactSettingDword(0,szModuleName,"colorKeyt",(UINT)-1); + if (colorBack==(UINT)-1) colorBack=colorBackKey; + if (colorText==(UINT)-1) colorText=colorTextKey; + + res=DBGetContactSetting(0,szModuleName,"timeoutKey",&dbv_timeout); + if (res==0) timeout=atoi(dbv_timeout.pszVal); + DBFreeVariant(&dbv_timeout); + } + else if (type==1) { + colorBack=DBGetContactSettingDword(0,szModuleName,"colorSecb",(UINT)-1); + colorText=DBGetContactSettingDword(0,szModuleName,"colorSect",(UINT)-1); + if (colorBack==(UINT)-1) colorBack=colorBackSec; + if (colorText==(UINT)-1) colorText=colorTextSec; + + res=DBGetContactSetting(0,szModuleName,"timeoutSec",&dbv_timeout); + if (res==0) timeout=atoi(dbv_timeout.pszVal); + DBFreeVariant(&dbv_timeout); + } + else if (type>=2) { + colorBack=DBGetContactSettingDword(0, szModuleName, "colorSRb", (UINT)-1); + colorText=DBGetContactSettingDword(0, szModuleName, "colorSRt", (UINT)-1); + if (colorBack==(UINT)-1) colorBack=colorBackSR; + if (colorText==(UINT)-1) colorText=colorTextSR; + + res=DBGetContactSetting(0,szModuleName,"timeoutSR",&dbv_timeout); + if (res==0) timeout=atoi(dbv_timeout.pszVal); + DBFreeVariant(&dbv_timeout); + } + + if ( bCoreUnicode && bPopupUnicode ) { + POPUPDATAW ppd = {0}; + + ppd.lchContact = hContact; //Be sure to use a GOOD handle, since this will not be checked. + ppd.lchIcon = hIcon; + LPWSTR lpwzContactName = (LPWSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GSMDF_UNICODE); + wcscpy(ppd.lpwzContactName, lpwzContactName); + LPWSTR lpwzText = mir_a2u(lpzText); + wcscpy(ppd.lpwzText, TranslateW(lpwzText)); + mir_free(lpwzText); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.iSeconds = timeout; +// ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; + + //Now that the plugin data has been filled, we add it to the PopUpData. +// ppd.PluginData = NULL; + + //Now that every field has been filled, we want to see the popup. + PUAddPopUpW(&ppd); + } + else { + POPUPDATAEX ppd = {0}; + + ppd.lchContact = hContact; //Be sure to use a GOOD handle, since this will not be checked. + ppd.lchIcon = hIcon; + LPSTR lpzContactName = (LPSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); + strcpy(ppd.lpzContactName, lpzContactName); + strcpy(ppd.lpzText, Translate(lpzText)); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.iSeconds = timeout; +// ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; + + //Now that the plugin data has been filled, we add it to the PopUpData. +// ppd.PluginData = NULL; + + //Now that every field has been filled, we want to see the popup. + PUAddPopUpEx(&ppd); + } +} + + +void showPopUpDCmsg(HANDLE hContact,LPCSTR msg) { + int indic=DBGetContactSettingByte(0, szModuleName, "dc",1); + if (indic==1) showPopUp(msg,hContact,g_hPOP[POP_PU_DIS],1); +} +void showPopUpDC(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "dc",1); + if (indic==1) showPopUp(sim006,hContact,g_hPOP[POP_PU_DIS],1); +} +void showPopUpEC(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "ec",1); + if (indic==1) showPopUp(sim001,hContact,g_hPOP[POP_PU_EST],1); +} +void showPopUpKS(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "ks",1); + if (indic==1) showPopUp(sim007,hContact,g_hPOP[POP_PU_PRC],0); +} +void showPopUpKRmsg(HANDLE hContact,LPCSTR msg) { + int indic=DBGetContactSettingByte(0, szModuleName, "kr",1); + if (indic==1) showPopUp(msg,hContact,g_hPOP[POP_PU_PRC],0); +} +void showPopUpKR(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "kr",1); + if (indic==1) showPopUp(sim008,hContact,g_hPOP[POP_PU_PRC],0); +} +void showPopUpSM(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "ss",0); + if (indic==1) showPopUp(sim009,hContact,g_hPOP[POP_PU_MSS],2); + SkinPlaySound("OutgoingSecureMessage"); +} +void showPopUpRM(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "sr",0); + if (indic==1) showPopUp(sim010,hContact,g_hPOP[POP_PU_MSR],2); + SkinPlaySound("IncomingSecureMessage"); +} + + +// EOF diff --git a/plugins/SecureIM/src/cryptopp.h b/plugins/SecureIM/src/cryptopp.h new file mode 100644 index 0000000000..bfa4e097b3 --- /dev/null +++ b/plugins/SecureIM/src/cryptopp.h @@ -0,0 +1,73 @@ +#ifndef __CRYPTOPP_H__ +#define __CRYPTOPP_H__ + +#define CPP_FEATURES_UTF8 0x01 +#define CPP_FEATURES_BASE64 0x02 +#define CPP_FEATURES_GZIP 0x04 +#define CPP_FEATURES_CRC32 0x08 +#define CPP_FEATURES_PSK 0x10 +#define CPP_FEATURES_NEWPG 0x20 +#define CPP_FEATURES_RSA 0x40 + +#define CPP_MODE_BASE16 0x0000 +#define CPP_MODE_BASE64 0x0001 +#define CPP_MODE_PGP 0x0002 +#define CPP_MODE_GPG 0x0004 +#define CPP_MODE_GPG_ANSI 0x0008 +#define CPP_MODE_PRIV_KEY 0x0010 +#define CPP_MODE_RSA_2048 0x0020 +#define CPP_MODE_RSA_4096 0x0040 +#define CPP_MODE_RSA CPP_MODE_RSA_4096 +#define CPP_MODE_RSA_ONLY 0x0080 +#define CPP_MODE_RSA_ZLIB 0x0100 +#define CPP_MODE_RSA_BER 0x0200 + +#define CPP_ERROR_NONE 0 +#define CPP_ERROR_SEH 1 +#define CPP_ERROR_NO_KEYA 2 +#define CPP_ERROR_NO_KEYB 3 +#define CPP_ERROR_NO_KEYX 4 +#define CPP_ERROR_BAD_LEN 5 +#define CPP_ERROR_BAD_CRC 6 +#define CPP_ERROR_NO_PSK 7 +#define CPP_ERROR_BAD_PSK 8 +#define CPP_ERROR_BAD_KEYB 9 +#define CPP_ERROR_NO_PGP_KEY 10 + +typedef struct { + int (__cdecl *rsa_gen_keypair)(short); // генерит RSA-ключи для указанной длины (либо тока 2048, либо 2048 и 4096) + int (__cdecl *rsa_get_keypair)(short,PBYTE,int*,PBYTE,int*); // возвращает пару ключей для указанной длины + int (__cdecl *rsa_get_keyhash)(short,PBYTE,int*,PBYTE,int*); // возвращает hash пары ключей для указанной длины + int (__cdecl *rsa_set_keypair)(short,PBYTE,int); // устанавливает ключи, указанной длины + int (__cdecl *rsa_get_pubkey)(HANDLE,PBYTE,int*); // возвращает паблик ключ из указанного контекста + int (__cdecl *rsa_set_pubkey)(HANDLE,PBYTE,int); // загружает паблик ключ для указанного контекста + void (__cdecl *rsa_set_timeout)(int); // установить таймаут для установки секюрного соединения + int (__cdecl *rsa_get_state)(HANDLE); // получить статус указанного контекста + int (__cdecl *rsa_get_hash)(PBYTE,int,PBYTE,int*); // вычисляет SHA1(key) + int (__cdecl *rsa_connect)(HANDLE); // запускает процесс установки содинения с указанным контекстом + int (__cdecl *rsa_disconnect)(HANDLE); // разрывает соединение с указанным контекстом + int (__cdecl *rsa_disabled)(HANDLE); // разрывает соединение по причине "disabled" + LPSTR (__cdecl *rsa_recv)(HANDLE,LPCSTR); // необходимо передавать сюда все входящие протокольные сообщения + int (__cdecl *rsa_send)(HANDLE,LPCSTR); // вызываем для отправки сообщения клиенту + int (__cdecl *rsa_encrypt_file)(HANDLE,LPCSTR,LPCSTR); + int (__cdecl *rsa_decrypt_file)(HANDLE,LPCSTR,LPCSTR); + LPSTR (__cdecl *utf8encode)(LPCWSTR); + LPWSTR (__cdecl *utf8decode)(LPCSTR); + int (__cdecl *is_7bit_string)(LPCSTR); + int (__cdecl *is_utf8_string)(LPCSTR); + int (__cdecl *rsa_export_keypair)(short,LPSTR,LPSTR,LPSTR); // export private key + int (__cdecl *rsa_import_keypair)(short,LPSTR,LPSTR); // import & activate private key + int (__cdecl *rsa_export_pubkey)(HANDLE,LPSTR); // export public key from context + int (__cdecl *rsa_import_pubkey)(HANDLE,LPSTR); // import public key into context +} RSA_EXPORT; +typedef RSA_EXPORT* pRSA_EXPORT; + +typedef struct { + int (__cdecl *rsa_inject)(HANDLE,LPCSTR); // вставляет сообщение в очередь на отправку + int (__cdecl *rsa_check_pub)(HANDLE,PBYTE,int,PBYTE,int); // проверяет интерактивно SHA и сохраняет ключ, если все нормально + void (__cdecl *rsa_notify)(HANDLE,int); // нотификация о смене состояния +} RSA_IMPORT; +typedef RSA_IMPORT* pRSA_IMPORT; + + +#endif diff --git a/plugins/SecureIM/src/dbevent.cpp b/plugins/SecureIM/src/dbevent.cpp new file mode 100644 index 0000000000..9b7d8f10c0 --- /dev/null +++ b/plugins/SecureIM/src/dbevent.cpp @@ -0,0 +1,21 @@ +#include "commonheaders.h" + + +void HistoryLog(HANDLE hContact, LPCSTR szText) { + + DBEVENTINFO dbei; + memset(&dbei, 0, sizeof(dbei)); + + dbei.cbSize = sizeof(dbei); + dbei.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + dbei.flags = DBEF_SENT|DBEF_READ; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = (int)strlen(szText) + 1; + dbei.pBlob = (PBYTE)szText; + + CallService(MS_DB_EVENT_ADD, (WPARAM)0, (LPARAM)&dbei); +} + + +// EOF diff --git a/plugins/SecureIM/src/dbevent.h b/plugins/SecureIM/src/dbevent.h new file mode 100644 index 0000000000..68719c21c0 --- /dev/null +++ b/plugins/SecureIM/src/dbevent.h @@ -0,0 +1,8 @@ +#ifndef __DBEVENT_H__ +#define __DBEVENT_H__ + +#include + +void HistoryLog(HANDLE,LPCSTR); + +#endif diff --git a/plugins/SecureIM/src/gettime.cpp b/plugins/SecureIM/src/gettime.cpp new file mode 100644 index 0000000000..529a8e0c8e --- /dev/null +++ b/plugins/SecureIM/src/gettime.cpp @@ -0,0 +1,29 @@ +#include "commonheaders.h" + + +/* FILETIME unit is 100 nanoseconds */ +const static long div_100_nsec = 10000000; + +/* POSIX or Unix Epoch (1-Jan-1970 00:00) in FILETIME units */ +#ifdef _MSC_VER +const static ULONGLONG ix_epoch = 116444736000000000; +#else +const static ULONGLONG ix_epoch = 116444736000000000LL; +#endif + +DWORD gettime(void) { + + ULONGLONG diff_100_nsec; + union { + FILETIME f; + ULARGE_INTEGER u; + } now; + + GetSystemTimeAsFileTime( &now.f ); + + diff_100_nsec = now.u.QuadPart - ix_epoch; + + return (DWORD)( diff_100_nsec / div_100_nsec ); +} + +// EOF diff --git a/plugins/SecureIM/src/gettime.h b/plugins/SecureIM/src/gettime.h new file mode 100644 index 0000000000..e84276c609 --- /dev/null +++ b/plugins/SecureIM/src/gettime.h @@ -0,0 +1,8 @@ +#ifndef __GETTIME_H__ +#define __GETTIME_H__ + +#include + +DWORD gettime(void); + +#endif diff --git a/plugins/SecureIM/src/images.cpp b/plugins/SecureIM/src/images.cpp new file mode 100644 index 0000000000..eb4c87dea1 --- /dev/null +++ b/plugins/SecureIM/src/images.cpp @@ -0,0 +1,358 @@ +#include "commonheaders.h" + + +void HalfBitmap32Alpha(HBITMAP hBitmap) +{ + BITMAP bmp; + DWORD dwLen; + BYTE *p; + int x, y; + + GetObject(hBitmap, sizeof(bmp), &bmp); + + if (bmp.bmBitsPixel != 32) + return; + + dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8); + p = (BYTE *)malloc(dwLen); + if (p == NULL) + return; + memset(p, 0, dwLen); + + GetBitmapBits(hBitmap, dwLen, p); + + for (y = 0; y < bmp.bmHeight; ++y) { + BYTE *px = p + bmp.bmWidth * 4 * y; + + for (x = 0; x < bmp.bmWidth; ++x) + { + px[3]>>=1; + px += 4; + } + } + + SetBitmapBits(hBitmap, dwLen, p); + + free(p); +} + + +// Make a bitmap all transparent, but only if it is a 32bpp +void MakeBmpTransparent(HBITMAP hBitmap) +{ + BITMAP bmp; + DWORD dwLen; + BYTE *p; + + GetObject(hBitmap, sizeof(bmp), &bmp); + + if (bmp.bmBitsPixel != 32) + return; + + dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8); + p = (BYTE *)malloc(dwLen); + if (p == NULL) + return; + + memset(p, 0, dwLen); + SetBitmapBits(hBitmap, dwLen, p); + + free(p); +} + + +// Correct alpha from bitmaps loaded without it (it cames with 0 and should be 255) +void CorrectBitmap32Alpha(HBITMAP hBitmap, BOOL force) +{ + BITMAP bmp; + DWORD dwLen; + BYTE *p; + int x, y; + BOOL fixIt; + + GetObject(hBitmap, sizeof(bmp), &bmp); + + if (bmp.bmBitsPixel != 32) + return; + + dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8); + p = (BYTE *)malloc(dwLen); + if (p == NULL) + return; + memset(p, 0, dwLen); + + GetBitmapBits(hBitmap, dwLen, p); + + fixIt = TRUE; + for (y = 0; fixIt && y < bmp.bmHeight; ++y) { + BYTE *px = p + bmp.bmWidth * 4 * y; + + for (x = 0; fixIt && x < bmp.bmWidth; ++x) + { + if (px[3] != 0 && !force) + { + fixIt = FALSE; + } + else + { + if (px[0] != 0 || px[1] != 0 || px[2] != 0) + px[3] = 255; + } + + px += 4; + } + } + + if (fixIt) + SetBitmapBits(hBitmap, dwLen, p); + + free(p); +} + + +HBITMAP CopyBitmapTo32(HBITMAP hBitmap) +{ + BITMAPINFO RGB32BitsBITMAPINFO; + BYTE * ptPixels; + HBITMAP hDirectBitmap; + + BITMAP bmp; + DWORD dwLen; + BYTE *p; + + GetObject(hBitmap, sizeof(bmp), &bmp); + + dwLen = bmp.bmWidth * bmp.bmHeight * 4; + p = (BYTE *)malloc(dwLen); + if (p == NULL) + return NULL; + + // Create bitmap + ZeroMemory(&RGB32BitsBITMAPINFO, sizeof(BITMAPINFO)); + RGB32BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + RGB32BitsBITMAPINFO.bmiHeader.biWidth = bmp.bmWidth; + RGB32BitsBITMAPINFO.bmiHeader.biHeight = bmp.bmHeight; + RGB32BitsBITMAPINFO.bmiHeader.biPlanes = 1; + RGB32BitsBITMAPINFO.bmiHeader.biBitCount = 32; + + hDirectBitmap = CreateDIBSection(NULL, + (BITMAPINFO *)&RGB32BitsBITMAPINFO, + DIB_RGB_COLORS, + (void **)&ptPixels, + NULL, 0); + + // Copy data + if (bmp.bmBitsPixel != 32) + { + HDC hdcOrig, hdcDest; + HBITMAP oldOrig, oldDest; + + hdcOrig = CreateCompatibleDC(NULL); + oldOrig = (HBITMAP) SelectObject(hdcOrig, hBitmap); + + hdcDest = CreateCompatibleDC(NULL); + oldDest = (HBITMAP) SelectObject(hdcDest, hDirectBitmap); + + BitBlt(hdcDest, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcOrig, 0, 0, SRCCOPY); + + SelectObject(hdcDest, oldDest); + DeleteObject(hdcDest); + SelectObject(hdcOrig, oldOrig); + DeleteObject(hdcOrig); + + // Set alpha + CorrectBitmap32Alpha(hDirectBitmap, FALSE); + } + else + { + GetBitmapBits(hBitmap, dwLen, p); + SetBitmapBits(hDirectBitmap, dwLen, p); + } + + free(p); + + return hDirectBitmap; +} + + +HBITMAP CreateBitmap32(int cx, int cy) +{ + BITMAPINFO RGB32BitsBITMAPINFO; + UINT * ptPixels; + HBITMAP DirectBitmap; + + ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO)); + RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); + RGB32BitsBITMAPINFO.bmiHeader.biWidth=cx;//bm.bmWidth; + RGB32BitsBITMAPINFO.bmiHeader.biHeight=cy;//bm.bmHeight; + RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1; + RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32; + + DirectBitmap = CreateDIBSection(NULL, + (BITMAPINFO *)&RGB32BitsBITMAPINFO, + DIB_RGB_COLORS, + (void **)&ptPixels, + NULL, 0); + return DirectBitmap; +} + + +BOOL MakeBitmap32(HBITMAP *hBitmap) +{ + BITMAP bmp; + + GetObject(*hBitmap, sizeof(bmp), &bmp); + + if (bmp.bmBitsPixel != 32) { + // Convert to 32 bpp + HBITMAP hBmpTmp = CopyBitmapTo32(*hBitmap); + DeleteObject(*hBitmap); + *hBitmap = hBmpTmp; + } + + return TRUE; +} + + +#define GET_PIXEL(__P__, __X__, __Y__) ( __P__ + width * 4 * (__Y__) + 4 * (__X__)) + +BOOL MakeGrayscale(HBITMAP *hBitmap) +{ + BYTE *p = NULL; + BYTE *p1; + DWORD dwLen; + int width, height, x, y; + BITMAP bmp; + + GetObject(*hBitmap, sizeof(bmp), &bmp); + width = bmp.bmWidth; + height = bmp.bmHeight; + + dwLen = width * height * 4; + p = (BYTE *)malloc(dwLen); + if (p == NULL) + { + return FALSE; + } + + if (bmp.bmBitsPixel != 32) + { + // Convert to 32 bpp + HBITMAP hBmpTmp = CopyBitmapTo32(*hBitmap); + DeleteObject(*hBitmap); + *hBitmap = hBmpTmp; + } + GetBitmapBits(*hBitmap, dwLen, p); + + // Make grayscale + for (y = 0 ; y < height ; y++) + { + for (x = 0 ; x < width ; x++) + { + p1 = GET_PIXEL(p, x, y); + p1[0] = p1[1] = p1[2] = ( p1[0] + p1[1] + p1[2] ) / 3; + } + } + + dwLen = SetBitmapBits(*hBitmap, dwLen, p); + free(p); + + return TRUE; +} + + +HICON MakeHalfAlphaIcon(HICON SourceIcon) +{ + ICONINFO TargetIconInfo; + BITMAP TargetBitmapInfo; + HICON TargetIcon, TempIcon; + + TempIcon = CopyIcon(SourceIcon); + if ( !GetIconInfo(TempIcon, &TargetIconInfo)) + return NULL; + + if ( !GetObject(TargetIconInfo.hbmColor, sizeof(BITMAP), &TargetBitmapInfo)) + return NULL; + + MakeBitmap32(&TargetIconInfo.hbmColor); + HalfBitmap32Alpha(TargetIconInfo.hbmColor); + TargetIcon = CreateIconIndirect(&TargetIconInfo); + + DestroyIcon(TempIcon); + DeleteObject(TargetIconInfo.hbmColor); + DeleteObject(TargetIconInfo.hbmMask); + return TargetIcon; +} + + +HICON MakeGrayscaleIcon(HICON SourceIcon) +{ + ICONINFO TargetIconInfo; + BITMAP TargetBitmapInfo; + HICON TargetIcon, TempIcon; + + TempIcon = CopyIcon(SourceIcon); + if (! GetIconInfo(TempIcon, &TargetIconInfo) || GetObject(TargetIconInfo.hbmColor, sizeof(BITMAP), &TargetBitmapInfo)==0) return NULL; + + MakeGrayscale(&TargetIconInfo.hbmColor); + + TargetIcon = CreateIconIndirect(&TargetIconInfo); + DestroyIcon(TempIcon); + + return TargetIcon; +} + + +HICON BindOverlayIcon(HICON SourceIcon,HICON OverlayIcon) +{ + ICONINFO OverlayIconInfo, TargetIconInfo; + BITMAP OverlayBitmapInfo, TargetBitmapInfo; + HBITMAP OldOverlayBitmap, OldTargetBitmap; + HICON TargetIcon, TempIcon; + HDC OverlayDC, TargetDC; + BLENDFUNCTION bf = {0,0,255,1}; + + TempIcon = CopyIcon(SourceIcon); + if ( !GetIconInfo( TempIcon, &TargetIconInfo )) + return NULL; + + MakeBitmap32(&TargetIconInfo.hbmColor); + CorrectBitmap32Alpha(TargetIconInfo.hbmColor, FALSE); + GetObject(TargetIconInfo.hbmColor, sizeof(BITMAP), &TargetBitmapInfo); + + if ( !GetIconInfo(OverlayIcon, &OverlayIconInfo) || !GetObject(OverlayIconInfo.hbmColor, sizeof(BITMAP), &OverlayBitmapInfo)) + return NULL; + + TargetDC = CreateCompatibleDC(NULL); + OldTargetBitmap = (HBITMAP)SelectObject(TargetDC, TargetIconInfo.hbmColor); + + OverlayDC = CreateCompatibleDC(NULL); + OldOverlayBitmap = (HBITMAP)SelectObject(OverlayDC, OverlayIconInfo.hbmColor); + + AlphaBlend(TargetDC, 0, 0, TargetBitmapInfo.bmWidth, TargetBitmapInfo.bmHeight, + OverlayDC, 0, 0, OverlayBitmapInfo.bmWidth, OverlayBitmapInfo.bmHeight, bf); + + SelectObject(TargetDC, TargetIconInfo.hbmMask); + SelectObject(OverlayDC, OverlayIconInfo.hbmMask); + + BitBlt(TargetDC, 0, 0, TargetBitmapInfo.bmWidth, TargetBitmapInfo.bmHeight, + OverlayDC, 0, 0, SRCCOPY); + + TargetIcon = CreateIconIndirect(&TargetIconInfo); + DestroyIcon(TempIcon); + + SelectObject(TargetDC, OldTargetBitmap); + DeleteObject(TargetIconInfo.hbmColor); + DeleteObject(TargetIconInfo.hbmMask); + DeleteDC(TargetDC); + + SelectObject(OverlayDC, OldOverlayBitmap); + DeleteObject(OverlayIconInfo.hbmColor); + DeleteObject(OverlayIconInfo.hbmMask); + DeleteDC(OverlayDC); + + return TargetIcon; +} + + +// EOF diff --git a/plugins/SecureIM/src/images.h b/plugins/SecureIM/src/images.h new file mode 100644 index 0000000000..ea65b09893 --- /dev/null +++ b/plugins/SecureIM/src/images.h @@ -0,0 +1,8 @@ +#ifndef __IMAGE_UTILS_H__ +#define __IMAGE_UTILS_H__ + +HICON BindOverlayIcon(HICON,HICON); +//HICON MakeGrayscaleIcon(HICON); +HICON MakeHalfAlphaIcon(HICON); + +#endif // __IMAGE_UTILS_H__ diff --git a/plugins/SecureIM/src/language.cpp b/plugins/SecureIM/src/language.cpp new file mode 100644 index 0000000000..9bdf620cea --- /dev/null +++ b/plugins/SecureIM/src/language.cpp @@ -0,0 +1,104 @@ +#include "commonheaders.h" + +//Popup Messages +LPCSTR sim001 = "SecureIM established..."; +LPCSTR sim002 = "Key exchange failed..."; +LPCSTR sim003 = "Key from disabled..."; +LPCSTR sim004 = "Sended back message received..."; +LPCSTR sim005 = "Sending back secure message..."; +LPCSTR sim006 = "SecureIM disabled..."; +LPCSTR sim007 = "Sending Key..."; +LPCSTR sim008 = "Key Received..."; +LPCSTR sim009 = "Sending Message..."; +LPCSTR sim010 = "Message Received..."; +LPCSTR sim011 = "Encrypting File:"; +LPCSTR sim012 = "Decrypting File:"; +LPCSTR sim013 = "Bad key received..."; + +//Error Messages +LPCSTR sim101 = "SecureIM: Error while decrypting the message."; +LPCSTR sim102 = "SecureIM: Error while decrypting the message, bad message length."; +LPCSTR sim103 = "SecureIM: Error while decrypting the message, bad message CRC."; +LPCSTR sim104 = "User has not answered to key exchange !\nYour messages are still in SecureIM queue, do you want to send them Unencrypted now ?"; +LPCSTR sim105 = "SecureIM not enabled! You Must Enable SecureIM with this user..."; +LPCSTR sim106 = "Can't Send Encrypted Message !\nUser is offline now and his secure key has been expired, Do you want to send your message ?\nIt will be unencrypted !"; +LPCSTR sim107 = "SecureIM won't be loaded because cryptopp.dll is missing or wrong version !"; +LPCSTR sim108 = "SecureIM can't load PGP/GPG key! Check PGP/GPG settings!"; +LPCSTR sim109 = "SecureIM can't encrypt message! Check trust of PGP/GPG key!"; +LPCSTR sim110 = "Can't Send Encrypted Message !\nDo you want to send your message ?\nIt will be unencrypted !"; +LPCSTR sim111 = "Can't change mode! Secure connection established!"; +LPCSTR sim112 = "Can't export RSA private key!"; +LPCSTR sim113 = "Can't import RSA private key!"; +LPCSTR sim114 = "Can't export RSA public key!"; +LPCSTR sim115 = "Can't import RSA public key!"; + +//Options +LPCSTR sim201 = "General"; +LPCSTR sim202 = "Protocols"; +LPCSTR sim203 = "Nickname"; +LPCSTR sim204 = "UIN/Email/Jid/..."; +LPCSTR sim205 = "Status"; +LPCSTR sim206 = "PSK"; +LPCSTR sim210 = "Name"; +LPCSTR sim211 = "Password is too short!"; +LPCSTR sim212 = "ON"; +LPCSTR sim213 = "Off"; +LPCSTR sim214 = "PGP"; +LPCSTR sim215 = "Key ID"; +LPCSTR sim216 = "Keyrings loaded."; +LPCSTR sim217 = "Keyrings not loaded!"; +LPCSTR sim218 = "PGP SDK v%i.%i.%i found."; +LPCSTR sim219 = "PGP SDK not found!"; +LPCSTR sim220 = "This version not supported!"; +LPCSTR sim221 = "(none)"; +LPCSTR sim222 = "Private key loaded."; +LPCSTR sim223 = "Private key not loaded!"; +LPCSTR sim224 = "The new settings will become valid when you restart MirandaIM!"; +LPCSTR sim225 = "Keyrings disabled!"; +LPCSTR sim226 = "GPG"; +LPCSTR sim227 = "CP"; +LPCSTR sim228 = "ANSI"; +LPCSTR sim229 = "UTF8"; +LPCSTR sim230 = "Mode"; +LPCSTR sim231[] = { "Native", "PGP", "GPG", "RSA/AES", "RSA" }; +LPCSTR sim232[] = { "Disabled", "Enabled", "Always try" }; +LPCSTR sim233 = "PUB"; +LPCSTR sim234 = "SHA1"; + +//Context Menu +LPCSTR sim301 = "Create SecureIM connection"; +LPCSTR sim302 = "Disable SecureIM connection"; +LPCSTR sim306 = "Load PGP Key"; +LPCSTR sim307 = "Unload PGP Key"; +LPCSTR sim308 = "Load GPG Key"; +LPCSTR sim309 = "Unload GPG Key"; +LPCSTR sim310 = "Delete RSA Key"; +LPCSTR sim311[] = { "SecureIM mode (Native)", + "SecureIM mode (PGP)", + "SecureIM mode (GPG)", + "SecureIM mode (RSA/AES)", + "SecureIM mode (RSA)" }; +LPCSTR sim312[] = { "SecureIM status (disabled)", + "SecureIM status (enabled)", + "SecureIM status (always try)" }; + +//System messages +LPCSTR sim401 = "SecureIM: Sorry, unable to decrypt this message due you have no PGP/GPG installed. Visit www.pgp.com or www.gnupg.org for more info."; +LPCSTR sim402 = "SecureIM received unencryped message:\n"; +LPCSTR sim403 = "SecureIM received encryped message:\n"; + +//RSA messages +LPCSTR sim501 = "Session closed by receiving incorrect message type"; +LPCSTR sim502 = "Session closed by other side on error"; +LPCSTR sim505 = "Error while decoding AES message"; +LPCSTR sim506 = "Error while decoding RSA message"; +LPCSTR sim507 = "Session closed on timeout"; +LPCSTR sim508 = "Session closed by other side when status \"disabled\""; +LPCSTR sim510 = "Session closed on error: %02x"; +LPCSTR sim520 = "SecureIM received RSA Public Key from \"%s\"\n\nSHA1: %s\n\nDo you Accept this Key ?"; +LPCSTR sim521 = "SecureIM auto accepted RSA Public key from: %s uin: %s SHA1: %s"; +LPCSTR sim522 = "SecureIM received NEW RSA Public Key from \"%s\"\n\nNew SHA1: %s\n\nOld SHA1: %s\n\nDo you Replace this Key ?"; +LPCSTR sim523 = "SecureIM auto accepted NEW RSA Public key from: %s uin: %s New SHA1: %s Old SHA1: %s"; + + +// EOF diff --git a/plugins/SecureIM/src/language.h b/plugins/SecureIM/src/language.h new file mode 100644 index 0000000000..154e306814 --- /dev/null +++ b/plugins/SecureIM/src/language.h @@ -0,0 +1,100 @@ +#ifndef __LANGUAGE_H__ +#define __LANGUAGE_H__ + +#include + +//Popup Messages +extern LPCSTR sim001; +extern LPCSTR sim002; +extern LPCSTR sim003; +extern LPCSTR sim004; +extern LPCSTR sim005; +extern LPCSTR sim006; +extern LPCSTR sim007; +extern LPCSTR sim008; +extern LPCSTR sim009; +extern LPCSTR sim010; +extern LPCSTR sim011; +extern LPCSTR sim012; +extern LPCSTR sim013; + +//Error Messages +extern LPCSTR sim101; +extern LPCSTR sim102; +extern LPCSTR sim103; +extern LPCSTR sim104; +extern LPCSTR sim105; +extern LPCSTR sim106; +extern LPCSTR sim107; +extern LPCSTR sim108; +extern LPCSTR sim109; +extern LPCSTR sim110; +extern LPCSTR sim111; +extern LPCSTR sim112; +extern LPCSTR sim113; +extern LPCSTR sim114; +extern LPCSTR sim115; + +//Options +extern LPCSTR sim201; +extern LPCSTR sim202; +extern LPCSTR sim203; +extern LPCSTR sim204; +extern LPCSTR sim205; +extern LPCSTR sim206; +extern LPCSTR sim210; +extern LPCSTR sim211; +extern LPCSTR sim212; +extern LPCSTR sim213; +extern LPCSTR sim214; +extern LPCSTR sim215; +extern LPCSTR sim216; +extern LPCSTR sim217; +extern LPCSTR sim218; +extern LPCSTR sim219; +extern LPCSTR sim220; +extern LPCSTR sim221; +extern LPCSTR sim222; +extern LPCSTR sim223; +extern LPCSTR sim224; +extern LPCSTR sim225; +extern LPCSTR sim226; +extern LPCSTR sim227; +extern LPCSTR sim228; +extern LPCSTR sim229; +extern LPCSTR sim230; +extern LPCSTR sim231[]; +extern LPCSTR sim232[]; +extern LPCSTR sim233; +extern LPCSTR sim234; + +//Context Menu +extern LPCSTR sim301; +extern LPCSTR sim302; +extern LPCSTR sim306; +extern LPCSTR sim307; +extern LPCSTR sim308; +extern LPCSTR sim309; +extern LPCSTR sim310; +extern LPCSTR sim311[]; +extern LPCSTR sim312[]; + +//System messages +extern LPCSTR sim401; +extern LPCSTR sim402; +extern LPCSTR sim403; + +//RSA messages +extern LPCSTR sim501; +extern LPCSTR sim502; +extern LPCSTR sim505; +extern LPCSTR sim506; +extern LPCSTR sim507; +extern LPCSTR sim508; +extern LPCSTR sim510; +extern LPCSTR sim520; +extern LPCSTR sim521; +extern LPCSTR sim522; +extern LPCSTR sim523; + +#endif diff --git a/plugins/SecureIM/src/loadicons.cpp b/plugins/SecureIM/src/loadicons.cpp new file mode 100644 index 0000000000..3303424626 --- /dev/null +++ b/plugins/SecureIM/src/loadicons.cpp @@ -0,0 +1,96 @@ +#include "commonheaders.h" + + +HINSTANCE LoadIconsPack(const char* szIconsPack) +{ + HINSTANCE hNewIconInst = NULL; + WORD i; + + hNewIconInst = LoadLibrary(szIconsPack); + + if (hNewIconInst != NULL) + { + for(i=ID_FIRSTICON; i<=ID_LASTICON; i++) + if (LoadIcon(hNewIconInst, MAKEINTRESOURCE(i)) == NULL) + { + FreeLibrary(hNewIconInst); + hNewIconInst = NULL; + break; + } + } + return hNewIconInst; +} + + + +int ReloadIcons(WPARAM wParam, LPARAM lParam) +{ + HICON hIcon; + for (int i=0; icons[i].key; i++) { + hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)icons[i].name); + if(icons[i].tbl == TBL_IEC) + g_hIEC[icons[i].idx]=hIcon; + else + if(icons[i].tbl == TBL_ICO) + g_hICO[icons[i].idx]=hIcon; + else + if(icons[i].tbl == TBL_POP) + g_hPOP[icons[i].idx]=hIcon; + } + + return 0; +} + + +void InitIcons(void) +{ + HINSTANCE hNewIconInst = NULL; + + if ( g_hFolders ) { + LPSTR pathname = (LPSTR) alloca(MAX_PATH); + FoldersGetCustomPathEx(g_hFolders, pathname, MAX_PATH, "icons\\", "secureim_icons.dll"); + if (hNewIconInst == NULL) + hNewIconInst = LoadIconsPack(pathname); + } + + if (hNewIconInst == NULL) + hNewIconInst = LoadIconsPack("icons\\secureim_icons.dll"); + + if (hNewIconInst == NULL) + hNewIconInst = LoadIconsPack("plugins\\secureim_icons.dll"); + + if (hNewIconInst == NULL) + g_hIconInst = g_hInst; + else + g_hIconInst = hNewIconInst; + + + SKINICONDESC sid = { 0 }; + sid.cbSize = sizeof(sid); + sid.pszSection = "SecureIM"; + + HICON hIcon; + for (int i=0; icons[i].key; i++) { + sid.pszSection = icons[i].section; + sid.pszName = icons[i].name; + sid.pszDescription = icons[i].text; + sid.pszDefaultFile = "secureim_icons.dll"; + sid.iDefaultIndex = icons[i].key; + sid.hDefaultIcon = (HICON)LoadImage(g_hIconInst, MAKEINTRESOURCE(icons[i].key), IMAGE_ICON, 16, 16, LR_SHARED); + Skin_AddIcon(&sid); + hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)icons[i].name); + + if(icons[i].tbl == TBL_IEC) + g_hIEC[icons[i].idx]=hIcon; + else + if(icons[i].tbl == TBL_ICO) + g_hICO[icons[i].idx]=hIcon; + else + if(icons[i].tbl == TBL_POP) + g_hPOP[icons[i].idx]=hIcon; + } + + AddHookFunction(ME_SKIN2_ICONSCHANGED, ReloadIcons); +} + +// EOF diff --git a/plugins/SecureIM/src/loadicons.h b/plugins/SecureIM/src/loadicons.h new file mode 100644 index 0000000000..f5258a41a0 --- /dev/null +++ b/plugins/SecureIM/src/loadicons.h @@ -0,0 +1,7 @@ +#ifndef __LOADICONS_H__ +#define __LOADICONS_H__ + +HINSTANCE LoadIconsPack(const char*); +void InitIcons(); + +#endif diff --git a/plugins/SecureIM/src/loadlib.cpp b/plugins/SecureIM/src/loadlib.cpp new file mode 100644 index 0000000000..ac0d2f9272 --- /dev/null +++ b/plugins/SecureIM/src/loadlib.cpp @@ -0,0 +1,76 @@ +#include "commonheaders.h" + +CRYPTOPP_INFO cpp; + +BOOL loadlib(void) { + + HMODULE h = LoadLibraryA("plugins/cryptopp.dll"); + if ( h == NULL ) { + h = LoadLibraryA("cryptopp.dll"); + if ( h == NULL ) return 0; + } + + cpp.cc = (_cpp_create_context) GetProcAddress(h, "cpp_create_context"); + cpp.dc = (_cpp_delete_context) GetProcAddress(h, "cpp_delete_context"); + cpp.rc = (_cpp_reset_context) GetProcAddress(h, "cpp_reset_context"); + cpp.ika = (_cpp_init_keya) GetProcAddress(h, "cpp_init_keya"); + cpp.ikb = (_cpp_init_keyb) GetProcAddress(h, "cpp_init_keyb"); + cpp.ckx = (_cpp_calc_keyx) GetProcAddress(h, "cpp_calc_keyx"); + cpp.ikp = (_cpp_init_keyp) GetProcAddress(h, "cpp_init_keyp"); + cpp.ea = (_cpp_encodeA) GetProcAddress(h, "cpp_encodeA"); + cpp.ew = (_cpp_encodeW) GetProcAddress(h, "cpp_encodeW"); + cpp.eu = (_cpp_encodeU) GetProcAddress(h, "cpp_encodeU"); + cpp.daw = (_cpp_decode) GetProcAddress(h, "cpp_decode"); + cpp.du = (_cpp_decodeU) GetProcAddress(h, "cpp_decodeU"); + cpp.ef = (_cpp_encrypt_file) GetProcAddress(h, "cpp_encrypt_file"); + cpp.df = (_cpp_decrypt_file) GetProcAddress(h, "cpp_decrypt_file"); + cpp.gf = (_cpp_get_features) GetProcAddress(h, "cpp_get_features"); + cpp.ge = (_cpp_get_error) GetProcAddress(h, "cpp_get_error"); + cpp.gv = (_cpp_get_version) GetProcAddress(h, "cpp_get_version"); + cpp.kxs = (_cpp_size_keyx) GetProcAddress(h, "cpp_size_keyx"); + cpp.gkx = (_cpp_get_keyx) GetProcAddress(h, "cpp_get_keyx"); + cpp.skx = (_cpp_set_keyx) GetProcAddress(h, "cpp_set_keyx"); + cpp.kps = (_cpp_size_keyp) GetProcAddress(h, "cpp_size_keyp"); + cpp.gkp = (_cpp_get_keyp) GetProcAddress(h, "cpp_get_keyp"); + cpp.skp = (_cpp_set_keyp) GetProcAddress(h, "cpp_set_keyp"); + cpp.ka = (_cpp_keya) GetProcAddress(h, "cpp_keya"); + cpp.kb = (_cpp_keyb) GetProcAddress(h, "cpp_keyb"); + cpp.kx = (_cpp_keyx) GetProcAddress(h, "cpp_keyx"); + cpp.kp = (_cpp_keyp) GetProcAddress(h, "cpp_keyp"); + + cpp.pgp_i = (_pgp_init ) GetProcAddress(h, "pgp_init"); + cpp.pgp_d = (_pgp_done ) GetProcAddress(h, "pgp_done"); + cpp.pgp_ok = (_pgp_open_keyrings ) GetProcAddress(h, "pgp_open_keyrings"); + cpp.pgp_ck = (_pgp_close_keyrings ) GetProcAddress(h, "pgp_close_keyrings"); + cpp.pgp_gv = (_pgp_get_version ) GetProcAddress(h, "pgp_get_version"); + cpp.pgp_ge = (_pgp_get_error ) GetProcAddress(h, "pgp_get_error"); + cpp.pgp_spk = (_pgp_set_priv_key ) GetProcAddress(h, "pgp_set_priv_key"); + cpp.pgp_sk = (_pgp_set_key ) GetProcAddress(h, "pgp_set_key"); + cpp.pgp_ski = (_pgp_set_keyid ) GetProcAddress(h, "pgp_set_keyid"); + cpp.pgp_szki = (_pgp_size_keyid ) GetProcAddress(h, "pgp_size_keyid"); + cpp.pgp_slki = (_pgp_select_keyid ) GetProcAddress(h, "pgp_select_keyid"); + cpp.pgp_eu = (_pgp_encode ) GetProcAddress(h, "pgp_encode"); + cpp.pgp_de = (_pgp_decode ) GetProcAddress(h, "pgp_decode"); + + cpp.gpg_i = (_gpg_init ) GetProcAddress(h, "gpg_init"); + cpp.gpg_d = (_gpg_done ) GetProcAddress(h, "gpg_done"); + cpp.gpg_ok = (_gpg_open_keyrings ) GetProcAddress(h, "gpg_open_keyrings"); + cpp.gpg_ck = (_gpg_close_keyrings ) GetProcAddress(h, "gpg_close_keyrings"); + cpp.gpg_sl = (_gpg_set_log ) GetProcAddress(h, "gpg_set_log"); + cpp.gpg_st = (_gpg_set_tmp ) GetProcAddress(h, "gpg_set_tmp"); + cpp.gpg_ge = (_gpg_get_error ) GetProcAddress(h, "gpg_get_error"); + cpp.gpg_ski = (_gpg_set_keyid ) GetProcAddress(h, "gpg_set_keyid"); + cpp.gpg_szki = (_gpg_size_keyid ) GetProcAddress(h, "gpg_size_keyid"); + cpp.gpg_slki = (_gpg_select_keyid ) GetProcAddress(h, "gpg_select_keyid"); + cpp.gpg_eu = (_gpg_encode ) GetProcAddress(h, "gpg_encode"); + cpp.gpg_de = (_gpg_decode ) GetProcAddress(h, "gpg_decode"); + cpp.gpg_gph = (_gpg_get_passphrases ) GetProcAddress(h, "gpg_get_passphrases"); + cpp.gpg_sph = (_gpg_set_passphrases ) GetProcAddress(h, "gpg_set_passphrases"); + + cpp.rsa_i = (_rsa_init) GetProcAddress(h, "rsa_init"); + cpp.rsa_d = (_rsa_done) GetProcAddress(h, "rsa_done"); + + return (cpp_get_version()>=0x01000403); +} + +// EOF diff --git a/plugins/SecureIM/src/loadlib.h b/plugins/SecureIM/src/loadlib.h new file mode 100644 index 0000000000..105f441dc9 --- /dev/null +++ b/plugins/SecureIM/src/loadlib.h @@ -0,0 +1,188 @@ +#ifndef __LOADLIB_H__ +#define __LOADLIB_H__ + +#include +#include "cryptopp.h" + +BOOL loadlib(void); + +typedef HANDLE (__cdecl * _cpp_create_context) (int); +typedef void (__cdecl * _cpp_delete_context) (HANDLE); +typedef void (__cdecl * _cpp_reset_context) (HANDLE); +typedef LPSTR (__cdecl * _cpp_init_keya) (HANDLE,int); +typedef int (__cdecl * _cpp_init_keyb) (HANDLE,LPCSTR); +typedef int (__cdecl * _cpp_calc_keyx) (HANDLE); +typedef int (__cdecl * _cpp_init_keyp) (HANDLE,LPCSTR); +typedef LPSTR (__cdecl * _cpp_encodeA) (HANDLE,LPCSTR); +typedef LPSTR (__cdecl * _cpp_encodeW) (HANDLE,LPWSTR); +typedef LPSTR (__cdecl * _cpp_encodeU) (HANDLE,LPCSTR); +typedef LPSTR (__cdecl * _cpp_decode) (HANDLE,LPCSTR); +typedef LPSTR (__cdecl * _cpp_decodeU) (HANDLE,LPCSTR); +typedef int (__cdecl * _cpp_encrypt_file) (HANDLE,LPCSTR,LPCSTR); +typedef int (__cdecl * _cpp_decrypt_file) (HANDLE,LPCSTR,LPCSTR); +typedef int (__cdecl * _cpp_get_features) (HANDLE); +typedef int (__cdecl * _cpp_get_error) (HANDLE); +typedef int (__cdecl * _cpp_get_version) (void); +typedef int (__cdecl * _cpp_size_keyx) (void); +typedef void (__cdecl * _cpp_get_keyx) (HANDLE,BYTE*); +typedef void (__cdecl * _cpp_set_keyx) (HANDLE,BYTE*); +typedef int (__cdecl * _cpp_size_keyp) (void); +typedef void (__cdecl * _cpp_get_keyp) (HANDLE,BYTE*); +typedef void (__cdecl * _cpp_set_keyp) (HANDLE,BYTE*); +typedef int (__cdecl * _cpp_keya) (HANDLE); +typedef int (__cdecl * _cpp_keyb) (HANDLE); +typedef int (__cdecl * _cpp_keyx) (HANDLE); +typedef int (__cdecl * _cpp_keyp) (HANDLE); + +typedef int (__cdecl * _pgp_init) (void); +typedef int (__cdecl * _pgp_done) (void); +typedef int (__cdecl * _pgp_open_keyrings) (LPSTR,LPSTR); +typedef int (__cdecl * _pgp_close_keyrings) (void); +typedef int (__cdecl * _pgp_get_version) (void); +typedef LPSTR (__cdecl * _pgp_get_error) (void); +typedef int (__cdecl * _pgp_set_priv_key) (LPCSTR); +typedef int (__cdecl * _pgp_set_key) (HANDLE,LPCSTR); +typedef int (__cdecl * _pgp_set_keyid) (HANDLE,PVOID); +typedef int (__cdecl * _pgp_size_keyid) (void); +typedef PVOID (__cdecl * _pgp_select_keyid) (HWND,LPSTR); +typedef LPSTR (__cdecl * _pgp_encode) (HANDLE,LPCSTR); +typedef LPSTR (__cdecl * _pgp_decode) (HANDLE,LPCSTR); + +typedef int (__cdecl * _gpg_init) (void); +typedef int (__cdecl * _gpg_done) (void); +typedef int (__cdecl * _gpg_open_keyrings) (LPSTR,LPSTR); +typedef int (__cdecl * _gpg_close_keyrings) (void); +typedef void (__cdecl * _gpg_set_log) (LPCSTR); +typedef void (__cdecl * _gpg_set_tmp) (LPCSTR); +typedef LPSTR (__cdecl * _gpg_get_error) (void); +typedef int (__cdecl * _gpg_set_keyid) (HANDLE,LPCSTR); +typedef int (__cdecl * _gpg_size_keyid) (void); +typedef int (__cdecl * _gpg_select_keyid) (HWND,LPSTR); +typedef LPSTR (__cdecl * _gpg_encode) (HANDLE,LPCSTR); +typedef LPSTR (__cdecl * _gpg_decode) (HANDLE,LPCSTR); +typedef LPSTR (__cdecl * _gpg_get_passphrases) (void); +typedef void (__cdecl * _gpg_set_passphrases) (LPCSTR); + +typedef int (__cdecl * _rsa_init) (pRSA_EXPORT*,pRSA_IMPORT); +typedef int (__cdecl * _rsa_done) (void); + + +typedef struct { + _cpp_create_context cc; + _cpp_delete_context dc; + _cpp_reset_context rc; + _cpp_init_keya ika; + _cpp_init_keyb ikb; + _cpp_calc_keyx ckx; + _cpp_init_keyp ikp; + _cpp_encodeA ea; + _cpp_encodeW ew; + _cpp_encodeU eu; + _cpp_decode daw; + _cpp_decodeU du; + _cpp_encrypt_file ef; + _cpp_decrypt_file df; + _cpp_get_features gf; + _cpp_get_error ge; + _cpp_get_version gv; + _cpp_size_keyx kxs; + _cpp_get_keyx gkx; + _cpp_set_keyx skx; + _cpp_size_keyp kps; + _cpp_get_keyp gkp; + _cpp_set_keyp skp; + _cpp_keya ka; + _cpp_keyb kb; + _cpp_keyx kx; + _cpp_keyp kp; + _pgp_init pgp_i; + _pgp_done pgp_d; + _pgp_open_keyrings pgp_ok; + _pgp_close_keyrings pgp_ck; + _pgp_get_version pgp_gv; + _pgp_get_error pgp_ge; + _pgp_set_keyid pgp_ski; + _pgp_set_key pgp_sk; + _pgp_set_priv_key pgp_spk; + _pgp_size_keyid pgp_szki; + _pgp_select_keyid pgp_slki; + _pgp_encode pgp_eu; + _pgp_decode pgp_de; + _gpg_init gpg_i; + _gpg_done gpg_d; + _gpg_open_keyrings gpg_ok; + _gpg_close_keyrings gpg_ck; + _gpg_set_log gpg_sl; + _gpg_set_tmp gpg_st; + _gpg_get_error gpg_ge; + _gpg_set_keyid gpg_ski; + _gpg_size_keyid gpg_szki; + _gpg_select_keyid gpg_slki; + _gpg_encode gpg_eu; + _gpg_decode gpg_de; + _gpg_get_passphrases gpg_gph; + _gpg_set_passphrases gpg_sph; + _rsa_init rsa_i; + _rsa_done rsa_d; +} CRYPTOPP_INFO; + +extern CRYPTOPP_INFO cpp; + +#define cpp_create_context cpp.cc +#define cpp_delete_context cpp.dc +#define cpp_reset_context cpp.rc +#define cpp_init_keya cpp.ika +#define cpp_init_keyb cpp.ikb +#define cpp_calc_keyx cpp.ckx +#define cpp_init_keyp cpp.ikp +#define cpp_encodeA cpp.ea +#define cpp_encodeW cpp.ew +#define cpp_encodeU cpp.eu +#define cpp_decode cpp.daw +#define cpp_decodeU cpp.du +#define cpp_encrypt_file cpp.ef +#define cpp_decrypt_file cpp.df +#define cpp_get_features cpp.gf +#define cpp_get_error cpp.ge +#define cpp_get_version cpp.gv +#define cpp_size_keyx cpp.kxs +#define cpp_get_keyx cpp.gkx +#define cpp_set_keyx cpp.skx +#define cpp_size_keyp cpp.kps +#define cpp_get_keyp cpp.gkp +#define cpp_set_keyp cpp.skp +#define cpp_keya cpp.ka +#define cpp_keyb cpp.kb +#define cpp_keyx cpp.kx +#define cpp_keyp cpp.kp +#define pgp_init cpp.pgp_i +#define pgp_done cpp.pgp_d +#define pgp_open_keyrings cpp.pgp_ok +#define pgp_close_keyrings cpp.pgp_ck +#define pgp_get_version cpp.pgp_gv +#define pgp_get_error cpp.pgp_ge +#define pgp_set_priv_key cpp.pgp_spk +#define pgp_set_key cpp.pgp_sk +#define pgp_set_keyid cpp.pgp_ski +#define pgp_size_keyid cpp.pgp_szki +#define pgp_select_keyid cpp.pgp_slki +#define pgp_encode cpp.pgp_eu +#define pgp_decode cpp.pgp_de +#define gpg_init cpp.gpg_i +#define gpg_done cpp.gpg_d +#define gpg_open_keyrings cpp.gpg_ok +#define gpg_close_keyrings cpp.gpg_ck +#define gpg_set_log cpp.gpg_sl +#define gpg_set_tmp cpp.gpg_st +#define gpg_get_error cpp.gpg_ge +#define gpg_set_keyid cpp.gpg_ski +#define gpg_size_keyid cpp.gpg_szki +#define gpg_select_keyid cpp.gpg_slki +#define gpg_encode cpp.gpg_eu +#define gpg_decode cpp.gpg_de +#define gpg_get_passphrases cpp.gpg_gph +#define gpg_set_passphrases cpp.gpg_sph +#define rsa_init cpp.rsa_i +#define rsa_done cpp.rsa_d + +#endif diff --git a/plugins/SecureIM/src/main.cpp b/plugins/SecureIM/src/main.cpp new file mode 100644 index 0000000000..205a025ffe --- /dev/null +++ b/plugins/SecureIM/src/main.cpp @@ -0,0 +1,534 @@ +#include "commonheaders.h" + +int hLangpack = 0; + +BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID) { + g_hInst = hInst; + if (dwReason == DLL_PROCESS_ATTACH) { + INITCOMMONCONTROLSEX icce = { + sizeof(icce), ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES + }; + InitCommonControlsEx(&icce); + } + return TRUE; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SECUREIM, MIID_LAST}; + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfoEx; +} + +void AddServiceFunction(LPCSTR serviceName, MIRANDASERVICE serviceFunction) { + + g_hService = (HANDLE*) mir_realloc(g_hService,sizeof(HANDLE)*(iService+1)); + g_hService[iService] = CreateServiceFunction(serviceName, serviceFunction); + iService++; +} + + +void AddProtoServiceFunction(LPCSTR serviceName, MIRANDASERVICE serviceFunction) { + + g_hService = (HANDLE*) mir_realloc(g_hService,sizeof(HANDLE)*(iService+1)); + g_hService[iService] = CreateProtoServiceFunction(szModuleName, serviceName, serviceFunction); + iService++; +} + + +void AddHookFunction(LPCSTR eventName, MIRANDAHOOK hookFunction) { + + g_hHook = (HANDLE*) mir_realloc(g_hHook,sizeof(HANDLE)*(iHook+1)); + g_hHook[iHook] = HookEvent(eventName, hookFunction); + iHook++; +} + + +HANDLE AddMenuItem(LPCSTR name,int pos,HICON hicon,LPCSTR service,int flags=0,WPARAM wParam=0) +{ + CLISTMENUITEM mi = { 0 }; + mi.cbSize=sizeof(mi); + mi.flags=flags | CMIF_HIDDEN; + mi.position=pos; + mi.hIcon=hicon; + mi.pszName= (char*)name; + mi.pszPopupName=(char*)-1; + mi.pszService=(char*)service; + return Menu_AddContactMenuItem(&mi); +} + + +HANDLE AddSubItem(HANDLE rootid,LPCSTR name,int pos,int poppos,LPCSTR service,WPARAM wParam=0) +{ + CLISTMENUITEM mi = { 0 }; + memset(&mi,0,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.flags=CMIF_CHILDPOPUP | CMIF_HIDDEN; + mi.position=pos; + mi.popupPosition=poppos; + mi.hIcon=NULL; + mi.pszName=(char*)name; + mi.pszPopupName=(char*)rootid; + mi.pszService=(char*)service; + return Menu_AddContactMenuItem(&mi); +} + + +extern "C" __declspec(dllexport) int __cdecl Load(void) +{ + DisableThreadLibraryCalls(g_hInst); + InitializeCriticalSection(&localQueueMutex); + + { + char temp[MAX_PATH]; + GetTempPath(sizeof(temp),temp); + GetLongPathName(temp,TEMP,sizeof(TEMP)); + TEMP_SIZE = (int)strlen(TEMP); + if(TEMP[TEMP_SIZE-1]=='\\') { + TEMP_SIZE--; + TEMP[TEMP_SIZE]='\0'; + } + } + + // get memoryManagerInterface address + //get per-plugin langpack interface + mir_getLP(&pluginInfoEx); + + // check for support TrueColor Icons + BOOL bIsComCtl6 = FALSE; + HMODULE hComCtlDll = LoadLibrary("comctl32.dll"); + if ( hComCtlDll ) { + typedef HRESULT (CALLBACK *PFNDLLGETVERSION)(DLLVERSIONINFO*); + PFNDLLGETVERSION pfnDllGetVersion = (PFNDLLGETVERSION) GetProcAddress(hComCtlDll,"DllGetVersion"); + if ( pfnDllGetVersion ) { + DLLVERSIONINFO dvi; + memset(&dvi,0,sizeof(dvi)); + dvi.cbSize = sizeof(dvi); + HRESULT hRes = (*pfnDllGetVersion)( &dvi ); + if ( SUCCEEDED(hRes) && dvi.dwMajorVersion >= 6 ) { + bIsComCtl6 = TRUE; + } + } + FreeLibrary(hComCtlDll); + } + if (bIsComCtl6) iBmpDepth = ILC_COLOR32 | ILC_MASK; // 32-bit images are supported + else iBmpDepth = ILC_COLOR24 | ILC_MASK; + +// iBmpDepth = ILC_COLOR32 | ILC_MASK; + + char version[512]; + CallService(MS_SYSTEM_GETVERSIONTEXT, sizeof(version), (LPARAM)&version); + bCoreUnicode = strstr(version, "Unicode")!=0; + iCoreVersion = CallService(MS_SYSTEM_GETVERSION,0,0); + + // load crypo++ dll + if ( !loadlib()) { + msgbox1(0,sim107,szModuleName,MB_OK|MB_ICONSTOP); + return 1; + } + + load_rtfconv(); + + // register plugin module + PROTOCOLDESCRIPTOR pd; + memset(&pd,0,sizeof(pd)); + pd.cbSize = sizeof(pd); + pd.szName = (char*)szModuleName; + pd.type = PROTOTYPE_ENCRYPTION; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + // hook events + AddHookFunction(ME_SYSTEM_MODULESLOADED, onModulesLoaded); + AddHookFunction(ME_SYSTEM_OKTOEXIT, onSystemOKToExit); + + g_hEvent[0] = CreateHookableEvent(MODULENAME"/Disabled"); + g_hEvent[1] = CreateHookableEvent(MODULENAME"/Established"); + + AddServiceFunction(MODULENAME"/IsContactSecured",Service_IsContactSecured); + AddServiceFunction(MODULENAME"/SIM_EST",Service_CreateIM); + AddServiceFunction(MODULENAME"/SIM_DIS",Service_DisableIM); + AddServiceFunction(MODULENAME"/SIM_ST_DIS",Service_StatusDis); + AddServiceFunction(MODULENAME"/SIM_ST_ENA",Service_StatusEna); + AddServiceFunction(MODULENAME"/SIM_ST_TRY",Service_StatusTry); + AddServiceFunction(MODULENAME"/PGP_SET",Service_PGPsetKey); + AddServiceFunction(MODULENAME"/PGP_DEL",Service_PGPdelKey); + AddServiceFunction(MODULENAME"/GPG_SET",Service_GPGsetKey); + AddServiceFunction(MODULENAME"/GPG_DEL",Service_GPGdelKey); + AddServiceFunction(MODULENAME"/MODE_NAT",Service_ModeNative); + AddServiceFunction(MODULENAME"/MODE_PGP",Service_ModePGP); + AddServiceFunction(MODULENAME"/MODE_GPG",Service_ModeGPG); + AddServiceFunction(MODULENAME"/MODE_RSA",Service_ModeRSAAES); + + return 0; +} + +extern "C" __declspec(dllexport) int __cdecl Unload() { + DeleteCriticalSection(&localQueueMutex); + return 0; +} + + +int __cdecl onModulesLoaded(WPARAM wParam,LPARAM lParam) { + +#if defined(_DEBUG) || defined(NETLIB_LOG) + InitNetlib(); + Sent_NetLog("onModuleLoaded begin"); +#endif + + bMetaContacts = ServiceExists(MS_MC_GETMETACONTACT)!=0; + bPopupExists = ServiceExists(MS_POPUP_ADDPOPUPEX)!=0; + bPopupUnicode = ServiceExists(MS_POPUP_ADDPOPUPW)!=0; + + g_hFolders = FoldersRegisterCustomPath(szModuleName, "Icons", MIRANDA_PATH"\\icons"); + if ( g_hFolders==(HANDLE)CALLSERVICE_NOTFOUND ) g_hFolders = 0; + + InitIcons(); + GetFlags(); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_init"); +#endif + { // RSA/AES + rsa_init(&exp,&imp); + + DBVARIANT dbv; + dbv.type = DBVT_BLOB; + + if ( DBGetContactSetting(0,szModuleName,"rsa_priv",&dbv) == 0 ) { + exp->rsa_set_keypair(CPP_MODE_RSA_4096,dbv.pbVal,dbv.cpbVal); + DBFreeVariant(&dbv); + rsa_4096=1; + } + else + if ( DBGetContactSetting(0,szModuleName,"rsa_priv_4096",&dbv) == 0 ) { + exp->rsa_set_keypair(CPP_MODE_RSA_4096|CPP_MODE_RSA_BER,dbv.pbVal,dbv.cpbVal); + DBFreeVariant(&dbv); + + char priv_key[4096]; int priv_len; + char pub_key[4096]; int pub_len; + + DBCONTACTWRITESETTING cws; + cws.szModule = szModuleName; + cws.value.type = DBVT_BLOB; + + exp->rsa_get_keypair(CPP_MODE_RSA_4096,(PBYTE)&priv_key,&priv_len,(PBYTE)&pub_key,&pub_len); + + cws.szSetting = "rsa_priv"; + cws.value.pbVal = (PBYTE)&priv_key; + cws.value.cpbVal = priv_len; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)0, (LPARAM)&cws); + + cws.szSetting = "rsa_pub"; + cws.value.pbVal = (PBYTE)&pub_key; + cws.value.cpbVal = pub_len; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)0, (LPARAM)&cws); + + DBDeleteContactSetting(0, szModuleName, "rsa_priv_2048"); + DBDeleteContactSetting(0, szModuleName, "rsa_pub_2048"); +// DBDeleteContactSetting(0, szModuleName, "rsa_priv_4096"); +// DBDeleteContactSetting(0, szModuleName, "rsa_pub_4096"); + + rsa_4096=1; + } + + if ( !rsa_4096 ) { + unsigned int tID; + CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttGenerateRSA, NULL, 0, &tID)); + } + + exp->rsa_set_timeout( DBGetContactSettingWord(0,szModuleName,"ket",10)); + } + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("pgp_init"); +#endif + bPGP = DBGetContactSettingByte(0, szModuleName, "pgp", 0); + if(bPGP) { //PGP + bPGPloaded = pgp_init(); + bUseKeyrings = DBGetContactSettingByte(0,szModuleName,"ukr",1); + LPSTR priv = myDBGetStringDecode(0,szModuleName,"pgpPrivKey"); + if(priv) { + bPGPprivkey = true; + if(bPGPloaded) + pgp_set_priv_key(priv); + mir_free(priv); + }// if(priv) + if(bPGPloaded && bUseKeyrings) { + char PubRingPath[MAX_PATH], SecRingPath[MAX_PATH]; + PubRingPath[0]='\0'; SecRingPath[0]='\0'; + if(pgp_get_version()<0x02000000) { // 6xx + bPGPkeyrings = pgp_open_keyrings(PubRingPath,SecRingPath); + } + else { + LPSTR tmp; + tmp = myDBGetString(0,szModuleName,"pgpPubRing"); + if(tmp) { + strncpy(PubRingPath,tmp,sizeof(PubRingPath)); + mir_free(tmp); + } + tmp = myDBGetString(0,szModuleName,"pgpSecRing"); + if(tmp) { + strncpy(SecRingPath,tmp,sizeof(SecRingPath)); + mir_free(tmp); + } + if(PubRingPath[0] && SecRingPath[0]) { + bPGPkeyrings = pgp_open_keyrings(PubRingPath,SecRingPath); + if(bPGPkeyrings) { + DBWriteContactSettingString(0,szModuleName,"pgpPubRing",PubRingPath); + DBWriteContactSettingString(0,szModuleName,"pgpSecRing",SecRingPath); + } + else { + DBDeleteContactSetting(0, szModuleName, "pgpPubRing"); + DBDeleteContactSetting(0, szModuleName, "pgpSecRing"); + } + } + } + }// if(bPGPloaded && bUseKeyrings) + }// if(bPGP) + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("gpg_init"); +#endif + bGPG = DBGetContactSettingByte(0, szModuleName, "gpg", 0); + if(bGPG) { //GPG + + LPSTR tmp; + + bGPGloaded = gpg_init(); + + char gpgexec[MAX_PATH], gpghome[MAX_PATH]; + gpgexec[0]='\0'; gpghome[0]='\0'; + + tmp = myDBGetString(0,szModuleName,"gpgExec"); + if(tmp) { + strncpy(gpgexec,tmp,sizeof(gpgexec)); + mir_free(tmp); + } + tmp = myDBGetString(0,szModuleName,"gpgHome"); + if(tmp) { + strncpy(gpghome,tmp,sizeof(gpghome)); + mir_free(tmp); + } + + if(DBGetContactSettingByte(0, szModuleName, "gpgLogFlag",0)) { + tmp = myDBGetString(0,szModuleName,"gpgLog"); + if(tmp) { + gpg_set_log(tmp); + mir_free(tmp); + } + } + + if(DBGetContactSettingByte(0, szModuleName, "gpgTmpFlag",0)) { + tmp = myDBGetString(0,szModuleName,"gpgTmp"); + if(tmp) { + gpg_set_tmp(tmp); + mir_free(tmp); + } + } + + bGPGkeyrings = gpg_open_keyrings(gpgexec,gpghome); + if(bGPGkeyrings) { + DBWriteContactSettingString(0,szModuleName,"gpgExec",gpgexec); + DBWriteContactSettingString(0,szModuleName,"gpgHome",gpghome); + } + else { + DBDeleteContactSetting(0, szModuleName, "gpgExec"); + DBDeleteContactSetting(0, szModuleName, "gpgHome"); + } + + bSavePass = DBGetContactSettingByte(0,szModuleName,"gpgSaveFlag",0); + if(bSavePass) { + tmp = myDBGetString(0,szModuleName,"gpgSave"); + if(tmp) { + gpg_set_passphrases(tmp); + mir_free(tmp); + } + } + } + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("loadContactList"); +#endif + loadContactList(); + + // add new skin sound + SkinAddNewSound("IncomingSecureMessage",LPGEN("Incoming Secure Message"),"Sounds\\iSecureMessage.wav"); + SkinAddNewSound("OutgoingSecureMessage",LPGEN("Outgoing Secure Message"),"Sounds\\oSecureMessage.wav"); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("init extra icons"); +#endif + // init extra icons + for(int i=0;i<1+MODE_CNT*IEC_CNT;i++) { + g_IEC[i].cbSize = sizeof(g_IEC[i]); + g_IEC[i].ColumnType = bADV; + g_IEC[i].hImage = (HANDLE)-1; + } + + // build extra imagelist + //onExtraImageListRebuilding(0,0); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("hook events"); +#endif + AddHookFunction(ME_CLIST_PREBUILDCONTACTMENU, onRebuildContactMenu); +// g_hMC = HookEvent(ME_MC_SUBCONTACTSCHANGED, onMC); + + if ( ServiceExists(MS_EXTRAICON_REGISTER)) { + g_hCLIcon = ExtraIcon_Register(szModuleName, Translate("SecureIM status"), "sim_cm_est", + onExtraImageListRebuilding, + onExtraImageApplying); + } + else { + AddHookFunction(ME_CLIST_EXTRA_LIST_REBUILD, onExtraImageListRebuilding); + AddHookFunction(ME_CLIST_EXTRA_IMAGE_APPLY, onExtraImageApplying); + } + + // hook init options + AddHookFunction(ME_OPT_INITIALISE, onRegisterOptions); + if(bPopupExists) + AddHookFunction(ME_OPT_INITIALISE, onRegisterPopOptions); + AddHookFunction(ME_PROTO_ACK, onProtoAck); + AddHookFunction(ME_DB_CONTACT_SETTINGCHANGED, onContactSettingChanged); + AddHookFunction(ME_DB_CONTACT_ADDED, onContactAdded); + AddHookFunction(ME_DB_CONTACT_DELETED, onContactDeleted); + + // hook message transport + AddProtoServiceFunction(PSR_MESSAGE, onRecvMsg); + AddProtoServiceFunction(PSS_MESSAGE, (MIRANDASERVICE)onSendMsg); + AddProtoServiceFunction(PSS_MESSAGE"W", (MIRANDASERVICE)onSendMsgW); + AddProtoServiceFunction(PSS_FILE, (MIRANDASERVICE)onSendFile); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("create Native/RSA menu"); +#endif + // create a menu item for creating a secure im connection to the user. + g_hMenu[0] = AddMenuItem(sim301,110000,g_hICO[ICO_CM_EST],MODULENAME"/SIM_EST",CMIF_NOTOFFLINE); + g_hMenu[1] = AddMenuItem(sim302,110001,g_hICO[ICO_CM_DIS],MODULENAME"/SIM_DIS",CMIF_NOTOFFLINE); + + if(ServiceExists(MS_CLIST_MENUBUILDSUBGROUP)) { + g_hMenu[2] = AddMenuItem(sim312[0],110002,NULL,NULL,CMIF_ROOTPOPUP); + g_hMenu[3] = AddSubItem(g_hMenu[2],sim232[0],110003,110002,MODULENAME"/SIM_ST_DIS"); + g_hMenu[4] = AddSubItem(g_hMenu[2],sim232[1],110004,110002,MODULENAME"/SIM_ST_ENA"); + g_hMenu[5] = AddSubItem(g_hMenu[2],sim232[2],110005,110002,MODULENAME"/SIM_ST_TRY"); + } + else { + g_hMenu[2] = 0; + g_hMenu[3] = AddMenuItem(sim232[0],110003,NULL,MODULENAME"/SIM_ST_DIS"); + g_hMenu[4] = AddMenuItem(sim232[1],110004,NULL,MODULENAME"/SIM_ST_ENA"); + g_hMenu[5] = AddMenuItem(sim232[2],110005,NULL,MODULENAME"/SIM_ST_TRY"); + } + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("create PGP/GPG menu"); +#endif + HICON icon; + if ( bPGPloaded ) { + icon=mode2icon(MODE_PGP|SECURED,2); + g_hMenu[6] = AddMenuItem(sim306,110006,icon,MODULENAME"/PGP_SET",0); + icon=mode2icon(MODE_PGP,2); + g_hMenu[7] = AddMenuItem(sim307,110007,icon,MODULENAME"/PGP_DEL",0); + } + + if(bGPGloaded) { + icon=mode2icon(MODE_GPG|SECURED,2); + g_hMenu[8] = AddMenuItem(sim308,110008,icon,MODULENAME"/GPG_SET",0); + icon=mode2icon(MODE_GPG,2); + g_hMenu[9] = AddMenuItem(sim309,110009,icon,MODULENAME"/GPG_DEL",0); + } + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("create Mode menu"); +#endif + if(ServiceExists(MS_CLIST_MENUBUILDSUBGROUP)) { + g_hMenu[10] = AddMenuItem(sim311[0],110010,NULL,NULL,CMIF_ROOTPOPUP); + g_hMenu[11] = AddSubItem(g_hMenu[10],sim231[0],110011,110010,MODULENAME"/MODE_NAT"); + g_hMenu[12] = AddSubItem(g_hMenu[10],sim231[1],110012,110010,MODULENAME"/MODE_PGP"); + g_hMenu[13] = AddSubItem(g_hMenu[10],sim231[2],110013,110010,MODULENAME"/MODE_GPG"); + g_hMenu[14] = AddSubItem(g_hMenu[10],sim231[3],110014,110010,MODULENAME"/MODE_RSA"); + } + else { + g_hMenu[10] = 0; + g_hMenu[11] = AddMenuItem(sim231[0],110011,NULL,MODULENAME"/MODE_NAT"); + g_hMenu[12] = AddMenuItem(sim231[1],110012,NULL,MODULENAME"/MODE_PGP"); + g_hMenu[13] = AddMenuItem(sim231[2],110013,NULL,MODULENAME"/MODE_GPG"); + g_hMenu[14] = AddMenuItem(sim231[3],110014,NULL,MODULENAME"/MODE_RSA"); + } + + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("create srmm icons"); +#endif + // add icon to srmm status icons + if(ServiceExists(MS_MSG_ADDICON)) { + + StatusIconData sid; + memset(&sid,0,sizeof(sid)); + sid.cbSize = sizeof(sid); + sid.szModule = (char*)szModuleName; + sid.flags = MBF_DISABLED|MBF_HIDDEN; + // Native + sid.dwId = MODE_NATIVE; + sid.hIcon = mode2icon(MODE_NATIVE|SECURED,3); + sid.hIconDisabled = mode2icon(MODE_NATIVE,3); + sid.szTooltip = Translate("SecureIM [Native]"); + CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid); + // PGP + sid.dwId = MODE_PGP; + sid.hIcon = mode2icon(MODE_PGP|SECURED,3); + sid.hIconDisabled = mode2icon(MODE_PGP,3); + sid.szTooltip = Translate("SecureIM [PGP]"); + CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid); + // GPG + sid.dwId = MODE_GPG; + sid.hIcon = mode2icon(MODE_GPG|SECURED,3); + sid.hIconDisabled = mode2icon(MODE_GPG,3); + sid.szTooltip = Translate("SecureIM [GPG]"); + CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid); + // RSAAES + sid.dwId = MODE_RSAAES; + sid.hIcon = mode2icon(MODE_RSAAES|SECURED,3); + sid.hIconDisabled = mode2icon(MODE_RSAAES,3); + sid.szTooltip = Translate("SecureIM [RSA/AES]"); + CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid); + + // hook the window events so that we can can change the status of the icon + AddHookFunction(ME_MSG_WINDOWEVENT, onWindowEvent); + AddHookFunction(ME_MSG_ICONPRESSED, onIconPressed); + } + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onModuleLoaded end"); +#endif + return 0; +} + + +int __cdecl onSystemOKToExit(WPARAM wParam,LPARAM lParam) { + + if(bSavePass) { + LPSTR tmp = gpg_get_passphrases(); + DBWriteContactSettingString(0,szModuleName,"gpgSave",tmp); + LocalFree(tmp); + } + else { + DBDeleteContactSetting(0,szModuleName,"gpgSave"); + } + if(bPGPloaded) pgp_done(); + if(bGPGloaded) gpg_done(); + rsa_done(); + while(iHook--) UnhookEvent(g_hHook[iHook]); + mir_free(g_hHook); + while(iService--) DestroyServiceFunction(g_hService[iService]); + mir_free(g_hService); + DestroyHookableEvent(g_hEvent[0]); + DestroyHookableEvent(g_hEvent[1]); + freeContactList(); + free_rtfconv(); +#if defined(_DEBUG) || defined(NETLIB_LOG) + DeinitNetlib(); +#endif + return 0; +} + +// EOF diff --git a/plugins/SecureIM/src/mmi.cpp b/plugins/SecureIM/src/mmi.cpp new file mode 100644 index 0000000000..2269d76a51 --- /dev/null +++ b/plugins/SecureIM/src/mmi.cpp @@ -0,0 +1,155 @@ +#include "commonheaders.h" + + +void *operator new(size_t sz) { + return mir_alloc(sz); +} + + +void *operator new[](size_t size) { + return operator new(size); +} + + +void operator delete(void *p) { + mir_free(p); +} + + +void operator delete[](void * p) { + operator delete(p); +} + + +// ANSIzUCS2z + ANSIzUCS2z = ANSIzUCS2z +char *m_wwstrcat(LPCSTR strA, LPCSTR strB) { + int lenA = (int)strlen(strA); + int lenB = (int)strlen(strB); + LPSTR str = (LPSTR)mir_alloc((lenA+lenB+1)*(sizeof(WCHAR)+1)); + memcpy(str, strA, lenA); + memcpy(str+lenA, strB, lenB+1); + memcpy(str+lenA+lenB+1, strA+lenA+1, lenA*sizeof(WCHAR)); + memcpy(str+lenA+lenB+1+lenA*sizeof(WCHAR), strB+lenB+1, (lenB+1)*sizeof(WCHAR)); + return str; +} + + +// ANSIz + ANSIzUCS2z = ANSIzUCS2z +char *m_awstrcat(LPCSTR strA, LPCSTR strB) { + int lenA = (int)strlen(strA); + LPSTR tmpA = (LPSTR)mir_alloc((lenA+1)*(sizeof(WCHAR)+1)); + strcpy(tmpA, strA); + MultiByteToWideChar(CP_ACP, 0, strA, -1, (LPWSTR)(tmpA+lenA+1), (lenA+1)*sizeof(WCHAR)); + LPSTR str = m_wwstrcat(tmpA, strB); + mir_free(tmpA); + return str; +} + + +// ANSIz + ANSIz = ANSIzUCS2z +char *m_aastrcat(LPCSTR strA, LPCSTR strB) { + int lenA = (int)strlen(strA); + int lenB = (int)strlen(strB); + LPSTR str = (LPSTR)mir_alloc((lenA+lenB+1)*(sizeof(WCHAR)+1)); + strcpy(str,strA); + strcat(str,strB); + MultiByteToWideChar(CP_ACP, 0, str, -1, (LPWSTR)(str+lenA+lenB+1), (lenA+lenB+1)*sizeof(WCHAR)); + return str; +} + + +LPSTR m_string = NULL; + +// ANSIz + ANSIz = ANSIz +char *m_ustrcat(LPCSTR strA, LPCSTR strB) { + SAFE_FREE(m_string); + m_string = (LPSTR) mir_alloc(strlen(strA)+strlen(strB)+1); + strcpy(m_string,strA); strcat(m_string,strB); + return m_string; +} + + +LPSTR m_hex = NULL; + +LPSTR to_hex(PBYTE bin, int len) { + SAFE_FREE(m_hex); + m_hex = (LPSTR) mir_alloc(len*3+1); + LPSTR m_ptr = m_hex; + for ( int i=0; iutf8decode(szUtfMsg); + LPSTR szMsg = mir_u2a(wszMsg); + if ( bCoreUnicode ) { + flags |= PREF_UNICODE; + int olen = (int)wcslen((LPWSTR)wszMsg)+1; + int nlen = olen*(sizeof(WCHAR)+1); + szNewMsg = (LPSTR) mir_alloc(nlen); + memcpy(szNewMsg,szMsg,olen); + memcpy(szNewMsg+olen,wszMsg,olen*sizeof(WCHAR)); + mir_free(szMsg); + } + else { + szNewMsg = szMsg; + } + } + else { + flags &= ~PREF_UNICODE; flags |= PREF_UTF; + szNewMsg = (LPSTR) mir_strdup(szUtfMsg); + } + return szNewMsg; +} + + +// ЇаҐ®Ўа §гҐ¬ ⥪бв Ё§ д®а¬ в  ¬Ёа ­¤л ў зЁбвл© UTF8 +LPSTR miranda_to_utf8(LPCSTR szMirMsg, DWORD flags) { + LPSTR szNewMsg; + if(flags & PREF_UTF) { + szNewMsg = (LPSTR) szMirMsg; + } + else + if(flags & PREF_UNICODE) { + szNewMsg = exp->utf8encode((LPCWSTR)(szMirMsg+strlen(szMirMsg)+1)); + } + else { + LPWSTR wszMirMsg = mir_a2u(szMirMsg); + szNewMsg = exp->utf8encode((LPCWSTR)wszMirMsg); + mir_free(wszMirMsg); + } + return mir_strdup(szNewMsg); +} + + +// EOF diff --git a/plugins/SecureIM/src/mmi.h b/plugins/SecureIM/src/mmi.h new file mode 100644 index 0000000000..7b3027e232 --- /dev/null +++ b/plugins/SecureIM/src/mmi.h @@ -0,0 +1,27 @@ +#ifndef __MMI_H__ +#define __MMI_H__ + +#include "commonheaders.h" + +char *m_wwstrcat(LPCSTR,LPCSTR); +char *m_awstrcat(LPCSTR,LPCSTR); +char *m_aastrcat(LPCSTR,LPCSTR); +char *m_ustrcat(LPCSTR,LPCSTR); +LPSTR to_hex(PBYTE,int); + +LPSTR utf8_to_miranda(LPCSTR,DWORD&); +LPSTR miranda_to_utf8(LPCSTR,DWORD); + +void *operator new(size_t sz); +void operator delete(void *p); +void *operator new[](size_t size); +void operator delete[](void * p); + +#define SAFE_INIT(t,p) t p=NULL; +#define SAFE_FREE(p) safe_free((void **)&(p)); +#define SAFE_DELETE(p) safe_delete((void **)&(p)); + +void __fastcall safe_free(void** p); +void __fastcall safe_delete(void** p); + +#endif diff --git a/plugins/SecureIM/src/options.cpp b/plugins/SecureIM/src/options.cpp new file mode 100644 index 0000000000..d6cc1a70d6 --- /dev/null +++ b/plugins/SecureIM/src/options.cpp @@ -0,0 +1,1928 @@ +#include "commonheaders.h" + +#define PSKSIZE (4096+1) +#define RSASIZE (4096+1) + +BOOL bChangeSortOrder = false; +const char *szAdvancedIcons[] = {"None", "Email", "Protocol", "SMS", "Advanced 1", "Advanced 2", "Web", "Client", "VisMode", "Advanced 6", "Advanced 7", 0}; + + +BOOL hasKey(pUinKey ptr) { + BOOL ret = 0; + if ( ptr->mode==MODE_NATIVE ) { + LPSTR str = myDBGetString(ptr->hContact,szModuleName,"PSK"); + ret = (str!=NULL); SAFE_FREE(str); + } + else + if ( ptr->mode==MODE_RSAAES ) { + DBVARIANT dbv; + dbv.type = DBVT_BLOB; + if ( DBGetContactSetting(ptr->hContact,szModuleName,"rsa_pub",&dbv) == 0 ) { + ret = 1; + DBFreeVariant(&dbv); + } + } + return ret; +} + + +void TC_InsertItem(HWND hwnd, WPARAM wparam, TCITEM *tci) { + if ( bCoreUnicode ) { + LPWSTR tmp = mir_a2u(tci->pszText); + tci->pszText = (LPSTR)TranslateW(tmp); + SNDMSG(hwnd, TCM_INSERTITEMW, wparam, (LPARAM)tci); + mir_free(tmp); + } + else { + tci->pszText = Translate(tci->pszText); + SNDMSG(hwnd, TCM_INSERTITEMA, wparam, (LPARAM)tci); + } +} + + +static void LV_InsertColumn(HWND hwnd, WPARAM wparam, LVCOLUMN *lvc) { + if ( bCoreUnicode ) { + LPWSTR tmp = mir_a2u(lvc->pszText); + lvc->pszText = (LPSTR)TranslateW(tmp); + SNDMSG(hwnd, LVM_INSERTCOLUMNW, wparam, (LPARAM)lvc); + mir_free(tmp); + } + else { + lvc->pszText = Translate(lvc->pszText); + SNDMSG(hwnd, LVM_INSERTCOLUMNA, wparam, (LPARAM)lvc); + } +} + + +int LV_InsertItem(HWND hwnd, LVITEM *lvi) { + return SNDMSG(hwnd, bCoreUnicode ? LVM_INSERTITEMW : LVM_INSERTITEMA, 0, (LPARAM)lvi); +} + + +int LV_InsertItemA(HWND hwnd, LVITEM *lvi) { + if ( bCoreUnicode ) lvi->pszText = (LPSTR) mir_a2u(lvi->pszText); + int ret = LV_InsertItem(hwnd, lvi); + if ( bCoreUnicode ) mir_free(lvi->pszText); + return ret; +} + + +void LV_SetItemText(HWND hwnd, WPARAM wparam, int subitem, LPSTR text) { + LV_ITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.iSubItem = subitem; + lvi.pszText = text; + SNDMSG(hwnd, bCoreUnicode ? LVM_SETITEMTEXTW : LVM_SETITEMTEXTA, wparam, (LPARAM)&lvi); +} + + +void LV_SetItemTextA(HWND hwnd, WPARAM wparam, int subitem, LPSTR text) { + if ( bCoreUnicode ) text = (LPSTR) mir_a2u(text); + LV_SetItemText(hwnd, wparam, subitem, text); + if ( bCoreUnicode ) mir_free(text); +} + + +void LV_GetItemTextA(HWND hwnd, WPARAM wparam, int iSubItem, LPSTR text, int cchTextMax) { + LV_ITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.iSubItem = iSubItem; + lvi.cchTextMax = cchTextMax; + lvi.pszText = text; + SNDMSG(hwnd, bCoreUnicode ? LVM_GETITEMTEXTW : LVM_GETITEMTEXTA, wparam, (LPARAM)&lvi); + if ( bCoreUnicode ) { + lvi.pszText = mir_u2a((LPWSTR)text); + strcpy(text, lvi.pszText); + mir_free(lvi.pszText); + } +} + +/* + * tabbed options dialog + */ + +INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + + static int iInit = TRUE; + TCITEM tci; + + switch(msg) { + case WM_INITDIALOG: { + RECT rcClient; + GetClientRect(hwnd, &rcClient); + + iInit = TRUE; + tci.mask = TCIF_PARAM|TCIF_TEXT; + + tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_TAB_GENERAL),hwnd,DlgProcOptionsGeneral); + tci.pszText = (LPSTR)sim201; + TC_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci); + MoveWindow((HWND)tci.lParam,5,26,rcClient.right-8,rcClient.bottom-29,1); + + tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_TAB_PROTO),hwnd,DlgProcOptionsProto); + tci.pszText = (LPSTR)sim202; + TC_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 2, &tci); + MoveWindow((HWND)tci.lParam,5,26,rcClient.right-8,rcClient.bottom-29,1); + ShowWindow((HWND)tci.lParam, SW_HIDE); + + if(bPGP && bPGPloaded) { + tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_TAB_PGP),hwnd,DlgProcOptionsPGP); + tci.pszText = (LPSTR)sim214; + TC_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 3, &tci); + MoveWindow((HWND)tci.lParam,5,26,rcClient.right-8,rcClient.bottom-29,1); + ShowWindow((HWND)tci.lParam, SW_HIDE); + } + + if(bGPG && bGPGloaded) { + tci.lParam = (LPARAM)CreateDialog(g_hInst,MAKEINTRESOURCE(IDD_TAB_GPG),hwnd,DlgProcOptionsGPG); + tci.pszText = (LPSTR)sim226; + TC_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 4, &tci); + MoveWindow((HWND)tci.lParam,5,26,rcClient.right-8,rcClient.bottom-29,1); + ShowWindow((HWND)tci.lParam, SW_HIDE); + } + + // add more tabs here if needed + // activate the final tab + iInit = FALSE; + return TRUE; + } + break; + + case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0); + if (!iInit) + SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0); + break; + + case WM_COMMAND: { + switch(LOWORD(wParam)) { + case ID_UPDATE_CLIST: { + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),0,&tci); + SendMessage((HWND)tci.lParam,WM_COMMAND,ID_UPDATE_CLIST,0); + } + break; +/* case ID_UPDATE_PROTO: { + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),1,&tci); + SendMessage((HWND)tci.lParam,WM_COMMAND,ID_UPDATE_PROTO,0); + } + break;*/ + case ID_UPDATE_PLIST: { + if ( !bPGP ) break; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),2,&tci); + SendMessage((HWND)tci.lParam,WM_COMMAND,ID_UPDATE_CLIST,0); + } + break; + case ID_UPDATE_GLIST: { + if ( !bGPG ) break; + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),3,&tci); + SendMessage((HWND)tci.lParam,WM_COMMAND,ID_UPDATE_GLIST,0); + } + break; + } + } + break; + + case WM_NOTIFY: { + switch(((LPNMHDR)lParam)->idFrom) { + case 0: { + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: { + tci.mask = TCIF_PARAM; + int cnt = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB)); + for (int i=0;icode) { + case TCN_SELCHANGING: { + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); + ShowWindow((HWND)tci.lParam,SW_HIDE); + } + break; + case TCN_SELCHANGE: { + tci.mask = TCIF_PARAM; + TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci); + ShowWindow((HWND)tci.lParam,SW_SHOW); + } + break; + } + } // case IDC_OPTIONSTAB + break; + } + } // case WM_NOTIFY + break; + } + return FALSE; +} + + +INT_PTR CALLBACK DlgProcOptionsGeneral(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { + + static int iInit = TRUE; + static HIMAGELIST hLarge, hSmall; + int i,idx; pUinKey ptr; + + HWND hLV = GetDlgItem(hDlg,IDC_STD_USERLIST); + + switch (wMsg) { + case WM_INITDIALOG: { + + TranslateDialogDefault(hDlg); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("DlgProcOptionsGeneral(WN_INITDIALOG)"); +#endif + iInit = TRUE; +// SendMessage(hLV, WM_SETREDRAW, FALSE, 0); + ListView_SetExtendedListViewStyle(hLV, ListView_GetExtendedListViewStyle(hLV) | LVS_EX_FULLROWSELECT); + + hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), iBmpDepth, 1, 1); + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), iBmpDepth, 1, 1); +// COLORREF rgbTransparentColor; + for (i = 0; i < ICO_CNT; i++) { +// ImageList_AddMasked(himgl, hbmp, rgbTransparentColor); + ImageList_AddIcon(hSmall, g_hICO[i]); + ImageList_AddIcon(hLarge, g_hICO[i]); + } + + ListView_SetImageList(hLV, hSmall, LVSIL_SMALL); + ListView_SetImageList(hLV, hLarge, LVSIL_NORMAL); + + static const char *szColHdr[] = { sim203, sim204, sim230, sim205, "", sim234, 0 }; + static int iColWidth[] = { 150, 110, 60, 55, 35, 330 }; + LVCOLUMN lvc; + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvc.fmt = LVCFMT_LEFT; + for (i = 0; szColHdr[i]; i++) { + lvc.iSubItem = i; + lvc.pszText = (LPSTR)szColHdr[i]; + lvc.cx = iColWidth[i]; + LV_InsertColumn(hLV, i, &lvc); + } + for (i = 0; szAdvancedIcons[i]; i++) { + SendMessage(GetDlgItem(hDlg, IDC_ADVICON), CB_ADDSTRING, 0, (LPARAM) Translate(szAdvancedIcons[i])); + } + + RefreshGeneralDlg(hDlg,TRUE); + EnableWindow(hLV, true); +// SendMessage(hLV, WM_SETREDRAW, TRUE, 0); + + iInit = FALSE; + return TRUE; + } // WM_INITDIALOG + break; + + case WM_DESTROY: { + ImageList_Destroy(hSmall); + ImageList_Destroy(hLarge); + } // WM_DESTROY + break; + + case WM_PAINT: { + if (!iInit) + InvalidateRect(hDlg,NULL,FALSE); + } // WM_PAINT + break; + + case WM_COMMAND: { + switch(LOWORD(wParam)) { + case ID_ALWAYS: + case ID_ENABLED: + case ID_DISABLED: { + idx = ListView_GetSelectionMark(hLV); + ptr = (pUinKey) getListViewParam(hLV,idx); + if (ptr) { + ptr->tstatus = LOWORD(wParam)-ID_DISABLED; + setListViewStatus(hLV,idx,ptr->tstatus); + setListViewIcon(hLV,idx,ptr); + } + } + break; + + case ID_SIM_NATIVE: + case ID_SIM_PGP: + case ID_SIM_GPG: + case ID_SIM_RSAAES: + case ID_SIM_RSA: { + idx = ListView_GetSelectionMark(hLV); + ptr = (pUinKey) getListViewParam(hLV,idx); + if (ptr) { + ptr->tmode = LOWORD(wParam)-ID_SIM_NATIVE; + setListViewMode(hLV,idx,ptr->tmode); + setListViewIcon(hLV,idx,ptr); + } + } + break; + + case ID_SETPSK: { + idx = ListView_GetSelectionMark(hLV); + ptr = (pUinKey) getListViewParam(hLV,idx); + if(ptr) { + LPSTR buffer = (LPSTR)alloca(PSKSIZE+1); + getContactName(ptr->hContact, buffer); + int res = DialogBoxParam(g_hInst,MAKEINTRESOURCE(IDD_PSK),NULL,(DLGPROC)DlgProcSetPSK,(LPARAM)buffer); + if(res == IDOK) { + setListViewPSK(hLV,idx,1); + DBWriteContactSettingString(ptr->hContact,szModuleName,"tPSK",buffer); + } + } + } + break; + + case ID_DELPSK: { + idx = ListView_GetSelectionMark(hLV); + ptr = (pUinKey) getListViewParam(hLV,idx); + if(ptr) { + setListViewPSK(hLV,idx,0); + DBDeleteContactSetting(ptr->hContact, szModuleName, "tPSK"); + } + } + break; + + case ID_DELPUBL: { + idx = ListView_GetSelectionMark(hLV); + ptr = (pUinKey) getListViewParam(hLV,idx); + if(ptr) { + setListViewPUB(hLV,idx,0); + } + } + break; + + case ID_EXPPUBL: { + idx = ListView_GetSelectionMark(hLV); + ptr = (pUinKey) getListViewParam(hLV,idx); + if(ptr) { + if ( !ptr->keyLoaded ) { + createRSAcntx(ptr); + loadRSAkey(ptr); + } + if ( ptr->keyLoaded ) { + LPSTR buffer = (LPSTR) alloca(RSASIZE); + exp->rsa_export_pubkey(ptr->cntx,buffer); + if ( !SaveExportRSAKeyDlg(hDlg,buffer,0)) + msgbox(hDlg,sim114,szModuleName,MB_OK|MB_ICONEXCLAMATION); + } + } + return TRUE; + } + break; + + case ID_IMPPUBL: { + idx = ListView_GetSelectionMark(hLV); + ptr = (pUinKey) getListViewParam(hLV,idx); + if(ptr) { + createRSAcntx(ptr); + LPSTR pub = (LPSTR) alloca(RSASIZE); + if ( !LoadImportRSAKeyDlg(hDlg,pub,0)) return TRUE; + if ( exp->rsa_import_pubkey(ptr->cntx,pub)) { + int len; + exp->rsa_get_pubkey(ptr->cntx,(PBYTE)pub,&len); + + DBCONTACTWRITESETTING cws; + cws.szModule = szModuleName; + cws.szSetting = "rsa_pub"; + cws.value.type = DBVT_BLOB; + cws.value.pbVal = (PBYTE)pub; + cws.value.cpbVal = len; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)ptr->hContact, (LPARAM)&cws); + + setListViewPUB(hLV,idx,1); + } + else + msgbox(hDlg,sim115,szModuleName,MB_OK|MB_ICONEXCLAMATION); + } + return TRUE; + } + break; + + case ID_UPDATE_CLIST: { +// iInit = TRUE; +// RefreshGeneralDlg(hDlg,FALSE); +// iInit = FALSE; + return TRUE; + } + break; + + case IDC_RESET: { + if (!iInit) + ResetGeneralDlg(hDlg); + } + break; + + case IDC_ADV8: + case IDC_ADV7: + case IDC_ADV6: + case IDC_ADV5: + case IDC_ADV4: + case IDC_ADV3: + case IDC_ADV2: + case IDC_ADV1: + case IDC_ADV0: + case IDC_GPG: + case IDC_PGP: + case IDC_NO_PGP: + case IDC_NOL: + case IDC_AAK: + case IDC_MCM: + case IDC_AIP: + case IDC_SOM: + case IDC_SFT: + case IDC_ASI: + case IDC_MCD: + case IDC_KET: + case IDC_SCM: + case IDC_DGP: + case IDC_OKT: + case IDC_ADVICON: + break; + + default: + return FALSE; + } + if (!iInit) + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } // WM_COMMAND + break; + + case WM_NOTIFY: { + switch(((LPNMHDR)lParam)->idFrom) { + case 0: { + if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY) { + iInit = TRUE; + ApplyGeneralSettings(hDlg); + RefreshContactListIcons(); +// SendMessage(GetParent(hDlg),WM_COMMAND,ID_UPDATE_PLIST,0); +// SendMessage(GetParent(hDlg),WM_COMMAND,ID_UPDATE_GLIST,0); + iInit = FALSE; + } + } + break; + + case IDC_STD_USERLIST: { + switch(((LPNMHDR)lParam)->code) { + case NM_DBLCLK: { + if(LPNMLISTVIEW(lParam)->iSubItem == 2) { + idx = LPNMLISTVIEW(lParam)->iItem; + ptr = (pUinKey) getListViewParam(hLV,idx); + if (ptr) { + ptr->tmode++; + if ( !bPGP && ptr->tmode==MODE_PGP ) ptr->tmode++; + if ( !bGPG && ptr->tmode==MODE_GPG ) ptr->tmode++; + if ( ptr->tmode>=MODE_CNT ) ptr->tmode=MODE_NATIVE; + setListViewMode(hLV,idx,ptr->tmode); + setListViewIcon(hLV,idx,ptr); + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } + } + if(LPNMLISTVIEW(lParam)->iSubItem == 3) { + idx = LPNMLISTVIEW(lParam)->iItem; + ptr = (pUinKey) getListViewParam(hLV,idx); + if (ptr) { + ptr->tstatus++; if(ptr->tstatus>(ptr->tmode==MODE_RSAAES?1:2)) ptr->tstatus=0; + setListViewStatus(hLV,idx,ptr->tstatus); + setListViewIcon(hLV,idx,ptr); + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } + } + } break; + case NM_RCLICK: { +// idx = ListView_GetSelectionMark(hLV); + LPNMLISTVIEW lpLV = (LPNMLISTVIEW)lParam; + ptr = (pUinKey) getListViewParam(hLV,lpLV->iItem); + if (ptr) { + POINT p; GetCursorPos(&p); + HMENU hMenu = NULL; + if ( ptr->tmode==MODE_NATIVE || ptr->tmode==MODE_RSAAES ) { + switch( lpLV->iSubItem ) { + case 2: // mode + hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDM_CLIST2)); + break; + case 3: // status + hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE((ptr->tmode==MODE_NATIVE)?IDM_CLIST01:IDM_CLIST11)); + break; + case 4: // PSK/PUB + case 5: // SHA1 + hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE((ptr->tmode==MODE_NATIVE)?IDM_CLIST02:IDM_CLIST12)); + break; + default: // full menu + hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE((ptr->tmode==MODE_NATIVE)?IDM_CLIST0:IDM_CLIST1)); + break; + } + CheckMenuItem(hMenu, ID_DISABLED+ptr->tstatus, MF_CHECKED ); + if ( ptr->tmode==MODE_NATIVE ) { + if ( !hasKey(ptr)) EnableMenuItem(hMenu, ID_DELPSK, MF_GRAYED ); + } + else + if ( ptr->tmode==MODE_RSAAES ) { + if ( !hasKey(ptr)) { + EnableMenuItem(hMenu, ID_EXPPUBL, MF_GRAYED ); + EnableMenuItem(hMenu, ID_DELPUBL, MF_GRAYED ); + } + } + } + if ( !hMenu ) + hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDM_CLIST2)); + TranslateMenu(hMenu); + CheckMenuItem(hMenu, ID_SIM_NATIVE+ptr->tmode, MF_CHECKED ); + if ( !bPGP ) EnableMenuItem(hMenu, ID_SIM_PGP, MF_GRAYED ); + if ( !bGPG ) EnableMenuItem(hMenu, ID_SIM_GPG, MF_GRAYED ); +// CheckMenuItem(hMenu, ID_ENCRYPTION, MF_BYCOMMAND ); + TrackPopupMenu(GetSubMenu(hMenu, 0), TPM_LEFTALIGN | TPM_TOPALIGN, p.x, p.y, 0, hDlg, 0); + DestroyMenu(hMenu); + } + } break; + case LVN_COLUMNCLICK: { + bChangeSortOrder = true; + ListView_Sort(hLV,(LPARAM)(LPNMLISTVIEW(lParam)->iSubItem+0x01)); + bChangeSortOrder = false; + } + } + } + break; + } + } // WM_NOTIFY + break; + } + return FALSE; +} + + +INT_PTR CALLBACK DlgProcOptionsProto(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { + + static int iInit = TRUE; + char buf[32]; + int idx; + + HWND hLV = GetDlgItem(hDlg,IDC_PROTO); + + switch (wMsg) { + case WM_INITDIALOG: { + + TranslateDialogDefault(hDlg); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("DlgProcOptionsProto(WN_INITDIALOG)"); +#endif + iInit = TRUE; + ListView_SetExtendedListViewStyle(hLV, ListView_GetExtendedListViewStyle(hLV) | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES); + + LVCOLUMN lvc; + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvc.fmt = LVCFMT_LEFT; + lvc.pszText = (LPSTR)sim210; + lvc.cx = 150; + LV_InsertColumn(hLV, 0, &lvc); + + RefreshProtoDlg(hDlg); + EnableWindow(hLV, true); + + iInit = FALSE; + return TRUE; + } // WM_INITDIALOG + break; + + case WM_PAINT: { + if (!iInit) + InvalidateRect(hDlg,NULL,FALSE); + } // WM_PAINT + break; + + case WM_COMMAND: { + switch(LOWORD(wParam)) { + case IDC_RSA_COPY: { + char txt[128]; + GetDlgItemText(hDlg, IDC_RSA_SHA, txt, sizeof(txt)); + CopyToClipboard(hDlg,txt); + return TRUE; + } break; + case IDC_RSA_EXP: { + LPSTR pub = (LPSTR) alloca(RSASIZE); + exp->rsa_export_keypair(CPP_MODE_RSA,NULL,pub,NULL); + if ( !SaveExportRSAKeyDlg(hDlg,pub,0)) + msgbox(hDlg,sim114,szModuleName,MB_OK|MB_ICONEXCLAMATION); + return TRUE; + } break; + case IDC_RSA_EXPPRIV: { + LPSTR passphrase = (LPSTR) alloca(RSASIZE); + int res = DialogBoxParam(g_hInst,MAKEINTRESOURCE(IDD_PASSPHRASE),NULL,(DLGPROC)DlgProcSetPassphrase,(LPARAM)passphrase); + if ( res==IDOK ) { + LPSTR priv = (LPSTR) alloca(RSASIZE); + exp->rsa_export_keypair(CPP_MODE_RSA,priv,NULL,passphrase); + if ( !SaveExportRSAKeyDlg(hDlg,priv,1)) + msgbox(hDlg,sim112,szModuleName,MB_OK|MB_ICONEXCLAMATION); + } + return TRUE; + } break; + case IDC_RSA_IMPPRIV: { + LPSTR priv = (LPSTR) alloca(RSASIZE); + if ( !LoadImportRSAKeyDlg(hDlg,priv,1)) return TRUE; + // + LPSTR passphrase = (LPSTR) alloca(RSASIZE); + int res = DialogBoxParam(g_hInst,MAKEINTRESOURCE(IDD_PASSPHRASE),NULL,(DLGPROC)DlgProcSetPassphrase,(LPARAM)passphrase); + if ( res==IDOK ) { + if ( !exp->rsa_import_keypair(CPP_MODE_RSA,priv,passphrase)) { + msgbox(hDlg,sim113,szModuleName,MB_OK|MB_ICONEXCLAMATION); + } + else { + // обновить SHA1 значение + RefreshProtoDlg(hDlg); + } + } + return TRUE; + } break; + case IDC_SPLITON: + case IDC_SPLITOFF: { + if ( HIWORD(wParam) == EN_CHANGE ) { + idx = ListView_GetSelectionMark(hLV); + if ( idx == -1 ) break; + idx = (int) getListViewParam(hLV,idx); + switch(LOWORD(wParam)) { + case IDC_SPLITON: + GetDlgItemText(hDlg,IDC_SPLITON,buf,5); + proto[idx].tsplit_on = atoi(buf); + break; + case IDC_SPLITOFF: + GetDlgItemText(hDlg,IDC_SPLITOFF,buf,5); + proto[idx].tsplit_off = atoi(buf); + break; + } + } + if (!iInit) + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } break; + } + } + break; + + case WM_NOTIFY: { + switch(((LPNMHDR)lParam)->idFrom) { + case 0: { + if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY) { + iInit = TRUE; + ApplyProtoSettings(hDlg); + RefreshProtoDlg(hDlg); + RefreshContactListIcons(); + SendMessage(GetParent(hDlg),WM_COMMAND,ID_UPDATE_CLIST,0); +// SendMessage(GetParent(hDlg),WM_COMMAND,ID_UPDATE_PLIST,0); +// SendMessage(GetParent(hDlg),WM_COMMAND,ID_UPDATE_GLIST,0); + iInit = FALSE; + } + } + break; + + case IDC_PROTO: { + if (((LPNMHDR)lParam)->code == (UINT)NM_CLICK) { + idx = (int) getListViewParam(hLV,LPNMLISTVIEW(lParam)->iItem); + if ( idx == -1 ) break; + EnableWindow(GetDlgItem(hDlg,IDC_SPLITON), true); + EnableWindow(GetDlgItem(hDlg,IDC_SPLITOFF), true); + mir_itoa(proto[idx].tsplit_on,buf,10); SetDlgItemText(hDlg,IDC_SPLITON,buf); + mir_itoa(proto[idx].tsplit_off,buf,10); SetDlgItemText(hDlg,IDC_SPLITOFF,buf); + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } + } + break; + } + } // WM_NOTIFY + break; + } + return FALSE; +} + + +static BOOL bPGP9; + +INT_PTR CALLBACK DlgProcOptionsPGP(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { + + static int iInit = TRUE; + static HIMAGELIST hLarge, hSmall; + int i; + + HWND hLV = GetDlgItem(hDlg,IDC_PGP_USERLIST); + + switch (wMsg) { + case WM_INITDIALOG: { + + TranslateDialogDefault(hDlg); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("DlgProcOptionsPGP(WN_INITDIALOG)"); +#endif + iInit = TRUE; + ListView_SetExtendedListViewStyle(hLV, ListView_GetExtendedListViewStyle(hLV) | LVS_EX_FULLROWSELECT); + + hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), iBmpDepth, 1, 1); + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), iBmpDepth, 1, 1); + for (i = ICO_ST_DIS; i <= ICO_ST_TRY; i++) { + ImageList_AddIcon(hSmall, g_hICO[i]); + ImageList_AddIcon(hLarge, g_hICO[i]); + } + + ListView_SetImageList(hLV, hSmall, LVSIL_SMALL); + ListView_SetImageList(hLV, hLarge, LVSIL_NORMAL); + + static const char *szColHdr[] = { sim203, sim204, sim215, 0 }; + static int iColWidth[] = { 160, 150, 80 }; + LVCOLUMN lvc; + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvc.fmt = LVCFMT_LEFT; + for (i = 0; szColHdr[i]; i++) { + lvc.iSubItem = i; + lvc.pszText = (LPSTR)szColHdr[i]; + lvc.cx = iColWidth[i]; + LV_InsertColumn(hLV, i, &lvc); + } + + RefreshPGPDlg(hDlg,TRUE); +// EnableWindow(hLV, bPGPkeyrings); + + iInit = FALSE; + return TRUE; + } // WM_INITDIALOG + break; + + case WM_DESTROY: { + ImageList_Destroy(hSmall); + ImageList_Destroy(hLarge); + } // WM_DESTROY + break; + + case WM_PAINT: { + if (!iInit) + InvalidateRect(hDlg,NULL,FALSE); + } // WM_PAINT + break; + + case WM_COMMAND: { + switch(LOWORD(wParam)) { + case IDC_SET_KEYRINGS: { + char PubRingPath[MAX_PATH], SecRingPath[MAX_PATH]; + PubRingPath[0]='\0'; SecRingPath[0]='\0'; + bPGPkeyrings = pgp_open_keyrings(PubRingPath,SecRingPath); + if(bPGPkeyrings && PubRingPath[0] && SecRingPath[0]) { + DBWriteContactSettingString(0,szModuleName,"pgpPubRing",PubRingPath); + DBWriteContactSettingString(0,szModuleName,"pgpSecRing",SecRingPath); + } + SetDlgItemText(hDlg, IDC_KEYRING_STATUS, bPGPkeyrings?Translate(sim216):Translate(sim217)); +// EnableWindow(hLV, bPGPkeyrings); +// RefreshPGPDlg(hDlg); + return FALSE; + } + break; + case IDC_NO_KEYRINGS: { + BOOL bNoKR = (SendMessage(GetDlgItem(hDlg, IDC_NO_KEYRINGS),BM_GETCHECK,0L,0L)==BST_CHECKED); + EnableWindow(GetDlgItem(hDlg, IDC_SET_KEYRINGS), !bNoKR); + EnableWindow(GetDlgItem(hDlg, IDC_LOAD_PRIVKEY), bNoKR); + SetDlgItemText(hDlg, IDC_KEYRING_STATUS, bNoKR?Translate(sim225):((bPGP9)?Translate(sim220):(bPGPkeyrings?Translate(sim216):Translate(sim217)))); + } + break; + case IDC_LOAD_PRIVKEY: { + char KeyPath[MAX_PATH]; KeyPath[0]='\0'; + if(ShowSelectKeyDlg(hDlg,KeyPath)) { + char *priv = LoadKeys(KeyPath,true); + if(priv) { + DBWriteContactSettingString(0,szModuleName,"tpgpPrivKey",priv); + mir_free(priv); + } + else { + DBDeleteContactSetting(0,szModuleName,"tpgpPrivKey"); + } + } + } + break; + case ID_UPDATE_PLIST: { + iInit = TRUE; + RefreshPGPDlg(hDlg,FALSE); + iInit = FALSE; + return TRUE; + } + break; + default: + break; + } + if (!iInit) + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } + break; + + case WM_NOTIFY: { + switch(((LPNMHDR)lParam)->idFrom) { + case 0: { + if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY) { + iInit = TRUE; + ApplyPGPSettings(hDlg); + RefreshPGPDlg(hDlg,FALSE); +// SendMessage(GetParent(hDlg),WM_COMMAND,ID_UPDATE_CLIST,0); + iInit = FALSE; + } + } + break; + case IDC_PGP_USERLIST: { + switch(((LPNMHDR)lParam)->code) { +/* case NM_RCLICK: { + POINT p; + GetCursorPos(&p); + HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDM_CLIST)); + CheckMenuItem(hMenu, ID_ENCRYPTION, MF_BYCOMMAND ); + TranslateMenu(hMenu); + TrackPopupMenu(GetSubMenu(hMenu, 0), TPM_LEFTALIGN | TPM_TOPALIGN, p.x, p.y, 0, hDlg, 0); + DestroyMenu(hMenu); + } break;*/ + case LVN_COLUMNCLICK: { + bChangeSortOrder = true; + ListView_Sort(hLV,(LPARAM)(LPNMLISTVIEW(lParam)->iSubItem+0x11)); + bChangeSortOrder = false; + } + } + } + break; + } + } // WM_NOTIFY + break; + } + return FALSE; +} + + +INT_PTR CALLBACK DlgProcOptionsGPG(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { + + static int iInit = TRUE; + static HIMAGELIST hLarge, hSmall; + int i, idx; pUinKey ptr; + + HWND hLV = GetDlgItem(hDlg,IDC_GPG_USERLIST); + + switch (wMsg) { + case WM_INITDIALOG: { + + TranslateDialogDefault(hDlg); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("DlgProcOptionsGPG(WN_INITDIALOG)"); +#endif + iInit = TRUE; + ListView_SetExtendedListViewStyle(hLV, ListView_GetExtendedListViewStyle(hLV) | LVS_EX_FULLROWSELECT); + + hLarge = ImageList_Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), iBmpDepth, 1, 1); + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), iBmpDepth, 1, 1); + for (i = ICO_ST_DIS; i <= ICO_ST_TRY; i++) { + ImageList_AddIcon(hSmall, g_hICO[i]); + ImageList_AddIcon(hLarge, g_hICO[i]); + } + + ListView_SetImageList(hLV, hSmall, LVSIL_SMALL); + ListView_SetImageList(hLV, hLarge, LVSIL_NORMAL); + + static const char *szColHdr[] = { sim203, sim204, sim215, sim227, 0 }; + static int iColWidth[] = { 140, 120, 120, 40 }; + LVCOLUMN lvc; + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + lvc.fmt = LVCFMT_LEFT; + for (i = 0; szColHdr[i]; i++) { + lvc.iSubItem = i; + lvc.pszText = (LPSTR)szColHdr[i]; + lvc.cx = iColWidth[i]; + LV_InsertColumn(hLV, i, &lvc); + } + + RefreshGPGDlg(hDlg,TRUE); +// EnableWindow(hLV, bPGPkeyrings); + + iInit = FALSE; + return TRUE; + } // WM_INITDIALOG + break; + + case WM_DESTROY: { + ImageList_Destroy(hSmall); + ImageList_Destroy(hLarge); + } // WM_DESTROY + break; + + case WM_PAINT: { + if (!iInit) + InvalidateRect(hDlg,NULL,FALSE); + } // WM_PAINT + break; + + case WM_COMMAND: { + switch(LOWORD(wParam)) { +/* case IDC_LOAD_PRIVKEY: { + char KeyPath[MAX_PATH] = {0}; + if(ShowSelectKeyDlg(hDlg,KeyPath)) { + char *priv = LoadKeys(KeyPath,true); + if(priv) { + DBWriteContactSettingString(0,szModuleName,"tpgpPrivKey",priv); + mir_free(priv); + } + else { + DBDeleteContactSetting(0,szModuleName,"tpgpPrivKey"); + } + } + } + break;*/ + case IDC_BROWSEEXECUTABLE_BTN: { + char gpgexe[256]; + char filter[128]; + OPENFILENAME ofn; + + GetDlgItemText(hDlg, IDC_GPGEXECUTABLE_EDIT, gpgexe, sizeof(gpgexe)); + + char *txtexecutablefiles="Executable Files"; /*lang*/ + char *txtselectexecutable="Select GnuPG Executable"; /*lang*/ + + // filter zusammensetzen + memset(&filter,0,sizeof(filter)); + strcpy(filter, Translate(txtexecutablefiles)); + strcat(filter, " (*.exe)"); + strcpy(filter+strlen(filter)+1, "*.exe"); + + // OPENFILENAME initialisieren + memset(&ofn,0,sizeof(ofn)); + ofn.lStructSize=sizeof(ofn); + ofn.hwndOwner=hDlg; + ofn.lpstrFilter=filter; + ofn.lpstrFile=gpgexe; + ofn.nMaxFile=sizeof(gpgexe); + ofn.lpstrTitle=Translate(txtselectexecutable); + ofn.Flags=OFN_FILEMUSTEXIST|OFN_LONGNAMES|OFN_HIDEREADONLY; + + if (GetOpenFileName(&ofn)) + { + SetDlgItemText(hDlg, IDC_GPGEXECUTABLE_EDIT, ofn.lpstrFile); + } + } + break; + case ID_UPDATE_GLIST: { + iInit = TRUE; + RefreshGPGDlg(hDlg,FALSE); + iInit = FALSE; + return TRUE; + } + break; + default: + break; + } + if (!iInit) + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } + break; + + case WM_NOTIFY: { + switch(((LPNMHDR)lParam)->idFrom) { + case 0: { + if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY) { + iInit = TRUE; + ApplyGPGSettings(hDlg); + RefreshGPGDlg(hDlg,FALSE); +// SendMessage(GetParent(hDlg),WM_COMMAND,ID_UPDATE_CLIST,0); + iInit = FALSE; + } + } + break; + case IDC_GPG_USERLIST: { + switch(((LPNMHDR)lParam)->code) { + case NM_DBLCLK: { + if(LPNMLISTVIEW(lParam)->iSubItem == 3) { + idx = LPNMLISTVIEW(lParam)->iItem; + ptr = (pUinKey) getListViewParam(hLV,idx); + if ( !ptr ) break; + ptr->tgpgMode++; ptr->tgpgMode&=1; + LV_SetItemTextA(hLV, LPNMLISTVIEW(lParam)->iItem, LPNMLISTVIEW(lParam)->iSubItem, (ptr->tgpgMode)?Translate(sim228):Translate(sim229)); + SendMessage(GetParent(hDlg), PSM_CHANGED, 0, 0); + } + } break; +/* case NM_RCLICK: { + POINT p; + GetCursorPos(&p); + HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDM_CLIST)); + CheckMenuItem(hMenu, ID_ENCRYPTION, MF_BYCOMMAND ); + TranslateMenu(hMenu); + TrackPopupMenu(GetSubMenu(hMenu, 0), TPM_LEFTALIGN | TPM_TOPALIGN, p.x, p.y, 0, hDlg, 0); + DestroyMenu(hMenu); + } break;*/ + case LVN_COLUMNCLICK: { + bChangeSortOrder = true; + ListView_Sort(hLV,(LPARAM)(LPNMLISTVIEW(lParam)->iSubItem+0x21)); + bChangeSortOrder = false; + } + } + } + break; + } + } // WM_NOTIFY + break; + } + return FALSE; +} + + +BOOL CALLBACK DlgProcSetPSK(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) { + static char *buffer; + switch(uMsg) { + case WM_INITDIALOG: { + TranslateDialogDefault(hDlg); + SendDlgItemMessage(hDlg,IDC_EDIT1,EM_LIMITTEXT,PSKSIZE-1,0); + if ( bCoreUnicode ) SetDlgItemTextW(hDlg,IDC_EDIT2,(LPWSTR)lParam); + else SetDlgItemTextA(hDlg,IDC_EDIT2,(LPCSTR)lParam); + buffer = (LPSTR)lParam; + return (TRUE); + } + case WM_COMMAND: { + switch(LOWORD(wParam)) { + case IDOK: { + int len = GetDlgItemTextA(hDlg,IDC_EDIT1,buffer,PSKSIZE); + if(len<8) { + msgbox1(hDlg,sim211,szModuleName,MB_OK|MB_ICONEXCLAMATION); + return TRUE; + } + else { + EndDialog(hDlg,IDOK); + } + } + break; + case IDCANCEL: { + EndDialog(hDlg,IDCANCEL); + } + break; + } + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +BOOL CALLBACK DlgProcSetPassphrase(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam) { + static LPSTR buffer; + switch(uMsg) { + case WM_INITDIALOG: { + TranslateDialogDefault(hDlg); + SendDlgItemMessage(hDlg,IDC_PASSPHRASE,EM_LIMITTEXT,RSASIZE-1,0); + buffer = (LPSTR)lParam; + return (TRUE); + } + case WM_COMMAND: { + switch(LOWORD(wParam)) { + case IDOK: { +// memset(buffer,0,RSASIZE); + GetDlgItemTextA(hDlg,IDC_PASSPHRASE,buffer,RSASIZE); + EndDialog(hDlg,IDOK); + } + break; + case IDCANCEL: { + EndDialog(hDlg,IDCANCEL); + } + break; + } + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/////////////////// +// R E F R E S H // +/////////////////// + + +void RefreshGeneralDlg(HWND hDlg, BOOL iInit) { + + char timeout[10]; + UINT data; + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("RefreshGeneralDlg"); +#endif + // Key Exchange Timeout + data = DBGetContactSettingWord(0, szModuleName, "ket", 10); + mir_itoa(data,timeout,10); + SetDlgItemText(hDlg,IDC_KET,timeout); + + // Offline Key Timeout + data = DBGetContactSettingWord(0, szModuleName, "okt", 2); + mir_itoa(data,timeout,10); + SetDlgItemText(hDlg,IDC_OKT,timeout); + + GetFlags(); + + SendMessage(GetDlgItem(hDlg,IDC_SFT),BM_SETCHECK,(bSFT)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_SOM),BM_SETCHECK,(bSOM)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_ASI),BM_SETCHECK,(bASI)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_MCD),BM_SETCHECK,(bMCD)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_SCM),BM_SETCHECK,(bSCM)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_DGP),BM_SETCHECK,(bDGP)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_AIP),BM_SETCHECK,(bAIP)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_NOL),BM_SETCHECK,(bNOL)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_AAK),BM_SETCHECK,(bAAK)?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_MCM),BM_SETCHECK,(bMCM)?BST_CHECKED:BST_UNCHECKED,0L); + + // Advanced + SendMessage(GetDlgItem(hDlg, IDC_ADVICON), CB_SETCURSEL, bADV, 0); + if ( g_hCLIcon ) { + EnableWindow(GetDlgItem(hDlg, IDC_ADVICON), false); + } + + // Select {OFF,PGP,GPG} + SendMessage(GetDlgItem(hDlg,IDC_PGP),BM_SETCHECK,bPGP?BST_CHECKED:BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_GPG),BM_SETCHECK,bGPG?BST_CHECKED:BST_UNCHECKED,0L); + + // rebuild list of contacts + HWND hLV = GetDlgItem(hDlg,IDC_STD_USERLIST); + ListView_DeleteAllItems(hLV); + + LVITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + char tmp[NAMSIZE]; + + while (hContact) { + + pUinKey ptr = getUinKey(hContact); + if ( ptr && isSecureProtocol(hContact) /*&& !getMetaContact(hContact)*/ && !isChatRoom(hContact)) { + + if ( iInit ) { + ptr->tmode = ptr->mode; + ptr->tstatus = ptr->status; + } + + lvi.iItem++; + lvi.iImage = ptr->tstatus; + lvi.lParam = (LPARAM)ptr; + + getContactName(hContact, tmp); + lvi.pszText = (LPSTR)&tmp; + int itemNum = LV_InsertItem(hLV, &lvi); + + getContactUin(hContact, tmp); + LV_SetItemText(hLV, itemNum, 1, tmp); + + setListViewMode(hLV, itemNum, ptr->tmode); + setListViewStatus(hLV, itemNum, ptr->tstatus); + if ( ptr->mode==MODE_NATIVE ) setListViewPSK(hLV, itemNum, hasKey(ptr)); + else setListViewPUB(hLV, itemNum, hasKey(ptr)); + setListViewIcon(hLV, itemNum, ptr); + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + ListView_Sort(hLV,(LPARAM)0); +} + + +void RefreshProtoDlg(HWND hDlg) { + + int i; + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("RefreshProtoDlg"); +#endif + HWND hLV = GetDlgItem(hDlg,IDC_PROTO); + ListView_DeleteAllItems(hLV); + + LVITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.mask = LVIF_TEXT | LVIF_PARAM; + + for(i=0;irsa_get_keyhash(CPP_MODE_RSA,NULL,NULL,(PBYTE)&sha,&len); + LPSTR txt = mir_strdup(to_hex(sha,len)); + SetDlgItemText(hDlg, IDC_RSA_SHA, txt); + mir_free(txt); +} + + +void RefreshPGPDlg(HWND hDlg, BOOL iInit) { + + int ver = pgp_get_version(); + bPGP9 = (ver>=0x03050000); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("RefreshPGPDlg"); +#endif + EnableWindow(GetDlgItem(hDlg, IDC_SET_KEYRINGS), bUseKeyrings && !bPGP9); + EnableWindow(GetDlgItem(hDlg, IDC_LOAD_PRIVKEY), !bUseKeyrings); + SetDlgItemText(hDlg, IDC_PGP_PRIVKEY, bPGPprivkey?Translate(sim222):Translate(sim223)); + + if(bPGPloaded && ver) { + char pgpVerStr[64]; + sprintf(pgpVerStr, Translate(sim218), ver >> 24, (ver >> 16) & 255, (ver >> 8) & 255); + SetDlgItemText(hDlg, IDC_PGP_SDK, pgpVerStr); + } + else { + SetDlgItemText(hDlg, IDC_PGP_SDK, Translate(sim219)); + } + SetDlgItemText(hDlg, IDC_KEYRING_STATUS, !bUseKeyrings?Translate(sim225):((bPGP9)?Translate(sim220):(bPGPkeyrings?Translate(sim216):Translate(sim217)))); + + // Disable keyrings use + SendMessage(GetDlgItem(hDlg,IDC_NO_KEYRINGS),BM_SETCHECK,(bUseKeyrings)?BST_UNCHECKED:BST_CHECKED,0L); + + // rebuild list of contacts + HWND hLV = GetDlgItem(hDlg,IDC_PGP_USERLIST); + ListView_DeleteAllItems(hLV); + + LVITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + char tmp[NAMSIZE]; + + while (hContact) { + + pUinKey ptr = getUinKey(hContact); + if (ptr && ptr->mode==MODE_PGP && isSecureProtocol(hContact) /*&& !getMetaContact(hContact)*/ && !isChatRoom(hContact)) { + + LPSTR szKeyID = myDBGetString(hContact,szModuleName,"pgp_abbr"); + + lvi.iItem++; + lvi.iImage = (szKeyID!=0); + lvi.lParam = (LPARAM)ptr; + + getContactName(hContact, tmp); + lvi.pszText = (LPSTR)&tmp; + int itemNum = LV_InsertItem(hLV, &lvi); + + getContactUin(hContact, tmp); + LV_SetItemText(hLV, itemNum, 1, tmp); + + LV_SetItemTextA(hLV, itemNum, 2, (szKeyID)?szKeyID:Translate(sim221)); + SAFE_FREE(szKeyID); + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + ListView_Sort(hLV,(LPARAM)0x10); +} + + +void RefreshGPGDlg(HWND hDlg, BOOL iInit) { + + LPSTR path; + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("RefreshGPGDlg"); +#endif + path = myDBGetString(0,szModuleName,"gpgExec"); + if(path) { + SetDlgItemText(hDlg, IDC_GPGEXECUTABLE_EDIT, path); + mir_free(path); + } + path = myDBGetString(0,szModuleName,"gpgHome"); + if(path) { + SetDlgItemText(hDlg, IDC_GPGHOME_EDIT, path); + mir_free(path); + } + BOOL bGPGLogFlag = DBGetContactSettingByte(0, szModuleName, "gpgLogFlag",0); + SendMessage(GetDlgItem(hDlg,IDC_LOGGINGON_CBOX),BM_SETCHECK,(bGPGLogFlag)?BST_CHECKED:BST_UNCHECKED,0L); + path = myDBGetString(0,szModuleName,"gpgLog"); + if(path) { + SetDlgItemText(hDlg, IDC_GPGLOGFILE_EDIT, path); + mir_free(path); + } + SendMessage(GetDlgItem(hDlg,IDC_SAVEPASS_CBOX),BM_SETCHECK,(bSavePass)?BST_CHECKED:BST_UNCHECKED,0L); + BOOL bGPGTmpFlag = DBGetContactSettingByte(0, szModuleName, "gpgTmpFlag",0); + SendMessage(GetDlgItem(hDlg,IDC_TMPPATHON_CBOX),BM_SETCHECK,(bGPGTmpFlag)?BST_CHECKED:BST_UNCHECKED,0L); + path = myDBGetString(0,szModuleName,"gpgTmp"); + if(path) { + SetDlgItemText(hDlg, IDC_GPGTMPPATH_EDIT, path); + mir_free(path); + } + + // rebuild list of contacts + HWND hLV = GetDlgItem(hDlg,IDC_GPG_USERLIST); + ListView_DeleteAllItems(hLV); + + LVITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; + + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + char tmp[NAMSIZE]; + + while (hContact) { + + pUinKey ptr = getUinKey(hContact); + if (ptr && ptr->mode==MODE_GPG && isSecureProtocol(hContact) /*&& !getMetaContact(hContact)*/ && !isChatRoom(hContact)) { + + if ( iInit ) { + ptr->tgpgMode = ptr->gpgMode; + } + + LPSTR szKeyID = myDBGetString(hContact,szModuleName,"gpg"); + + lvi.iItem++; + lvi.iImage = (szKeyID!=0); + lvi.lParam = (LPARAM)ptr; + + getContactName(hContact, tmp); + lvi.pszText = (LPSTR)&tmp; + int itemNum = LV_InsertItem(hLV, &lvi); + + getContactUin(hContact, tmp); + LV_SetItemText(hLV, itemNum, 1, tmp); + + LV_SetItemTextA(hLV, itemNum, 2, (szKeyID)?szKeyID:Translate(sim221)); + LV_SetItemTextA(hLV, itemNum, 3, (ptr->tgpgMode)?Translate(sim228):Translate(sim229)); + SAFE_FREE(szKeyID); + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + ListView_Sort(hLV,(LPARAM)0x20); +} + + +/////////////// +// R E S E T // +/////////////// + + +void ResetGeneralDlg(HWND hDlg) { + + SetDlgItemText(hDlg,IDC_KET,"10"); + SetDlgItemText(hDlg,IDC_OKT,"2"); + + SendMessage(GetDlgItem(hDlg,IDC_SFT),BM_SETCHECK,BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_SOM),BM_SETCHECK,BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_ASI),BM_SETCHECK,BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_MCD),BM_SETCHECK,BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_SCM),BM_SETCHECK,BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_DGP),BM_SETCHECK,BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_AIP),BM_SETCHECK,BST_UNCHECKED,0L); + SendMessage(GetDlgItem(hDlg,IDC_MCM),BM_SETCHECK,BST_UNCHECKED,0L); + +// for(int i=0;itmode=MODE_NATIVE; + ptr->tstatus=STATUS_ENABLED; + + lvi.iItem++; + lvi.iImage = ptr->tstatus; + lvi.lParam = (LPARAM)ptr; + + getContactName(hContact, tmp); + lvi.pszText = (LPSTR)&tmp; + int itemNum = LV_InsertItem(hLV, &lvi); + + getContactUin(hContact, tmp); + LV_SetItemText(hLV, itemNum, 1, tmp); + + setListViewMode(hLV, itemNum, ptr->tmode); + setListViewStatus(hLV, itemNum, ptr->tstatus); + if ( ptr->mode==MODE_NATIVE ) setListViewPSK(hLV, itemNum, 0); + else setListViewPUB(hLV, itemNum, 0); + setListViewIcon(hLV, itemNum, ptr); + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } +} + + +void ResetProtoDlg(HWND hDlg) { +} + + +/////////////// +// A P P L Y // +/////////////// + + +void ApplyGeneralSettings(HWND hDlg) { + + char timeout[5]; + int tmp,i; + + // Key Exchange Timeout + GetDlgItemText(hDlg,IDC_KET,timeout,5); + tmp = atoi(timeout); if(tmp > 65535) tmp = 65535; + DBWriteContactSettingWord(0,szModuleName,"ket",tmp); + exp->rsa_set_timeout( DBGetContactSettingWord(0,szModuleName,"ket",10)); + mir_itoa(tmp,timeout,10); + SetDlgItemText(hDlg,IDC_KET,timeout); + + // Offline Key Timeout + GetDlgItemText(hDlg,IDC_OKT,timeout,5); + tmp = atoi(timeout); if(tmp > 65535) tmp = 65535; + DBWriteContactSettingWord(0,szModuleName,"okt",tmp); + mir_itoa(tmp,timeout,10); + SetDlgItemText(hDlg,IDC_OKT,timeout); + + bSFT = (SendMessage(GetDlgItem(hDlg, IDC_SFT),BM_GETCHECK,0L,0L)==BST_CHECKED); + bSOM = (SendMessage(GetDlgItem(hDlg, IDC_SOM),BM_GETCHECK,0L,0L)==BST_CHECKED); + bASI = (SendMessage(GetDlgItem(hDlg, IDC_ASI),BM_GETCHECK,0L,0L)==BST_CHECKED); + bMCD = (SendMessage(GetDlgItem(hDlg, IDC_MCD),BM_GETCHECK,0L,0L)==BST_CHECKED); + bSCM = (SendMessage(GetDlgItem(hDlg, IDC_SCM),BM_GETCHECK,0L,0L)==BST_CHECKED); + bDGP = (SendMessage(GetDlgItem(hDlg, IDC_DGP),BM_GETCHECK,0L,0L)==BST_CHECKED); + bAIP = (SendMessage(GetDlgItem(hDlg, IDC_AIP),BM_GETCHECK,0L,0L)==BST_CHECKED); + bNOL = (SendMessage(GetDlgItem(hDlg, IDC_NOL),BM_GETCHECK,0L,0L)==BST_CHECKED); + bAAK = (SendMessage(GetDlgItem(hDlg, IDC_AAK),BM_GETCHECK,0L,0L)==BST_CHECKED); + bMCM = (SendMessage(GetDlgItem(hDlg, IDC_MCM),BM_GETCHECK,0L,0L)==BST_CHECKED); + bADV = (BYTE)SendMessage(GetDlgItem(hDlg, IDC_ADVICON), CB_GETCURSEL, 0, 0); + + SetFlags(); + + // PGP &| GPG flags + { + tmp = 0; + i = SendMessage(GetDlgItem(hDlg, IDC_PGP),BM_GETCHECK,0L,0L)==BST_CHECKED; + if(i!=bPGP) { + bPGP = i; tmp++; + DBWriteContactSettingByte(0, szModuleName, "pgp", bPGP); + } + i = SendMessage(GetDlgItem(hDlg, IDC_GPG),BM_GETCHECK,0L,0L)==BST_CHECKED; + if(i!=bGPG) { + bGPG = i; tmp++; + DBWriteContactSettingByte(0, szModuleName, "gpg", bGPG); + } + if(tmp) msgbox1(hDlg, sim224, szModuleName, MB_OK|MB_ICONINFORMATION); + } + + HWND hLV = GetDlgItem(hDlg,IDC_STD_USERLIST); + i = ListView_GetNextItem(hLV,(UINT)-1,LVNI_ALL); + while(i!=-1) { + pUinKey ptr = (pUinKey)getListViewParam(hLV,i); + if ( !ptr ) continue; + if ( ptr->mode!=ptr->tmode ) { + ptr->mode = ptr->tmode; + DBWriteContactSettingByte(ptr->hContact, szModuleName, "mode", ptr->mode); + } + if ( ptr->status!=ptr->tstatus ) { + ptr->status = ptr->tstatus; + if(ptr->status==STATUS_ENABLED) DBDeleteContactSetting(ptr->hContact, szModuleName, "StatusID"); + else DBWriteContactSettingByte(ptr->hContact, szModuleName, "StatusID", ptr->status); + } + if ( ptr->mode==MODE_NATIVE ) { + if ( getListViewPSK(hLV,i)) { + LPSTR tmp = myDBGetString(ptr->hContact,szModuleName,"tPSK"); + DBWriteContactSettingString(ptr->hContact, szModuleName, "PSK", tmp); + mir_free(tmp); + } + else { + DBDeleteContactSetting(ptr->hContact, szModuleName, "PSK"); + } + DBDeleteContactSetting(ptr->hContact, szModuleName, "tPSK"); + } + else + if ( ptr->mode==MODE_RSAAES ) { + if ( !getListViewPUB(hLV,i)) { + DBDeleteContactSetting(ptr->hContact, szModuleName, "rsa_pub"); + } + } + i = ListView_GetNextItem(hLV,i,LVNI_ALL); + } +} + + +void ApplyProtoSettings(HWND hDlg) { + + LPSTR szNames = (LPSTR) alloca(2048); *szNames = '\0'; + + HWND hLV = GetDlgItem(hDlg,IDC_PROTO); + int i = ListView_GetNextItem(hLV,(UINT)-1,LVNI_ALL); + while(i!=-1) { + int j = getListViewProto(hLV,i); + proto[j].inspecting = ListView_GetCheckState(hLV,i); + char tmp[128]; + sprintf(tmp,"%s:%d:%d:%d;",proto[j].name,proto[j].inspecting,proto[j].tsplit_on,proto[j].tsplit_off); + strcat(szNames,tmp); + proto[j].split_on = proto[j].tsplit_on; + proto[j].split_off = proto[j].tsplit_off; + i = ListView_GetNextItem(hLV,i,LVNI_ALL); + } + + DBWriteContactSettingString(0,szModuleName,"protos",szNames); +} + + +void ApplyPGPSettings(HWND hDlg) { + + bUseKeyrings = !(SendMessage(GetDlgItem(hDlg, IDC_NO_KEYRINGS),BM_GETCHECK,0L,0L)==BST_CHECKED); + DBWriteContactSettingByte(0,szModuleName,"ukr",bUseKeyrings); + + char *priv = myDBGetString(0,szModuleName,"tpgpPrivKey"); + if(priv) { + bPGPprivkey = true; + pgp_set_priv_key(priv); + myDBWriteStringEncode(0,szModuleName,"pgpPrivKey",priv); + mir_free(priv); + DBDeleteContactSetting(0,szModuleName,"tpgpPrivKey"); + } +} + + +void ApplyGPGSettings(HWND hDlg) { + + char tmp[256]; + + GetDlgItemText(hDlg, IDC_GPGEXECUTABLE_EDIT, tmp, sizeof(tmp)); + DBWriteContactSettingString(0,szModuleName,"gpgExec",tmp); + GetDlgItemText(hDlg, IDC_GPGHOME_EDIT, tmp, sizeof(tmp)); + DBWriteContactSettingString(0,szModuleName,"gpgHome",tmp); + + bSavePass = (SendMessage(GetDlgItem(hDlg, IDC_SAVEPASS_CBOX),BM_GETCHECK,0L,0L)==BST_CHECKED); + DBWriteContactSettingByte(0,szModuleName,"gpgSaveFlag",bSavePass); + + BOOL bgpgLogFlag = (SendMessage(GetDlgItem(hDlg, IDC_LOGGINGON_CBOX),BM_GETCHECK,0L,0L)==BST_CHECKED); + DBWriteContactSettingByte(0,szModuleName,"gpgLogFlag",bgpgLogFlag); + GetDlgItemText(hDlg, IDC_GPGLOGFILE_EDIT, tmp, sizeof(tmp)); + DBWriteContactSettingString(0,szModuleName,"gpgLog",tmp); + if(bgpgLogFlag) gpg_set_log(tmp); + else gpg_set_log(0); + + BOOL bgpgTmpFlag = (SendMessage(GetDlgItem(hDlg, IDC_TMPPATHON_CBOX),BM_GETCHECK,0L,0L)==BST_CHECKED); + DBWriteContactSettingByte(0,szModuleName,"gpgTmpFlag",bgpgTmpFlag); + GetDlgItemText(hDlg, IDC_GPGTMPPATH_EDIT, tmp, sizeof(tmp)); + DBWriteContactSettingString(0,szModuleName,"gpgTmp",tmp); + if(bgpgTmpFlag) gpg_set_tmp(tmp); + else gpg_set_tmp(0); + + HWND hLV = GetDlgItem(hDlg,IDC_GPG_USERLIST); + int i = ListView_GetNextItem(hLV,(UINT)-1,LVNI_ALL); + while(i!=-1) { + pUinKey ptr = (pUinKey)getListViewParam(hLV,i); + if ( !ptr ) continue; + if ( ptr->gpgMode != ptr->tgpgMode ) { + ptr->gpgMode = ptr->tgpgMode; + if ( ptr->gpgMode ) DBWriteContactSettingByte(ptr->hContact,szModuleName,"gpgANSI",1); + else DBDeleteContactSetting(ptr->hContact,szModuleName,"gpgANSI"); + } + + i = ListView_GetNextItem(hLV,i,LVNI_ALL); + } +} + + +/////////////// +// O T H E R // +/////////////// + + +LPARAM getListViewParam(HWND hLV, UINT iItem) { + + LVITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.iItem = iItem; + lvi.mask = LVIF_PARAM; + ListView_GetItem(hLV, &lvi); + return lvi.lParam; +} + + +void setListViewIcon(HWND hLV, UINT iItem, pUinKey ptr) { + + LVITEM lvi; memset(&lvi,0,sizeof(lvi)); + lvi.iItem = iItem; + switch(ptr->tmode) { + case MODE_NATIVE: + case MODE_RSAAES: + lvi.iImage = ICO_ST_DIS+ptr->tstatus; + break; + case MODE_PGP: + lvi.iImage = ICO_OV_PGP; + break; + case MODE_GPG: + lvi.iImage = ICO_OV_GPG; + break; + } + lvi.mask = LVIF_IMAGE; + ListView_SetItem(hLV, &lvi); +} + + +void setListViewMode(HWND hLV, UINT iItem, UINT iMode) { + + char tmp[256]; + strncpy(tmp, Translate(sim231[iMode]), sizeof(tmp)); + LV_SetItemTextA(hLV, iItem, 2, tmp); +} + + +void setListViewStatus(HWND hLV, UINT iItem, UINT iStatus) { + + char tmp[128]; + strncpy(tmp, Translate(sim232[iStatus]), sizeof(tmp)); + LV_SetItemTextA(hLV, iItem, 3, tmp); +} + + +UINT getListViewPSK(HWND hLV, UINT iItem) { + + char str[128]; + LV_GetItemTextA(hLV, iItem, 4, str, sizeof(str)); + return strncmp(str, Translate(sim206), sizeof(str))==0; +} + + +void setListViewPSK(HWND hLV, UINT iItem, UINT iStatus) { + + char str[128]; + strncpy(str, (iStatus)?Translate(sim206):"-", sizeof(str)); + LV_SetItemTextA(hLV, iItem, 4, str); +} + + +UINT getListViewPUB(HWND hLV, UINT iItem) { + + char str[128]; + LV_GetItemTextA(hLV, iItem, 4, str, sizeof(str)); + return strncmp(str, Translate(sim233), sizeof(str))==0; +} + + +void setListViewPUB(HWND hLV, UINT iItem, UINT iStatus) { + + char str[128]; + strncpy(str, (iStatus)?Translate(sim233):"-", sizeof(str)); + LV_SetItemTextA(hLV, iItem, 4, str); + + LPSTR sha = NULL; + if ( iStatus ) { + DBVARIANT dbv; + dbv.type = DBVT_BLOB; + pUinKey ptr = (pUinKey) getListViewParam(hLV, iItem); + if ( DBGetContactSetting(ptr->hContact,szModuleName,"rsa_pub",&dbv) == 0 ) { + int len; + exp->rsa_get_hash((PBYTE)dbv.pbVal,dbv.cpbVal,(PBYTE)str,&len); + sha = mir_strdup(to_hex((PBYTE)str,len)); + DBFreeVariant(&dbv); + } + } + if ( sha ) { + LV_SetItemTextA(hLV, iItem, 5, sha); + mir_free(sha); + } + else LV_SetItemTextA(hLV, iItem, 5, ""); +} + + +int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { + char t1[NAMSIZE], t2[NAMSIZE]; + int s,d,m=1; + DBVARIANT dbv1,dbv2; + + if(lParamSort&0x100) { + lParamSort&=0xFF; + m=-1; + } + + switch(lParamSort){ + case 0x01: + case 0x11: + case 0x21: { + getContactNameA(pUinKey(lParam1)->hContact, t1); + getContactNameA(pUinKey(lParam2)->hContact, t2); + return strncmp(t1,t2,NAMSIZE)*m; + } break; + case 0x02: + case 0x12: + case 0x22: { + getContactUinA(pUinKey(lParam1)->hContact, t1); + getContactUinA(pUinKey(lParam2)->hContact, t2); + return strncmp(t1,t2,NAMSIZE)*m; + } break; + case 0x03: { + s = pUinKey(lParam1)->tmode; + d = pUinKey(lParam2)->tmode; + return (s-d)*m; + } break; + case 0x13: { + DBGetContactSetting(pUinKey(lParam1)->hContact,szModuleName,"pgp_abbr",&dbv1); + DBGetContactSetting(pUinKey(lParam2)->hContact,szModuleName,"pgp_abbr",&dbv2); + s=(dbv1.type==DBVT_ASCIIZ); + d=(dbv2.type==DBVT_ASCIIZ); + if(s && d) { + s=strcmp(dbv1.pszVal,dbv2.pszVal); + d=0; + } + DBFreeVariant(&dbv1); + DBFreeVariant(&dbv2); + return (s-d)*m; + } break; + case 0x23: { + DBGetContactSetting(pUinKey(lParam1)->hContact,szModuleName,"gpg",&dbv1); + DBGetContactSetting(pUinKey(lParam2)->hContact,szModuleName,"gpg",&dbv2); + s=(dbv1.type==DBVT_ASCIIZ); + d=(dbv2.type==DBVT_ASCIIZ); + if(s && d) { + s=strcmp(dbv1.pszVal,dbv2.pszVal); + d=0; + } + DBFreeVariant(&dbv1); + DBFreeVariant(&dbv2); + return (s-d)*m; + } break; + case 0x04: { + s = pUinKey(lParam1)->tstatus; + d = pUinKey(lParam2)->tstatus; + return (s-d)*m; + } break; + case 0x05: { + DBGetContactSetting(pUinKey(lParam1)->hContact,szModuleName,"PSK",&dbv1); + s=(dbv1.type==DBVT_ASCIIZ); + DBFreeVariant(&dbv1); + DBGetContactSetting(pUinKey(lParam2)->hContact,szModuleName,"PSK",&dbv2); + d=(dbv2.type==DBVT_ASCIIZ); + DBFreeVariant(&dbv2); + return (s-d)*m; + } break; + } + return 0; +} + + +void ListView_Sort(HWND hLV, LPARAM lParamSort) { + char t[32]; + + // restore sort column + sprintf(t,"os%02x",(UINT)lParamSort&0xF0); + if ((lParamSort&0x0F)==0) { + lParamSort=(int)DBGetContactSettingByte(0, szModuleName, t, lParamSort+1); + } + DBWriteContactSettingByte(0, szModuleName, t, (BYTE)lParamSort); + + // restore sort order + sprintf(t,"os%02x",(UINT)lParamSort); + int m=DBGetContactSettingByte(0, szModuleName, t, 0); + if(bChangeSortOrder){ m=!m; DBWriteContactSettingByte(0, szModuleName, t, m); } + + ListView_SortItems(hLV,&CompareFunc,lParamSort|(m<<8)); +} + + +BOOL ShowSelectKeyDlg(HWND hParent, LPSTR KeyPath) +{ + OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hParent; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON; + + ofn.lpstrFile = KeyPath; + ofn.lpstrFilter = "ASC files\0*.asc\0All files (*.*)\0*.*\0"; + ofn.lpstrTitle = "Open Key File"; + if (!GetOpenFileName(&ofn)) return FALSE; + + return TRUE; +} + + +LPCSTR priv_beg = "-----BEGIN PGP PRIVATE KEY BLOCK-----"; +LPCSTR priv_end = "-----END PGP PRIVATE KEY BLOCK-----"; +LPCSTR publ_beg = "-----BEGIN PGP PUBLIC KEY BLOCK-----"; +LPCSTR publ_end = "-----END PGP PUBLIC KEY BLOCK-----"; + +LPSTR LoadKeys(LPCSTR file,BOOL priv) { + FILE *f=fopen(file,"r"); + if (!f) return NULL; + + fseek(f,0,SEEK_END); + int flen = ftell(f); + fseek(f,0,SEEK_SET); + + LPCSTR beg,end; + if(priv) { + beg = priv_beg; + end = priv_end; + } + else { + beg = publ_beg; + end = publ_end; + } + + LPSTR keys = (LPSTR)mir_alloc(flen+1); + int i=0; BOOL b=false; + while(fgets(keys+i,128,f)) { + if (!b && strncmp(keys+i,beg,strlen(beg))==0) { + b=true; + } + else + if(b && strncmp(keys+i,end,strlen(end))==0) { + i+=(int)strlen(keys+i); + b=false; + } + if(b) { + i+=(int)strlen(keys+i); + } + } + *(keys+i)='\0'; +/* while(flen) { + int block = (flen>32768)?32768:flen; + fread(keys+i,block,1,f); + i+=block; + flen-=block; + }*/ + fclose(f); + return keys; +} + + +BOOL SaveExportRSAKeyDlg(HWND hParent, LPSTR key, BOOL priv) +{ + char szFile[MAX_PATH] = "rsa_pub.asc"; + if ( priv ) strcpy(szFile,"rsa_priv.asc"); + + OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hParent; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON; + ofn.lpstrFile = szFile; + ofn.lpstrFilter = "ASC files\0*.asc\0All files (*.*)\0*.*\0"; + ofn.lpstrTitle = (priv)?"Save Private Key File":"Save Public Key File"; + if (!GetSaveFileName(&ofn)) return FALSE; + + FILE *f=fopen(szFile,"wb"); + if ( !f ) return FALSE; + fwrite(key,strlen(key),1,f); + fclose(f); + + return TRUE; +} + + +BOOL LoadImportRSAKeyDlg(HWND hParent, LPSTR key, BOOL priv) +{ + char szFile[MAX_PATH] = "rsa_pub.asc"; + if ( priv ) strcpy(szFile,"rsa_priv.asc"); + + OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hParent; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT | OFN_NOREADONLYRETURN; + ofn.lpstrFile = szFile; + ofn.lpstrFilter = "ASC files\0*.asc\0All files (*.*)\0*.*\0"; + ofn.lpstrTitle = (priv)?"Load Private Key File":"Load Public Key File"; + if (!GetOpenFileName(&ofn)) return FALSE; + + FILE *f=fopen(szFile,"rb"); + if ( !f ) return FALSE; + + fseek(f,0,SEEK_END); + int flen = ftell(f); if(flen>RSASIZE) { fclose(f); return FALSE; } + fseek(f,0,SEEK_SET); + + fread(key,flen,1,f); + fclose(f); + + return TRUE; +} + + +int onRegisterOptions(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.hInstance = g_hInst; + odp.pszTemplate = MAKEINTRESOURCE(IDD_OPTIONSTAB); + odp.pszTitle = (char*)szModuleName; + odp.pszGroup = LPGEN("Services"); + odp.pfnDlgProc = OptionsDlgProc; + Options_AddPage(wParam, &odp); + return 0; +} + +// EOF diff --git a/plugins/SecureIM/src/options.h b/plugins/SecureIM/src/options.h new file mode 100644 index 0000000000..c87a0de34d --- /dev/null +++ b/plugins/SecureIM/src/options.h @@ -0,0 +1,40 @@ +#ifndef __OPTIONS_H__ +#define __OPTIONS_H__ + +INT_PTR CALLBACK OptionsDlgProc(HWND,UINT,WPARAM,LPARAM); +INT_PTR CALLBACK DlgProcOptionsGeneral(HWND,UINT,WPARAM,LPARAM); +INT_PTR CALLBACK DlgProcOptionsProto(HWND,UINT,WPARAM,LPARAM); +INT_PTR CALLBACK DlgProcOptionsPGP(HWND,UINT,WPARAM,LPARAM); +INT_PTR CALLBACK DlgProcOptionsGPG(HWND,UINT,WPARAM,LPARAM); +BOOL CALLBACK DlgProcSetPSK(HWND,UINT,WPARAM,LPARAM); +BOOL CALLBACK DlgProcSetPassphrase(HWND,UINT,WPARAM,LPARAM); +void ApplyGeneralSettings(HWND); +void ApplyProtoSettings(HWND); +void ApplyPGPSettings(HWND); +void ApplyGPGSettings(HWND); +void RefreshGeneralDlg(HWND,BOOL); +void RefreshProtoDlg(HWND); +void RefreshPGPDlg(HWND,BOOL); +void RefreshGPGDlg(HWND,BOOL); +void ResetGeneralDlg(HWND); +void ResetProtoDlg(HWND); +LPARAM getListViewParam(HWND,UINT); +void setListViewIcon(HWND,UINT,pUinKey); +void setListViewMode(HWND,UINT,UINT); +void setListViewStatus(HWND,UINT,UINT); +UINT getListViewPSK(HWND,UINT); +void setListViewPSK(HWND,UINT,UINT); +UINT getListViewPUB(HWND,UINT); +void setListViewPUB(HWND,UINT,UINT); +int onRegisterOptions(WPARAM,LPARAM); +int CALLBACK CompareFunc(LPARAM,LPARAM,LPARAM); +void ListView_Sort(HWND,LPARAM); +BOOL ShowSelectKeyDlg(HWND,LPSTR); +LPSTR LoadKeys(LPCSTR,BOOL); +BOOL SaveExportRSAKeyDlg(HWND,LPSTR,BOOL); +BOOL LoadImportRSAKeyDlg(HWND,LPSTR,BOOL); + +#define getListViewContact(h,i) (HANDLE)getListViewParam(h,i) +#define getListViewProto(h,i) (int)getListViewParam(h,i) + +#endif diff --git a/plugins/SecureIM/src/popupOptions.cpp b/plugins/SecureIM/src/popupOptions.cpp new file mode 100644 index 0000000000..6e08cd81fc --- /dev/null +++ b/plugins/SecureIM/src/popupOptions.cpp @@ -0,0 +1,239 @@ +#include "commonheaders.h" + + +INT_PTR CALLBACK PopOptionsDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { + + char getTimeout[5]; + + HWND hec = GetDlgItem(hDlg, IDC_EC); + HWND hdc = GetDlgItem(hDlg, IDC_DC); + HWND hks = GetDlgItem(hDlg, IDC_KS); + HWND hkr = GetDlgItem(hDlg, IDC_KR); + HWND hss = GetDlgItem(hDlg, IDC_SS); + HWND hsr = GetDlgItem(hDlg, IDC_SR); + + switch (wMsg) { + case WM_COMMAND: { + + if (HIWORD(wParam) == CPN_COLOURCHANGED) { + //It's a colour picker change. LOWORD(wParam) is the control id. + DWORD color = SendDlgItemMessage(hDlg,LOWORD(wParam),CPM_GETCOLOUR,0,0); + + switch(LOWORD(wParam)) { + case IDC_BACKKEY: + DBWriteContactSettingDword(0, szModuleName, "colorKeyb", color); + break; + case IDC_TEXTKEY: + DBWriteContactSettingDword(0, szModuleName, "colorKeyt", color); + break; + case IDC_BACKSEC: + DBWriteContactSettingDword(0, szModuleName, "colorSecb", color); + break; + case IDC_TEXTSEC: + DBWriteContactSettingDword(0, szModuleName, "colorSect", color); + break; + case IDC_BACKSR: + DBWriteContactSettingDword(0, szModuleName, "colorSRb", color); + break; + case IDC_TEXTSR: + DBWriteContactSettingDword(0, szModuleName, "colorSRt", color); + break; + } + return TRUE; + } + + switch (LOWORD(wParam)) { + case IDC_PREV: { + //preview popups... + showPopUp("Key Popup",NULL,g_hPOP[POP_PU_PRC],0); + showPopUp("Secure Popup",NULL,g_hPOP[POP_PU_EST],1); + showPopUp("Message Popup",NULL,g_hPOP[POP_PU_MSR],2); + } + break; + case IDC_EC: { + //set ec checkbox value + DBWriteContactSettingByte(0, szModuleName, "ec", (BYTE)(SendMessage(hec,BM_GETCHECK,0L,0L)==BST_CHECKED)); + } + break; + case IDC_DC: { + //set dc checkbox value + DBWriteContactSettingByte(0, szModuleName, "dc", (BYTE)(SendMessage(hdc,BM_GETCHECK,0L,0L)==BST_CHECKED)); + } + break; + case IDC_SS: { + //set ss checkbox value + DBWriteContactSettingByte(0, szModuleName, "ss", (BYTE)(SendMessage(hss,BM_GETCHECK,0L,0L)==BST_CHECKED)); + } + break; + case IDC_SR: { + //set sr checkbox value + DBWriteContactSettingByte(0, szModuleName, "sr", (BYTE)(SendMessage(hsr,BM_GETCHECK,0L,0L)==BST_CHECKED)); + } + break; + case IDC_KS: { + //set indicator checkbox value + DBWriteContactSettingByte(0, szModuleName, "ks", (BYTE)(SendMessage(hks,BM_GETCHECK,0L,0L)==BST_CHECKED)); + } + break; + case IDC_KR: { + //set indicator checkbox value + DBWriteContactSettingByte(0, szModuleName, "kr", (BYTE)(SendMessage(hkr,BM_GETCHECK,0L,0L)==BST_CHECKED)); + } + break; + case IDC_TIMEKEY: { + //set timeout value + GetDlgItemText(hDlg,IDC_TIMEKEY,getTimeout,sizeof(getTimeout)); + mir_itoa(atoi(getTimeout),getTimeout,10); + DBWriteContactSettingString(0, szModuleName, "timeoutKey", getTimeout); + } + break; + case IDC_TIMESEC: { + //set timeout value + GetDlgItemText(hDlg,IDC_TIMESEC,getTimeout,sizeof(getTimeout)); + mir_itoa(atoi(getTimeout),getTimeout,10); + DBWriteContactSettingString(0, szModuleName, "timeoutSec", getTimeout); + } + break; + case IDC_TIMESR: { + //set timeout value + GetDlgItemText(hDlg,IDC_TIMESR,getTimeout,sizeof(getTimeout)); + mir_itoa(atoi(getTimeout),getTimeout,10); + DBWriteContactSettingString(0, szModuleName, "timeoutSR", getTimeout); + } + break; + } //switch + + RefreshPopupOptionsDlg(hec,hdc,hss,hsr,hks,hkr); + break; + } + + case WM_DESTROY: + break; + + case WM_INITDIALOG: { + TranslateDialogDefault(hDlg); + RefreshPopupOptionsDlg(hec,hdc,hss,hsr,hks,hkr); + + DBVARIANT dbv; + char *timeout; + + //set timeout value for Key + if (DBGetContactSetting(0, szModuleName, "timeoutKey", &dbv) == 0) timeout=dbv.pszVal; + else timeout="0"; + SetDlgItemText(hDlg, IDC_TIMEKEY, timeout); + DBFreeVariant(&dbv); + + //set timeout value for SEC + if (DBGetContactSetting(0, szModuleName, "timeoutSec", &dbv) == 0) timeout=dbv.pszVal; + else timeout="0"; + SetDlgItemText(hDlg, IDC_TIMESEC, timeout); + DBFreeVariant(&dbv); + + //set timeout value for SR + if (DBGetContactSetting(0, szModuleName, "timeoutSR", &dbv) == 0) timeout=dbv.pszVal; + else timeout="0"; + SetDlgItemText(hDlg, IDC_TIMESR, timeout); + DBFreeVariant(&dbv); + + //key color + SendDlgItemMessage(hDlg,IDC_BACKKEY,CPM_SETCOLOUR,0,DBGetContactSettingDword(0, szModuleName, "colorKeyb", RGB(230,230,255))); + SendDlgItemMessage(hDlg,IDC_TEXTKEY,CPM_SETCOLOUR,0,DBGetContactSettingDword(0, szModuleName, "colorKeyt", RGB(0,0,0))); + + //Session color + SendDlgItemMessage(hDlg,IDC_BACKSEC,CPM_SETCOLOUR,0,DBGetContactSettingDword(0, szModuleName, "colorSecb", RGB(255,255,200))); + SendDlgItemMessage(hDlg,IDC_TEXTSEC,CPM_SETCOLOUR,0,DBGetContactSettingDword(0, szModuleName, "colorSect", RGB(0,0,0))); + + //SR color + SendDlgItemMessage(hDlg,IDC_BACKSR,CPM_SETCOLOUR,0,DBGetContactSettingDword(0, szModuleName, "colorSRb", RGB(200,255,200))); + SendDlgItemMessage(hDlg,IDC_TEXTSR,CPM_SETCOLOUR,0,DBGetContactSettingDword(0, szModuleName, "colorSRt", RGB(0,0,0))); + + break; + } + + case WM_NOTIFY: { + break; + } + default: + return FALSE; + } + return TRUE; +} + + +void RefreshPopupOptionsDlg(HWND hec,HWND hdc,HWND hss,HWND hsr,HWND hks,HWND hkr) { + + DBVARIANT dbv; + int indic; + + // ec checkbox + if (DBGetContactSetting(0, szModuleName, "ec", &dbv) == 0) + {indic=dbv.bVal; + } + else indic=1; + + if(indic==1)SendMessage(hec,BM_SETCHECK,BST_CHECKED,0L); + else SendMessage(hec,BM_SETCHECK,BST_UNCHECKED,0L); + + // dc checkbox + if (DBGetContactSetting(0, szModuleName, "dc", &dbv) == 0) + {indic=dbv.bVal; + } + else indic=1; + + if(indic==1)SendMessage(hdc,BM_SETCHECK,BST_CHECKED,0L); + else SendMessage(hdc,BM_SETCHECK,BST_UNCHECKED,0L); + + // ks checkbox + if (DBGetContactSetting(0, szModuleName, "ks", &dbv) == 0) + {indic=dbv.bVal; + } + else indic=1; + + if(indic==1)SendMessage(hks,BM_SETCHECK,BST_CHECKED,0L); + else SendMessage(hks,BM_SETCHECK,BST_UNCHECKED,0L); + + // kr checkbox + if (DBGetContactSetting(0, szModuleName, "kr", &dbv) == 0) + {indic=dbv.bVal; + } + else indic=1; + + if(indic==1)SendMessage(hkr,BM_SETCHECK,BST_CHECKED,0L); + else SendMessage(hkr,BM_SETCHECK,BST_UNCHECKED,0L); + + //ss checkbox + if (DBGetContactSetting(0, szModuleName, "ss", &dbv) == 0) + {indic=dbv.bVal; + } + else indic=0; + + if(indic==1)SendMessage(hss,BM_SETCHECK,BST_CHECKED,0L); + else SendMessage(hss,BM_SETCHECK,BST_UNCHECKED,0L); + + //sr checkbox + if (DBGetContactSetting(0, szModuleName, "sr", &dbv) == 0) + {indic=dbv.bVal; + } + else indic=0; + + if(indic==1)SendMessage(hsr,BM_SETCHECK,BST_CHECKED,0L); + else SendMessage(hsr,BM_SETCHECK,BST_UNCHECKED,0L); + + DBFreeVariant(&dbv); +} + + +int onRegisterPopOptions(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = {0}; + odp.cbSize = sizeof(odp); + odp.hInstance = g_hInst; + odp.pszTemplate = MAKEINTRESOURCE(IDD_POPUP); + odp.pszTitle = (char*)szModuleName; + odp.pszGroup = LPGEN("Popups"); + odp.pfnDlgProc = PopOptionsDlgProc; + Options_AddPage(wParam, &odp); + return 0; +} + +// EOF diff --git a/plugins/SecureIM/src/popupOptions.h b/plugins/SecureIM/src/popupOptions.h new file mode 100644 index 0000000000..22d3453adc --- /dev/null +++ b/plugins/SecureIM/src/popupOptions.h @@ -0,0 +1,8 @@ +#ifndef __POPUP_OPTIONS__ +#define __POPUP_OPTIONS__ + +INT_PTR CALLBACK PopOptionsDlgProc(HWND,UINT,WPARAM,LPARAM); +void RefreshPopupOptionsDlg(HWND,HWND,HWND,HWND,HWND,HWND); +int onRegisterPopOptions(WPARAM,LPARAM); + +#endif diff --git a/plugins/SecureIM/src/resource.h b/plugins/SecureIM/src/resource.h new file mode 100644 index 0000000000..f8a753773d --- /dev/null +++ b/plugins/SecureIM/src/resource.h @@ -0,0 +1,160 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define ID_FIRSTICON 1 +#define IDI_CL_DIS 1 +#define IDI_CL_EST 2 +#define IDI_CM_DIS 3 +#define IDI_CM_EST 4 +#define IDI_MW_DIS 5 +#define IDI_MW_EST 6 +#define IDI_PU_DIS 7 +#define IDI_PU_EST 8 +#define IDI_PU_PRC 9 +#define IDI_PU_MSG 10 +#define IDI_ST_DIS 11 +#define IDI_ST_ENA 12 +#define IDI_ST_TRY 13 +#define IDI_OV_NAT 14 +#define IDI_OV_PGP 15 +#define IDI_OV_GPG 16 +#define IDI_OV_RSA 17 +#define ID_LASTICON 17 + +#define ID_DISABLED 111 +#define ID_ENABLED 112 +#define ID_ALWAYS 113 +#define ID_SETPSK 114 +#define ID_DELPSK 115 +#define ID_UPDATE_CLIST 116 +#define ID_UPDATE_PROTO 117 +#define ID_UPDATE_PLIST 118 +#define ID_UPDATE_GLIST 119 +#define ID_GETPUBL 120 +#define ID_DELPUBL 121 +#define ID_EXPPUBL 122 +#define ID_IMPPUBL 123 + +#define ID_SIM_NATIVE 130 +#define ID_SIM_PGP 131 +#define ID_SIM_GPG 132 +#define ID_SIM_RSAAES 133 +#define ID_SIM_RSA 134 + +#define IDM_CLIST0 150 +#define IDM_CLIST1 151 +#define IDM_CLIST2 152 +#define IDM_CLIST01 153 +#define IDM_CLIST02 154 +#define IDM_CLIST11 155 +#define IDM_CLIST12 156 + +#define IDD_OPTIONSTAB 501 +#define IDD_TAB_GENERAL 502 +#define IDD_TAB_PROTO 503 +#define IDD_TAB_PGP 504 +#define IDD_TAB_GPG 505 +#define IDD_TAB_MESSAGES 506 +#define IDD_POPUP 507 +#define IDD_PSK 508 +#define IDD_PASSPHRASE 509 + +#define IDC_STD_USERLIST 1001 +#define IDC_TIMEOUT 1002 +#define IDC_BACKKEY 1003 +#define IDC_TEXTKEY 1004 +#define IDC_PREV 1005 +#define IDC_BACKSEC 1006 +#define IDC_TEXTSEC 1007 +#define IDC_RESET 1008 +#define IDC_ALWAYSICON 1009 +#define IDC_EC 1010 +#define IDC_DC 1011 +#define IDC_KS 1012 +#define IDC_KR 1013 +#define IDC_SS 1014 +#define IDC_SR 1015 +#define IDC_BACKSR 1016 +#define IDC_BACKKEY6 1017 +#define IDC_TEXTSR 1018 +#define IDC_TIMEKEY 1019 +#define IDC_TIMESEC 1020 +#define IDC_TIMESR 1021 +#define IDC_PVALUES 1022 +#define IDC_ADD 1023 +#define IDC_DELETE 1024 +#define IDC_SFT 1025 +#define IDC_ASI 1026 +#define IDC_SOM 1027 +#define IDC_ADV0 1028 +#define IDC_ADV1 1029 +#define IDC_ADV2 1030 +#define IDC_ADV3 1031 +#define IDC_ADV4 1032 +#define IDC_ADV5 1033 +#define IDC_ADV6 1034 +#define IDC_ADV7 1035 +#define IDC_ADV8 1036 +#define IDC_MCD 1037 +#define IDC_KET 1038 +#define IDC_OPTIONSTAB 1039 +#define IDC_PROTO 1040 +#define IDC_EDIT1 1041 +#define IDC_EDIT2 1042 +#define IDC_SCM 1043 +#define IDC_DGP 1044 +#define IDC_OKT 1045 +#define IDC_AIP 1046 +#define IDC_ADVICON 1047 +#define IDC_SPLITON 1048 +#define IDC_SPLITOFF 1049 +#define IDC_RSA_SHA 1050 +#define IDC_NOL 1051 +#define IDC_AAK 1052 +#define IDC_MCM 1053 +#define IDC_RSA_COPY 1054 +#define IDC_RSA_EXP 1055 +#define IDC_RSA_EXPPRIV 1056 +#define IDC_RSA_IMPPRIV 1057 +#define IDC_PASSPHRASE 1058 + +#define IDC_NO_PGP 1100 +#define IDC_PGP 1101 +#define IDC_GPG 1102 + +#define IDC_PGP_SDK 1200 +#define IDC_PGP_USERLIST 1201 +#define IDC_SET_KEYRINGS 1202 +#define IDC_KEYRING_STATUS 1203 +#define IDC_PGP_PRIVKEY 1204 +#define IDC_LOAD_PRIVKEY 1205 +#define IDC_NO_KEYRINGS 1206 + +#define IDC_GPGEXECUTABLE_EDIT 1300 +#define IDC_BROWSEEXECUTABLE_BTN 1301 +#define IDC_GPGHOME_EDIT 1302 +#define IDC_SECRETKEY_DDOWN 1303 +#define IDC_SECRETREFRESH_BTN 1304 +#define IDC_GPG_USERLIST 1305 +#define IDC_PUBLICKEY_DDOWN 1306 +#define IDC_PUBLICREFRESH_BTN 1307 +#define IDC_LOGGINGON_CBOX 1308 +#define IDC_GPGLOGFILE_EDIT 1309 +#define IDC_SAVEPASS_CBOX 1310 +#define IDC_TMPPATHON_CBOX 1311 +#define IDC_GPGTMPPATH_EDIT 1312 + +#define IDC_STATIC -1 +#define ID_ENCRYPTION 40001 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 119 +#define _APS_NEXT_COMMAND_VALUE 40002 +#define _APS_NEXT_CONTROL_VALUE 1400 +#define _APS_NEXT_SYMED_VALUE 119 +#endif +#endif diff --git a/plugins/SecureIM/src/rtfconv.cpp b/plugins/SecureIM/src/rtfconv.cpp new file mode 100644 index 0000000000..994f541373 --- /dev/null +++ b/plugins/SecureIM/src/rtfconv.cpp @@ -0,0 +1,46 @@ +#include "commonheaders.h" + + +HINSTANCE hRtfconv = NULL; +RTFCONVSTRING pRtfconvString = NULL; + + +BOOL load_rtfconv () { + + hRtfconv = LoadLibrary( "rtfconv.dll" ) ; + if ( hRtfconv == NULL ) { + hRtfconv = LoadLibrary( "plugins\\rtfconv.dll" ) ; + if ( hRtfconv == NULL ) + return FALSE; + } + + pRtfconvString = (RTFCONVSTRING) GetProcAddress( hRtfconv, "RtfconvString" ) ; + if ( pRtfconvString == NULL ) { + FreeLibrary( hRtfconv ) ; + return FALSE; + } + + return TRUE; +} + +void free_rtfconv () { + + if ( hRtfconv ) + FreeLibrary( hRtfconv ) ; + pRtfconvString = NULL; + hRtfconv = NULL; +} + + +void rtfconvA(LPCSTR rtf, LPWSTR plain) { + + pRtfconvString( rtf, plain, 0, 1200, CONVMODE_USE_SYSTEM_TABLE, (strlen(rtf)+1)*sizeof(WCHAR)); +} + + +void rtfconvW(LPCWSTR rtf, LPWSTR plain) { + + pRtfconvString( rtf, plain, 0, 1200, CONVMODE_USE_SYSTEM_TABLE, (wcslen(rtf)+1)*sizeof(WCHAR)); +} + +// EOF diff --git a/plugins/SecureIM/src/rtfconv.h b/plugins/SecureIM/src/rtfconv.h new file mode 100644 index 0000000000..2a3e75089b --- /dev/null +++ b/plugins/SecureIM/src/rtfconv.h @@ -0,0 +1,23 @@ +#ifndef __RTFCONV_H__ +#define __RTFCONV_H__ + +#include + +#ifndef _INTPTR_T_DEFINED +#define intptr_t int +#endif + +#define CONVMODE_USE_SYSTEM_TABLE 0x800000 /* Use OS's table only */ + +typedef intptr_t (WINAPI *RTFCONVSTRING) ( const void *pSrcBuffer, void *pDstBuffer, + int nSrcCodePage, int nDstCodePage, unsigned long dwFlags, + size_t nMaxLen ); + +extern RTFCONVSTRING pRtfconvString; + +BOOL load_rtfconv (); +void free_rtfconv (); +void rtfconvA(LPCSTR rtf, LPWSTR plain); +void rtfconvW(LPCWSTR rtf, LPWSTR plain); + +#endif diff --git a/plugins/SecureIM/src/secureim.h b/plugins/SecureIM/src/secureim.h new file mode 100644 index 0000000000..a307d1e5a2 --- /dev/null +++ b/plugins/SecureIM/src/secureim.h @@ -0,0 +1,172 @@ +#ifndef __SECURE_IM__ +#define __SECURE_IM__ + +#include "resource.h" + +// режимы шифрования SecureIM +#define MODE_NATIVE 0 +#define MODE_PGP 1 +#define MODE_GPG 2 +#define MODE_RSAAES 3 +#define MODE_CNT (3+1) +#define MODE_RSA 4 + +#define SECURED 0x10 + +// статусы для Native и RSA/AES режимов +#define STATUS_DISABLED 0 +#define STATUS_ENABLED 1 +#define STATUS_ALWAYSTRY 2 + +#define SiG_KEYR 0 +#define SiG_KEY3 SiG_KEYR +#define SiG_KEY4 SiG_KEYR +#define SiG_ENON 1 +#define SiG_ENOF 2 +#define SiG_RSND 3 +#define SiG_INIT 4 +#define SiG_DEIN 5 +#define SiG_DISA 6 +#define SiG_FAKE 7 +#define SiG_KEYA 8 +#define SiG_KEYB 9 +#define SiG_PART 10 +#define SiG_SECU 11 +#define SiG_SECP 12 +#define SiG_PGPM 13 +#define SiG_NONE -1 +#define SiG_GAME -2 + +struct SIG { + char *sig; + BYTE len; + char key; +}; + +const SIG signs[] = { + {"----Key3@hell----", 17, SiG_KEYR}, + {"----Key4@hell----", 17, SiG_KEYR}, + {"----Secured@hell----", 20, SiG_ENON}, + {"----Offline@hell----", 20, SiG_ENOF}, + {"----Resend@hell----", 19, SiG_RSND}, + {"----INIT@HELL----", 17, SiG_INIT}, + {"----DEINIT@HELL----", 19, SiG_DEIN}, + {"----DISABLED@HELL----", 21, SiG_DISA}, + {"----FAKE@HELL----", 17, SiG_FAKE}, + {"----KeyA@hell----", 17, SiG_KEYA}, + {"----KeyB@hell----", 17, SiG_KEYB}, + {"----Part@hell----", 17, SiG_PART}, + {"[SECURE]", 8, SiG_SECU}, + {"[$ECURE]", 8, SiG_SECP}, + {"-----BEGIN PGP MESSAGE-----", 27, SiG_PGPM}, + {"@@BattleShip", 12, SiG_GAME}, + {"GoMoku 0.0.2.2:", 15, SiG_GAME}, + {"@@GoMoku", 8, SiG_GAME}, + {"pbiChess:", 9, SiG_GAME}, + {"pbiReverse:", 11, SiG_GAME}, + {"pbiCorners:", 11, SiG_GAME}, + {"pbiCheckersInt:", 15, SiG_GAME}, + {"pbiCheckersRus:", 15, SiG_GAME}, + {"pbiCheckersPool:", 16, SiG_GAME}, + {0} +}; + +#define SIG_KEY3 signs[ 0].sig +#define SIG_KEY4 signs[ 1].sig +#define SIG_ENON signs[ 2].sig +#define SIG_ENOF signs[ 3].sig +#define SIG_RSND signs[ 4].sig +#define SIG_INIT signs[ 5].sig +#define SIG_DEIN signs[ 6].sig +#define SIG_DISA signs[ 7].sig +#define SIG_FAKE signs[ 8].sig +#define SIG_KEYA signs[ 9].sig +#define SIG_KEYB signs[10].sig +#define SIG_PART signs[11].sig +#define SIG_SECU signs[12].sig +#define SIG_SECP signs[13].sig + +#define LEN_KEY3 signs[ 0].len +#define LEN_KEY4 signs[ 1].len +#define LEN_ENON signs[ 2].len +#define LEN_ENOF signs[ 3].len +#define LEN_RSND signs[ 4].len +#define LEN_INIT signs[ 5].len +#define LEN_DEIN signs[ 6].len +#define LEN_DISA signs[ 7].len +#define LEN_FAKE signs[ 8].len +#define LEN_KEYA signs[ 9].len +#define LEN_KEYB signs[10].len +#define LEN_PART signs[11].len +#define LEN_SECU signs[12].len +#define LEN_SECP signs[13].len + +#define TBL_IEC 0x01 +#define TBL_ICO 0x02 +#define TBL_POP 0x03 + +#define IEC_CL_DIS 0x00 +#define IEC_CL_EST 0x01 +#define IEC_CNT (0x01+1) + +#define ICO_CM_DIS 0x00 +#define ICO_CM_EST 0x01 +#define ICO_MW_DIS 0x02 +#define ICO_MW_EST 0x03 +#define ICO_ST_DIS 0x04 +#define ICO_ST_ENA 0x05 +#define ICO_ST_TRY 0x06 +#define ICO_OV_NAT 0x07 +#define ICO_OV_PGP 0x08 +#define ICO_OV_GPG 0x09 +#define ICO_OV_RSA 0x0A +#define ICO_CNT (0x0A+1) + +#define POP_PU_DIS 0x00 +#define POP_PU_EST 0x01 +#define POP_PU_PRC 0x02 +#define POP_PU_MSR 0x03 +#define POP_PU_MSS 0x04 +#define POP_CNT (0x04+1) + +#define ADV_CNT 8 +#define ALL_CNT (IEC_CNT+ICO_CNT+POP_CNT) + +struct ICONS { + UINT key; // Resource ID + BYTE tbl; // Table NUM + BYTE idx; // Table IDX + char *section; + char *name; + char *text; +}; + +const ICONS icons[] = { + // Contact List + {IDI_CL_DIS, TBL_IEC, IEC_CL_DIS, MODULENAME"/Contact List", "sim_cl_dis", "Connection Disabled"}, + {IDI_CL_EST, TBL_IEC, IEC_CL_EST, MODULENAME"/Contact List", "sim_cl_est", "Connection Established"}, + // Contact Menu + {IDI_CM_DIS, TBL_ICO, ICO_CM_DIS, MODULENAME"/Contact Menu", "sim_cm_dis", "Disable Secure Connection"}, + {IDI_CM_EST, TBL_ICO, ICO_CM_EST, MODULENAME"/Contact Menu", "sim_cm_est", "Establishe Secure Connection"}, + // Message Window + {IDI_MW_DIS, TBL_ICO, ICO_MW_DIS, MODULENAME"/Message Window", "sim_mw_dis", "Connection Disabled"}, + {IDI_MW_EST, TBL_ICO, ICO_MW_EST, MODULENAME"/Message Window", "sim_mw_est", "Connection Established"}, + // popup's + {IDI_PU_DIS, TBL_POP, POP_PU_DIS, MODULENAME"/Popups", "sim_pu_dis", "Secure Connection Disabled"}, + {IDI_PU_EST, TBL_POP, POP_PU_EST, MODULENAME"/Popups", "sim_pu_est", "Secure Connection Established"}, + {IDI_PU_PRC, TBL_POP, POP_PU_PRC, MODULENAME"/Popups", "sim_pu_prc", "Secure Connection In Process"}, + {IDI_PU_MSG, TBL_POP, POP_PU_MSR, MODULENAME"/Popups", "sim_pu_msr", "Recv Secured Message"}, + {IDI_PU_MSG, TBL_POP, POP_PU_MSS, MODULENAME"/Popups", "sim_pu_mss", "Sent Secured Message"}, + // statuses + {IDI_ST_DIS, TBL_ICO, ICO_ST_DIS, MODULENAME"/Menu State", "sim_st_dis", "Disabled"}, + {IDI_ST_ENA, TBL_ICO, ICO_ST_ENA, MODULENAME"/Menu State", "sim_st_ena", "Enabled"}, + {IDI_ST_TRY, TBL_ICO, ICO_ST_TRY, MODULENAME"/Menu State", "sim_st_try", "Always Try"}, + // overlay + {IDI_OV_NAT, TBL_ICO, ICO_OV_NAT, MODULENAME"/Overlays", "sim_ov_nat", "Native mode"}, + {IDI_OV_PGP, TBL_ICO, ICO_OV_PGP, MODULENAME"/Overlays", "sim_ov_pgp", "PGP mode"}, + {IDI_OV_GPG, TBL_ICO, ICO_OV_GPG, MODULENAME"/Overlays", "sim_ov_gpg", "GPG mode"}, + {IDI_OV_RSA, TBL_ICO, ICO_OV_RSA, MODULENAME"/Overlays", "sim_ov_rsa", "RSA/AES mode"}, + {0} +}; + +#endif diff --git a/plugins/SecureIM/src/splitmsg.cpp b/plugins/SecureIM/src/splitmsg.cpp new file mode 100644 index 0000000000..ca4f0635cf --- /dev/null +++ b/plugins/SecureIM/src/splitmsg.cpp @@ -0,0 +1,124 @@ +#include "commonheaders.h" + + +// разбивает сообщение szMsg на части длиной iLen, возвращает строку вида PARTzPARTzz +LPSTR splitMsg(LPSTR szMsg, int iLen) { + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("split: msg: -----\n%s\n-----\n",szMsg); +#endif + int len = (int)strlen(szMsg); + LPSTR out = (LPSTR) mir_alloc(len*2); + LPSTR buf = out; + + WORD msg_id = DBGetContactSettingWord(0, szModuleName, "msgid", 0) + 1; + DBWriteContactSettingWord(0, szModuleName, "msgid", msg_id); + + int part_all = (len+iLen-1)/iLen; + for(int part_num=0; part_numiLen)?iLen:len; + mir_snprintf(buf,32,"%s%04X%02X%02X",SIG_SECP,msg_id,part_num,part_all); + memcpy(buf+LEN_SECP+8,szMsg,sz); + *(buf+LEN_SECP+8+sz) = '\0'; +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("split: part: %s",buf); +#endif + buf += LEN_SECP+8+sz+1; + szMsg += sz; + len -= sz; + } + *buf = '\0'; + return out; +} + + +// собираем сообщение из частей, части храним в структуре у контакта +LPSTR combineMessage(pUinKey ptr, LPSTR szMsg) { + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("combine: part: %s",szMsg); +#endif + int msg_id,part_num,part_all; + sscanf(szMsg,"%4X%2X%2X",&msg_id,&part_num,&part_all); + // + pPM ppm = NULL, pm = ptr->msgPart; + if ( !ptr->msgPart ) { + pm = ptr->msgPart = new partitionMessage; + memset(pm,0,sizeof(partitionMessage)); + pm->id = msg_id; + pm->message = new LPSTR[part_all]; + memset(pm->message,0,sizeof(LPSTR)*part_all); + } + else + while(pm) { + if ( pm->id == msg_id ) break; + ppm = pm; pm = pm->nextMessage; + } + if (!pm) { // nothing to found + pm = ppm->nextMessage = new partitionMessage; + memset(pm,0,sizeof(partitionMessage)); + pm->id = msg_id; + pm->message = new LPSTR[part_all]; + memset(pm->message,0,sizeof(LPSTR)*part_all); + } + pm->message[part_num] = new char[strlen(szMsg)]; + strcpy(pm->message[part_num],szMsg+8); +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("combine: save part: %s",pm->message[part_num]); +#endif + int len=0,i; + for ( i=0; imessage[i]==NULL) break; + len+=(int)strlen(pm->message[i]); + } + if ( i==part_all ) { // combine message + SAFE_FREE(ptr->tmp); + ptr->tmp = (LPSTR) mir_alloc(len+1); *(ptr->tmp)='\0'; + for ( i=0; itmp,pm->message[i]); + delete pm->message[i]; + } + delete pm->message; + if(ppm) ppm->nextMessage = pm->nextMessage; + else ptr->msgPart = pm->nextMessage; + delete pm; +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("combine: all parts: -----\n%s\n-----\n", ptr->tmp); +#endif + // собрали одно сообщение + return ptr->tmp; + } +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("combine: not all parts"); +#endif + // еще не собрали + return NULL; +} + + +// отправляет сообщение, если надо то разбивает на части +int splitMessageSend(pUinKey ptr, LPSTR szMsg) { + + int ret; + int len = (int)strlen(szMsg); + int par = (getContactStatus(ptr->hContact)==ID_STATUS_OFFLINE)?ptr->proto->split_off:ptr->proto->split_on; + if ( par && len>par ) { + LPSTR msg = splitMsg(szMsg,par); + LPSTR buf = msg; + while( *buf ) { + len = (int)strlen(buf); + LPSTR tmp = mir_strdup(buf); + ret = CallContactService(ptr->hContact,PSS_MESSAGE,(WPARAM)PREF_METANODB,(LPARAM)tmp); + mir_free(tmp); + buf += len+1; + } + SAFE_FREE(msg); + } + else { + ret = CallContactService(ptr->hContact,PSS_MESSAGE,(WPARAM)PREF_METANODB,(LPARAM)szMsg); + } + return ret; +} + + +// EOF diff --git a/plugins/SecureIM/src/splitmsg.h b/plugins/SecureIM/src/splitmsg.h new file mode 100644 index 0000000000..9f55c2784e --- /dev/null +++ b/plugins/SecureIM/src/splitmsg.h @@ -0,0 +1,9 @@ +#ifndef __SPLITMSG_H__ +#define __SPLITMSG_H__ + +#include + +LPSTR combineMessage(pUinKey,LPSTR); +int splitMessageSend(pUinKey,LPSTR); + +#endif diff --git a/plugins/SecureIM/src/svcs_clist.cpp b/plugins/SecureIM/src/svcs_clist.cpp new file mode 100644 index 0000000000..12402a58be --- /dev/null +++ b/plugins/SecureIM/src/svcs_clist.cpp @@ -0,0 +1,224 @@ +#include "commonheaders.h" + + +int __cdecl onContactSettingChanged(WPARAM wParam,LPARAM lParam) { + + HANDLE hContact = (HANDLE)wParam; + DBCONTACTWRITESETTING *cws=(DBCONTACTWRITESETTING*)lParam; + if (!hContact || strcmp(cws->szSetting,"Status")) return 0; + + pUinKey ptr = getUinKey(hContact); + int stat = getContactStatus(hContact); + if (!ptr || stat==-1) return 0; + +// HANDLE hMetaContact = getMetaContact(hContact); +// if(hMetaContact) { +// ptr = getUinKey(hMetaContact); +// if (!ptr) return 0; +// } + + if (stat==ID_STATUS_OFFLINE) { // go offline + if (ptr->mode==MODE_NATIVE && cpp_keyx(ptr->cntx)) { // have active context + cpp_delete_context(ptr->cntx); ptr->cntx=0; // reset context +// if(hMetaContact) { // is subcontact of metacontact +// showPopUpDC(hMetaContact); +// ShowStatusIconNotify(hMetaContact); +// if(getMostOnline(hMetaContact)) { // make handover +// CallContactService(hMetaContact,PSS_MESSAGE,0,(LPARAM)SIG_INIT); +// } +// } +// else { // is contact or metacontact (not subcontact) + showPopUpDC(hContact); // show popup "Disabled" + ShowStatusIconNotify(hContact); // change icon in CL +// } + } + else + if (ptr->mode==MODE_RSAAES && exp->rsa_get_state(ptr->cntx)==7) { + deleteRSAcntx(ptr); +// if(hMetaContact) { // is subcontact of metacontact +// showPopUpDC(hMetaContact); +// ShowStatusIconNotify(hMetaContact); +// if(getMostOnline(hMetaContact)) { // make handover +// CallContactService(hMetaContact,PSS_MESSAGE,0,(LPARAM)SIG_INIT); +// } +// } +// else { // is contact or metacontact (not subcontact) + showPopUpDC(hContact); // show popup "Disabled" + ShowStatusIconNotify(hContact); // change icon in CL +// } + } + } + else { // go not offline +// if (!hMetaContact) { // is contact or metacontact (not subcontact) + if (ptr->offlineKey) { + cpp_reset_context(ptr->cntx); + ptr->offlineKey = false; + } + ShowStatusIconNotify(hContact); // change icon in CL +// } + } + return 0; +} + + +// wParam=(WPARAM)(HANDLE)hContact +// lParam=0 +int __cdecl onContactAdded(WPARAM wParam,LPARAM lParam) { + addContact((HANDLE)wParam); + return 0; +} + + +// wParam=(WPARAM)(HANDLE)hContact +// lParam=0 +int __cdecl onContactDeleted(WPARAM wParam,LPARAM lParam) { + delContact((HANDLE)wParam); + return 0; +} + + +int __cdecl onExtraImageListRebuilding(WPARAM, LPARAM) { + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onExtraImageListRebuilding"); +#endif + if ( (bADV || g_hCLIcon) && ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) { + RefreshContactListIcons(); + } + return 0; +} + + +int __cdecl onExtraImageApplying(WPARAM wParam, LPARAM) { + + if ( (bADV || g_hCLIcon) && ServiceExists(MS_CLIST_EXTRA_SET_ICON) && isSecureProtocol((HANDLE)wParam)) { + IconExtraColumn iec = mode2iec(isContactSecured((HANDLE)wParam)); + if ( g_hCLIcon ) { + ExtraIcon_SetIcon(g_hCLIcon, (HANDLE)wParam, iec.hImage); + } + else { + CallService(MS_CLIST_EXTRA_SET_ICON, wParam, (LPARAM)&iec); + } + } + return 0; +} + + +int __cdecl onRebuildContactMenu(WPARAM wParam,LPARAM lParam) { + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRebuildContactMenu"); +#endif + HANDLE hContact = (HANDLE)wParam; + BOOL bMC = isProtoMetaContacts(hContact); + if ( bMC ) hContact = getMostOnline(hContact); // возьмем тот, через который пойдет сообщение + pUinKey ptr = getUinKey(hContact); + int i; + + CLISTMENUITEM mi; + memset(&mi,0,sizeof(mi)); + mi.cbSize = sizeof(CLISTMENUITEM); + + ShowStatusIconNotify(hContact); + + // check offline/online + if (!ptr) { + // hide menu bars + mi.flags = CMIM_FLAGS | CMIF_NOTOFFLINE | CMIF_HIDDEN; + for(i=0;imode==MODE_NATIVE || ptr->mode==MODE_RSAAES)) { + // Native/RSAAES + mi.flags = CMIM_FLAGS | CMIF_NOTOFFLINE | CMIM_ICON; + if ( !isSecured ) { + // create secureim connection + mi.hIcon = mode2icon(ptr->mode|SECURED,2); + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[0],(LPARAM)&mi); + } + else { + // disable secureim connection + mi.hIcon = mode2icon(ptr->mode,2); + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[1],(LPARAM)&mi); + } + // set status menu + if ( bSCM && !bMC && + ( !isSecured || ptr->mode==MODE_PGP || ptr->mode==MODE_GPG )) { + + mi.flags = CMIM_FLAGS | CMIM_NAME | CMIM_ICON; + mi.hIcon = g_hICO[ICO_ST_DIS+ptr->status]; + mi.pszName = (LPSTR)sim312[ptr->status]; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[2],(LPARAM)&mi); + + mi.flags = CMIM_FLAGS | CMIM_ICON; + for(i=0;i<=(ptr->mode==MODE_RSAAES?1:2);i++) { + mi.hIcon = (i == ptr->status) ? g_hICO[ICO_ST_DIS+ptr->status] : NULL; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[3+i],(LPARAM)&mi); + } + } + } + else + if ( isSecureProto && !isChat && (ptr->mode==MODE_PGP || ptr->mode==MODE_GPG)) { + // PGP, GPG + if ( ptr->mode==MODE_PGP && bPGPloaded ) { + if ((bPGPkeyrings || bPGPprivkey) && !isGPG) { + mi.flags = CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[isPGP+6],(LPARAM)&mi); + } + } + if ( ptr->mode==MODE_GPG && bGPGloaded ) { + if(bGPGkeyrings && !isPGP) { + mi.flags = CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[isGPG+8],(LPARAM)&mi); + } + } + } + if ( isSecureProto && !isChat && isMiranda ) { + // set mode menu + if ( bMCM && !bMC && + ( !isSecured || ptr->mode==MODE_PGP || ptr->mode==MODE_GPG )) { + + mi.flags = CMIM_FLAGS | CMIM_NAME | CMIM_ICON; + mi.hIcon = g_hICO[ICO_OV_NAT+ptr->mode]; + mi.pszName = (LPSTR)sim311[ptr->mode]; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[10],(LPARAM)&mi); + + mi.flags = CMIM_FLAGS | CMIM_ICON; + for(i=0;imode!=MODE_PGP && !bPGP ) continue; + if ( i==MODE_GPG && ptr->mode!=MODE_GPG && !bGPG ) continue; + mi.hIcon = (i == ptr->mode) ? g_hICO[ICO_ST_ENA] : NULL; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[11+i],(LPARAM)&mi); + } + } + } + + return 0; +} + + +// EOF diff --git a/plugins/SecureIM/src/svcs_clist.h b/plugins/SecureIM/src/svcs_clist.h new file mode 100644 index 0000000000..8c2dd192b6 --- /dev/null +++ b/plugins/SecureIM/src/svcs_clist.h @@ -0,0 +1,13 @@ +#ifndef __SVCS_CLIST_H__ +#define __SVCS_CLIST_H__ + +#include + +int __cdecl onContactSettingChanged(WPARAM,LPARAM); +int __cdecl onContactAdded(WPARAM,LPARAM); +int __cdecl onContactDeleted(WPARAM,LPARAM); +int __cdecl onExtraImageListRebuilding(WPARAM,LPARAM); +int __cdecl onExtraImageApplying(WPARAM,LPARAM); +int __cdecl onRebuildContactMenu(WPARAM,LPARAM); + +#endif diff --git a/plugins/SecureIM/src/svcs_menu.cpp b/plugins/SecureIM/src/svcs_menu.cpp new file mode 100644 index 0000000000..310d367e1b --- /dev/null +++ b/plugins/SecureIM/src/svcs_menu.cpp @@ -0,0 +1,232 @@ +#include "commonheaders.h" + + +INT_PTR __cdecl Service_IsContactSecured(WPARAM wParam, LPARAM lParam) { + + return (isContactSecured((HANDLE)wParam)&SECURED) || isContactPGP((HANDLE)wParam) || isContactGPG((HANDLE)wParam); +} + + +INT_PTR __cdecl Service_CreateIM(WPARAM wParam,LPARAM lParam){ + if (!CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)wParam, (LPARAM)szModuleName)) + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)wParam, (LPARAM)szModuleName); +// WPARAM flags = 0; +// HANDLE hMetaContact = getMetaContact((HANDLE)wParam); +// if ( hMetaContact ) { +// wParam = (WPARAM)hMetaContact; +// flags = PREF_METANODB; +// } + CallContactService((HANDLE)wParam,PSS_MESSAGE,(WPARAM)PREF_METANODB,(LPARAM)SIG_INIT); + return 1; +} + + +INT_PTR __cdecl Service_DisableIM(WPARAM wParam,LPARAM lParam) { +// WPARAM flags = 0; +// HANDLE hMetaContact = getMetaContact((HANDLE)wParam); +// if ( hMetaContact ) { +// wParam = (WPARAM)hMetaContact; +// flags = PREF_METANODB; +// } + CallContactService((HANDLE)wParam,PSS_MESSAGE,(WPARAM)PREF_METANODB,(LPARAM)SIG_DEIN); + return 1; +} + + +INT_PTR __cdecl Service_Status(WPARAM wParam, LPARAM lParam) { + + switch(--lParam) { + case STATUS_DISABLED: + case STATUS_ENABLED: + case STATUS_ALWAYSTRY: + pUinKey ptr = getUinKey((HANDLE)wParam); + if(ptr) { + ptr->status=ptr->tstatus=(BYTE)lParam; + if(ptr->status==STATUS_ENABLED) DBDeleteContactSetting(ptr->hContact, szModuleName, "StatusID"); + else DBWriteContactSettingByte(ptr->hContact, szModuleName, "StatusID", ptr->status); + } + break; + } + + return 1; +} + + +INT_PTR __cdecl Service_StatusDis(WPARAM wParam, LPARAM lParam) { + + return Service_Status(wParam,STATUS_DISABLED+1); +} + + +INT_PTR __cdecl Service_StatusEna(WPARAM wParam, LPARAM lParam) { + + return Service_Status(wParam,STATUS_ENABLED+1); +} + + +INT_PTR __cdecl Service_StatusTry(WPARAM wParam, LPARAM lParam) { + + return Service_Status(wParam,STATUS_ALWAYSTRY+1); +} + + +INT_PTR __cdecl Service_PGPdelKey(WPARAM wParam, LPARAM lParam) { + + if(bPGPloaded) { + DBDeleteContactSetting((HANDLE)wParam, szModuleName, "pgp"); + DBDeleteContactSetting((HANDLE)wParam, szModuleName, "pgp_mode"); + DBDeleteContactSetting((HANDLE)wParam, szModuleName, "pgp_abbr"); + } + { + pUinKey ptr = getUinKey((HANDLE)wParam); + cpp_delete_context(ptr->cntx); ptr->cntx=0; + } + ShowStatusIconNotify((HANDLE)wParam); + return 1; +} + + +INT_PTR __cdecl Service_PGPsetKey(WPARAM wParam, LPARAM lParam) { + + BOOL del = true; + if(bPGPloaded) { + if(bPGPkeyrings) { + char szKeyID[128]; szKeyID[0]='\0'; + PVOID KeyID = pgp_select_keyid(GetForegroundWindow(),szKeyID); + if(szKeyID[0]) { + DBDeleteContactSetting((HANDLE)wParam,szModuleName,"pgp"); + DBCONTACTWRITESETTING cws; + memset(&cws,0,sizeof(cws)); + cws.szModule = szModuleName; + cws.szSetting = "pgp"; + cws.value.type = DBVT_BLOB; + cws.value.pbVal = (LPBYTE)KeyID; + cws.value.cpbVal = pgp_size_keyid(); + CallService(MS_DB_CONTACT_WRITESETTING,wParam,(LPARAM)&cws); + DBWriteContactSettingByte((HANDLE)wParam,szModuleName,"pgp_mode",0); + DBWriteContactSettingString((HANDLE)wParam,szModuleName,"pgp_abbr",szKeyID); + del = false; + } + } + else + if(bPGPprivkey) { + char KeyPath[MAX_PATH]; KeyPath[0]='\0'; + if(ShowSelectKeyDlg(0,KeyPath)) { + char *publ = LoadKeys(KeyPath,false); + if(publ) { + DBDeleteContactSetting((HANDLE)wParam,szModuleName,"pgp"); + myDBWriteStringEncode((HANDLE)wParam,szModuleName,"pgp",publ); + DBWriteContactSettingByte((HANDLE)wParam,szModuleName,"pgp_mode",1); + DBWriteContactSettingString((HANDLE)wParam,szModuleName,"pgp_abbr","(binary)"); + mir_free(publ); + del = false; + } + } + } + } + + if(del) Service_PGPdelKey(wParam,lParam); + else { + pUinKey ptr = getUinKey((HANDLE)wParam); + cpp_delete_context(ptr->cntx); ptr->cntx=0; + } + ShowStatusIconNotify((HANDLE)wParam); + return 1; +} + + +INT_PTR __cdecl Service_GPGdelKey(WPARAM wParam, LPARAM lParam) { + + if(bGPGloaded) { + DBDeleteContactSetting((HANDLE)wParam, szModuleName, "gpg"); + } + { + pUinKey ptr = getUinKey((HANDLE)wParam); + cpp_delete_context(ptr->cntx); ptr->cntx=0; + } + ShowStatusIconNotify((HANDLE)wParam); + return 1; +} + + +INT_PTR __cdecl Service_GPGsetKey(WPARAM wParam, LPARAM lParam) { + + BOOL del = true; + if(bGPGloaded && bGPGkeyrings) { + char szKeyID[128]; szKeyID[0]='\0'; + gpg_select_keyid(GetForegroundWindow(),szKeyID); + if(szKeyID[0]) { + DBWriteContactSettingString((HANDLE)wParam,szModuleName,"gpg",szKeyID); + del = false; + } + } + + if(del) Service_GPGdelKey(wParam,lParam); + else { + pUinKey ptr = getUinKey((HANDLE)wParam); + cpp_delete_context(ptr->cntx); ptr->cntx=0; + } + ShowStatusIconNotify((HANDLE)wParam); + return 1; +} + + +INT_PTR __cdecl Service_Mode(WPARAM wParam, LPARAM lParam) { + + pUinKey ptr = getUinKey((HANDLE)wParam); + + switch(--lParam) { + case MODE_NATIVE: + case MODE_RSAAES: + if ( isContactSecured((HANDLE)wParam)&SECURED ) { + msgbox(NULL, sim111, szModuleName, MB_OK); + return 0; + } + if ( lParam!=MODE_NATIVE && ptr->status>STATUS_ENABLED ) { + Service_Status(wParam,STATUS_ENABLED+1); + } + case MODE_PGP: + case MODE_GPG: + // нужно много проверок и отключение активного контекста если необходимо + if(ptr) { + if ( ptr->cntx ) { + cpp_delete_context(ptr->cntx); + ptr->cntx = 0; + ptr->keyLoaded = 0; + } + ptr->mode=(BYTE)lParam; + DBWriteContactSettingByte((HANDLE)wParam, szModuleName, "mode", (BYTE)lParam); + } + ShowStatusIcon((HANDLE)wParam); + break; + } + + return 1; +} + + +INT_PTR __cdecl Service_ModeNative(WPARAM wParam, LPARAM lParam) { + + return Service_Mode(wParam,MODE_NATIVE+1); +} + + +INT_PTR __cdecl Service_ModePGP(WPARAM wParam, LPARAM lParam) { + + return Service_Mode(wParam,MODE_PGP+1); +} + + +INT_PTR __cdecl Service_ModeGPG(WPARAM wParam, LPARAM lParam) { + + return Service_Mode(wParam,MODE_GPG+1); +} + + +INT_PTR __cdecl Service_ModeRSAAES(WPARAM wParam, LPARAM lParam) { + + return Service_Mode(wParam,MODE_RSAAES+1); +} + + +// EOF diff --git a/plugins/SecureIM/src/svcs_menu.h b/plugins/SecureIM/src/svcs_menu.h new file mode 100644 index 0000000000..69b079ebf7 --- /dev/null +++ b/plugins/SecureIM/src/svcs_menu.h @@ -0,0 +1,26 @@ +#ifndef __SVCS_MENU_H__ +#define __SVCS_MENU_H__ + +#include + +INT_PTR __cdecl Service_IsContactSecured(WPARAM,LPARAM); + +INT_PTR __cdecl Service_CreateIM(WPARAM,LPARAM); +INT_PTR __cdecl Service_DisableIM(WPARAM,LPARAM); + +INT_PTR __cdecl Service_StatusDis(WPARAM,LPARAM); +INT_PTR __cdecl Service_StatusEna(WPARAM,LPARAM); +INT_PTR __cdecl Service_StatusTry(WPARAM,LPARAM); + +INT_PTR __cdecl Service_PGPdelKey(WPARAM,LPARAM); +INT_PTR __cdecl Service_PGPsetKey(WPARAM,LPARAM); + +INT_PTR __cdecl Service_GPGdelKey(WPARAM,LPARAM); +INT_PTR __cdecl Service_GPGsetKey(WPARAM,LPARAM); + +INT_PTR __cdecl Service_ModeNative(WPARAM,LPARAM); +INT_PTR __cdecl Service_ModePGP(WPARAM,LPARAM); +INT_PTR __cdecl Service_ModeGPG(WPARAM,LPARAM); +INT_PTR __cdecl Service_ModeRSAAES(WPARAM,LPARAM); + +#endif diff --git a/plugins/SecureIM/src/svcs_popup.cpp b/plugins/SecureIM/src/svcs_popup.cpp new file mode 100644 index 0000000000..bb1eb88355 --- /dev/null +++ b/plugins/SecureIM/src/svcs_popup.cpp @@ -0,0 +1,115 @@ +#include "commonheaders.h" + +/* +static int CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + switch(message) { + case WM_COMMAND: + if (wParam == STN_CLICKED) { // It was a click on the Popup. + PUDeletePopUp(hWnd); + return TRUE; + } + break; + case UM_FREEPLUGINDATA: { + return TRUE; //TRUE or FALSE is the same, it gets ignored. + } + default: + break; + } + return DefWindowProc(hWnd, message, wParam, lParam); +} +*/ + +void showPopupMsg(HANDLE hContact, LPCSTR lpzText, HICON hIcon, int type) { + + // type: + // 0 - error + // 1 - key sent + // 2 - key recv + // 3 - established + // 4 - disabled + // 5 - msg recv + // 6 - msg sent + // + + if (!bPopupExists) return; + + char nback[32]; mir_snprintf(nback,sizeof(nback),"popup%dback", $type); + char ntext[32]; mir_snprintf(ntext,sizeof(ntext),"popup%dtext", $type); + char ntime[32]; mir_snprintf(ntime,sizeof(ntime),"popup%dtime", $type); + + COLORREF colorBack = (COLORREF)DBGetContactSettingDword(0,szModuleName,nback,(DWORD)RGB(230,230,255)); + COLORREF colorText = (COLORREF)DBGetContactSettingDword(0,szModuleName,ntext,(DWORD)RGB(0,0,0)); + int timeout = (int)DBGetContactSettingWord(0,szModuleName,ntime,0); + + if ( bCoreUnicode && bPopupUnicode ) { + POPUPDATAW ppd; + memset(&ppd,0,sizeof(POPUPDATAW)); + ppd.lchContact = hContact; + ppd.lchIcon = hIcon; + LPWSTR lpwzContactName = (LPWSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCMDF_UNICODE); + wcscpy(ppd.lpwzContactName, lpwzContactName); + LPWSTR lpwzText = mir_a2u(lpzText); + wcscpy(ppd.lpwzText, TranslateW(lpwzText)); + mir_free(lpwzText); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.iSeconds = timeout; +// ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; +// ppd.PluginData = NULL; + CallService(MS_POPUP_ADDPOPUPW, (WPARAM)&ppd, 0); + } + else { + POPUPDATAEX ppd; + memset(&ppd,0,sizeof(POPUPDATAEX)); + ppd.lchContact = hContact; + ppd.lchIcon = hIcon; + LPSTR lpzContactName = (LPSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0); + strcpy(ppd.lpzContactName, lpzContactName); + strcpy(ppd.lpzText, Translate(lpzText)); + ppd.colorBack = colorBack; + ppd.colorText = colorText; + ppd.iSeconds = timeout; +// ppd.PluginWindowProc = (WNDPROC)PopupDlgProc; +// ppd.PluginData = NULL; + CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0); + } +} + + +void showPopUpDCmsg(HANDLE hContact,LPCSTR msg) { + int indic=DBGetContactSettingByte(0, szModuleName, "dc",1); + if (indic==1) showPopUp(msg,hContact,g_hPOP[POP_PU_DIS],1); +} +void showPopUpDC(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "dc",1); + if (indic==1) showPopUp(sim006,hContact,g_hPOP[POP_PU_DIS],1); +} +void showPopUpEC(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "ec",1); + if (indic==1) showPopUp(sim001,hContact,g_hPOP[POP_PU_EST],1); +} +void showPopUpKS(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "ks",1); + if (indic==1) showPopUp(sim007,hContact,g_hPOP[POP_PU_PRC],0); +} +void showPopUpKRmsg(HANDLE hContact,LPCSTR msg) { + int indic=DBGetContactSettingByte(0, szModuleName, "kr",1); + if (indic==1) showPopUp(msg,hContact,g_hPOP[POP_PU_PRC],0); +} +void showPopUpKR(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "kr",1); + if (indic==1) showPopUp(sim008,hContact,g_hPOP[POP_PU_PRC],0); +} +void showPopUpSM(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "ss",0); + if (indic==1) showPopUp(sim009,hContact,g_hPOP[POP_PU_MSS],2); + SkinPlaySound("OutgoingSecureMessage"); +} +void showPopUpRM(HANDLE hContact) { + int indic=DBGetContactSettingByte(0, szModuleName, "sr",0); + if (indic==1) showPopUp(sim010,hContact,g_hPOP[POP_PU_MSR],2); + SkinPlaySound("IncomingSecureMessage"); +} + + +// EOF diff --git a/plugins/SecureIM/src/svcs_proto.cpp b/plugins/SecureIM/src/svcs_proto.cpp new file mode 100644 index 0000000000..ef8d6c850c --- /dev/null +++ b/plugins/SecureIM/src/svcs_proto.cpp @@ -0,0 +1,1130 @@ +#include "commonheaders.h" + + +// return SignID +int getSecureSig(LPCSTR szMsg, LPSTR *szPlainMsg=NULL) { + if(szPlainMsg) *szPlainMsg=(LPSTR)szMsg; + for(int i=0;signs[i].len;i++) { + if (memcmp(szMsg,signs[i].sig,signs[i].len)==0) { +/* for(int i=strlen(szMsg)-1;i;i--) { + if ( szMsg[i] == '\x0D' || szMsg[i] == '\x0A' ) + ((LPSTR)szMsg)[i] = '\0'; + else + break; + }*/ + if(szPlainMsg) *szPlainMsg = (LPSTR)(szMsg+signs[i].len); + if(signs[i].key==SiG_GAME && !bDGP) + return SiG_NONE; + return signs[i].key; + } + } + return SiG_NONE; +} + + +int returnNoError(HANDLE hContact) { + HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + unsigned int tID; + CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttFakeAck, new TFakeAckParams(hEvent,hContact,777,0), 0, &tID)); + SetEvent( hEvent ); + return 777; +} + + +int returnError(HANDLE hContact, LPCSTR err) { + HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + unsigned int tID; + CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttFakeAck, new TFakeAckParams(hEvent,hContact,666,err), 0, &tID)); + SetEvent( hEvent ); + return 666; +} + + +LPSTR szUnrtfMsg = NULL; + + +// RecvMsg handler +INT_PTR __cdecl onRecvMsg(WPARAM wParam, LPARAM lParam) { + + CCSDATA *pccsd = (CCSDATA *)lParam; + PROTORECVEVENT *ppre = (PROTORECVEVENT *)pccsd->lParam; + pUinKey ptr = getUinKey(pccsd->hContact); + LPSTR szEncMsg = ppre->szMessage, szPlainMsg = NULL; + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: %s", szEncMsg); +#endif + + // cut rtf tags + if ( pRtfconvString && memcmp(szEncMsg,"{\\rtf1",6)==0 ) { + SAFE_FREE(szUnrtfMsg); + int len = (int)strlen(szEncMsg)+1; + LPWSTR szTemp = (LPWSTR)mir_alloc(len*sizeof(WCHAR)); + if(ppre->flags & PREF_UNICODE) + rtfconvW((LPWSTR)(szEncMsg+len),szTemp); + else + rtfconvA(szEncMsg,szTemp); + len = (int)wcslen(szTemp)-1; + while(len) { + if ( szTemp[len] == 0x0D || szTemp[len] == 0x0A ) + szTemp[len] = 0; + else + break; + len--; + } + len = (int)wcslen(&szTemp[1])+1; + szUnrtfMsg = (LPSTR)mir_alloc(len*(sizeof(WCHAR)+1)); + WideCharToMultiByte(CP_ACP, 0, &szTemp[1], -1, szUnrtfMsg, len*(sizeof(WCHAR)+1), NULL, NULL); + memcpy(szUnrtfMsg+len,&szTemp[1],len*sizeof(WCHAR)); + ppre->szMessage = szEncMsg = szUnrtfMsg; + ppre->flags |= PREF_UNICODE; + mir_free(szTemp); + } + + int ssig = getSecureSig(ppre->szMessage,&szEncMsg); + BOOL bSecured = isContactSecured(pccsd->hContact)&SECURED; + BOOL bPGP = isContactPGP(pccsd->hContact); + BOOL bGPG = isContactGPG(pccsd->hContact); + +// HANDLE hMetaContact = getMetaContact(pccsd->hContact); +// if ( hMetaContact ) { +// ptr = getUinKey(hMetaContact); +// } + + // pass any unchanged message + if ( !ptr || + ssig==SiG_GAME || + !isSecureProtocol(pccsd->hContact) || + (isProtoMetaContacts(pccsd->hContact) && (pccsd->wParam & PREF_SIMNOMETA)) || + isChatRoom(pccsd->hContact) || + (ssig==SiG_NONE && !ptr->msgSplitted && !bSecured && !bPGP && !bGPG) + ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: pass unhandled"); +#endif + return CallService(MS_PROTO_CHAINRECV, wParam, lParam); + } + + // drop message: fake, unsigned or from invisible contacts + if ( isContactInvisible(pccsd->hContact) || ssig==SiG_FAKE ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: drop unhandled (contact invisible or hidden)"); +#endif + return 1; + } + + // receive non-secure message in secure mode + if ( ssig==SiG_NONE && !ptr->msgSplitted ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: non-secure message"); +#endif + if(ppre->flags & PREF_UNICODE) { + szPlainMsg = m_awstrcat(Translate(sim402),szEncMsg); + } + else { + szPlainMsg = m_aastrcat(Translate(sim402),szEncMsg); + } + ppre->szMessage = szPlainMsg; + pccsd->wParam |= PREF_SIMNOMETA; + int ret = CallService(MS_PROTO_CHAINRECV, wParam, lParam); + mir_free(szPlainMsg); + return ret; + } + + // received non-pgp secure message from disabled contact + if ( ssig!=SiG_PGPM && !bPGP && !bGPG && ptr->status==STATUS_DISABLED ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: message from disabled"); +#endif + if ( ptr->mode==MODE_NATIVE ) { + // tell to the other side that we have the plugin disabled with him + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM) SIG_DISA; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); + + showPopUp(sim003,pccsd->hContact,g_hPOP[POP_PU_DIS],0); + } + else { + createRSAcntx(ptr); + exp->rsa_disabled(ptr->cntx); + deleteRSAcntx(ptr); + } + SAFE_FREE(ptr->msgSplitted); + return 1; + } + + // combine message splitted by protocol (no tags) + if ( ssig==SiG_NONE && ptr->msgSplitted ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: combine untagged splitted message"); +#endif + LPSTR tmp = (LPSTR) mir_alloc(strlen(ptr->msgSplitted)+strlen(szEncMsg)+1); + strcpy(tmp,ptr->msgSplitted); + strcat(tmp,szEncMsg); + mir_free(ptr->msgSplitted); + ptr->msgSplitted = szEncMsg = ppre->szMessage = tmp; + ssig = getSecureSig(tmp,&szEncMsg); + } + else { + SAFE_FREE(ptr->msgSplitted); + } + + // combine message splitted by secureim (with tags) + if ( ssig==SiG_SECP || ssig==SiG_PART ) { + LPSTR msg = combineMessage(ptr,szEncMsg); + if ( !msg ) return 1; + szEncMsg = ppre->szMessage = msg; + ssig = getSecureSig(msg,&szEncMsg); + } + + // decrypt PGP/GPG message + if ( ssig==SiG_PGPM && + ((bPGPloaded && (bPGPkeyrings || bPGPprivkey))|| + (bGPGloaded && bGPGkeyrings)) + ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: PGP/GPG message"); +#endif + szEncMsg = ppre->szMessage; + if ( !ptr->cntx ) { + ptr->cntx = cpp_create_context(((bGPGloaded && bGPGkeyrings)?CPP_MODE_GPG:CPP_MODE_PGP) | ((DBGetContactSettingByte(pccsd->hContact,szModuleName,"gpgANSI",0))?CPP_MODE_GPG_ANSI:0)); + ptr->keyLoaded = 0; + } + + if (!strstr(szEncMsg,"-----END PGP MESSAGE-----")) + return 1; // no end tag, don't display it ... + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = NULL; + + if (!ptr->keyLoaded && bPGPloaded) ptr->keyLoaded = LoadKeyPGP(ptr); + if (!ptr->keyLoaded && bGPGloaded) ptr->keyLoaded = LoadKeyGPG(ptr); + + if(ptr->keyLoaded==1) szOldMsg = pgp_decode(ptr->cntx, szEncMsg); + else + if(ptr->keyLoaded==2) szOldMsg = gpg_decode(ptr->cntx, szEncMsg); + + if (!szOldMsg) { // error while decrypting message, send error + SAFE_FREE(ptr->msgSplitted); + ppre->flags &= ~(PREF_UNICODE|PREF_UTF); + pccsd->wParam &= ~(PREF_UNICODE|PREF_UTF); + ppre->szMessage = Translate(sim401); + return CallService(MS_PROTO_CHAINRECV, wParam, lParam); + } + + // receive encrypted message in non-encrypted mode + if (!isContactPGP(pccsd->hContact) && !isContactGPG(pccsd->hContact)) { + szNewMsg = m_ustrcat(TranslateU(sim403),szOldMsg); + szOldMsg = szNewMsg; + } + szNewMsg = utf8_to_miranda(szOldMsg,ppre->flags); pccsd->wParam = ppre->flags; + ppre->szMessage = szNewMsg; + + // show decoded message + showPopUpRM(ptr->hContact); + SAFE_FREE(ptr->msgSplitted); + pccsd->wParam |= PREF_SIMNOMETA; + int ret = CallService(MS_PROTO_CHAINRECV, wParam, lParam); + mir_free(szNewMsg); + return ret; + } + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: switch(ssig)=%d",ssig); +#endif + switch(ssig) { + + case SiG_PGPM: + return CallService(MS_PROTO_CHAINRECV, wParam, lParam); + + case SiG_SECU: { // new secured msg, pass to rsa_recv +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: RSA/AES message"); +#endif + if ( ptr->mode==MODE_NATIVE ) { + ptr->mode = MODE_RSAAES; + deleteRSAcntx(ptr); + DBWriteContactSettingByte(ptr->hContact, szModuleName, "mode", ptr->mode); + } + createRSAcntx(ptr); + loadRSAkey(ptr); + if ( exp->rsa_get_state(ptr->cntx)==0 ) + showPopUpKR(ptr->hContact); + + LPSTR szOldMsg = exp->rsa_recv(ptr->cntx,szEncMsg); + if ( !szOldMsg ) return 1; // don't display it ... + + LPSTR szNewMsg = utf8_to_miranda(szOldMsg,ppre->flags); pccsd->wParam = ppre->flags; + ppre->szMessage = szNewMsg; + + // show decoded message + showPopUpRM(ptr->hContact); + SAFE_FREE(ptr->msgSplitted); + pccsd->wParam |= PREF_SIMNOMETA; + int ret = CallService(MS_PROTO_CHAINRECV, wParam, lParam); + mir_free(szNewMsg); + return ret; + } break; + + case SiG_ENON: { // online message +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Native SiG_ENON message"); +#endif + if ( cpp_keyx(ptr->cntx)) { + // decrypting message + szPlainMsg = decodeMsg(ptr,lParam,szEncMsg); + if (!ptr->decoded) { + mir_free(szPlainMsg); + SAFE_FREE(ptr->msgSplitted); + ptr->msgSplitted=mir_strdup(szEncMsg); + return 1; // don't display it ... + } +// showPopUpRM(ptr->hContact); + } + else { + // reinit key exchange user has send an encrypted message and i have no key + cpp_reset_context(ptr->cntx); + + LPSTR reSend = (LPSTR) mir_alloc(strlen(szEncMsg)+LEN_RSND); + strcpy(reSend,SIG_RSND); // copy resend sig + strcat(reSend,szEncMsg); // add mess + + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM) reSend; // reSend Message to reemit + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); // send back cipher message + mir_free(reSend); + + LPSTR keyToSend = InitKeyA(ptr,0); // calculate public and private key + + pccsd->lParam = (LPARAM) keyToSend; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); // send new key + mir_free(keyToSend); + + showPopUp(sim005,NULL,g_hPOP[POP_PU_DIS],0); + showPopUpKS(ptr->hContact); + + return 1; + } + } break; + + case SiG_ENOF: { // offline message +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Native SiG_ENOF message"); +#endif + // if offline key is set and we have not an offline message unset key + if (ptr->offlineKey && cpp_keyx(ptr->cntx)) { + cpp_reset_context(ptr->cntx); + ptr->offlineKey = false; + } + // decrypting message with last offline key + DBVARIANT dbv; + dbv.type = DBVT_BLOB; + + if ( DBGetContactSetting(ptr->hContact,szModuleName,"offlineKey",&dbv) == 0 ) { + // if valid key is succefully retrieved + ptr->offlineKey = true; + InitKeyX(ptr,dbv.pbVal); + DBFreeVariant(&dbv); + + // decrypting message + szPlainMsg = decodeMsg(ptr,lParam,szEncMsg); + +// showPopUpRM(ptr->hContact); + ShowStatusIconNotify(ptr->hContact); + } + else { + // exit and show messsage + return CallService(MS_PROTO_CHAINRECV, wParam, lParam); + } + } break; + + case SiG_RSND: { // resend message +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Native SiG_RSND message"); +#endif + if (cpp_keyx(ptr->cntx)) { + // decrypt sended back message and save message for future sending with a new secret key + szPlainMsg = decodeMsg(ptr,(LPARAM)pccsd,szEncMsg); + addMsg2Queue(ptr,pccsd->wParam,szPlainMsg); + mir_free(szPlainMsg); + + showPopUpRM(ptr->hContact); + showPopUp(sim004,NULL,g_hPOP[POP_PU_DIS],0); + } + return 1; // don't display it ... + } break; + + case SiG_DISA: { // disabled message +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Native SiG_DISA message"); +#endif +// ptr->status=ptr->tstatus=STATUS_DISABLED; +// DBWriteContactSettingByte(ptr->hContact, szModuleName, "StatusID", ptr->status); + } + case SiG_DEIN: { // deinit message + // other user has disabled SecureIM with you + cpp_delete_context(ptr->cntx); ptr->cntx=0; + + showPopUpDC(ptr->hContact); + ShowStatusIconNotify(ptr->hContact); + + waitForExchange(ptr,3); // дослать нешифрованно + return 1; + } break; + + case SiG_KEYR: // key3 message + case SiG_KEYA: // keyA message + case SiG_KEYB: { // keyB message + if ( ptr->mode==MODE_RSAAES ) { + ptr->mode = MODE_NATIVE; + cpp_delete_context(ptr->cntx); + ptr->cntx = 0; + ptr->keyLoaded = 0; + DBWriteContactSettingByte(ptr->hContact, szModuleName, "mode", ptr->mode); + } + switch(ssig) { + case SiG_KEYR: { // key3 message +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: SiG_KEYR received"); +#endif + // receive KeyB from user; + showPopUpKR(ptr->hContact); + + if ( ptr->cntx && cpp_keyb(ptr->cntx)) { + // reinit key exchange if an old key from user is found + cpp_reset_context(ptr->cntx); + } + + if ( InitKeyB(ptr,szEncMsg)!=CPP_ERROR_NONE ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: SiG_KEYR InitKeyB error"); +#endif + // tell to the other side that we have the plugin disabled with him +/* + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM) SIG_DISA; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); +*/ + showPopUp(sim013,ptr->hContact,g_hPOP[POP_PU_DIS],0); + ShowStatusIconNotify(ptr->hContact); + + waitForExchange(ptr,3); // дослать нешифрованно + return 1; + } + + // other side support RSA mode ? + if ( ptr->features & CPP_FEATURES_RSA ) { + // switch to RSAAES mode + ptr->mode = MODE_RSAAES; + DBWriteContactSettingByte(ptr->hContact, szModuleName, "mode", ptr->mode); + + resetRSAcntx(ptr); + loadRSAkey(ptr); + exp->rsa_connect(ptr->cntx); + + showPopUpKS(pccsd->hContact); + ShowStatusIconNotify(pccsd->hContact); + return 1; + } + + // other side support new key format ? + if ( ptr->features & CPP_FEATURES_NEWPG ) { + cpp_reset_context(ptr->cntx); + + LPSTR keyToSend = InitKeyA(ptr,CPP_FEATURES_NEWPG|KEY_A_SIG); // calculate NEW public and private key +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Sending KEYA %s", keyToSend); +#endif + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM)keyToSend; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); + mir_free(keyToSend); + + showPopUpKS(ptr->hContact); + waitForExchange(ptr); // запустим ожидание + return 1; + } + + // auto send my public key to keyB user if not done before + if ( !cpp_keya(ptr->cntx)) { + LPSTR keyToSend = InitKeyA(ptr,0); // calculate public and private key +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Sending KEYA %s", keyToSend); +#endif + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM)keyToSend; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); + mir_free(keyToSend); + + showPopUpKS(ptr->hContact); + } + } break; + + case SiG_KEYA: { // keyA message +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: SiG_KEYA received"); +#endif + // receive KeyA from user; + showPopUpKR(ptr->hContact); + + cpp_reset_context(ptr->cntx); + if(InitKeyB(ptr,szEncMsg)!=CPP_ERROR_NONE) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: SiG_KEYA InitKeyB error"); +#endif + // tell to the other side that we have the plugin disabled with him +/* + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM) SIG_DISA; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); +*/ + showPopUp(sim013,ptr->hContact,g_hPOP[POP_PU_DIS],0); + ShowStatusIconNotify(ptr->hContact); + + waitForExchange(ptr,3); // дослать нешифрованно + return 1; + } + + LPSTR keyToSend = InitKeyA(ptr,CPP_FEATURES_NEWPG|KEY_B_SIG); // calculate NEW public and private key +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Sending KEYB %s", keyToSend); +#endif + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM)keyToSend; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); + mir_free(keyToSend); + } break; + + case SiG_KEYB: { // keyB message +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: SiG_KEYB received"); +#endif + // receive KeyB from user; + showPopUpKR(ptr->hContact); + + // clear all and send DISA if received KeyB, and not exist KeyA or error on InitKeyB + if (!cpp_keya(ptr->cntx) || InitKeyB(ptr,szEncMsg)!=CPP_ERROR_NONE) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: SiG_KEYB InitKeyB error"); +#endif + // tell to the other side that we have the plugin disabled with him +/* + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM) SIG_DISA; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); +*/ + showPopUp(sim013,ptr->hContact,g_hPOP[POP_PU_DIS],0); + ShowStatusIconNotify(ptr->hContact); + + cpp_reset_context(ptr->cntx); + waitForExchange(ptr,3); // дослать нешифрованно + return 1; + } + } break; + + } // switch + + /* common part (CalcKeyX & SendQueue) */ + // calculate KeyX + if ( cpp_keya(ptr->cntx) && cpp_keyb(ptr->cntx) && !cpp_keyx(ptr->cntx)) + CalculateKeyX(ptr,ptr->hContact); + + ShowStatusIconNotify(ptr->hContact); +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: Session established"); +#endif + + waitForExchange(ptr,2); // дошлем через шифрованное соединение + return 1; + /* common part (CalcKeyX & SendQueue) */ + } break; + + } //switch + + // receive message + if ( cpp_keyx(ptr->cntx) && (ssig==SiG_ENON||ssig==SiG_ENOF)) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: message received"); +#endif + showPopUpRM(ptr->hContact); + } +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onRecvMsg: exit"); +#endif + pccsd->wParam |= PREF_SIMNOMETA; + int ret = CallService(MS_PROTO_CHAINRECV, wParam, lParam); + SAFE_FREE(szPlainMsg); + return ret; +} + + +// SendMsgW handler +INT_PTR __cdecl onSendMsgW(WPARAM wParam, LPARAM lParam) { + if (!lParam) return 0; + + CCSDATA *ccs = (CCSDATA *) lParam; + if ( !(ccs->wParam & PREF_UTF)) + ccs->wParam |= PREF_UNICODE; + + return onSendMsg(wParam, lParam); +} + + +// SendMsg handler +INT_PTR __cdecl onSendMsg(WPARAM wParam, LPARAM lParam) { + + CCSDATA *pccsd = (CCSDATA *)lParam; + pUinKey ptr = getUinKey(pccsd->hContact); + int ssig = getSecureSig((LPCSTR)pccsd->lParam); + int stat = getContactStatus(pccsd->hContact); + +// HANDLE hMetaContact = getMetaContact(pccsd->hContact); +// if ( hMetaContact ) { +// ptr = getUinKey(hMetaContact); +// } +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSend: %s",(LPSTR)pccsd->lParam); +#endif + // pass unhandled messages + if ( !ptr || + ssig==SiG_GAME || ssig==SiG_PGPM || ssig==SiG_SECU || ssig==SiG_SECP || + isChatRoom(pccsd->hContact) || +/* (ssig!=SiG_NONE && hMetaContact && (pccsd->wParam & PREF_METANODB)) || */ + stat==-1 || + (ssig==SiG_NONE && ptr->sendQueue) || + (ssig==SiG_NONE && ptr->status==STATUS_DISABLED) // Disabled - pass unhandled + ) { + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: pass unhandled"); +#endif + } + + // + // PGP/GPG mode + // + if ( ptr->mode==MODE_PGP || ptr->mode==MODE_GPG ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: PGP|GPG mode"); +#endif + // если можно зашифровать - шифруем + if ( isContactPGP(ptr->hContact) || isContactGPG(ptr->hContact)) { +/* + if(stat==ID_STATUS_OFFLINE) { + if (msgbox1(0,sim110,szModuleName,MB_YESNO|MB_ICONQUESTION)==IDNO) { + return returnNoError(pccsd->hContact); + } + // exit and send unencrypted message + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } +*/ + if ( !ptr->cntx ) { + ptr->cntx = cpp_create_context((isContactGPG(ptr->hContact)?CPP_MODE_GPG:CPP_MODE_PGP) | ((DBGetContactSettingByte(ptr->hContact,szModuleName,"gpgANSI",0))?CPP_MODE_GPG_ANSI:0)); + ptr->keyLoaded = 0; + } + if ( !ptr->keyLoaded && bPGPloaded ) ptr->keyLoaded = LoadKeyPGP(ptr); + if ( !ptr->keyLoaded && bGPGloaded ) ptr->keyLoaded = LoadKeyGPG(ptr); + if ( !ptr->keyLoaded ) return returnError(pccsd->hContact,Translate(sim108)); + + LPSTR szNewMsg = NULL; + LPSTR szUtfMsg = miranda_to_utf8((LPCSTR)pccsd->lParam,pccsd->wParam); + if ( ptr->keyLoaded == 1 ) { // PGP + szNewMsg = pgp_encode(ptr->cntx,szUtfMsg); + } + else + if ( ptr->keyLoaded == 2 ) { // GPG + szNewMsg = gpg_encode(ptr->cntx,szUtfMsg); + } + mir_free(szUtfMsg); + if ( !szNewMsg ) { + return returnError(pccsd->hContact,Translate(sim109)); + } + + // отправляем зашифрованное сообщение + splitMessageSend(ptr,szNewMsg); + + showPopUpSM(ptr->hContact); + + return returnNoError(pccsd->hContact); + } + else { + // отправляем незашифрованное + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + } + + // get contact SecureIM status + int stid = ptr->status; + + // + // RSA/AES mode + // + if ( ptr->mode==MODE_RSAAES ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: RSA/AES mode"); +#endif + // contact is offline + if ( stat==ID_STATUS_OFFLINE ) { + if ( ptr->cntx ) { + if ( exp->rsa_get_state(ptr->cntx)!=0 ) { + resetRSAcntx(ptr); + } + } + else { + createRSAcntx(ptr); + } + if ( !bSOM || (!isClientMiranda(ptr,1) && !isSecureIM(ptr,1)) || !loadRSAkey(ptr)) { + if ( ssig==SiG_NONE ) { + // просто шлем незашифрованное в оффлайн + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + else { + // ничего не шлем дальше - это служебное сообщение + return returnNoError(pccsd->hContact); + } + } + // шлем шифрованное в оффлайн + LPSTR szUtfMsg = miranda_to_utf8((LPCSTR)pccsd->lParam,pccsd->wParam); + exp->rsa_send(ptr->cntx,szUtfMsg); + mir_free(szUtfMsg); + showPopUpSM(ptr->hContact); + return returnNoError(pccsd->hContact); + } + // SecureIM connection with this contact is disabled + if ( stid==STATUS_DISABLED ) { + if ( ptr->cntx ) { + exp->rsa_disabled(ptr->cntx); + deleteRSAcntx(ptr); + } + if ( ssig==SiG_NONE ) { + // просто шлем незашифрованное + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + // ничего не шлем дальше - это служебное сообщение + return returnNoError(pccsd->hContact); + } + // разорвать соединение + if ( ssig==SiG_DEIN ) { + if ( ptr->cntx ) { + exp->rsa_disconnect(ptr->cntx); + deleteRSAcntx(ptr); + } + waitForExchange(ptr,3); // дошлем нешифрованно + return returnNoError(pccsd->hContact); + } + // соединение установлено + if ( ptr->cntx && exp->rsa_get_state(ptr->cntx)==7 ) { + LPSTR szUtfMsg = miranda_to_utf8((LPCSTR)pccsd->lParam,pccsd->wParam); + exp->rsa_send(ptr->cntx,szUtfMsg); + mir_free(szUtfMsg); + showPopUpSM(ptr->hContact); + return returnNoError(pccsd->hContact); + } + // просто сообщение (без тэгов, нет контекста и работают AIP & NOL) + if ( ssig==SiG_NONE && isSecureIM(ptr->hContact)) { + // добавим его в очередь + addMsg2Queue(ptr, pccsd->wParam, (LPSTR)pccsd->lParam); + // запускаем процесс установки соединения + ssig=SiG_INIT; + // запускаем трэд ожидания и досылки + waitForExchange(ptr); + } + // установить соединение + if ( ssig==SiG_INIT ) { + createRSAcntx(ptr); + loadRSAkey(ptr); + exp->rsa_connect(ptr->cntx); + showPopUpKS(pccsd->hContact); + ShowStatusIconNotify(pccsd->hContact); + return returnNoError(pccsd->hContact); + } + // просто шлем незашифрованное (не знаю даже когда такое случится) + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + + // + // Native mode + // +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: Native mode"); +#endif + + // SecureIM connection with this contact is disabled + if ( stid==STATUS_DISABLED ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: message for Disabled"); +#endif + // if user try initialize connection + if ( ssig==SiG_INIT ) { + // secure IM is disabled ... + return returnError(pccsd->hContact,Translate(sim105)); + } + if (ptr->cntx) { // if exist secure context + cpp_delete_context(ptr->cntx); ptr->cntx=0; + + CCSDATA ccsd; + memcpy(&ccsd, (HLOCAL)lParam, sizeof(CCSDATA)); + + pccsd->wParam |= PREF_METANODB; + ccsd.lParam = (LPARAM) SIG_DEIN; + ccsd.szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, (LPARAM)&ccsd); + + showPopUpDC(pccsd->hContact); + ShowStatusIconNotify(pccsd->hContact); + } + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + + // contact is offline + if ( stat==ID_STATUS_OFFLINE ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: message for offline"); +#endif + if ( ssig==SiG_INIT && cpp_keyx(ptr->cntx)) { + // reinit key exchange + cpp_reset_context(ptr->cntx); + } + + if ( !bSOM ) { + if ( ssig!=SiG_NONE ) { + return returnNoError(pccsd->hContact); + } + // exit and send unencrypted message + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + BOOL isMiranda = isClientMiranda(ptr->hContact); + + if ( stid==STATUS_ALWAYSTRY && isMiranda ) { // always try && Miranda + // set key for offline user + DBVARIANT dbv; dbv.type = DBVT_BLOB; + if ( DBGetContactSettingDword(ptr->hContact, szModuleName, "offlineKeyTimeout", 0) > gettime() && + DBGetContactSetting(ptr->hContact, szModuleName, "offlineKey", &dbv) == 0 + ) { + // if valid key is succefully retrieved + ptr->offlineKey = true; + InitKeyX(ptr,dbv.pbVal); + DBFreeVariant(&dbv); + } + else { + DBDeleteContactSetting(ptr->hContact,szModuleName,"offlineKey"); + DBDeleteContactSetting(ptr->hContact,szModuleName,"offlineKeyTimeout"); + if (msgbox1(0,sim106,szModuleName,MB_YESNO|MB_ICONQUESTION)==IDNO) { + return returnNoError(pccsd->hContact); + } + // exit and send unencrypted message + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + } + else { +/* if (stid==STATUS_ALWAYSTRY && !isMiranda || stid!=STATUS_ALWAYSTRY && isMiranda) { + int res=msgbox1(0,"User is offline now, Do you want to send your message ?\nIt will be unencrypted !","Can't Send Encrypted Message !",MB_YESNO); + if (res==IDNO) return 1; + }*/ + if ( ssig!=SiG_NONE ) { + return returnNoError(pccsd->hContact); + } + // exit and send unencrypted message + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } + + } + else { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: message for online"); +#endif + // contact is online and we use an offline key -> reset offline key + if ( ptr->offlineKey ) { + cpp_reset_context(ptr->cntx); + ptr->offlineKey = false; + ShowStatusIconNotify(ptr->hContact); + } + } + + // if init is called from contact menu list reinit secure im connection + if ( ssig==SiG_INIT ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: SiG_INIT"); +#endif + cpp_reset_context(ptr->cntx); + } + + // if deinit is called from contact menu list deinit secure im connection + if ( ssig==SiG_DEIN ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: SiG_DEIN"); +#endif + // disable SecureIM only if it was enabled + if (ptr->cntx) { + cpp_delete_context(ptr->cntx); ptr->cntx=0; + + pccsd->wParam |= PREF_METANODB; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); + + showPopUpDC(pccsd->hContact); + ShowStatusIconNotify(pccsd->hContact); + } + return returnNoError(pccsd->hContact); + } + + if ( cpp_keya(ptr->cntx) && cpp_keyb(ptr->cntx) && !cpp_keyx(ptr->cntx)) + CalculateKeyX(ptr,ptr->hContact); + + ShowStatusIconNotify(pccsd->hContact); + + // if cryptokey exist + if ( cpp_keyx(ptr->cntx)) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: cryptokey exist"); +#endif +/* if ( !hMetaContact && isProtoMetaContacts(pccsd->hContact) && (DBGetContactSettingByte(NULL, "MetaContacts", "SubcontactHistory", 1) == 1)) { + // add sent event to subcontact + DBEVENTINFO dbei; HANDLE hC = getMostOnline(pccsd->hContact); + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + dbei.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hC, 0); + dbei.flags = DBEF_SENT; + dbei.timestamp = time(NULL); + dbei.eventType = EVENTTYPE_MESSAGE; + if(pccsd->wParam & PREF_RTL) dbei.flags |= DBEF_RTL; + if(pccsd->wParam & PREF_UTF) dbei.flags |= DBEF_UTF; + dbei.cbBlob = strlen((char *)pccsd->lParam) + 1; + if ( pccsd->wParam & PREF_UNICODE ) + dbei.cbBlob *= ( sizeof( wchar_t )+1 ); + dbei.pBlob = (PBYTE)pccsd->lParam; + + CallService(MS_DB_EVENT_ADD, (WPARAM)hC, (LPARAM)&dbei); + } */ + + LPSTR szNewMsg = encodeMsg(ptr,(LPARAM)pccsd); + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSend: encrypted msg '%s'",szNewMsg); +#endif + + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM) szNewMsg; + pccsd->szProtoService = PSS_MESSAGE; + int ret = CallService(MS_PROTO_CHAINSEND, wParam, lParam); + + mir_free(szNewMsg); + + showPopUpSM(ptr->hContact); + + return ret; + } + else { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: cryptokey not exist, try establishe connection"); +#endif + // send KeyA if init || always_try || waitkey || always_if_possible + if ( ssig==SiG_INIT || (stid==STATUS_ALWAYSTRY && isClientMiranda(ptr->hContact)) || isSecureIM(ptr->hContact) || ptr->waitForExchange ) { + if (ssig==SiG_NONE) { + addMsg2Queue(ptr, pccsd->wParam, (LPSTR)pccsd->lParam); + } + if ( !ptr->waitForExchange ) { + // init || always_try || always_if_possible + LPSTR keyToSend = InitKeyA(ptr,0); // calculate public and private key & fill KeyA +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("Sending KEY3: %s", keyToSend); +#endif + pccsd->wParam &= ~PREF_UNICODE; + pccsd->wParam |= PREF_METANODB; + pccsd->lParam = (LPARAM) keyToSend; + pccsd->szProtoService = PSS_MESSAGE; + CallService(MS_PROTO_CHAINSEND, wParam, lParam); + mir_free(keyToSend); + + showPopUpKS(pccsd->hContact); + ShowStatusIconNotify(pccsd->hContact); + + waitForExchange(ptr); // запускаем ожидание + } + return returnNoError(pccsd->hContact); + } +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("onSendMsg: pass unchanged to chain"); +#endif + return CallService(MS_PROTO_CHAINSEND, wParam, lParam); + } +} + + +int file_idx = 0; + +INT_PTR __cdecl onSendFile(WPARAM wParam, LPARAM lParam) { + + CCSDATA *pccsd=(CCSDATA*)lParam; + + pUinKey ptr = getUinKey(pccsd->hContact); + if (!ptr || !bSFT) return CallService(PSS_FILE, wParam, lParam); + + if ( isContactSecured(pccsd->hContact)&SECURED ) { + + char **file=(char **)pccsd->lParam; + if(file_idx==100) file_idx=0; + int i; + for(i=0;file[i];i++) { + + if (strstr(file[i],".AESHELL")) continue; + + char *name = strrchr(file[i],'\\'); + if ( !name ) name = file[i]; + else name++; + + char *file_out = (char*) mir_alloc(TEMP_SIZE+strlen(name)+20); + sprintf(file_out,"%s\\%s.AESHELL(%d)",TEMP,name,file_idx++); + + char buf[MAX_PATH]; + sprintf(buf,"%s\n%s",Translate(sim011),file[i]); + showPopUp(buf,NULL,g_hPOP[POP_PU_MSS],2); + + if ( ptr->mode==MODE_RSAAES ) { + exp->rsa_encrypt_file(ptr->cntx,file[i],file_out); + } + else { + cpp_encrypt_file(ptr->cntx,file[i],file_out); + } + + mir_free(file[i]); + file[i]=file_out; + } + if ( ptr->fileSend ) { // очистим сохраненный список + for(int j=0;ptr->fileSend[j];j++) { + mir_free(ptr->fileSend[j]); + } + SAFE_FREE(ptr->fileSend); + } + if ( i ) { // скопируем новый список + ptr->fileSend = (char **) mir_alloc(sizeof(char*)*(i+1)); + for(i=0;file[i];i++) { + ptr->fileSend[i] = mir_strdup(file[i]); + } + ptr->fileSend[i] = NULL; + } + } + return CallService(PSS_FILE, wParam, lParam); +} + + +/* +typedef struct { + size_t cbSize; + HANDLE hContact; + int sending; //true if sending, false if receiving + char **files; + int totalFiles; + int currentFileNumber; + unsigned long totalBytes; + unsigned long totalProgress; + char *workingDir; + char *currentFile; + unsigned long currentFileSize; + unsigned long currentFileProgress; + unsigned long currentFileTime; //as seconds since 1970 +} PROTOFILETRANSFERSTATUS; +*/ + +int __cdecl onProtoAck(WPARAM wParam,LPARAM lParam) { + + ACKDATA *ack=(ACKDATA*)lParam; + if (ack->type!=ACKTYPE_FILE) return 0; //quit if not file transfer event + PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->lParam; + + pUinKey ptr = getUinKey(ack->hContact); + if (!ptr || (f && (f->flags & PFTS_SENDING) && !bSFT)) return 0; + + if ( isContactSecured(ack->hContact)&SECURED ) { + switch(ack->result) { +// case ACKRESULT_FILERESUME: + case ACKRESULT_DATA: { + if ( !( f->flags & PFTS_SENDING )) { + ptr->finFileRecv = (f->currentFileSize == f->currentFileProgress); + if ( !ptr->lastFileRecv ) ptr->lastFileRecv = mir_strdup(f->szCurrentFile); + } + else + if ( f->flags & PFTS_SENDING ) { + ptr->finFileSend = (f->currentFileSize == f->currentFileProgress); + if ( !ptr->lastFileSend ) ptr->lastFileSend = mir_strdup(f->szCurrentFile); + } + } break; +// case ACKRESULT_INITIALISING: + case ACKRESULT_DENIED: + case ACKRESULT_FAILED: { + if ( ptr->lastFileRecv ) { + if (strstr(ptr->lastFileRecv,".AESHELL")) mir_unlink(ptr->lastFileRecv); + SAFE_FREE(ptr->lastFileRecv); + } + if ( ptr->lastFileSend ) { + if (strstr(ptr->lastFileSend,".AESHELL")) mir_unlink(ptr->lastFileSend); + SAFE_FREE(ptr->lastFileSend); + } + if ( ptr->fileSend ) { + char **file=ptr->fileSend; + for(int j=0;file[j];j++) { + if ( strstr(file[j],".AESHELL")) mir_unlink(file[j]); + mir_free(file[j]); + } + SAFE_FREE(ptr->fileSend); + } + return 0; + } break; + case ACKRESULT_NEXTFILE: + case ACKRESULT_SUCCESS: { + if ( ptr->finFileRecv && ptr->lastFileRecv ) { + if ( strstr(ptr->lastFileRecv,".AESHELL")) { + char buf[MAX_PATH]; + LPSTR file_out=mir_strdup(ptr->lastFileRecv); + LPSTR pos=strrchr(file_out,'.'); //find last . + if (pos) *pos='\0'; //remove AESHELL from name + + if ( isFileExist(file_out)) { + buf[0]='\0'; + LPSTR p=strrchr(file_out,'.'); + LPSTR x=strrchr(file_out,'\\'); + if(p>x) { + strcpy(buf,p); + pos=p; + } + for(int i=1;i<10000;i++) { + sprintf(pos," (%d)%s",i,buf); + if ( !isFileExist(file_out)) break; + } + } + + sprintf(buf,"%s\n%s",Translate(sim012),file_out); + showPopUp(buf,NULL,g_hPOP[POP_PU_MSR],2); + + if ( ptr->mode==MODE_RSAAES ) { + exp->rsa_decrypt_file(ptr->cntx,ptr->lastFileRecv,file_out); + } + else { + cpp_decrypt_file(ptr->cntx,ptr->lastFileRecv,file_out); + } + mir_free(file_out); + mir_unlink(ptr->lastFileRecv); + } + SAFE_FREE(ptr->lastFileRecv); + ptr->finFileRecv = false; + } + if ( ptr->finFileSend && ptr->lastFileSend ) { + if ( strstr(ptr->lastFileSend,".AESHELL")) mir_unlink(ptr->lastFileSend); + SAFE_FREE(ptr->lastFileSend); + ptr->finFileSend = false; + } + } break; + } // switch + } + return 0; +} + + +// EOF diff --git a/plugins/SecureIM/src/svcs_proto.h b/plugins/SecureIM/src/svcs_proto.h new file mode 100644 index 0000000000..64ce1c43a3 --- /dev/null +++ b/plugins/SecureIM/src/svcs_proto.h @@ -0,0 +1,14 @@ +#ifndef __SVCS_PROTO_H__ +#define __SVCS_PROTO_H__ + +#include + +INT_PTR __cdecl onRecvMsg(WPARAM,LPARAM); +INT_PTR __cdecl onSendMsgW(WPARAM,LPARAM); +INT_PTR __cdecl onSendMsg(WPARAM,LPARAM); +INT_PTR __cdecl onSendFile(WPARAM,LPARAM); + +int __cdecl onProtoAck(WPARAM,LPARAM); +int __cdecl onContactSettingChanged(WPARAM,LPARAM); + +#endif diff --git a/plugins/SecureIM/src/svcs_rsa.cpp b/plugins/SecureIM/src/svcs_rsa.cpp new file mode 100644 index 0000000000..e72221dc91 --- /dev/null +++ b/plugins/SecureIM/src/svcs_rsa.cpp @@ -0,0 +1,226 @@ +#include "commonheaders.h" + + +pRSA_EXPORT exp = NULL; +RSA_IMPORT imp = { + rsa_inject, + rsa_check_pub, + rsa_notify +}; + +BOOL rsa_4096=0; + + +int __cdecl rsa_inject(HANDLE context, LPCSTR msg) { + pUinKey ptr = getUinCtx(context); if (!ptr) return 0; +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_inject: '%s'", msg); +#endif + int len = (int)strlen(msg)+1; + LPSTR buf = (LPSTR) mir_alloc(LEN_SECU+len); + memcpy(buf,SIG_SECU,LEN_SECU); + memcpy(buf+LEN_SECU,msg,len); + // отправляем сообщение + splitMessageSend(ptr,buf); + mir_free(buf); + return 1; +} + + +#define MSGSIZE 1024 + +int __cdecl rsa_check_pub(HANDLE context, PBYTE pub, int pubLen, PBYTE sig, int sigLen) { + int v=0, k=0; + pUinKey ptr = getUinCtx(context); if (!ptr) return 0; + LPSTR cnm = (LPSTR) mir_alloc(NAMSIZE); getContactNameA(ptr->hContact,cnm); + LPSTR uin = (LPSTR) mir_alloc(KEYSIZE); getContactUinA(ptr->hContact,uin); + LPSTR msg = (LPSTR) mir_alloc(MSGSIZE); + LPSTR sha = mir_strdup(to_hex(sig,sigLen)); + LPSTR sha_old = NULL; +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_check_pub: %s %s %s", cnm, uin, sha); +#endif + DBVARIANT dbv; + dbv.type = DBVT_BLOB; + if ( DBGetContactSetting(ptr->hContact,szModuleName,"rsa_pub",&dbv) == 0 ) { + k = 1; + PBYTE buf = (PBYTE) alloca(sigLen); int len; + exp->rsa_get_hash((PBYTE)dbv.pbVal,dbv.cpbVal,(PBYTE)buf,&len); + sha_old = mir_strdup(to_hex(buf,len)); + DBFreeVariant(&dbv); + } + if ( bAAK ) { + if ( k ) mir_snprintf(msg,MSGSIZE,Translate(sim523),cnm,uin,sha,sha_old); + else mir_snprintf(msg,MSGSIZE,Translate(sim521),cnm,uin,sha); + showPopUpKRmsg(ptr->hContact,msg); + HistoryLog(ptr->hContact,msg); + v = 1; +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_check_pub: auto accepted"); +#endif + } + else { + if ( k ) mir_snprintf(msg,MSGSIZE,Translate(sim522),cnm,sha,sha_old); + else mir_snprintf(msg,MSGSIZE,Translate(sim520),cnm,sha); + v = (msgbox(0,msg,szModuleName,MB_YESNO|MB_ICONQUESTION)==IDYES); +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_check_pub: manual accepted %d",v); +#endif + } + if(v) { + DBCONTACTWRITESETTING cws; + cws.szModule = szModuleName; + cws.szSetting = "rsa_pub"; + cws.value.type = DBVT_BLOB; + cws.value.pbVal = pub; + cws.value.cpbVal = pubLen; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)ptr->hContact, (LPARAM)&cws); + ptr->keyLoaded = true; + } + mir_free(cnm); + mir_free(uin); + mir_free(msg); + mir_free(sha); + SAFE_FREE(sha_old); + return v; +} + + +void __cdecl rsa_notify(HANDLE context, int state) { + pUinKey ptr = getUinCtx(context); if (!ptr) return; + LPCSTR msg=NULL; +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_notify: 0x%x", state); +#endif + switch( state ) { + case 1: { + showPopUpEC(ptr->hContact); + ShowStatusIconNotify(ptr->hContact); + waitForExchange(ptr,2); // досылаем сообщения из очереди + return; + } + case -1: // сессия разорвана по ошибке, неверный тип сообщения + msg=sim501; break; + case -2: // сессия разорвана по ошибке другой стороной + msg=sim502; break; + case -5: // ошибка декодирования AES сообщения + msg=sim505; break; + case -6: // ошибка декодирования RSA сообщения + msg=sim506; break; + case -7: // таймаут установки соединения (10 секунд) + msg=sim507; break; + case -8: { // сессия разорвана по причине "disabled" + msg=sim508; +// ptr->status=ptr->tstatus=STATUS_DISABLED; +// DBWriteContactSettingByte(ptr->hContact, szModuleName, "StatusID", ptr->status); + } break; + case -0x10: // сессия разорвана по ошибке + case -0x21: + case -0x22: + case -0x23: + case -0x24: + case -0x32: + case -0x33: + case -0x34: + case -0x40: + case -0x50: + case -0x60: { + char buf[1024]; + sprintf(buf,sim510,-state); + showPopUpDCmsg(ptr->hContact,buf); + ShowStatusIconNotify(ptr->hContact); + if(ptr->cntx) deleteRSAcntx(ptr); + waitForExchange(ptr,3); // досылаем нешифровано + return; + } + case -3: // соединение разорвано вручную + case -4: { // соединение разорвано вручную другой стороной + showPopUpDC(ptr->hContact); + ShowStatusIconNotify(ptr->hContact); + if(ptr->cntx) deleteRSAcntx(ptr); + waitForExchange(ptr,3); // досылаем нешифровано + return; + } + default: + return; + } + showPopUpDCmsg(ptr->hContact,msg); + ShowStatusIconNotify(ptr->hContact); + if(ptr->cntx) deleteRSAcntx(ptr); + waitForExchange(ptr,3); // досылаем нешифровано +} + + +unsigned __stdcall sttGenerateRSA( LPVOID param ) { + + char priv_key[4096]; int priv_len; + char pub_key[4096]; int pub_len; + + exp->rsa_gen_keypair(CPP_MODE_RSA_4096); + + DBCONTACTWRITESETTING cws; + cws.szModule = szModuleName; + cws.value.type = DBVT_BLOB; + + exp->rsa_get_keypair(CPP_MODE_RSA_4096,(PBYTE)&priv_key,&priv_len,(PBYTE)&pub_key,&pub_len); + + cws.szSetting = "rsa_priv"; + cws.value.pbVal = (PBYTE)&priv_key; + cws.value.cpbVal = priv_len; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)0, (LPARAM)&cws); + + cws.szSetting = "rsa_pub"; + cws.value.pbVal = (PBYTE)&pub_key; + cws.value.cpbVal = pub_len; + CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)0, (LPARAM)&cws); + + rsa_4096=1; + + return 0; +} + + +// загружает паблик-ключ в RSA контекст +BYTE loadRSAkey(pUinKey ptr) { + if ( !ptr->keyLoaded ) { + DBVARIANT dbv; + dbv.type = DBVT_BLOB; + if ( DBGetContactSetting(ptr->hContact,szModuleName,"rsa_pub",&dbv) == 0 ) { + ptr->keyLoaded = exp->rsa_set_pubkey(ptr->cntx,dbv.pbVal,dbv.cpbVal); +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("loadRSAkey %d", ptr->keyLoaded); +#endif + DBFreeVariant(&dbv); + } + } + return ptr->keyLoaded; +} + +// создает RSA контекст +void createRSAcntx(pUinKey ptr) { + if ( !ptr->cntx ) { + ptr->cntx = cpp_create_context(CPP_MODE_RSA); + ptr->keyLoaded = 0; + } +} + + +// пересоздает RSA контекст +void resetRSAcntx(pUinKey ptr) { + if ( ptr->cntx ) { + cpp_delete_context(ptr->cntx); + ptr->cntx = cpp_create_context(CPP_MODE_RSA); + ptr->keyLoaded = 0; + } +} + + +// удаляет RSA контекст +void deleteRSAcntx(pUinKey ptr) { + cpp_delete_context(ptr->cntx); + ptr->cntx = 0; + ptr->keyLoaded = 0; +} + + +// EOF diff --git a/plugins/SecureIM/src/svcs_rsa.h b/plugins/SecureIM/src/svcs_rsa.h new file mode 100644 index 0000000000..3f43e71d30 --- /dev/null +++ b/plugins/SecureIM/src/svcs_rsa.h @@ -0,0 +1,20 @@ +#ifndef __SVCS_RSA_H__ +#define __SVCS_RSA_H__ + +#include + +extern pRSA_EXPORT exp; +extern RSA_IMPORT imp; +extern BOOL rsa_4096; + +int __cdecl rsa_inject(HANDLE,LPCSTR); +int __cdecl rsa_check_pub(HANDLE,PBYTE,int,PBYTE,int); +void __cdecl rsa_notify(HANDLE,int); + +unsigned __stdcall sttGenerateRSA(LPVOID); +BYTE loadRSAkey(pUinKey); +void createRSAcntx(pUinKey); +void resetRSAcntx(pUinKey); +void deleteRSAcntx(pUinKey); + +#endif diff --git a/plugins/SecureIM/src/svcs_srmm.cpp b/plugins/SecureIM/src/svcs_srmm.cpp new file mode 100644 index 0000000000..688246847e --- /dev/null +++ b/plugins/SecureIM/src/svcs_srmm.cpp @@ -0,0 +1,37 @@ +#include "commonheaders.h" + + +int __cdecl onWindowEvent(WPARAM wParam, LPARAM lParam) { + + MessageWindowEventData *mwd = (MessageWindowEventData *)lParam; + if(mwd->uType == MSG_WINDOW_EVT_OPEN || mwd->uType == MSG_WINDOW_EVT_OPENING) { + ShowStatusIcon(mwd->hContact); + } + return 0; +} + + +int __cdecl onIconPressed(WPARAM wParam, LPARAM lParam) { + HANDLE hContact = (HANDLE)wParam; + if ( isProtoMetaContacts(hContact)) + hContact = getMostOnline(hContact); // возьмем тот, через который пойдет сообщение + + StatusIconClickData *sicd = (StatusIconClickData *)lParam; + if ( strcmp(sicd->szModule, szModuleName) != 0 || + !isSecureProtocol(hContact)) return 0; // not our event + + BOOL isPGP = isContactPGP(hContact); + BOOL isGPG = isContactGPG(hContact); + BOOL isSecured = isContactSecured(hContact)&SECURED; + BOOL isChat = isChatRoom(hContact); + + if ( !isPGP && !isGPG && !isChat ) { + if(isSecured) Service_DisableIM(wParam,0); + else Service_CreateIM(wParam,0); + } + + return 0; +} + + +// EOF diff --git a/plugins/SecureIM/src/svcs_srmm.h b/plugins/SecureIM/src/svcs_srmm.h new file mode 100644 index 0000000000..d64c89ab4e --- /dev/null +++ b/plugins/SecureIM/src/svcs_srmm.h @@ -0,0 +1,9 @@ +#ifndef __SVCS_SRMM_H__ +#define __SVCS_SRMM_H__ + +#include + +int __cdecl onWindowEvent(WPARAM,LPARAM); +int __cdecl onIconPressed(WPARAM,LPARAM); + +#endif diff --git a/plugins/SecureIM/src/version.h b/plugins/SecureIM/src/version.h new file mode 100644 index 0000000000..22b458eac8 --- /dev/null +++ b/plugins/SecureIM/src/version.h @@ -0,0 +1,16 @@ +#ifndef __VERSION_H_INCLUDED +#define __VERSION_H_INCLUDED + +#define __MAJOR_VERSION 1 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 12 +#define __BUILD_NUM 4 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM +#define __STRINGIFY(x) #x +#define __TOSTRING(x) __STRINGIFY(x) +#define __VERSION_STRING __TOSTRING(__FILEVERSION_STRING_DOTS) +#define __VERSION_DWORD ((__MAJOR_VERSION<<24) | (__MINOR_VERSION<<16) | (__RELEASE_NUM<<8) | __BUILD_NUM) + +#endif //__VERSION_H_INCLUDED -- cgit v1.2.3