/* * Skype Login * * Based on: * FakeSkype : Skype reverse engineering proof-of-concept client * Ouanilo MEDEGAN (c) 2006 http://www.oklabs.net * pyskype : Skype login Python script by uunicorn * * Written by: leecher@dose.0wnz.at (c) 2015 * * Module: Main module which contains public functions of library * */ #ifdef _WIN32 #define EXPORT #define strcasecmp stricmp #endif #include #include "common.h" #include "login.h" #include "platform.h" #include "uic.h" #include "objects.h" #include "credentials.h" #include "skylogin.h" EXPORT SkyLogin SkyLogin_Init() { Skype_Inst *pInst = calloc(1, sizeof(Skype_Inst)); #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD( 2, 2 ); WSAStartup( wVersionRequested, &wsaData); #endif if (pInst) InitInstance(pInst); return (SkyLogin*)pInst; } EXPORT void SkyLogin_Exit(SkyLogin pPInst) { Skype_Inst *pInst = (Skype_Inst*)pPInst; if (pInst->LoginD.User) free(pInst->LoginD.User); if (pInst->LoginD.RSAKeys) RSA_free(pInst->LoginD.RSAKeys); if (pInst->LoginD.SignedCredentials.Memory) free(pInst->LoginD.SignedCredentials.Memory); free(pInst); } EXPORT void SkyLogin_SetLogFunction(SkyLogin pPInst, int (__cdecl *pfLog)(void *stream, const char *format, ...), void *pLogStream) { Skype_Inst *pInst = (Skype_Inst*)pPInst; pInst->pfLog = pfLog; pInst->pLogStream = pLogStream; } EXPORT int SkyLogin_LoadCredentials(SkyLogin pPInst, char *User) { Skype_Inst *pInst = (Skype_Inst*)pPInst; Memory_U creds = Credentials_Load(User); int ret = 0; if (creds.Memory) { // Credentials were found and loaded, now let's parse them. SResponse LoginDatas; if (Credentials_Read(pInst, creds, &LoginDatas) == 0) { // Credentials were successfully read :) // Now verify if they are still valid uint Idx; time_t t; for (Idx = 0, ret = 1; ret && Idx < LoginDatas.NbObj; Idx++) { switch (LoginDatas.Objs[Idx].Id) { case OBJ_ID_LDUSER: // Credentials for wrong user? ret = !strcasecmp((char*)LoginDatas.Objs[Idx].Value.Memory.Memory, User); if (pInst->LoginD.User) free(pInst->LoginD.User); pInst->LoginD.User = strdup((char*)LoginDatas.Objs[Idx].Value.Memory.Memory); break; case OBJ_ID_LDEXPIRY: // Credentials expired? ret = (int)LoginDatas.Objs[Idx].Value.Nbr * 60 > time(&t)-60; break; } } FreeResponse(&LoginDatas); } free(creds.Memory); } return ret; } EXPORT int SkyLogin_PerformLogin(SkyLogin pPInst, char *User, char *Pass) { int ret; Skype_Inst *pInst = (Skype_Inst*)pPInst; if ((ret = PerformLogin(pInst, User, Pass)) > 0) { // On successful login, save login datas Memory_U creds = Credentials_Write(pInst); if (creds.Memory) { Credentials_Save(creds, User); free (creds.Memory); } if (pInst->LoginD.User) free(pInst->LoginD.User); pInst->LoginD.User = strdup(User); } return ret; } EXPORT int SkyLogin_PerformLoginOAuth(SkyLogin pPInst, const char *OAuth) { int ret; Skype_Inst *pInst = (Skype_Inst*)pPInst; if ((ret = PerformLogin(pInst, OAuth, NULL)) > 0) { // On successful login, save login datas Memory_U creds = Credentials_Write(pInst); if (creds.Memory) { SResponse LoginDatas; // We don't know user name, so read it from Credentials if (Credentials_Parse(pInst, pInst->LoginD.SignedCredentials, &LoginDatas) == 0) { uint Idx; for (Idx = 0; Idx < LoginDatas.NbObj; Idx++) { if (LoginDatas.Objs[Idx].Id == OBJ_ID_LDUSER) { Credentials_Save(creds, (char*)LoginDatas.Objs[Idx].Value.Memory.Memory); if (pInst->LoginD.User) free(pInst->LoginD.User); pInst->LoginD.User = (uchar*)strdup((char*)LoginDatas.Objs[Idx].Value.Memory.Memory); break; } } FreeResponse(&LoginDatas); } free (creds.Memory); } } return ret; } EXPORT int SkyLogin_CreateUICString(SkyLogin pInst, const char *pszNonce, char *pszOutUIC) { return CreateUICString((Skype_Inst*)pInst, pszNonce, "WS-SecureConversationSESSION KEY TOKEN", pszOutUIC); } EXPORT int SkyLogin_GetCredentialsUIC(SkyLogin pInst, char *pszOutUIC) { return GetCredentialsUIC((Skype_Inst*)pInst, pszOutUIC); } EXPORT char *SkyLogin_GetUser(SkyLogin pInst) { return (char*)((Skype_Inst*)pInst)->LoginD.User; }