From ee073251eba82de6a4632b467b1574baddd6aeaa Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Sun, 31 May 2015 18:18:59 +0000 Subject: SkypeClassic moved to deprecated git-svn-id: http://svn.miranda-ng.org/main/trunk@13943 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/SkypeClassic/src/skypeproxy/skypeproxy.c | 651 --------------------- 1 file changed, 651 deletions(-) delete mode 100644 protocols/SkypeClassic/src/skypeproxy/skypeproxy.c (limited to 'protocols/SkypeClassic/src/skypeproxy/skypeproxy.c') diff --git a/protocols/SkypeClassic/src/skypeproxy/skypeproxy.c b/protocols/SkypeClassic/src/skypeproxy/skypeproxy.c deleted file mode 100644 index 200b79632a..0000000000 --- a/protocols/SkypeClassic/src/skypeproxy/skypeproxy.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - -Purpose -======= -This program opens a connection on a local TCP/IP port and sends/ -receives Skype-API calls on it so that you can remote-control -Skype over a network. -Note, that there are currently NO SECURITY mechanisms, so don't -use this over an untrusted network! - -Author -====== -This program was written by leecher in 2005 (mailto:leecher@dose.0wnz.at) -Please give feedback at http://forum.skype.com/viewtopic.php?t=16187 - -Protocol -======== -Basic protocol structure ------------------------- -Sender and receiver have the same protocol: - - [(UINT)Length of message][(char[])Message] - -The Length is so that you can malloc() enough space for the data buffer -to receive the next message. - -A special case is, if the [Length of message] is 0. In this case the -client tells the server that he wants to switch to command mode. - -Command mode ------------- -The server expects - - [(char)Command] - -next. Currently the following commands are supported: - - CAPABILITIES - returns the Server's capabilities - AUTHENTICATE - Starts the authentication process - -CAPABILITIES ------------- -The server returns - - [(char)Capabilities] - -where this currently can be the following: - - USE_AUTHENTICATION - The server supports and requires authentication - -AUTHENTICATE ------------- -The server returns - - [(char)0x01] - -if authentication is supported AND needed (skypeproxy started with -k switch) or - - [(char)0x00] - -if this is not the case. -If 0x01 was returned the server next expects a normal message -(see "Basic protocol structure) containing the password. -If the authentication was successful, the server replies with - - [(char)0x01] - -otherwise with - - [(char)0x00] - -PLEASE NOTE THAT THE AUTHENTICATION CURRENTLY IS PLAIN TEXT. SO DON'T -USE THIS PROGRAM OVER AN UNTRUSTED NETWORK, OTHERWISE THERE MAY BE THE -POSSIBILITY THAT SOMEONE SNIFFS YOUR PASSWORD! - -Code example ------------- - -SOCKET MySocket; - -int SendPacket(char *szSkypeMessage) { - unsigned int length=strlen(szSkypeMsg); - - if (send(MySocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || - send(MySocket, szSkypeMsg, length, 0)==SOCKET_ERROR) - return -1; - return 0; -} - -// don't forget to free() the return value on my Heap!! -char *ReceivePacket(void) { - unsigned int lenght, received; - char *buf; - - if ((received=recv(MySocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || - received==0) - return NULL; - if (!(buf=calloc(1, length+1))) return NULL; - if (recv(MySocket, buf, length, 0)==SOCKET_ERROR) { - free(buf); - return NULL; - } - return buf; -} - - -License -======= -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -History -======== -V1.0alpha - First preview release -V1.0 - Implemented killing & restarting Skype process when it dies - - BUGFIX: SendMessage() is a blocking call, if Skype hangs our app hangs too -> Fixed - - Added command line parsing. - - Renamed from Skype2Socket to skypeproxy - - Added authentication feature. -*/ - -#include -#include -#include -#include -#include "skypeproxy.h" - -UINT ControlAPIAttach, ControlAPIDiscover; -HWND hSkypeWnd=NULL, hWnd; -HANDLE SkypeReady, ServerThreadBye; -LONG AttachStatus=-1; -int exitcode=EXIT_SUCCESS; -char skype_path[MAX_PATH], *password=NULL; -BYTE WatchDog=1; -BOOL WatchDogRunning=FALSE, Authenticated=FALSE; -SOCKET ListenSocket, AcceptSocket; - - -void bail_out(int i) { - OUTPUT("Got termination signal, bailing out."); - if (i==1) exitcode=EXIT_FAILURE; - PostMessage(hWnd, WM_QUIT, 0, 0); -} - -BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) { - DWORD dwID ; - - GetWindowThreadProcessId(hwnd, &dwID) ; - if(dwID == (DWORD)lParam) - PostMessage(hwnd, WM_CLOSE, 0, 0) ; // May you be so kind to quit, please? - - return TRUE ; -} - -/* ConnectToSkypeAPI - * - * Purpose: Establish a connection to the Skype API - * Params : ForceRestart - Kill Skype if it's running before restarting - * Returns: 0 - Connecting succeeded - * -1 - Something went wrong - */ -void ConnectToSkypeAPI(void *ForceRestart) { - BOOL SkypeLaunched=FALSE; - int counter=0, i, j; - char *args[5]; - char *SkypeOptions[]={"/notray", "/nosplash", "/minimized"}; - char *szFuncName="ConnectToSkypeAPI"; - - ResetEvent(SkypeReady); - AttachStatus=-1; - if ((BOOL)ForceRestart) { - HANDLE hProc; - DWORD dwPID=0; - - if (!hSkypeWnd) { - OUTPUT("I can't kill Skype, as I don't even have its window handle!"); - return; - } - GetWindowThreadProcessId(hSkypeWnd, &dwPID); - LOG(("%s: Shutting down Skype as it was not behaving the way it should...", szFuncName)); - if (hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, dwPID)) { - - // Try to shutdown Skype the nice way by asking it to close - EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID); - - if(WaitForSingleObject(hProc, 10000)!=WAIT_OBJECT_0) { - // Try it the hard way by killing it - LOG(("%s: I tried it the nice way, but you were not listening! Now DIIIIEEE!", szFuncName)); - if (!TerminateProcess(hProc,0)) { - OUTPUT("Argh, process refused to die, it's too mighty for me, I've given up"); - CloseHandle(hProc); - return; - } - LOG(("%s: Process killed! >:)", szFuncName)); - } - CloseHandle(hProc); - } - } - do { - /* To initiate communication, Client should broadcast windows message - ('SkypeControlAPIDiscover') to all windows in the system, specifying its own - window handle in wParam parameter. - */ - LOG(("%s: Sending discover message..", szFuncName)); - SendMessageTimeout(HWND_BROADCAST, ControlAPIDiscover, (WPARAM)hWnd, 0, SMTO_ABORTIFHUNG, 3000, NULL); - LOG(("%s: Discover message sent, waiting for Skype to become ready..", szFuncName)); - - /* In response, Skype responds with - message 'SkypeControlAPIAttach' to the handle specified, and indicates - connection status - SkypeReady is set if there is an answer by Skype other than API_AVAILABLE. - If there is no answer after 3 seconds, launch Skype as it's propably - not running. - */ - if (WaitForSingleObject(SkypeReady, 3000)==WAIT_TIMEOUT && - AttachStatus!=SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) - { - if (hWnd==NULL) { - LOG(("%s: hWnd of SkypeDispatchWindow not yet set..", szFuncName)); - continue; - } - if (!SkypeLaunched && skype_path) { - LOG(("%s: Starting Skype, as it's not running", szFuncName)); - args[0]=skype_path; - j=1; - for (i=0; i<3; i++) { - args[j]=SkypeOptions[i]; - LOG(("%s: Using Skype parameter: ", szFuncName, args[j])); - j++; - } - args[j]=NULL; - _spawnv(_P_NOWAIT, skype_path, args); - ResetEvent(SkypeReady); - SkypeLaunched=TRUE; - LOG(("%s: Skype process started.", szFuncName)); - // Skype launching iniciated, keep sending Discover messages until it responds. - continue; - } else { - LOG(("%s: Check if Skype was launchable..", szFuncName)); - if (!skype_path) { - OUTPUT("There was no correct path for Skype application"); - bail_out(1); - return; - } - LOG("%s: Trying to attach: #%d", szFuncName, counter)); - counter++; - if (counter==5) { - OUTPUT("ERROR: Skype not running / too old / working!"); - bail_out(1); - return; - } - } - } - LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); - } while (AttachStatus==SKYPECONTROLAPI_ATTACH_API_AVAILABLE || AttachStatus==-1); - - while (AttachStatus==SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION) Sleep(1000); - LOG(("%s: Attachstatus %d", szFuncName, AttachStatus)); - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_SUCCESS) { - switch(AttachStatus) { - case SKYPECONTROLAPI_ATTACH_REFUSED: - OUTPUT("Skype refused the connection :("); - break; - case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: - OUTPUT("The Skype API is not available"); - break; - default: - LOG(("%s: ERROR: AttachStatus: %d", szFuncName, AttachStatus)); - OUTPUT("Wheee, Skype won't let me use the API. :("); - } - bail_out(1); - return; - } - OUTPUT("Attached to Skype successfully."); - if (!WatchDogRunning) - if (_beginthread(WatchDogTimer, 0, NULL)==-1) { - OUTPUT("Cannot start Watchdog."); - bail_out(1); - } - return; -} - -void SkypeSend(char *szMsg) { - COPYDATASTRUCT CopyData; - int count=0; - - if (!hSkypeWnd) { - LOG(("SkypeSend: DAMN! No Skype window handle! :(")); - return; - } - if (mir_strcmp(szMsg, "PING")) {LOG(("> %s", szMsg));} - CopyData.dwData=0; - CopyData.lpData=szMsg; - CopyData.cbData=strlen(szMsg)+1; - while (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { - count++; - LOG(("SkypeSend: failed, try #%d", count)); - if (count==5) { - OUTPUT("Sending message to Skype failed too often."); - OUTPUT("Skype may have died unexpectedly, I will try to restart it."); - ConnectToSkypeAPI((void *)TRUE); - OUTPUT("Restart complete. Trying to deliver message one more time."); - if (!SendMessageTimeout(hSkypeWnd, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&CopyData, SMTO_ABORTIFHUNG, 3000, NULL)) { - OUTPUT("It still failed. Skype seems to be completely f*cked up. I've given up. Bye.."); - bail_out(1); - break; - } else { - OUTPUT("Now it worked! :)"); - break; - } - } - Sleep(1000); - } -} - -void ServerThread(char *dummy) { - unsigned int length, received; - char *buf, command, reply; - - LOG(("ServerThread started")); - AcceptSocket=INVALID_SOCKET; - while( AcceptSocket == INVALID_SOCKET) { - if ((AcceptSocket = accept( ListenSocket, NULL, NULL ))==INVALID_SOCKET) { - LOG(("ServerThread: Byebye...")); - SetEvent(ServerThreadBye); - bail_out(1); - return; - } - OUTPUT("Connection by client"); - while(1) { - if ((received=recv(AcceptSocket, (char *)&length, sizeof(length), 0))==SOCKET_ERROR || - received==0) - { - OUTPUT("Connection was closed by client. See ya soon! :)"); - break; - } - // Command mode - if (length==0) { - reply=0; - if (recv(AcceptSocket, (char *)&command, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } -#ifdef USE_AUTHENTICATION - if (command==AUTHENTICATE) - if (password) reply=0x01; // Ok, go ahead - else command=0; -#endif - if (command==CAPABILITIES) - reply=password?USE_AUTHENTICATION:0; - - if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } - continue; - } - // Normal Skype API-call - if (!(buf=calloc(1, length+1))) { - OUTPUT("Out of memory error while allocating buffer space."); - break; - } - if (recv(AcceptSocket, buf, length, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - free(buf); - break; - } - switch (command) { -#ifdef USE_AUTHENTICATION - case 0x01: // Compare hash - if (password && !mir_strcmp(password, buf)) Authenticated=TRUE; - else Authenticated=FALSE; - if (Authenticated) { - OUTPUT("User authenticated succesfully."); - reply=1; - } else { - OUTPUT("User authentication failed!! (Intruder?)"); - reply=0; - } - if (send(AcceptSocket, (char *)&reply, 1, 0)==SOCKET_ERROR) { - OUTPUT("Connection to client was lost."); - break; - } - command=0; - break; -#endif - default: -#ifdef USE_AUTHENTICATION - if (password && !Authenticated) break; -#endif - SkypeSend(buf); - } - command=0; - free(buf); - } - AcceptSocket=INVALID_SOCKET; -#ifdef USE_AUTHENTICATION - Authenticated=FALSE; -#endif - } -} - - -void WatchDogTimer(char *dummy) { - LOG(("WatchDogTimer started")); - WatchDogRunning=TRUE; - while (1) { - Sleep(PING_INTERVAL); - if (!WatchDog) { - OUTPUT("Ouch.. It seems that Skype has died unexpectedly. Trying to restart."); - ConnectToSkypeAPI((void *)TRUE); - } - WatchDog=0; - SkypeSend("PING"); - } -} - -LONG APIENTRY WndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam) -{ - PCOPYDATASTRUCT CopyData; - char *szSkypeMsg=NULL; - - switch (message) - { - case WM_COPYDATA: -// LOG("WM_COPYDATA", "start"); - if(hSkypeWnd==(HWND)wParam) { - CopyData=(PCOPYDATASTRUCT)lParam; - szSkypeMsg=strdup(CopyData->lpData); - ReplyMessage(1); - if (!mir_strcmp(szSkypeMsg, "PONG")) { - WatchDog=1; - break; - } // Hide PING-PONG - LOG(("< %s", szSkypeMsg)); - if (!mir_strcmp(szSkypeMsg, "USERSTATUS LOGGEDOUT")) { - OUTPUT("Skype shut down gracefully. I'll leave too, bye.. :)"); - bail_out(1); - } -#ifdef USE_AUTHENTICATION - if (password && !Authenticated) break; -#endif - if (AcceptSocket!=INVALID_SOCKET) { - unsigned int length=strlen(szSkypeMsg); - - if (send(AcceptSocket, (char *)&length, sizeof(length), 0)==SOCKET_ERROR || - send(AcceptSocket, szSkypeMsg, length, 0)==SOCKET_ERROR) - OUTPUT("Cannot send to client :("); - } - } - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - default: - if(message==ControlAPIAttach) { - // Skype responds with Attach to the discover-message - AttachStatus=lParam; - if (AttachStatus==SKYPECONTROLAPI_ATTACH_SUCCESS) - hSkypeWnd=(HWND)wParam; // Skype gave us the communication window handle - if (AttachStatus!=SKYPECONTROLAPI_ATTACH_API_AVAILABLE) - SetEvent(SkypeReady); - break; - } - return (DefWindowProc(hWnd, message, wParam, lParam)); - } -// LOG("WM_COPYDATA", "exit"); - if (szSkypeMsg) free(szSkypeMsg); - return 1; -} - - -void TellError(DWORD err) { - LPVOID lpMsgBuf; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); - MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); - LocalFree( lpMsgBuf ); - return; -} - -int main(int argc, char *argv[]) { - DWORD Buffsize; - HKEY MyKey; - BOOL SkypeInstalled=TRUE; - MSG Message; - WNDCLASS WndClass; - SOCKADDR_IN service; - WSADATA wsaData; - int ExitCode=STILL_ACTIVE; - unsigned short BindPort=1401; - char BindIP[16]="0.0.0.0"; - - printf("Skypeproxy V1.0, by leecher 2005 \n\n"); - - if (argc>1) { - int i; - - if (!mir_strcmpi(argv[1], "-h") || !mir_strcmpi(argv[1], "--help") || !mir_strcmpi(argv[1], "/?")) { - printf("Usage: %s [-i BindIP] [-p BindPort]", argv[0]); -#ifdef USE_AUTHENTICATION - printf(" [-k Password]"); -#endif - printf("\n\n"); - return EXIT_SUCCESS; - } - for (i=0;ii+1) - strncpy(BindIP, argv[i+1], sizeof(BindIP)); - if (!mir_strcmpi(argv[i], "-p") && argc>i+1) - if (!(BindPort=atoi(argv[i+1]))) { - OUTPUT("ERROR: Cannot convert port to int. bye.."); - return EXIT_FAILURE; - } -#ifdef USE_AUTHENTICATION - if (!mir_strcmpi(argv[i], "-k") && argc>i+1) - password=strdup(argv[i+1]); -#endif - } - } - - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS || - RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Skype\\Phone", 0, KEY_READ, &MyKey)!=ERROR_SUCCESS) - SkypeInstalled=FALSE; - Buffsize=sizeof(skype_path); - if (SkypeInstalled==FALSE || - RegQueryValueEx(MyKey, "SkypePath", NULL, NULL, skype_path, &Buffsize)!=ERROR_SUCCESS) { - OUTPUT("Skype was not found on this machine :("); - RegCloseKey(MyKey); - skype_path[0]=0; - return EXIT_FAILURE; - } - RegCloseKey(MyKey); - - if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { - OUTPUT("Error at loading windows sockets."); - return EXIT_FAILURE; - } - - if ((ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { - printf("* Error at creating socket(): Error %d", WSAGetLastError()); - return EXIT_FAILURE; - } - - service.sin_family = AF_INET; - service.sin_addr.s_addr = inet_addr(BindIP); - service.sin_port = htons(BindPort); - - printf("* Binding to interface %s, Port %d..", BindIP, BindPort); - if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR || - listen( ListenSocket, 1 ) == SOCKET_ERROR) - { - OUTPUT("Failed."); - closesocket(ListenSocket); - return EXIT_FAILURE; - } - printf("OK\n"); - - - if (!(ControlAPIAttach=RegisterWindowMessage("SkypeControlAPIAttach")) || - !(ControlAPIDiscover=RegisterWindowMessage("SkypeControlAPIDiscover"))) { - OUTPUT("Cannot register Windows message."); - closesocket(ListenSocket); - return EXIT_FAILURE; - } - - // Create window class - hSkypeWnd=NULL; - WndClass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; - WndClass.lpfnWndProc = (WNDPROC)WndProc; - WndClass.cbClsExtra = 0; - WndClass.cbWndExtra = 0; - WndClass.hInstance = NULL; - WndClass.hIcon = NULL; - WndClass.hCursor = NULL; - WndClass.hbrBackground = NULL; - WndClass.lpszMenuName = NULL; - WndClass.lpszClassName = "SkypeApiDispatchWindow"; - RegisterClass(&WndClass); - // Do not check the retval of RegisterClass, because on non-unicode - // win98 it will fail, as it is a stub that returns false() there - - // Create main window - hWnd=CreateWindowEx( WS_EX_APPWINDOW|WS_EX_WINDOWEDGE, - "SkypeApiDispatchWindow", "", WS_BORDER|WS_SYSMENU|WS_MINIMIZEBOX, - CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, (HINSTANCE)WndClass.hInstance, 0); - - if (!hWnd) { - OUTPUT("Cannot create window."); - TellError(GetLastError()); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - return EXIT_FAILURE; - } - ShowWindow(hWnd, 0); - UpdateWindow(hWnd); - - if (!(SkypeReady=CreateEvent(NULL, TRUE, FALSE, NULL)) || - !(ServerThreadBye=CreateEvent(NULL, TRUE, FALSE, NULL))) { - OUTPUT("Unable to create Mutex!"); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - return EXIT_FAILURE; - } - - if (_beginthread(ConnectToSkypeAPI, 0, (void *)FALSE)==-1 || - _beginthread(ServerThread, 0, NULL)==-1) { - OUTPUT("Cannot create thread. Bye.."); - closesocket(ListenSocket); - CloseHandle(WndClass.hInstance); - CloseHandle(SkypeReady); - return EXIT_FAILURE; - } - - signal(SIGINT, &bail_out); - LOG(("Startup: Messagepump started.\nPress CTRL+C to terminate\n")); - - while (GetMessage(&Message, hWnd, 0, 0)) - { - TranslateMessage(&Message); - DispatchMessage(&Message); - } - - LOG(("Shutdown: Messagepump stopped")); - - if (password) free(password); - if (AcceptSocket != INVALID_SOCKET) closesocket(AcceptSocket); - closesocket(ListenSocket); - LOG(("Shutdown: Waiting for serverthread to quit...")); - if (WaitForSingleObject(ServerThreadBye, 3000)==WAIT_TIMEOUT) - {OUTPUT("Serverthread didn't terminate correctly, shutting down anyway...");} - else - {LOG(("ServerThread terminated"));} - CloseHandle(WndClass.hInstance); - CloseHandle(SkypeReady); - return exitcode; -} \ No newline at end of file -- cgit v1.2.3