summaryrefslogtreecommitdiff
path: root/plugins/SecureIM/src
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-07-23 13:49:28 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-07-23 13:49:28 +0000
commita9580df150d799246eaecbf3c1fb5cecf9f8ab49 (patch)
treece046b1cd432d65718c9f6af80521d533ce6d4ca /plugins/SecureIM/src
parent60338d55bb73d0c45b6e092703c4bb88a3c49755 (diff)
SecureIM, SeenPlugin, SendSS, Sessions: changed folder structure
git-svn-id: http://svn.miranda-ng.org/main/trunk@1122 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/SecureIM/src')
-rw-r--r--plugins/SecureIM/src/commonheaders.cpp197
-rw-r--r--plugins/SecureIM/src/commonheaders.h192
-rw-r--r--plugins/SecureIM/src/crypt.h183
-rw-r--r--plugins/SecureIM/src/crypt_check.cpp267
-rw-r--r--plugins/SecureIM/src/crypt_dll.cpp236
-rw-r--r--plugins/SecureIM/src/crypt_icons.cpp151
-rw-r--r--plugins/SecureIM/src/crypt_lists.cpp327
-rw-r--r--plugins/SecureIM/src/crypt_metacontacts.cpp60
-rw-r--r--plugins/SecureIM/src/crypt_misc.cpp139
-rw-r--r--plugins/SecureIM/src/crypt_popups.cpp153
-rw-r--r--plugins/SecureIM/src/cryptopp.h73
-rw-r--r--plugins/SecureIM/src/dbevent.cpp21
-rw-r--r--plugins/SecureIM/src/dbevent.h8
-rw-r--r--plugins/SecureIM/src/gettime.cpp29
-rw-r--r--plugins/SecureIM/src/gettime.h8
-rw-r--r--plugins/SecureIM/src/images.cpp358
-rw-r--r--plugins/SecureIM/src/images.h8
-rw-r--r--plugins/SecureIM/src/language.cpp104
-rw-r--r--plugins/SecureIM/src/language.h100
-rw-r--r--plugins/SecureIM/src/loadicons.cpp96
-rw-r--r--plugins/SecureIM/src/loadicons.h7
-rw-r--r--plugins/SecureIM/src/loadlib.cpp76
-rw-r--r--plugins/SecureIM/src/loadlib.h188
-rw-r--r--plugins/SecureIM/src/main.cpp534
-rw-r--r--plugins/SecureIM/src/mmi.cpp155
-rw-r--r--plugins/SecureIM/src/mmi.h27
-rw-r--r--plugins/SecureIM/src/options.cpp1928
-rw-r--r--plugins/SecureIM/src/options.h40
-rw-r--r--plugins/SecureIM/src/popupOptions.cpp239
-rw-r--r--plugins/SecureIM/src/popupOptions.h8
-rw-r--r--plugins/SecureIM/src/resource.h160
-rw-r--r--plugins/SecureIM/src/rtfconv.cpp46
-rw-r--r--plugins/SecureIM/src/rtfconv.h23
-rw-r--r--plugins/SecureIM/src/secureim.h172
-rw-r--r--plugins/SecureIM/src/splitmsg.cpp124
-rw-r--r--plugins/SecureIM/src/splitmsg.h9
-rw-r--r--plugins/SecureIM/src/svcs_clist.cpp224
-rw-r--r--plugins/SecureIM/src/svcs_clist.h13
-rw-r--r--plugins/SecureIM/src/svcs_menu.cpp232
-rw-r--r--plugins/SecureIM/src/svcs_menu.h26
-rw-r--r--plugins/SecureIM/src/svcs_popup.cpp115
-rw-r--r--plugins/SecureIM/src/svcs_proto.cpp1130
-rw-r--r--plugins/SecureIM/src/svcs_proto.h14
-rw-r--r--plugins/SecureIM/src/svcs_rsa.cpp226
-rw-r--r--plugins/SecureIM/src/svcs_rsa.h20
-rw-r--r--plugins/SecureIM/src/svcs_srmm.cpp37
-rw-r--r--plugins/SecureIM/src/svcs_srmm.h9
-rw-r--r--plugins/SecureIM/src/version.h16
48 files changed, 8508 insertions, 0 deletions
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;i<ca2u;i++) {
+ if ( pa2u[i].a == lpText ) {
+ return pa2u[i].u;
+ }
+ }
+ ca2u++;
+ pa2u = (pA2U) mir_realloc(pa2u,sizeof(A2U)*ca2u);
+ pa2u[i].a = (LPSTR) lpText;
+ if ( bCoreUnicode ) {
+ LPWSTR lpwText = mir_a2u(lpText);
+ LPWSTR lpwTran = TranslateW(lpwText);
+ mir_free(lpwText);
+ pa2u[i].u = mir_strdup(exp->utf8encode(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 <m_stdhdr.h>
+
+// Windows API
+#include <windows.h>
+#include <wingdi.h>
+#include <winsock2.h>
+#include <commdlg.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <io.h>
+#include <shlwapi.h>
+#include <process.h>
+#include <time.h>
+
+#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;j<clist_cnt;j++) {
+ if ( clist[j].hContact == hContact ) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if ( clist[j].hContact == hContact ) {
+ return isClientMiranda(&clist[j],emptyMirverAsMiranda);
+ }
+ }
+ return false;
+}
+
+
+BOOL isProtoSmallPackets(HANDLE hContact) {
+
+ if (!clist_cnt) return false;
+ for(int j=0;j<clist_cnt;j++) {
+ if ( clist[j].hContact == hContact ) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if ( clist[j].hContact == hContact ) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if (clist[j].hContact == hContact) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if (clist[j].hContact == hContact) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if (clist[j].hContact == hContact) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if (clist[j].hContact == hContact) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if (clist[j].hContact == hContact) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if ( clist[j].hContact == hContact ) {
+ if ( !clist[j].proto->inspecting ) 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;j<clist_cnt;j++) {
+ if (clist[j].hContact == hContact) {
+ return isSecureIM(&clist[j],emptyMirverAsSecureIM);
+ }
+ }
+ return false;
+}
+
+
+// EOF
diff --git a/plugins/SecureIM/src/crypt_dll.cpp b/plugins/SecureIM/src/crypt_dll.cpp
new file mode 100644
index 0000000000..6a97021886
--- /dev/null
+++ b/plugins/SecureIM/src/crypt_dll.cpp
@@ -0,0 +1,236 @@
+#include "commonheaders.h"
+
+
+// generate KeyA pair and return public key
+LPSTR InitKeyA(pUinKey ptr,int features) {
+#if defined(_DEBUG) || defined(NETLIB_LOG)
+ Sent_NetLog("InitKeyA: %04x", features);
+#endif
+ if ( !ptr->cntx )
+ 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<icons_cache;i++) {
+ if ( ICONS_CACHE[i].mode == ((type<<8) | mode)) {
+ return ICONS_CACHE[i].icon;
+ }
+ }
+ }
+
+ i=s;
+ switch(type) {
+ case 1: i+=IEC_CL_DIS; break;
+ case 2: i+=ICO_CM_DIS; break;
+ case 3: i+=ICO_MW_DIS; break;
+ }
+
+ if ( type==1 ) {
+ icon = BindOverlayIcon(g_hIEC[i],g_hICO[ICO_OV_NAT+m]);
+ }
+ else {
+ icon = BindOverlayIcon(g_hICO[i],g_hICO[ICO_OV_NAT+m]);
+ }
+
+ ICONS_CACHE = (ICON_CACHE*) mir_realloc(ICONS_CACHE,sizeof(ICON_CACHE)*(icons_cache+1));
+ ICONS_CACHE[icons_cache].icon = icon;
+ ICONS_CACHE[icons_cache].mode = (type<<8) | mode;
+ icons_cache++;
+
+ return icon;
+}
+
+
+// преобразует mode в HICON который НУЖНО разрушить в конце
+HICON mode2icon2(int mode,int type) {
+ return CopyIcon(mode2icon(mode,type));
+}
+
+
+// преобразует mode в IconExtraColumn который НЕ нужно разрушать в конце
+IconExtraColumn mode2iec(int mode) {
+
+ int m=mode&0x0f,s=(mode&SECURED)>>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; i<MODE_CNT;i++) {
+ sid.dwId = i;
+ sid.flags = (mode&SECURED)?0:MBF_DISABLED;
+ if ( mode==-1 || (mode&0x0f)!=i || isChatRoom(hContact))
+ sid.flags |= MBF_HIDDEN; // отключаем все ненужные иконки
+ CallService(MS_MSG_MODIFYICON, (WPARAM)hContact, (LPARAM)&sid);
+ if ( hMC )
+ CallService(MS_MSG_MODIFYICON, (WPARAM)hMC, (LPARAM)&sid);
+ }
+ }
+}
+
+
+void ShowStatusIcon(HANDLE hContact) {
+ ShowStatusIcon(hContact,isContactSecured(hContact));
+}
+
+
+void ShowStatusIconNotify(HANDLE hContact) {
+ int mode = isContactSecured(hContact);
+ NotifyEventHooks(g_hEvent[(mode&SECURED)!=0], (WPARAM)hContact, 0);
+ ShowStatusIcon(hContact,mode);
+}
+
+
+void RefreshContactListIcons(void) {
+
+ HANDLE hContact;
+// CallService(MS_CLUI_LISTBEGINREBUILD,0,0);
+ if ( !g_hCLIcon ) {
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) { // сначала все выключаем
+ ShowStatusIcon(hContact,-1);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ // менем местоположение иконки
+ for(int i=0;i<1+MODE_CNT*IEC_CNT;i++) {
+ g_IEC[i].ColumnType = bADV;
+ }
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) { // и снова зажигаем иконку
+ if ( isSecureProtocol(hContact))
+ ShowStatusIcon(hContact);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+// CallService(MS_CLUI_LISTENDREBUILD,0,0);
+}
+
+
+// EOF
diff --git a/plugins/SecureIM/src/crypt_lists.cpp b/plugins/SecureIM/src/crypt_lists.cpp
new file mode 100644
index 0000000000..7b68fbd250
--- /dev/null
+++ b/plugins/SecureIM/src/crypt_lists.cpp
@@ -0,0 +1,327 @@
+#include "commonheaders.h"
+
+pSupPro proto=NULL;
+pUinKey clist=NULL;
+int proto_cnt = 0;
+int clist_cnt = 0;
+int clist_inc = 100;
+
+
+void loadSupportedProtocols() {
+ int numberOfProtocols;
+ PROTOCOLDESCRIPTOR **protos;
+ LPSTR szNames = myDBGetString(0,szModuleName,"protos");
+ if ( szNames && strchr(szNames,':') == NULL ) {
+ LPSTR tmp = (LPSTR) mir_alloc(2048); int j=0;
+ for(int i=0; szNames[i]; i++) {
+ if ( szNames[i] == ';' ) {
+ memcpy((PVOID)(tmp+j),(PVOID)":1:0:0",6); j+=6;
+ }
+ tmp[j++] = szNames[i];
+ }
+ tmp[j] = '\0';
+ SAFE_FREE(szNames); szNames = tmp;
+ DBWriteContactSettingString(0,szModuleName,"protos",szNames);
+ }
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&numberOfProtocols, (LPARAM)&protos);
+
+ for (int i=0;i<numberOfProtocols;i++) {
+// if (protos[i]->type == 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;j<proto_cnt;j++) {
+ mir_free(proto[j].name);
+ }
+ SAFE_FREE(proto);
+ proto_cnt = 0;
+}
+
+
+pSupPro getSupPro(HANDLE hContact) {
+ int j;
+ for(j=0;j<proto_cnt && !CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)proto[j].name);j++);
+ if(j==proto_cnt) return NULL;
+ return &proto[j];
+}
+
+
+void MoveToFirstInFilterList(HANDLE hContact) {
+ int i;
+ char str[10];
+ DBVARIANT dbv;
+
+ for(i=0;;i++) {
+ mir_itoa(i,str,10);
+ if ( DBGetContactSettingString(hContact,"_Filter",str,&dbv)) break;
+ if ( !strcmp(szModuleName,dbv.pszVal)) { // нашли мой модуль
+ if ( i==0 ) return;
+ DBGetContactSettingString(hContact,"_Filter","0",&dbv);
+ DBWriteContactSettingString(hContact,"_Filter","0",szModuleName);
+ DBWriteContactSettingString(hContact,"_Filter",str,dbv.pszVal);
+ mir_free(dbv.pszVal);
+ return;
+ }
+ mir_free(dbv.pszVal);
+ }
+}
+
+
+void MoveToLastInFilterList(HANDLE hContact) {
+ int i,j;
+ char str[10];
+ char end[10];
+ DBVARIANT dbv;
+
+ for(i=0;;i++) {
+ mir_itoa(i,str,10);
+ if ( DBGetContactSettingString(hContact,"_Filter",str,&dbv)) break;
+ if ( !strcmp(szModuleName,dbv.pszVal)) { // нашли мой модуль
+ j=i;
+ }
+ mir_free(dbv.pszVal);
+ }
+ i--;
+ if ( j==i ) return;
+ mir_itoa(i,end,10);
+ mir_itoa(j,str,10);
+ DBGetContactSettingString(hContact,"_Filter",end,&dbv);
+ DBWriteContactSettingString(hContact,"_Filter",str,dbv.pszVal);
+ DBWriteContactSettingString(hContact,"_Filter",end,szModuleName);
+ mir_free(dbv.pszVal);
+ return;
+}
+
+
+// add contact in the list of secureIM users
+pUinKey addContact(HANDLE hContact) {
+ int j;
+ if (hContact) {
+// LPSTR szProto = (LPSTR) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ pSupPro proto = getSupPro(hContact);
+ if ( proto ) {
+ if ( !CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)szModuleName))
+ CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)szModuleName);
+ MoveToLastInFilterList(hContact);
+ for(j=0;j<clist_cnt;j++) {
+ if ( !clist[j].hContact ) break;
+ }
+ if(j==clist_cnt) {
+ clist_cnt+=clist_inc;
+ clist = (pUinKey) mir_realloc(clist,sizeof(UinKey)*clist_cnt);
+ memset(&clist[j],0,sizeof(UinKey)*clist_inc);
+ }
+ else
+ memset(&clist[j],0,sizeof(UinKey));
+ clist[j].header = HEADER;
+ clist[j].footer = FOOTER;
+ clist[j].hContact = hContact;
+ clist[j].proto = proto;
+ clist[j].mode = DBGetContactSettingByte(hContact, szModuleName, "mode", 99);
+ if ( clist[j].mode == 99 ) {
+ if ( isContactPGP(hContact)) clist[j].mode = MODE_PGP;
+ else
+ if ( isContactGPG(hContact)) clist[j].mode = MODE_GPG;
+ else
+ clist[j].mode = MODE_RSAAES;
+ DBWriteContactSettingByte(hContact, szModuleName, "mode", clist[j].mode);
+ }
+ clist[j].status = DBGetContactSettingByte(hContact, szModuleName, "StatusID", STATUS_ENABLED);
+ clist[j].gpgMode = DBGetContactSettingByte(hContact, szModuleName, "gpgANSI", 0);
+ return &clist[j];
+ }
+ }
+ return NULL;
+}
+
+
+// delete contact from the list of secureIM users
+void delContact(HANDLE hContact) {
+ if (hContact) {
+ int j;
+ for(j=0;j<clist_cnt;j++) {
+ if(clist[j].hContact == hContact) {
+ cpp_delete_context(clist[j].cntx); clist[j].cntx = 0;
+ clist[j].hContact = 0;
+ SAFE_FREE(clist[j].tmp);
+ SAFE_FREE(clist[j].msgSplitted);
+ clist[j].header = clist[j].footer = EMPTYH;
+ return;
+ }
+ }
+ }
+}
+
+
+// load contactlist in the list of secureIM users
+void loadContactList() {
+
+ freeContactList();
+ loadSupportedProtocols();
+
+ HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact) {
+ addContact(hContact);
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+}
+
+
+// free list of secureIM users
+void freeContactList() {
+
+ for(int j=0;j<clist_cnt;j++) {
+ cpp_delete_context(clist[j].cntx);
+ SAFE_FREE(clist[j].tmp);
+ SAFE_FREE(clist[j].msgSplitted);
+ }
+ SAFE_FREE(clist);
+ clist_cnt = 0;
+
+ freeSupportedProtocols();
+}
+
+
+// find user in the list of secureIM users and add him, if unknow
+pUinKey getUinKey(HANDLE hContact) {
+ int j;
+ for(j=0;j<clist_cnt && clist[j].hContact!=hContact;j++);
+ if (j==clist_cnt) return addContact(hContact);
+ return &clist[j];
+}
+
+
+pUinKey getUinCtx(HANDLE cntx) {
+ int j;
+ for(j=0;j<clist_cnt && clist[j].cntx!=cntx;j++);
+ if (j==clist_cnt) return NULL;
+ return &clist[j];
+}
+
+
+// add message to user queue for send later
+void addMsg2Queue(pUinKey ptr,WPARAM wParam,LPSTR szMsg) {
+
+#if defined(_DEBUG) || defined(NETLIB_LOG)
+ Sent_NetLog("addMsg2Queue: msg: -----\n%s\n-----\n",szMsg);
+#endif
+ pWM ptrMessage;
+
+ EnterCriticalSection(&localQueueMutex);
+
+ if(ptr->msgQueue==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;j<clist_cnt;j++)
+// if(clist[j].hContact==hContact && clist[j].proto->inspecting)
+// 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;i<CallService(MS_MC_GETNUMCONTACTS,(WPARAM)hMetaContact,0);i++) {
+ HANDLE hSubContact = (HANDLE)CallService(MS_MC_GETSUBCONTACT,(WPARAM)hMetaContact,(LPARAM)i);
+ if ( hSubContact && isContactSecured(hSubContact)&SECURED ) {
+ CallContactService(hSubContact,PSS_MESSAGE,(WPARAM)PREF_METANODB,(LPARAM)SIG_DEIN);
+ }
+ }
+ }
+}
+
+// EOF
diff --git a/plugins/SecureIM/src/crypt_misc.cpp b/plugins/SecureIM/src/crypt_misc.cpp
new file mode 100644
index 0000000000..7e0055913d
--- /dev/null
+++ b/plugins/SecureIM/src/crypt_misc.cpp
@@ -0,0 +1,139 @@
+#include "commonheaders.h"
+
+
+int SendBroadcast( HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam ) {
+ ACKDATA ack;
+ memset(&ack,0,sizeof(ack));
+ ack.cbSize = sizeof( ACKDATA );
+ ack.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ ack.hContact = hContact;
+ ack.type = type;
+ ack.result = result;
+ ack.hProcess = hProcess;
+ ack.lParam = lParam;
+ return CallService( MS_PROTO_BROADCASTACK, 0, ( LPARAM )&ack );
+}
+
+
+unsigned __stdcall sttFakeAck( LPVOID param ) {
+
+ TFakeAckParams* tParam = ( TFakeAckParams* )param;
+ WaitForSingleObject( tParam->hEvent, 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;i<DBGetContactSettingWord(0,szModuleName,"ket",10)*10; i++) {
+ Sleep( 100 );
+ if ( ptr->waitForExchange != 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 <windows.h>
+
+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 <windows.h>
+
+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 <windows.h>
+
+//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 <windows.h>
+#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; i<len; i++ ) {
+ if ( i ) {
+ *m_ptr = ' '; m_ptr++;
+ }
+ mir_snprintf(m_ptr,4,"%02X",bin[i]);
+ m_ptr += 2;
+ }
+ *m_ptr = 0;
+ return m_hex;
+}
+
+
+void __fastcall safe_free(void** p)
+{
+ if (*p) {
+ mir_free(*p);
+ *p = NULL;
+ }
+}
+
+
+void __fastcall safe_delete(void** p)
+{
+ if (*p) {
+ delete(*p);
+ *p = NULL;
+ }
+}
+
+
+// ЇаҐ®Ўа §гҐ¬ ⥪бв Ё§ зЁбв®Ј® UTF8 ў д®а¬ в ¬Ёа ­¤л
+LPSTR utf8_to_miranda(LPCSTR szUtfMsg, DWORD& flags) {
+ LPSTR szNewMsg;
+ if ( iCoreVersion < 0x00060000 ) {
+ flags &= ~(PREF_UTF|PREF_UNICODE);
+ LPWSTR wszMsg = exp->utf8decode(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;i<cnt;i++) {
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),i,&tci);
+ SendMessage((HWND)tci.lParam,WM_NOTIFY,0,lParam);
+ }
+ }
+ break;
+ }
+ } // case 0
+ break;
+
+ case IDC_OPTIONSTAB: {
+ switch (((LPNMHDR)lParam)->code) {
+ 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;i<proto_cnt;i++) {
+#if defined(_DEBUG) || defined(NETLIB_LOG)
+ Sent_NetLog("LV_InsertItemA(%d,%s);",i,proto[i].name);
+#endif
+ lvi.iItem = i+1;
+ lvi.pszText = proto[i].name;
+ lvi.lParam = (LPARAM)i;
+ int itemNum = LV_InsertItemA(hLV, &lvi);
+ ListView_SetCheckState(hLV,itemNum,proto[i].inspecting);
+ }
+
+ SetDlgItemText(hDlg,IDC_SPLITON,"0");
+ SetDlgItemText(hDlg,IDC_SPLITOFF,"0");
+ EnableWindow(GetDlgItem(hDlg,IDC_SPLITON), false);
+ EnableWindow(GetDlgItem(hDlg,IDC_SPLITOFF), false);
+
+ BYTE sha[64]; int len; exp->rsa_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;i<ADV_CNT;i++)
+// SendMessage(GetDlgItem(hDlg,IDC_ADV1+i),BM_SETCHECK,(i==0)?BST_CHECKED:BST_UNCHECKED,0L);
+ SendMessage(GetDlgItem(hDlg, IDC_ADVICON), CB_SETCURSEL, 0, 0);
+
+ // 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) {
+
+ if (isSecureProtocol(hContact) /*&& !getMetaContact(hContact)*/ && !isChatRoom(hContact)) {
+
+ pUinKey ptr = getUinKey(hContact);
+ if (!ptr) continue;
+
+ ptr->tmode=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 <windows.h>
+
+#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_num<part_all; part_num++) {
+ int sz = (len>iLen)?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; i<part_all; i++ ) {
+ if(pm->message[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; i<part_all; i++ ) {
+ strcat(ptr->tmp,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 <windows.h>
+
+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;i<SIZEOF(g_hMenu);i++) {
+ if ( g_hMenu[i] )
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[i],(LPARAM)&mi);
+ }
+ return 0;
+ }
+
+// char *szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+// if (szProto==NULL) // || DBGetContactSettingDword(hContact, szProto, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+// return 0;
+
+ BOOL isSecureProto = isSecureProtocol(hContact);
+ BOOL isPGP = isContactPGP(hContact);
+ BOOL isGPG = isContactGPG(hContact);
+// BOOL isRSAAES = isContactRSAAES(hContact);
+ BOOL isSecured = isContactSecured(hContact)&SECURED;
+ BOOL isChat = isChatRoom(hContact);
+ BOOL isMiranda = isClientMiranda(hContact);
+
+ // hide all menu bars
+ mi.flags = CMIM_FLAGS | CMIF_NOTOFFLINE | CMIF_HIDDEN;
+ for(i=0;i<SIZEOF(g_hMenu);i++) {
+ if ( g_hMenu[i] )
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)g_hMenu[i],(LPARAM)&mi);
+ }
+
+ if ( isSecureProto && !isChat && isMiranda &&
+ (ptr->mode==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;i<MODE_CNT;i++) {
+ if ( i==MODE_PGP && ptr->mode!=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 <windows.h>
+
+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 <windows.h>
+
+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 <windows.h>
+
+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 <windows.h>
+
+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 <windows.h>
+
+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