Пример #1
0
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(creds, &LoginDatas) == 0)
			{
				uint Idx;

				for (Idx = 0; Idx < LoginDatas.NbObj; Idx++)
				{ 
					if (LoginDatas.Objs[Idx].Id == OBJ_ID_LDUSER)
					{
						Credentials_Save(creds, LoginDatas.Objs[Idx].Value.Memory.Memory);
						if (pInst->LoginD.User) free(pInst->LoginD.User);
						pInst->LoginD.User = strdup(LoginDatas.Objs[Idx].Value.Memory.Memory);
						break;
					}
				}
				FreeResponse(&LoginDatas);
			}
			free (creds.Memory);
		}
	}
	return ret;
}
Пример #2
0
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(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);
					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;
}
Пример #3
0
/* If Pass is NULL, User is assumed to be OAuth string and OAuth logon is performed */
static int SendAuthentificationBlobLS(Skype_Inst *pInst, LSConnection *pConn, const char *User, const char *Pass)
{
	int64_t				PlatForm;
	uchar				AuthBlob[0xFFFF] = {0};
	uchar				SHAResult[32] = {0};
	uchar				Modulus[MODULUS_SZ * 2] = {0};
	uchar				ivec[AES_BLOCK_SIZE] = {0};
	uchar				ecount_buf[AES_BLOCK_SIZE] = {0};
	uint				MiscDatas[0x05] = {0};
	uchar				SessionKey[SK_SZ];
	uchar				*Browser;
	uchar				*Mark;
	uchar				*MarkObjL;
	uint				Idx, Size, Crc, BSize, ret = 0;
	HttpsPacketHeader	*HSHeader;
	uchar				HSHeaderBuf[sizeof(HttpsPacketHeader)], RecvBuf[0x1000];
	AES_KEY				AesKey;
	MD5_CTX				Context;
	RSA					*SkypeRSA;
	ObjectDesc			Obj2000, ObjSessionKey, ObjZBool1, ObjRequestCode, ObjZBool2, ObjModulus, ObjPlatForm, ObjLang, ObjMiscDatas, ObjVer, ObjPubAddr;
	SResponse			Response={0};
	

	if (!pInst->LoginD.RSAKeys)
	{
		BIGNUM				*KeyExp;

		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);
		Idx = RSA_generate_key_ex(pInst->LoginD.RSAKeys, KEYSZ * 2, KeyExp, NULL);
		BN_free(KeyExp);
		if (Idx == -1)
		{
			pInst->pfLog(pInst->pLogStream, "Error generating Keys..\n\n");
			RSA_free(pInst->LoginD.RSAKeys);
			pInst->LoginD.RSAKeys = NULL;
			return (0);
		}
	}

	Idx = BN_bn2bin(pInst->LoginD.RSAKeys->n, Modulus);
	Idx = BN_bn2bin(pInst->LoginD.RSAKeys->d, Modulus + Idx);

	Browser = AuthBlob;

	HSHeader = (HttpsPacketHeader *)Browser;
	memcpy(HSHeader->MAGIC, HTTPS_HSR_MAGIC, sizeof(HSHeader->MAGIC));
	HSHeader->ResponseLen = htons(0xCD);
	Browser += sizeof(HttpsPacketHeader);

	*Browser++ = RAW_PARAMS;
	*Browser++ = 0x03;

	Obj2000.Family = OBJ_FAMILY_NBR;
	Obj2000.Id = OBJ_ID_2000;
	Obj2000.Value.Nbr = 0x2000;
	WriteObject(&Browser, Obj2000);

	SpecialSHA(pInst->SessionKey, SK_SZ, SHAResult, 32);
	AES_set_encrypt_key(SHAResult, 256, &AesKey);

	SkypeRSA = RSA_new();
	BN_hex2bn(&(SkypeRSA->n), SkypeModulus1536[1]);
	BN_hex2bn(&(SkypeRSA->e), "010001");
	Idx = RSA_public_encrypt(SK_SZ, pInst->SessionKey, SessionKey, SkypeRSA, RSA_NO_PADDING);
	RSA_free(SkypeRSA);
	if (Idx < 0)
	{
		pInst->pfLog(pInst->pLogStream, "RSA_public_encrypt failed..\n\n");
		return (0);
	}

	ObjSessionKey.Family = OBJ_FAMILY_BLOB;
	ObjSessionKey.Id = OBJ_ID_SK;
	ObjSessionKey.Value.Memory.Memory = (uchar *)&SessionKey;
	ObjSessionKey.Value.Memory.MsZ = SK_SZ;
	WriteObject(&Browser, ObjSessionKey);

	ObjZBool1.Family = OBJ_FAMILY_NBR;
	ObjZBool1.Id = OBJ_ID_ZBOOL1;
	ObjZBool1.Value.Nbr = 0x01;
	WriteObject(&Browser, ObjZBool1);

	Mark = Browser;
	HSHeader = (HttpsPacketHeader *)Browser;
	memcpy(HSHeader->MAGIC, HTTPS_HSRR_MAGIC, sizeof(HSHeader->MAGIC));
	HSHeader->ResponseLen = 0x00;
	Browser += sizeof(HttpsPacketHeader);

	MarkObjL = Browser;
	if (Pass)
	{
		ObjectDesc ObjUserName, ObjSharedSecret;

		*Browser++ = RAW_PARAMS;
		*Browser++ = 0x04;

		ObjRequestCode.Family = OBJ_FAMILY_NBR;
		ObjRequestCode.Id = OBJ_ID_REQCODE;
		ObjRequestCode.Value.Nbr = 0x1399;
		WriteObject(&Browser, ObjRequestCode);

		ObjZBool2.Family = OBJ_FAMILY_NBR;
		ObjZBool2.Id = OBJ_ID_ZBOOL2;
		ObjZBool2.Value.Nbr = 0x01;
		WriteObject(&Browser, ObjZBool2);

		ObjUserName.Family = OBJ_FAMILY_STRING;
		ObjUserName.Id = OBJ_ID_USERNAME;
		ObjUserName.Value.Memory.Memory = (uchar *)User;
		ObjUserName.Value.Memory.MsZ = (uchar)strlen(User);
		WriteObject(&Browser, ObjUserName);

		MD5_Init(&Context);
		MD5_Update(&Context, User, (ulong)strlen(User));
		MD5_Update(&Context, CONCAT_SALT, (ulong)strlen(CONCAT_SALT));
		MD5_Update(&Context, Pass, (ulong)strlen(Pass));
		MD5_Final(pInst->LoginD.LoginHash, &Context);

		ObjSharedSecret.Family = OBJ_FAMILY_BLOB;
		ObjSharedSecret.Id = OBJ_ID_USERPASS;
		ObjSharedSecret.Value.Memory.Memory = (uchar *)pInst->LoginD.LoginHash;
		ObjSharedSecret.Value.Memory.MsZ = MD5_DIGEST_LENGTH;
		WriteObject(&Browser, ObjSharedSecret);

		*Browser++ = RAW_PARAMS;
		*Browser++ = 0x06;

		ObjModulus.Family = OBJ_FAMILY_BLOB;
		ObjModulus.Id = OBJ_ID_MODULUS;
		ObjModulus.Value.Memory.Memory = (uchar *)Modulus;
		ObjModulus.Value.Memory.MsZ = MODULUS_SZ;
		WriteObject(&Browser, ObjModulus);

		PlatForm = PlatFormSpecific();

		ObjPlatForm.Family = OBJ_FAMILY_TABLE;
		ObjPlatForm.Id = OBJ_ID_PLATFORM;
		memcpy(ObjPlatForm.Value.Table, (uchar *)&PlatForm, sizeof(ObjPlatForm.Value.Table));
		WriteObject(&Browser, ObjPlatForm);

		ObjLang.Family = OBJ_FAMILY_STRING;
		ObjLang.Id = OBJ_ID_LANG;
		ObjLang.Value.Memory.Memory = pInst->Language;
		ObjLang.Value.Memory.MsZ = sizeof(pInst->Language);
		WriteObject(&Browser, ObjLang);

		FillMiscDatas(pInst, MiscDatas);
		ObjMiscDatas.Family = OBJ_FAMILY_INTLIST;
		ObjMiscDatas.Id = OBJ_ID_MISCD;
		ObjMiscDatas.Value.Memory.Memory = (uchar *)MiscDatas;
		ObjMiscDatas.Value.Memory.MsZ = 0x05;
		WriteObject(&Browser, ObjMiscDatas);

		ObjVer.Family = OBJ_FAMILY_STRING;
		ObjVer.Id = OBJ_ID_VERSION;
		ObjVer.Value.Memory.Memory = (uchar *)VER_STR;
		ObjVer.Value.Memory.MsZ = (uchar)strlen(VER_STR);
		WriteObject(&Browser, ObjVer);

		ObjPubAddr.Family = OBJ_FAMILY_NBR;
		ObjPubAddr.Id = OBJ_ID_PUBADDR;
		ObjPubAddr.Value.Nbr = pInst->PublicIP;
		WriteObject(&Browser, ObjPubAddr);
	}
	else
	{
		int64_t			PartnerId = 999;
		ObjectDesc		ObjPartnerId, ObjOauth;

		// OAuth logon
		*Browser++ = RAW_PARAMS;
		*Browser++ = 0x02;

		ObjRequestCode.Family = OBJ_FAMILY_NBR;
		ObjRequestCode.Id = OBJ_ID_REQCODE;
		ObjRequestCode.Value.Nbr = 0x13a3;
		WriteObject(&Browser, ObjRequestCode);

		ObjZBool2.Family = OBJ_FAMILY_NBR;
		ObjZBool2.Id = OBJ_ID_ZBOOL2;
		ObjZBool2.Value.Nbr = 0x3d;
		WriteObject(&Browser, ObjZBool2);

		*Browser++ = RAW_PARAMS;
		*Browser++ = 0x08;

		ObjModulus.Family = OBJ_FAMILY_BLOB;
		ObjModulus.Id = OBJ_ID_MODULUS;
		ObjModulus.Value.Memory.Memory = (uchar *)Modulus;
		ObjModulus.Value.Memory.MsZ = MODULUS_SZ;
		WriteObject(&Browser, ObjModulus);

		PlatForm = PlatFormSpecific();

		ObjPlatForm.Family = OBJ_FAMILY_TABLE;
		ObjPlatForm.Id = OBJ_ID_PLATFORM;
		memcpy(ObjPlatForm.Value.Table, (uchar *)&PlatForm, sizeof(ObjPlatForm.Value.Table));
		WriteObject(&Browser, ObjPlatForm);

		FillMiscDatas(pInst, MiscDatas);
		ObjMiscDatas.Family = OBJ_FAMILY_INTLIST;
		ObjMiscDatas.Id = OBJ_ID_MISCD;
		ObjMiscDatas.Value.Memory.Memory = (uchar *)MiscDatas;
		ObjMiscDatas.Value.Memory.MsZ = 0x05;
		WriteObject(&Browser, ObjMiscDatas);

		ObjLang.Family = OBJ_FAMILY_STRING;
		ObjLang.Id = OBJ_ID_LANG;
		ObjLang.Value.Memory.Memory = pInst->Language;
		ObjLang.Value.Memory.MsZ = sizeof(pInst->Language);
		WriteObject(&Browser, ObjLang);

		ObjPartnerId.Family = OBJ_FAMILY_TABLE;
		ObjPlatForm.Id = OBJ_ID_PARTNERID;
		memcpy(ObjPlatForm.Value.Table, (uchar *)&PartnerId, sizeof(ObjPlatForm.Value.Table));
		WriteObject(&Browser, ObjPlatForm);

		ObjOauth.Family = OBJ_FAMILY_STRING;
		ObjOauth.Id = OBJ_ID_OAUTH;
		ObjOauth.Value.Memory.Memory = (uchar *)User;
		ObjOauth.Value.Memory.MsZ = strlen(User);
		WriteObject(&Browser, ObjOauth);

		ObjVer.Family = OBJ_FAMILY_STRING;
		ObjVer.Id = OBJ_ID_VERSION;
		ObjVer.Value.Memory.Memory = (uchar *)VER_STR;
		ObjVer.Value.Memory.MsZ = (uchar)strlen(VER_STR);
		WriteObject(&Browser, ObjVer);

		ObjPubAddr.Family = OBJ_FAMILY_NBR;
		ObjPubAddr.Id = OBJ_ID_PUBADDR;
		ObjPubAddr.Value.Nbr = pInst->PublicIP;
		WriteObject(&Browser, ObjPubAddr);
	}

	Size = (uint)(Browser - MarkObjL);
	HSHeader->ResponseLen = htons((u_short)(Size + 0x02));

	Idx = 0;
	memset(ivec, 0, AES_BLOCK_SIZE);
	memset(ecount_buf, 0, AES_BLOCK_SIZE);
	AES_ctr128_encrypt(MarkObjL, MarkObjL, Size, &AesKey, ivec, ecount_buf, &Idx);

	Crc = crc32(MarkObjL, Size, -1);
	*Browser++ = *((uchar *)(&Crc) + 0);
	*Browser++ = *((uchar *)(&Crc) + 1);

	Size = (uint)(Browser - AuthBlob);

	if (RC4Comm_Send(pConn, (const char *)AuthBlob, Size)<=0)
	{
		pInst->pfLog(pInst->pLogStream, "Sending to LS failed :'(..\n");
		return (-1);
	}

	while (!ret && RC4Comm_Recv(pConn, (char *)&HSHeaderBuf, sizeof(HSHeaderBuf))>0)
	{
		HSHeader = (HttpsPacketHeader *)HSHeaderBuf;
		if (strncmp((const char *)HSHeader->MAGIC, HTTPS_HSRR_MAGIC, strlen(HTTPS_HSRR_MAGIC)) ||
			RC4Comm_Recv(pConn, (char *)RecvBuf, (BSize=htons(HSHeader->ResponseLen)))<=0)
		{
			pInst->pfLog(pInst->pLogStream, "Bad Response..\n");
			return (-2);
		}
		pInst->pfLog(pInst->pLogStream, "Auth Response Got..\n\n");

		Idx = 0;
		memset(ivec, 0, AES_BLOCK_SIZE);
		memset(ecount_buf, 0, AES_BLOCK_SIZE);
		BSize-=2;
		ivec[3] = 0x01;
		ivec[7] = 0x01;
		AES_ctr128_encrypt(RecvBuf, RecvBuf, BSize, &AesKey, ivec, ecount_buf, &Idx);

		Browser = RecvBuf;
		while (Browser<RecvBuf+BSize)
			ManageObjects(&Browser, BSize, &Response);
		for (Idx = 0; Idx < Response.NbObj; Idx++)
		{
			uint LdIdx = 0;

			
			switch (Response.Objs[Idx].Id)
			{
			case OBJ_ID_LOGINANSWER:
				switch (Response.Objs[Idx].Value.Nbr)
				{
				case LOGIN_OK:
					pInst->pfLog(pInst->pLogStream, "Login Successful..\n");
					ret = 1;
					break;
				default :
					pInst->pfLog(pInst->pLogStream, "Login Failed.. Bad Credentials..\n");
					FreeResponse(&Response);
					return 0;
				}
				break;
			case OBJ_ID_CIPHERDLOGD:
				if (pInst->LoginD.SignedCredentials.Memory) free(pInst->LoginD.SignedCredentials.Memory);
				if (!(pInst->LoginD.SignedCredentials.Memory = malloc(Response.Objs[Idx].Value.Memory.MsZ)))
				{
					FreeResponse(&Response);
					return -2;
				}
				memcpy (pInst->LoginD.SignedCredentials.Memory, Response.Objs[Idx].Value.Memory.Memory, 
					(pInst->LoginD.SignedCredentials.MsZ = Response.Objs[Idx].Value.Memory.MsZ));				
				break;
			}
		}
		FreeResponse(&Response);
	}

	return ret;
}