summaryrefslogtreecommitdiff
path: root/protocols/Skype/src/skype.cpp
diff options
context:
space:
mode:
authorAlexander Lantsev <aunsane@gmail.com>2013-04-23 19:47:32 +0000
committerAlexander Lantsev <aunsane@gmail.com>2013-04-23 19:47:32 +0000
commita2184eb00d2b02d48ec14e72615736281b9d5f81 (patch)
tree94ade86705cd11d5868d6b33675773642a05f199 /protocols/Skype/src/skype.cpp
parentbfeb3b2b1088278afb247d82085174aaf97e2cc6 (diff)
- changed project file structure
- skype runtime initialization moved to plugin load func - fixed password encription - disabled message sync git-svn-id: http://svn.miranda-ng.org/main/trunk@4518 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Skype/src/skype.cpp')
-rw-r--r--protocols/Skype/src/skype.cpp261
1 files changed, 258 insertions, 3 deletions
diff --git a/protocols/Skype/src/skype.cpp b/protocols/Skype/src/skype.cpp
index 06376b70c9..9f080883bb 100644
--- a/protocols/Skype/src/skype.cpp
+++ b/protocols/Skype/src/skype.cpp
@@ -1,9 +1,16 @@
-#include "skype.h"
+//#include "skype.h"
#include "skype_proto.h"
+#include "aes\aes.h"
+#include "base64\base64.h"
+//#include "skypekit\skype.h"
+
+#include "..\..\..\skypekit\key.h"
+
int hLangpack;
+CSkype *g_skype;
HINSTANCE g_hInstance;
-XML_API xi = {0};
+
TIME_API tmi = {0};
PLUGININFOEX pluginInfo =
@@ -35,10 +42,255 @@ extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD miranda
extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_PROTOCOL, MIID_LAST};
+// ---
+
+BOOL IsRunAsAdmin()
+{
+ BOOL fIsRunAsAdmin = FALSE;
+ DWORD dwError = ERROR_SUCCESS;
+ PSID pAdministratorsGroup = NULL;
+
+ // Allocate and initialize a SID of the administrators group.
+ SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
+ if ( !AllocateAndInitializeSid(
+ &NtAuthority,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &pAdministratorsGroup))
+ {
+ dwError = GetLastError();
+ goto Cleanup;
+ }
+
+ // Determine whether the SID of administrators group is enabled in
+ // the primary access token of the process.
+ if ( !CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
+ {
+ dwError = GetLastError();
+ goto Cleanup;
+ }
+
+Cleanup:
+ // Centralized cleanup for all allocated resources.
+ if (pAdministratorsGroup)
+ {
+ FreeSid(pAdministratorsGroup);
+ pAdministratorsGroup = NULL;
+ }
+
+ // Throw the error if something failed in the function.
+ if (ERROR_SUCCESS != dwError)
+ {
+ throw dwError;
+ }
+
+ return fIsRunAsAdmin;
+}
+
+char *LoadKeyPair(HINSTANCE hInstance)
+{
+ HRSRC hRes = FindResource(hInstance, MAKEINTRESOURCE(IDR_KEY), L"BIN");
+ if (hRes)
+ {
+ HGLOBAL hResource = LoadResource(hInstance, hRes);
+ if (hResource)
+ {
+ aes_context ctx;
+ unsigned char key[128];
+
+ int basedecoded = Base64::Decode(MY_KEY, (char *)key, MAX_PATH);
+ ::aes_set_key(&ctx, key, 128);
+ memset(key, 0, sizeof(key));
+
+ basedecoded = ::SizeofResource(hInstance, hRes);
+ char *pData = (char *)hResource;
+ if (!pData)
+ return NULL;
+
+ unsigned char *bufD = (unsigned char*)::malloc(basedecoded + 1);
+ unsigned char *tmpD = (unsigned char*)::malloc(basedecoded + 1);
+ basedecoded = Base64::Decode(pData, (char *)tmpD, basedecoded);
+
+ for (int i = 0; i < basedecoded; i += 16)
+ aes_decrypt(&ctx, tmpD+i, bufD+i);
+
+ ::free(tmpD);
+ bufD[basedecoded] = 0; //cert should be null terminated
+ return (char *)bufD;
+ }
+ return NULL;
+ }
+ return NULL;
+}
+
+int StartSkypeRuntime(HINSTANCE hInstance, const wchar_t *profileName, int &port/*, const wchar_t *dbPath*/)
+{
+ STARTUPINFO cif;
+ PROCESS_INFORMATION pi;
+ wchar_t param[128];
+
+ ::ZeroMemory(&cif, sizeof(STARTUPINFO));
+ cif.cb = sizeof(STARTUPINFO);
+ cif.dwFlags = STARTF_USESHOWWINDOW;
+ cif.wShowWindow = SW_HIDE;
+
+ //HRSRC hRes;
+ //HGLOBAL hResource;
+ wchar_t fileName[MAX_PATH];
+
+ HRSRC hRes = ::FindResource(hInstance, MAKEINTRESOURCE(/*IDR_RUNTIME*/102), L"BIN");
+ if (hRes)
+ {
+ HGLOBAL hResource = ::LoadResource(hInstance, hRes);
+ if (hResource)
+ {
+ HANDLE hFile;
+ char *pData = (char *)LockResource(hResource);
+ DWORD dwSize = SizeofResource(hInstance, hRes), written = 0;
+ ::GetModuleFileName(hInstance, fileName, MAX_PATH);
+
+ wchar_t *skypeKitPath = ::wcsrchr(fileName, '\\');
+ if (skypeKitPath != NULL)
+ *skypeKitPath = 0;
+ ::swprintf(fileName, SIZEOF(fileName), L"%s\\%s", fileName, L"SkypeKit.exe");
+ if ( !::PathFileExists(fileName))
+ {
+ if ((hFile = ::CreateFile(
+ fileName,
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ 0)) != INVALID_HANDLE_VALUE)
+ {
+ ::WriteFile(hFile, (void *)pData, dwSize, &written, NULL);
+ ::CloseHandle(hFile);
+ }
+ else
+ {
+ // Check the current process's "run as administrator" status.
+ // Elevate the process if it is not run as administrator.
+ if (!IsRunAsAdmin())
+ {
+ wchar_t path[MAX_PATH], cmdLine[100];
+ ::GetModuleFileName(NULL, path, ARRAYSIZE(path));
+
+ if (profileName)
+ ::swprintf(
+ cmdLine,
+ SIZEOF(cmdLine),
+ L" /restart:%d /profile=%s",
+ ::GetCurrentProcessId(),
+ profileName);
+ else
+ ::swprintf(
+ cmdLine,
+ SIZEOF(cmdLine),
+ L" /restart:%d",
+ ::GetCurrentProcessId());
+
+ // Launch itself as administrator.
+ SHELLEXECUTEINFO sei = { sizeof(sei) };
+ sei.lpVerb = L"runas";
+ sei.lpFile = path;
+ sei.lpParameters = cmdLine;
+ //sei.hwnd = hDlg;
+ sei.nShow = SW_NORMAL;
+
+ if ( !::ShellExecuteEx(&sei))
+ {
+ DWORD dwError = ::GetLastError();
+ if (dwError == ERROR_CANCELLED)
+ {
+ // The user refused to allow privileges elevation.
+ // Do nothing ...
+ }
+ }
+ //else
+ //{
+ // //DestroyWindow(hDlg); // Quit itself
+ // ::CallService("CloseAction", 0, 0);
+ //}
+ }
+ return 0;
+ }
+ }
+ }
+ }
+
+ PROCESSENTRY32 entry;
+ entry.dwSize = sizeof(PROCESSENTRY32);
+
+ HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
+ if (::Process32First(snapshot, &entry) == TRUE) {
+ while (::Process32Next(snapshot, &entry) == TRUE) {
+ if (::wcsicmp(entry.szExeFile, L"SkypeKit.exe") == 0) {
+ HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
+ port += rand() % 8963 + 1000;
+ ::CloseHandle(hProcess);
+ break;
+ }
+ }
+ }
+ ::CloseHandle(snapshot);
+
+ //::swprintf(param, SIZEOF(param), L"-p -P %d -f %s", port, dbPath);
+ ::swprintf(param, SIZEOF(param), L"-p -P %d", port);
+ int startingrt = ::CreateProcess(
+ fileName, param,
+ NULL, NULL, FALSE,
+ CREATE_NEW_CONSOLE,
+ NULL, NULL, &cif, &pi);
+ DWORD rterr = GetLastError();
+
+ //if (startingrt && rterr == ERROR_SUCCESS)
+ //return 1;
+ //else
+ //return 0;
+ return startingrt;
+}
+
+// ---
extern "C" int __declspec(dllexport) Load(void)
{
- mir_getXI(&xi);
+ int port = 8963;
+ VARST profilename( _T("%miranda_profilename%"));
+
+ if ( !StartSkypeRuntime(g_hInstance, (TCHAR*)profilename, port))
+ {
+ ::MessageBoxA(NULL, "", MODULE, MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ char *keyPair = LoadKeyPair(g_hInstance);
+ if ( !keyPair)
+ {
+ ::MessageBoxA(NULL, "", MODULE, MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ g_skype = new CSkype();
+ TransportInterface::Status status = g_skype->init(keyPair, "127.0.0.1", port);
+ if (status != TransportInterface::OK)
+ {
+ ::MessageBoxA(NULL, "", MODULE, MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ if ( !g_skype->start())
+ {
+ ::MessageBoxA(NULL, "", MODULE, MB_OK | MB_ICONERROR);
+ return 1;
+ }
+
+ free(keyPair);
+
+ // ---
+
mir_getTMI(&tmi);
mir_getLP(&pluginInfo);
@@ -61,5 +313,8 @@ extern "C" int __declspec(dllexport) Unload(void)
CSkypeProto::UninitMenus();
CSkypeProto::UninitIcons();
+ g_skype->stop();
+ delete g_skype;
+
return 0;
} \ No newline at end of file