summaryrefslogtreecommitdiff
path: root/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c')
-rw-r--r--plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c565
1 files changed, 0 insertions, 565 deletions
diff --git a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c b/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c
deleted file mode 100644
index 20c56a7a66..0000000000
--- a/plugins/!NotAdopted/IMO2sProxy/src/imo2skype/socksproxy.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/* Module: imo2skypeproxy.c
- Purpose: Implementation of imo2skype API as Skype proxy (for Miranda Skype plugin)
- Author: leecher
- Date: 01.09.2009
-
- Changelog:
- 1.00 - 01.09.2009 - Initial release
- 1.01 - 02.09.2009 - Little bugfix for Onlinestatus, introduced mutex for send thread.
- 1.02 - 02.09.2009 - Added support for incoming call notifications and expired sessions.
- 1.03 - 03.09.2009 - As WIN32-port of libcurl is a total mess, Win32-version now uses WinINET.
- 1.04 - 04.09.2009 - Added support for searching, adding and removing buddies
- 1.05 - 06.09.2009 - * Mapped "busy" to DND, not NA, as forum user AL|EN proposed.
- * Mood text will now also be sent on status change of a contact
- (doesn't really have an effect though)
- * New Parameter -d (daemonize) to launch proxy in background
- * Fixed a bug with a crash when encoding umlauts on Win32
- 1.06 - 25.09.2009 - Added parameter -t for local timestamps.
- 1.07 - 07.10.2009 - Bugfix: Added parsing of multiple JSON messages
- Added support for writing to logfile while in daemon mode (-l)
- 1.08 - 18.10.2009 - Added support for voice calls via imo.im flash on WIN32 (-i)
- - Limited memory queues to 50 entries to reduce memory usage.
- 1.09 - 07.11.2009 - Split command line main module and proxy module to make proxy
- accessible by different layers (i.e. new Miranda Plugin layer)
- 1.10 - 14.12.2009 - Bug in the cJson library. The authors used the String as second
- sprintf-Parameter which contains the format string instead of
- ["%s", StringParam] causing problems sending Messages containt a %
- - Added some space in the dialog for translations and added Translate()
- function to some strings in the Wrapper-DLL
- - More verbose output if you enable logging
- - Fixes a Bug that caused the plugin to block after going offline
- and reconnecting back online
- - Hopefully fixed a severe threading problem: The Send-Mutex was not
- covering a full transaction, but only 1 send causing the receiver
- the receive garbled data causing "An existing connection was forcibly
- closed by the remote host." error.
- - Imo2S_Exit freed the temporary buffer too early resulting in a crash
- on exit.
- 1.12 - 19.04.2010 - POST interface changed from www.imo.im/amy to s.imo.im/amy
- 1.13 - 19.12.2010 - imo.im modified their interface, so tried to adapt the communication
- routines at low level to be compatible again. There still may be
- many bugs. Don't forget to turn off history logging in the options
- at https://imo.im
- There also seems to be a nice new feature called "reflection" so that
- you can login from multiple sessions and messages etc. entered there
- will be reflected to the current session. This may be addressed in one
- of the next builds...
-*/
-
-#include <stdio.h>
-#include "imo2sproxy.h"
-#ifdef WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winsock2.h>
-#include <process.h>
-#define thread_t HANDLE
-#define LockMutex(x) EnterCriticalSection (&x)
-#define UnlockMutex(x) LeaveCriticalSection(&x)
-#define InitMutex(x) InitializeCriticalSection(&x)
-#define ExitMutex(x) DeleteCriticalSection(&x)
-#define strcasecmp stricmp
-#define strncasecmp stricmpn
-#define mutex_t CRITICAL_SECTION
-#define SHUT_RD SD_RECEIVE
-#define SHUT_WR SD_SEND
-#define SHUT_RDWR SD_BOTH
-#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <pthread.h>
-#include <errno.h>
-#include <unistd.h>
-#include <pthread.h>
-#define SOCKET int
-#define thread_t pthread_t
-#define mutex_t pthread_mutex_t
-#define INVALID_SOCKET -1
-#define SOCKET_ERROR INVALID_SOCKET
-#define closesocket close
-#define LockMutex(x) pthread_mutex_lock(&x)
-#define UnlockMutex(x) pthread_mutex_unlock(&x)
-#define InitMutex(x) pthread_mutex_init(&x, NULL);
-#define ExitMutex(x)
-#endif
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include "memlist.h"
-#include "socksproxy.h"
-
-// -----------------------------------------------------------------------------
-
-#define AUTHENTICATE 0x01
-#define CAPABILITIES 0x02
-#define USE_AUTHENTICATION 0x01
-
-typedef struct
-{
- IMO2SPROXY vtbl; // Must be first!
- IMO2SPROXY_CFG *pCfg;
- SOCKSPROXY_CFG *pMyCfg;
-
- SOCKET listen_fd;
- volatile int iRunning;
- mutex_t loopmutex;
-} IMO2SPROXY_INST;
-
-typedef struct
-{
- SOCKET hSock;
- thread_t hThread;
- IMOSAPI *hInst;
- int iConnectionStat;
- mutex_t connected;
- mutex_t sendmutex;
- IMO2SPROXY_INST *hProxy;
-} CONNINST;
-
-
-// -----------------------------------------------------------------------------
-
-static void EventHandler(char *pszMsg, void *pUser);
-static void DispatcherThread(void *pUser);
-static int Dispatcher_Start(CONNINST *pInst);
-static int Dispatcher_Stop(CONNINST *pInst);
-static char *GetError(void);
-static int RcvPacket (CONNINST *pInst, void *buf, int len);
-static int SendPacket (CONNINST *pInst, void *buf, int len);
-static void FreeConnection (CONNINST *pInst);
-static void CleanConnections (TYP_LIST *hList);
-static SOCKET Init(unsigned long int lHost, short sPort, int iMaxConn);
-static void Loop(SOCKET listen_fd);
-static void Exit(SOCKET listen_fd);
-
-static int Imo2sproxy_Open(IMO2SPROXY *hInst);
-static void Imo2sproxy_Loop(IMO2SPROXY *hInst);
-static void Imo2sproxy_Exit(IMO2SPROXY *hInst);
-
-// -----------------------------------------------------------------------------
-static void EventHandler(char *pszMsg, void *pUser)
-{
- CONNINST *pInst = (CONNINST*)pUser;
- unsigned int uiLen = strlen (pszMsg);
- static BOOL bFirstLogin = TRUE;
-
- if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
- {
- fprintf (pInst->hProxy->pCfg->fpLog, "%03d> %s\n", pInst->hSock, pszMsg);
- fflush (pInst->hProxy->pCfg->fpLog);
- }
- if (bFirstLogin && strncmp (pszMsg, "CONNSTATUS", 10) == 0 &&
- strcmp(pszMsg+11, "CONNECTING"))
- {
- pInst->iConnectionStat = (strcmp(pszMsg+11, "ONLINE")==0);
- UnlockMutex (pInst->connected);
- bFirstLogin = FALSE;
- }
- LockMutex(pInst->sendmutex);
- if (!(SendPacket (pInst, &uiLen, sizeof(uiLen)) && SendPacket (pInst, pszMsg, uiLen)))
- {
- //Dispatcher_Stop(pInst);
- //FreeConnection (pInst);
- }
- UnlockMutex(pInst->sendmutex);
-}
-
-// -----------------------------------------------------------------------------
-
-static void DispatcherThread(void *pUser)
-{
- CONNINST *pInst = (CONNINST*)pUser;
- char *pszUser, *pszPass, *pszError, *pszMsgBuf=NULL;
- unsigned int uiLength, cbMsgBuf=0, bAuthenticated = 0, iConnected=0, iLogin=1;
- char command=0, reply=0;
-
- if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
- fprintf (pInst->hProxy->pCfg->fpLog, "Imo2sproxy::DispatcherThread()\n");
-
- if (!(pInst->hInst = Imo2S_Init(EventHandler, pInst, pInst->hProxy->pCfg->iFlags)))
- {
- pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot start Imo2Skype instance.\n", pInst->hSock);
- FreeConnection (pInst);
- return;
- }
-
- // FIXME: Static user+pass from cmdline, until there is a possibility for
- // a client to authenticate
- pszUser = pInst->hProxy->pCfg->pszUser;
- pszPass = pInst->hProxy->pCfg->pszPass;
-
- // FIXME: We should enable logging dependent on a loglevel rather than just enabling it
- if (pInst->hProxy->pCfg->bVerbose)
- Imo2S_SetLog (pInst->hInst, pInst->hProxy->pCfg->fpLog);
-
-
- while (pInst->hProxy->iRunning)
- {
- if (RcvPacket(pInst, &uiLength, sizeof(uiLength))<=0) break;
- LockMutex(pInst->sendmutex);
-
- if (uiLength == 0)
- {
- if (RcvPacket(pInst, &command, 1)<=0)
- {
- UnlockMutex(pInst->sendmutex);
- break;
- }
- switch (command)
- {
- case AUTHENTICATE:
- if (pInst->hProxy->pMyCfg->pszAuthPass) reply=1;
- break;
- case CAPABILITIES:
- if (pInst->hProxy->pMyCfg->pszAuthPass) reply=USE_AUTHENTICATION;
- break;
- }
- if (SendPacket (pInst, &reply, 1)<=0)
- {
- UnlockMutex(pInst->sendmutex);
- break;
- }
- UnlockMutex(pInst->sendmutex);
- continue;
- }
-
- if (uiLength >= cbMsgBuf)
- {
- pszMsgBuf = realloc (pszMsgBuf, uiLength+1);
- if (!pszMsgBuf)
- {
- UnlockMutex(pInst->sendmutex);
- break;
- }
- cbMsgBuf=uiLength+1;
- }
-
- if (RcvPacket(pInst, pszMsgBuf, uiLength)<=0)
- {
- UnlockMutex(pInst->sendmutex);
- break;
- }
-
- if (command)
- {
- if (command == AUTHENTICATE)
- {
- bAuthenticated = pInst->hProxy->pMyCfg->pszAuthPass && strcmp(pInst->hProxy->pMyCfg->pszAuthPass, pszMsgBuf) == 0;
- if (SendPacket (pInst, &bAuthenticated, 1)<=0)
- {
- UnlockMutex(pInst->sendmutex);
- break;
- }
- }
- command = 0;
- }
- UnlockMutex(pInst->sendmutex);
-
- if (iLogin)
- {
- if (Imo2S_Login (pInst->hInst, pszUser, pszPass, &pszError) != 1)
- {
- pInst->hProxy->pCfg->logerror (stderr, "Connection %d: Cannot login with (%s/****): %s\n",
- pInst->hSock, pszUser, pszError);
- FreeConnection (pInst);
- return;
- }
- iLogin = 0;
- }
-
- if (pInst->hProxy->pMyCfg->pszAuthPass && !bAuthenticated)continue;
- pszMsgBuf[uiLength]=0;
- if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
- {
- fprintf (pInst->hProxy->pCfg->fpLog, "%03d< [%s]\n", pInst->hSock, pszMsgBuf);
- fflush (pInst->hProxy->pCfg->fpLog);
- }
- if (!iConnected)
- {
- LockMutex (pInst->connected);
- iConnected = pInst->iConnectionStat;
- if (!iConnected)
- {
- pInst->hProxy->pCfg->logerror(stderr, "Invalid username / password");
- }
- }
- Imo2S_Send (pInst->hInst, pszMsgBuf);
- }
-
- FreeConnection (pInst);
- if (pszMsgBuf) free (pszMsgBuf);
- return;
-}
-
-// -----------------------------------------------------------------------------
-
-#ifdef WIN32
-static int Dispatcher_Start(CONNINST *pInst)
-{
- DWORD ThreadID;
-
- return (pInst->hThread=(thread_t)_beginthreadex(NULL, 0,
- (unsigned(__stdcall *)(void*))DispatcherThread, pInst, 0, &ThreadID))!=0;
-
-}
-
-static int Dispatcher_Stop(CONNINST *pInst)
-{
- return pInst->hThread?TerminateThread (pInst->hThread, 0):1;
-}
-
-static char *GetError(void)
-{
- static char szMessage[1024];
- DWORD dwErr = WSAGetLastError();
-
- FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, 0, szMessage, sizeof(szMessage), NULL);
- return szMessage;
-}
-
-#else
-static int Dispatcher_Start(CONNINST *pInst)
-{
- return pthread_create(&pInst->hThread, NULL, DispatcherThread, pInst)==0;
-}
-
-static int Dispatcher_Stop(CONNINST *pInst)
-{
- if (!pInst->hThread || pthread_cancel(pInst->hThread))
- {
- pInst->hThread=0;
- return 1;
- }
- return 0;
-}
-
-static char *GetError(void)
-{
- return strerror (errno);
-}
-
-#endif
-
-// -----------------------------------------------------------------------------
-
-static int RcvPacket (CONNINST *pInst, void *buf, int len)
-{
- int iReceived = recv (pInst->hSock, buf, len, 0);
- if (iReceived <= 0)
- pInst->hProxy->pCfg->logerror(stderr, "Connection %d (Receive): %s", pInst->hSock, GetError());
- return iReceived;
-}
-
-// -----------------------------------------------------------------------------
-
-static int SendPacket (CONNINST *pInst, void *buf, int len)
-{
- int iSent;
-
- iSent = send (pInst->hSock, buf, len, 0);
- if (iSent <= 0)
- pInst->hProxy->pCfg->logerror (stderr, "Connection %d (Send): %s", pInst->hSock, GetError());
- return iSent;
-}
-// -----------------------------------------------------------------------------
-
-static void FreeConnection (CONNINST *pInst)
-{
- if (pInst->hProxy->pCfg->bVerbose && pInst->hProxy->pCfg->fpLog)
- {
- fprintf (pInst->hProxy->pCfg->fpLog, "Closed connection %d\n", pInst->hSock);
- fflush (pInst->hProxy->pCfg->fpLog);
- }
- if (pInst->hSock != INVALID_SOCKET)
- closesocket(pInst->hSock);
- pInst->hSock = INVALID_SOCKET;
- pInst->hThread = 0;
- ExitMutex (pInst->connected);
- ExitMutex (pInst->sendmutex);
- if (pInst->hInst)
- {
- IMOSAPI *hInst = pInst->hInst;
- pInst->hInst = NULL;
- Imo2S_Exit(hInst);
- }
-}
-
-// -----------------------------------------------------------------------------
-
-static void CleanConnections (TYP_LIST *hList)
-{
- unsigned int i;
- CONNINST *hInst;
-
- for (i=0; i<List_Count(hList); i++)
- {
- hInst = List_ElementAt (hList, i);
- if (hInst->hThread == 0)
- {
- free (List_RemoveElementAt(hList, i));
- i--;
- }
- }
-}
-
-// -----------------------------------------------------------------------------
-// PUBLIC
-// -----------------------------------------------------------------------------
-
-void SocksProxy_Defaults (SOCKSPROXY_CFG *pMyCfg)
-{
- memset (pMyCfg, 0, sizeof(SOCKSPROXY_CFG));
- pMyCfg->lAddr = htonl(INADDR_ANY);
- pMyCfg->sPort = 1401;
- pMyCfg->iMaxConn = SOMAXCONN;
-}
-
-// -----------------------------------------------------------------------------
-
-IMO2SPROXY *SocksProxy_Init (IMO2SPROXY_CFG *pCfg, SOCKSPROXY_CFG *pMyCfg)
-{
- IMO2SPROXY_INST *pstInst = calloc(sizeof(IMO2SPROXY_INST), 1);
-
- pstInst->vtbl.Open = Imo2sproxy_Open;
- pstInst->vtbl.Loop = Imo2sproxy_Loop;
- pstInst->vtbl.Exit = Imo2sproxy_Exit;
- pstInst->pCfg = pCfg;
- pstInst->pMyCfg = pMyCfg;
- InitMutex(pstInst->loopmutex);
- return (IMO2SPROXY*)pstInst;
-}
-
-// -----------------------------------------------------------------------------
-// IMPLEMENTATION
-// -----------------------------------------------------------------------------
-static int Imo2sproxy_Open(IMO2SPROXY *hInst)
-{
- struct sockaddr_in sock={0};
- int yes = 1;
- IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
-
-#ifdef WIN32
- WSADATA wsaData;
-
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- hProxy->pCfg->logerror (stderr, "WSAStartup failed");
- return INVALID_SOCKET;
- }
-#endif
- if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
- fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n");
- hProxy->listen_fd = socket(PF_INET, SOCK_STREAM, 0);
- if(hProxy->listen_fd == INVALID_SOCKET) return -1;
- if (setsockopt(hProxy->listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(int))<0)
- {
- hProxy->pCfg->logerror (stderr, "Cannot set socket options to SO_REUSEADDR");
- closesocket(hProxy->listen_fd);
- return -1;
- }
- sock.sin_family = AF_INET;
- sock.sin_addr.s_addr = hProxy->pMyCfg->lAddr;
- sock.sin_port = htons(hProxy->pMyCfg->sPort);
-
- if (bind(hProxy->listen_fd, (struct sockaddr *) &sock, sizeof(sock)) != 0)
- {
- hProxy->pCfg->logerror (stderr, "Cannot bind socket");
- closesocket(hProxy->listen_fd);
- return -1;
- }
-
- if (listen(hProxy->listen_fd, hProxy->pMyCfg->iMaxConn) < 0)
- {
- hProxy->pCfg->logerror (stderr, "Cannot listen on socket");
- closesocket(hProxy->listen_fd);
- return -1;
- }
-
- return 0;
-}
-
-// -----------------------------------------------------------------------------
-
-static void Imo2sproxy_Loop(IMO2SPROXY *hInst)
-{
- struct sockaddr_in sock;
- int socklen;
- SOCKET new_fd;
- TYP_LIST *hConns = List_Init(32);
- CONNINST *pInst;
- IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
- fd_set fdListen;
-
- if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
- fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(Start)\n");
- hProxy->iRunning = 1;
- LockMutex(hProxy->loopmutex);
- while (hProxy->iRunning)
- {
- FD_ZERO(&fdListen);
- FD_SET(hProxy->listen_fd, &fdListen);
- socklen = sizeof(sock);
- if (select (0, &fdListen, NULL, NULL, NULL) != SOCKET_ERROR && FD_ISSET(hProxy->listen_fd, &fdListen))
- {
- new_fd = accept(hProxy->listen_fd, (struct sockaddr *) &sock, &socklen);
- if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
- {
- fprintf (hProxy->pCfg->fpLog, "Connection from %s:%d -> Connection: %d\n", inet_ntoa(sock.sin_addr),
- ntohs(sock.sin_port), new_fd);
- fflush (hProxy->pCfg->fpLog);
- }
- if (new_fd != INVALID_SOCKET && (pInst = calloc (1, sizeof(CONNINST))))
- {
- CleanConnections (hConns);
- List_Push(hConns, pInst);
- pInst->hSock = new_fd;
- pInst->hProxy = hProxy;
- InitMutex(pInst->connected);
- LockMutex(pInst->connected);
- InitMutex(pInst->sendmutex);
- Dispatcher_Start(pInst);
- }
- }
- }
- if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
- fprintf (hProxy->pCfg->fpLog, "Socksproxy:Loop(End)\n");
-
- CleanConnections (hConns);
- while (pInst=List_Pop(hConns))
- {
- Dispatcher_Stop(pInst);
- FreeConnection(pInst);
- free (pInst);
- }
- List_Exit(hConns);
- UnlockMutex(hProxy->loopmutex);
-}
-
-
-// -----------------------------------------------------------------------------
-
-static void Imo2sproxy_Exit(IMO2SPROXY *hInst)
-{
- IMO2SPROXY_INST *hProxy = (IMO2SPROXY_INST*)hInst;
-
- if (hProxy->pCfg->bVerbose && hProxy->pCfg->fpLog)
- fprintf (hProxy->pCfg->fpLog, "Socksproxy:Exit()\n");
-
- hProxy->iRunning = 0;
- shutdown (hProxy->listen_fd, SHUT_RDWR);
- closesocket (hProxy->listen_fd);
- LockMutex(hProxy->loopmutex);
-
-/*
-#ifdef WIN32
- WSACleanup();
-#endif
-*/
- UnlockMutex(hProxy->loopmutex);
- ExitMutex(hProxy->loopmutex);
- free (hProxy);
-}
-