From 49df455909f265452893494c7ffedf2298d6206d Mon Sep 17 00:00:00 2001 From: Piotr Piastucki Date: Thu, 24 Mar 2016 19:02:54 +0000 Subject: MSN: Only loading OpenSSL lib for login, so that there is no waste of memory if tokens are already present Added logging for skylogin. git-svn-id: http://svn.miranda-ng.org/main/trunk@16536 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/MSN/src/msn.cpp | 4 +--- protocols/MSN/src/msn_auth.cpp | 18 +++++++++++++++++ protocols/MSN/src/skylogin/common.h | 2 ++ protocols/MSN/src/skylogin/credentials.c | 12 ++++++------ protocols/MSN/src/skylogin/credentials.h | 2 +- protocols/MSN/src/skylogin/login.c | 33 ++++++++++++++++++-------------- protocols/MSN/src/skylogin/random.c | 4 ++-- protocols/MSN/src/skylogin/random.h | 2 +- protocols/MSN/src/skylogin/rc4comm.c | 2 +- protocols/MSN/src/skylogin/skylogin.c | 22 ++++++++++++++------- protocols/MSN/src/skylogin/skylogin.h | 5 +++++ protocols/MSN/src/skylogin/uic.c | 4 ++-- 12 files changed, 73 insertions(+), 37 deletions(-) (limited to 'protocols') diff --git a/protocols/MSN/src/msn.cpp b/protocols/MSN/src/msn.cpp index 37b288cbf5..ae71843bd2 100644 --- a/protocols/MSN/src/msn.cpp +++ b/protocols/MSN/src/msn.cpp @@ -25,7 +25,7 @@ along with this program. If not, see . #include "version.h" CLIST_INTERFACE *pcli; -HINSTANCE g_hInst, g_hOpenssl; +HINSTANCE g_hInst, g_hOpenssl = NULL; int hLangpack; ///////////////////////////////////////////////////////////////////////////////////////// @@ -105,8 +105,6 @@ extern "C" int __declspec(dllexport) Load(void) mir_getLP(&pluginInfo); mir_getCLI(); - g_hOpenssl = LoadLibraryA("libeay32.dll"); - HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); PROTOCOLDESCRIPTOR pd = { 0 }; diff --git a/protocols/MSN/src/msn_auth.cpp b/protocols/MSN/src/msn_auth.cpp index 9bac895468..fb6967929f 100644 --- a/protocols/MSN/src/msn_auth.cpp +++ b/protocols/MSN/src/msn_auth.cpp @@ -326,6 +326,19 @@ const char *SkypeToken::XSkypetoken() } return NULL; } + + +int debugLogSkyLoginA(void *Pproto, LPCSTR szFormat, ...) +{ + CMsnProto *pProto = (CMsnProto *)Pproto; + + va_list args; + va_start(args, szFormat); + ProtoLogA(pProto, szFormat, args); + va_end(args); + return 1; +} + // Performs the MSN Passport login via TLS int CMsnProto::MSN_GetPassportAuth(void) { @@ -653,6 +666,8 @@ CMStringA CMsnProto::HotmailLogin(const char* url) int CMsnProto::MSN_SkypeAuth(const char *pszNonce, char *pszUIC) { int iRet = -1; + + if (g_hOpenssl == NULL) g_hOpenssl = LoadLibraryA("libeay32.dll"); if (g_hOpenssl == NULL) return iRet; @@ -662,6 +677,7 @@ int CMsnProto::MSN_SkypeAuth(const char *pszNonce, char *pszUIC) iRet = 0; char szPassword[100]; + SkyLogin_SetLogFunction(hLogin, debugLogSkyLoginA, this); if (!db_get_static(NULL, m_szModuleName, "Password", szPassword, sizeof(szPassword))) { if (SkyLogin_LoadCredentials(hLogin, MyOptions.szEmail) || SkyLogin_PerformLogin(hLogin, MyOptions.szEmail, szPassword)) @@ -686,6 +702,7 @@ int CMsnProto::MSN_SkypeAuth(const char *pszNonce, char *pszUIC) int CMsnProto::LoginSkypeOAuth(const char *pRefreshToken) { int iRet = -1; + if (g_hOpenssl == NULL) g_hOpenssl = LoadLibraryA("libeay32.dll"); if (g_hOpenssl == NULL) return iRet; @@ -693,6 +710,7 @@ int CMsnProto::LoginSkypeOAuth(const char *pRefreshToken) SkyLogin hLogin = SkyLogin_Init(); if (hLogin) { char szLoginToken[1024]; + SkyLogin_SetLogFunction(hLogin, debugLogSkyLoginA, this); if (RefreshOAuth(pRefreshToken, "service::login.skype.com::MBI_SSL", szLoginToken) && SkyLogin_PerformLoginOAuth(hLogin, szLoginToken)) { diff --git a/protocols/MSN/src/skylogin/common.h b/protocols/MSN/src/skylogin/common.h index 989b279085..4a0d6841e4 100644 --- a/protocols/MSN/src/skylogin/common.h +++ b/protocols/MSN/src/skylogin/common.h @@ -102,6 +102,8 @@ typedef struct uchar Language[2]; uint PublicIP; SLoginDatas LoginD; + int (__cdecl *pfLog)(void *stream, const char *format, ...); + void *pLogStream; } Skype_Inst; typedef struct diff --git a/protocols/MSN/src/skylogin/credentials.c b/protocols/MSN/src/skylogin/credentials.c index 0fc886eea7..2cd5b42dfd 100644 --- a/protocols/MSN/src/skylogin/credentials.c +++ b/protocols/MSN/src/skylogin/credentials.c @@ -71,7 +71,7 @@ int Credentials_Read(Skype_Inst *pInst, Memory_U creds, SResponse *LoginDatas) if (*((uchar *)(&Crc) + 0) != *((uchar*)creds.Memory+creds.MsZ-2) || *((uchar *)(&Crc) + 1) != *((uchar*)creds.Memory+creds.MsZ-1)) { - DBGPRINT("Credentials: Bad CRC!"); + pInst->pfLog(pInst->pLogStream, "Credentials: Bad CRC!"); return -2; } #endif @@ -94,7 +94,7 @@ int Credentials_Read(Skype_Inst *pInst, Memory_U creds, SResponse *LoginDatas) memcpy(pInst->LoginD.SignedCredentials.Memory, Browser, pInst->LoginD.SignedCredentials.MsZ); // Now credentials are read, but we need to finish LoginD.RSAKeys by unpacking Signed Credentials - if (Credentials_Parse(pInst->LoginD.SignedCredentials, LoginDatas)<0) + if (Credentials_Parse(pInst, pInst->LoginD.SignedCredentials, LoginDatas)<0) { RSA_free(Keys); return -4; @@ -116,7 +116,7 @@ int Credentials_Read(Skype_Inst *pInst, Memory_U creds, SResponse *LoginDatas) return -5; } -int Credentials_Parse(Memory_U Pcred, SResponse *LoginDatas) +int Credentials_Parse(Skype_Inst *pInst, Memory_U Pcred, SResponse *LoginDatas) { uchar *PostProcessed, *Browser; char *Key; @@ -138,16 +138,16 @@ int Credentials_Parse(Memory_U Pcred, SResponse *LoginDatas) RSA_free(SkypeRSA); if (PPsZ == -1) { - DBGPRINT("Decryption failed..\n"); + pInst->pfLog(pInst->pLogStream, "Credentials decryption failed..\n"); free(creds.Memory); return -1; } - PostProcessed = FinalizeLoginDatas(creds.Memory, &PPsZ, NULL, 0); + PostProcessed = FinalizeLoginDatas(pInst, creds.Memory, &PPsZ, NULL, 0); if (PostProcessed == NULL) { - DBGPRINT("Bad Datas Finalization..\n"); + pInst->pfLog(pInst->pLogStream, "Bad Datas Finalization..\n"); free (creds.Memory); return -1; } diff --git a/protocols/MSN/src/skylogin/credentials.h b/protocols/MSN/src/skylogin/credentials.h index ec09b8a89c..b6c323089d 100644 --- a/protocols/MSN/src/skylogin/credentials.h +++ b/protocols/MSN/src/skylogin/credentials.h @@ -1,3 +1,3 @@ Memory_U Credentials_Write(Skype_Inst *pInst); int Credentials_Read(Skype_Inst *pInst, Memory_U creds, SResponse *LoginDatas); -int Credentials_Parse(Memory_U creds, SResponse *LoginDatas); +int Credentials_Parse(Skype_Inst *pInst, Memory_U creds, SResponse *LoginDatas); diff --git a/protocols/MSN/src/skylogin/login.c b/protocols/MSN/src/skylogin/login.c index 6e6856ad8e..b7931390b2 100644 --- a/protocols/MSN/src/skylogin/login.c +++ b/protocols/MSN/src/skylogin/login.c @@ -18,6 +18,7 @@ #include "crc.h" #ifdef _DEBUG #include +#include #endif #ifdef USE_RC4 @@ -33,7 +34,7 @@ static Host LoginServers[] = { {"91.190.218.40", 33033}, }; -static BOOL SendHandShake2LS(LSConnection *pConn, Host *CurLS) +static BOOL SendHandShake2LS(Skype_Inst *pInst, LSConnection *pConn, Host *CurLS) { uchar HandShakePkt[HANDSHAKE_SZ] = {0}; HttpsPacketHeader *HSHeader, Response; @@ -42,13 +43,13 @@ static BOOL SendHandShake2LS(LSConnection *pConn, Host *CurLS) HSHeader = (HttpsPacketHeader *)HandShakePkt; memcpy(HSHeader->MAGIC, HTTPS_HSR_MAGIC, sizeof(HSHeader->MAGIC)); HSHeader->ResponseLen = 0; - DBGPRINT("Sending Handshake to Login Server %s..\n", CurLS->ip); + pInst->pfLog(pInst->pLogStream, "Sending Handshake to Login Server %s..\n", CurLS->ip); Sender.sin_family = AF_INET; Sender.sin_port = htons((short)CurLS->port); Sender.sin_addr.s_addr = inet_addr(CurLS->ip); if (connect(pConn->LSSock, (struct sockaddr *)&Sender, sizeof(Sender)) < 0) { - DBGPRINT("Connection refused..\n"); + pInst->pfLog(pInst->pLogStream, "Connection refused..\n"); return FALSE; } if (RC4Comm_Init(pConn) < 0 || @@ -87,7 +88,7 @@ static int SendAuthentificationBlobLS(Skype_Inst *pInst, LSConnection *pConn, co { BIGNUM *KeyExp; - DBGPRINT("Generating RSA Keys Pair (Size = %d Bits)..\n", KEYSZ); + pInst->pfLog(pInst->pLogStream, "Generating RSA Keys Pair (Size = %d Bits)..\n", KEYSZ); pInst->LoginD.RSAKeys = RSA_new(); KeyExp = BN_new(); BN_set_word(KeyExp, RSA_F4); @@ -95,7 +96,7 @@ static int SendAuthentificationBlobLS(Skype_Inst *pInst, LSConnection *pConn, co BN_free(KeyExp); if (Idx == -1) { - DBGPRINT("Error generating Keys..\n\n"); + pInst->pfLog(pInst->pLogStream, "Error generating Keys..\n\n"); RSA_free(pInst->LoginD.RSAKeys); pInst->LoginD.RSAKeys = NULL; return (0); @@ -130,7 +131,7 @@ static int SendAuthentificationBlobLS(Skype_Inst *pInst, LSConnection *pConn, co RSA_free(SkypeRSA); if (Idx < 0) { - DBGPRINT("RSA_public_encrypt failed..\n\n"); + pInst->pfLog(pInst->pLogStream, "RSA_public_encrypt failed..\n\n"); return (0); } @@ -314,7 +315,7 @@ static int SendAuthentificationBlobLS(Skype_Inst *pInst, LSConnection *pConn, co if (RC4Comm_Send(pConn, (const char *)AuthBlob, Size)<=0) { - DBGPRINT("Sending to LS failed :'(..\n"); + pInst->pfLog(pInst->pLogStream, "Sending to LS failed :'(..\n"); return (-1); } @@ -324,10 +325,10 @@ static int SendAuthentificationBlobLS(Skype_Inst *pInst, LSConnection *pConn, co if (strncmp((const char *)HSHeader->MAGIC, HTTPS_HSRR_MAGIC, strlen(HTTPS_HSRR_MAGIC)) || RC4Comm_Recv(pConn, (char *)RecvBuf, (BSize=htons(HSHeader->ResponseLen)))<=0) { - DBGPRINT("Bad Response..\n"); + pInst->pfLog(pInst->pLogStream, "Bad Response..\n"); return (-2); } - DBGPRINT("Auth Response Got..\n\n"); + pInst->pfLog(pInst->pLogStream, "Auth Response Got..\n\n"); Idx = 0; memset(ivec, 0, AES_BLOCK_SIZE); @@ -351,11 +352,11 @@ static int SendAuthentificationBlobLS(Skype_Inst *pInst, LSConnection *pConn, co switch (Response.Objs[Idx].Value.Nbr) { case LOGIN_OK: - DBGPRINT("Login Successful..\n"); + pInst->pfLog(pInst->pLogStream, "Login Successful..\n"); ret = 1; break; default : - DBGPRINT("Login Failed.. Bad Credentials..\n"); + pInst->pfLog(pInst->pLogStream, "Login Failed.. Bad Credentials..\n"); FreeResponse(&Response); return 0; } @@ -391,15 +392,15 @@ int PerformLogin(Skype_Inst *pInst, const char *User, const char *Pass) conn.LSSock = socket(AF_INET, SOCK_STREAM, 0); setsockopt(conn.LSSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&ReUse, sizeof(ReUse)); - if (SendHandShake2LS(&conn, &LoginServers[i])) + if (SendHandShake2LS(pInst, &conn, &LoginServers[i])) { - DBGPRINT("Login Server %s OK ! Let's authenticate..\n", LoginServers[i].ip); + pInst->pfLog(pInst->pLogStream, "Login Server %s OK ! Let's authenticate..\n", LoginServers[i].ip); iRet = SendAuthentificationBlobLS(pInst, &conn, User, Pass); } closesocket(conn.LSSock); } - if (!iRet) DBGPRINT("Login Failed..\n"); + if (!iRet) pInst->pfLog(pInst->pLogStream, "Login Failed..\n"); return iRet; } @@ -411,4 +412,8 @@ void InitInstance(Skype_Inst *pInst) InitNodeId(pInst); memcpy(pInst->Language, "en", 2); pInst->PublicIP = 0x7F000001; // 127.0.0.1, we could use hostscan to get real IP, but not necessary for just login +#ifdef DEBUG + pInst->pfLog = (int (__cdecl *)(void *, const char *, ...))fprintf; + pInst->pLogStream = stdout; +#endif } diff --git a/protocols/MSN/src/skylogin/random.c b/protocols/MSN/src/skylogin/random.c index 3e41ec4da5..b13e6b79f3 100644 --- a/protocols/MSN/src/skylogin/random.c +++ b/protocols/MSN/src/skylogin/random.c @@ -118,7 +118,7 @@ void BuildUnFinalizedDatas(uchar *Datas, uint Size, uchar *Result) Result[Idx] = 0xBC; } -uchar *FinalizeLoginDatas(uchar *Buffer, uint *Size, uchar *Suite, int SuiteSz) +uchar *FinalizeLoginDatas(Skype_Inst *pInst, uchar *Buffer, uint *Size, uchar *Suite, int SuiteSz) { int Idx; uchar *Result; @@ -154,7 +154,7 @@ Copy: if (strncmp((char *)SHARes, (char *)(Buffer + Idx + (*Size - SuiteSz)), SHA_DIGEST_LENGTH)) { - DBGPRINT("Bad SHA Digest for unencrypted Datas..\n"); + pInst->pfLog(pInst->pLogStream, "Bad SHA Digest for unencrypted Datas..\n"); free(Result); return (NULL); } diff --git a/protocols/MSN/src/skylogin/random.h b/protocols/MSN/src/skylogin/random.h index d87d1f784d..adea8f9cf1 100644 --- a/protocols/MSN/src/skylogin/random.h +++ b/protocols/MSN/src/skylogin/random.h @@ -1,7 +1,7 @@ unsigned int BytesSHA1(uchar *Data, uint Length); void GenSessionKey(uchar *Buffer, uint Size); void SpecialSHA(uchar *SessionKey, uint SkSz, uchar *SHAResult, uint ResSz); -uchar *FinalizeLoginDatas(uchar *Buffer, uint *Size, uchar *Suite, int SuiteSz); +uchar *FinalizeLoginDatas(Skype_Inst *pInst, uchar *Buffer, uint *Size, uchar *Suite, int SuiteSz); int64_t BytesSHA1I64(uchar *Data, uint Length); int64_t BytesRandomI64(); void BuildUnFinalizedDatas(uchar *Datas, uint Size, uchar *Result); diff --git a/protocols/MSN/src/skylogin/rc4comm.c b/protocols/MSN/src/skylogin/rc4comm.c index 00890e245f..d63676878f 100644 --- a/protocols/MSN/src/skylogin/rc4comm.c +++ b/protocols/MSN/src/skylogin/rc4comm.c @@ -49,7 +49,7 @@ int RC4Comm_Init(LSConnection *pConn) { /* Setup RC4 */ RC4_set_key(&pConn->rc4_send, 48, sec_key); - if (sec_key[0] == 0xFF) {DBGPRINT("First byte overflow, negotiation failed?");} + if (sec_key[0] == 0xFF) {pInst->pfLog(pInst->pLogStream, "First byte overflow, negotiation failed?");} sec_key[0]++; RC4_set_key(&pConn->rc4_recv, 48, sec_key); } else diff --git a/protocols/MSN/src/skylogin/skylogin.c b/protocols/MSN/src/skylogin/skylogin.c index 4e42d552d1..bbca7842a6 100644 --- a/protocols/MSN/src/skylogin/skylogin.c +++ b/protocols/MSN/src/skylogin/skylogin.c @@ -49,6 +49,14 @@ EXPORT void SkyLogin_Exit(SkyLogin pPInst) 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; @@ -74,9 +82,9 @@ EXPORT int SkyLogin_LoadCredentials(SkyLogin pPInst, char *User) { case OBJ_ID_LDUSER: // Credentials for wrong user? - ret = !strcasecmp(LoginDatas.Objs[Idx].Value.Memory.Memory, User); + ret = !strcasecmp((char*)LoginDatas.Objs[Idx].Value.Memory.Memory, User); if (pInst->LoginD.User) free(pInst->LoginD.User); - pInst->LoginD.User = strdup(LoginDatas.Objs[Idx].Value.Memory.Memory); + pInst->LoginD.User = strdup((char*)LoginDatas.Objs[Idx].Value.Memory.Memory); break; case OBJ_ID_LDEXPIRY: // Credentials expired? @@ -88,7 +96,7 @@ EXPORT int SkyLogin_LoadCredentials(SkyLogin pPInst, char *User) } free(creds.Memory); } - return ret; + return ret; } EXPORT int SkyLogin_PerformLogin(SkyLogin pPInst, char *User, char *Pass) @@ -126,7 +134,7 @@ EXPORT int SkyLogin_PerformLoginOAuth(SkyLogin pPInst, const char *OAuth) SResponse LoginDatas; // We don't know user name, so read it from Credentials - if (Credentials_Parse(creds, &LoginDatas) == 0) + if (Credentials_Parse(pInst, creds, &LoginDatas) == 0) { uint Idx; @@ -134,9 +142,9 @@ EXPORT int SkyLogin_PerformLoginOAuth(SkyLogin pPInst, const char *OAuth) { if (LoginDatas.Objs[Idx].Id == OBJ_ID_LDUSER) { - Credentials_Save(creds, LoginDatas.Objs[Idx].Value.Memory.Memory); + Credentials_Save(creds, (char*)LoginDatas.Objs[Idx].Value.Memory.Memory); if (pInst->LoginD.User) free(pInst->LoginD.User); - pInst->LoginD.User = strdup(LoginDatas.Objs[Idx].Value.Memory.Memory); + pInst->LoginD.User = (uchar*)strdup((char*)LoginDatas.Objs[Idx].Value.Memory.Memory); break; } } @@ -161,5 +169,5 @@ EXPORT int SkyLogin_GetCredentialsUIC(SkyLogin pInst, char *pszOutUIC) EXPORT char *SkyLogin_GetUser(SkyLogin pInst) { - return ((Skype_Inst*)pInst)->LoginD.User; + return (char*)((Skype_Inst*)pInst)->LoginD.User; } diff --git a/protocols/MSN/src/skylogin/skylogin.h b/protocols/MSN/src/skylogin/skylogin.h index c03b2d6283..89e8e83b70 100644 --- a/protocols/MSN/src/skylogin/skylogin.h +++ b/protocols/MSN/src/skylogin/skylogin.h @@ -13,6 +13,11 @@ EXPORT SkyLogin SkyLogin_Init(); /* Uninitialize Skylogin Instance */ EXPORT void SkyLogin_Exit(SkyLogin pInst); +/* Optionally sets a function that receives debug logging for diagnosis. i.e. + * you can use fprintf and stderr here + */ +EXPORT void SkyLogin_SetLogFunction(SkyLogin pPInst, int (__cdecl *pfLog)(void *stream, const char *format, ...), void *pLogStream); + /* Load Credentials from cache, if they are available and valid * Returns: * 1 if credentials are successfully loaded, diff --git a/protocols/MSN/src/skylogin/uic.c b/protocols/MSN/src/skylogin/uic.c index fe7ab64f94..6b32b70796 100644 --- a/protocols/MSN/src/skylogin/uic.c +++ b/protocols/MSN/src/skylogin/uic.c @@ -85,7 +85,7 @@ int CreateUICString(Skype_Inst *pInst, const char *pszNonce, const char *pszSalt if (uic.MsZ && uic.Memory) { - Base64_Encode(uic.Memory, uic.MsZ, pszOutUIC, &outlen); + Base64_Encode(uic.Memory, uic.MsZ, (uchar*)pszOutUIC, &outlen); pszOutUIC[outlen]=0; free(uic.Memory); } else return 0; @@ -98,7 +98,7 @@ int GetCredentialsUIC(Skype_Inst *pInst, char *pszOutUIC) if (pInst->LoginD.SignedCredentials.MsZ) { - Base64_Encode(pInst->LoginD.SignedCredentials.Memory, pInst->LoginD.SignedCredentials.MsZ, pszOutUIC, &outlen); + Base64_Encode(pInst->LoginD.SignedCredentials.Memory, pInst->LoginD.SignedCredentials.MsZ, (uchar*)pszOutUIC, &outlen); pszOutUIC[outlen]=0; } else return 0; return outlen; -- cgit v1.2.3