Exemplo n.º 1
0
void WardenBase::RequestModule()
{
    sLog->outDebug(LOG_FILTER_UNITS, "Request module");

    // Create packet structure
    WardenModuleUse Request;
    Request.Command = WARDEN_SMSG_MODULE_USE;

    memcpy(Request.Module_Id, Module->ID, 16);
    memcpy(Request.Module_Key, Module->Key, 16);
    Request.Size = Module->CompressedSize;

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenModuleUse));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenModuleUse));
    pkt.append((uint8*)&Request, sizeof(WardenModuleUse));
    Client->SendPacket(&pkt);
}
Exemplo n.º 2
0
void WardenWin::InitializeModule()
{
    sLog->outDebug(LOG_FILTER_WARDEN, "Initialize module");

    // Create packet structure
    WardenInitModuleRequest Request;
    Request.Command1 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size1 = 20;
    Request.Unk1 = 1;
    Request.Unk2 = 0;
    Request.Type = 1;
    Request.String_library1 = 0;
    Request.Function1[0] = 0x00024F80;                      // 0x00400000 + 0x00024F80 SFileOpenFile
    Request.Function1[1] = 0x000218C0;                      // 0x00400000 + 0x000218C0 SFileGetFileSize
    Request.Function1[2] = 0x00022530;                      // 0x00400000 + 0x00022530 SFileReadFile
    Request.Function1[3] = 0x00022910;                      // 0x00400000 + 0x00022910 SFileCloseFile
    Request.CheckSumm1 = BuildChecksum(&Request.Unk1, 20);

    Request.Command2 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size2 = 8;
    Request.Unk3 = 4;
    Request.Unk4 = 0;
    Request.String_library2 = 0;
    Request.Function2 = 0x00419D40;                         // 0x00400000 + 0x00419D40 FrameScript::GetText
    Request.Function2_set = 1;
    Request.CheckSumm2 = BuildChecksum(&Request.Unk2, 8);

    Request.Command3 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size3 = 8;
    Request.Unk5 = 1;
    Request.Unk6 = 1;
    Request.String_library3 = 0;
    Request.Function3 = 0x0046AE20;                         // 0x00400000 + 0x0046AE20 PerformanceCounter
    Request.Function3_set = 1;
    Request.CheckSumm3 = BuildChecksum(&Request.Unk5, 8);

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenInitModuleRequest));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenInitModuleRequest));
    pkt.append((uint8*)&Request, sizeof(WardenInitModuleRequest));
    _session->SendPacket(&pkt);
}
Exemplo n.º 3
0
void Warden::RequestModule()
{
    sLog->outDebug(LOG_FILTER_WARDEN, "Request module");

    // Create packet structure
    WardenModuleUse request;
    request.Command = WARDEN_SMSG_MODULE_USE;

    memcpy(request.ModuleId, _module->Id, 16);
    memcpy(request.ModuleKey, _module->Key, 16);
    request.Size = _module->CompressedSize;

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&request, sizeof(WardenModuleUse));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenModuleUse));
    pkt.append((uint8*)&request, sizeof(WardenModuleUse));
    _session->SendPacket(&pkt);
}
Exemplo n.º 4
0
// 发送重新处理循环码的数据
bool PasServer::SendCrcData(socket_t *sock, const char* data, int len)
{
	// 处理循环码
	char *buf = new char[len + 1];
	memset(buf, 0, len + 1);
	memcpy(buf, data, len);

	// 处理加密数据
	EncryptData((unsigned char*) buf, len, true);

	// 计算循环码处理,这里需要先加密后处理循环码校验
	ResetCrcCode(buf, len);

	// 添加5B的处理
	bool bSend = Send5BCodeData(sock, buf, len);

	delete[] buf;

	return bSend;
}
Exemplo n.º 5
0
void WardenMac::RequestData()
{
    sLog.outDebug("Request data");

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    std::string str = "Test string!";

    buff << uint8(str.size());
    buff.append(str.c_str(), str.size());

    buff.hexlike();

    // Encrypt with warden RC4 key.
    EncryptData(const_cast<uint8*>(buff.contents()), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    Client->SendPacket(&pkt);

    m_WardenDataSent = true;
}
Exemplo n.º 6
0
void WardenMac::RequestData()
{
    sLog->outDebug(LOG_FILTER_WARDEN, "Request data");

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    std::string str = "Test string!";

    buff << uint8(str.size());
    buff.append(str.c_str(), str.size());

    buff.hexlike();

    // Encrypt with warden RC4 key.
    EncryptData(buff.contents(), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    _session->SendPacket(&pkt);

    _dataSent = true;
}
Exemplo n.º 7
0
bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId)
{
	if (!param) {
		return false;
	}

	std::string dirPath = GetSaveFilePath(param, saveId);

	if (!pspFileSystem.GetFileInfo(dirPath).exists)
		pspFileSystem.MkDir(dirPath);

	u8* cryptedData = 0;
	int cryptedSize = 0;
	u8 cryptedHash[0x10];
	memset(cryptedHash,0,0x10);
	// Encrypt save.
	if(param->dataBuf != 0 && g_Config.bEncryptSave)
	{
		cryptedSize = param->dataSize;
		if(cryptedSize == 0 || (SceSize)cryptedSize > param->dataBufSize)
			cryptedSize = param->dataBufSize; // fallback, should never use this
		u8* data_ = (u8*)Memory::GetPointer(param->dataBuf);

		int aligned_len = align16(cryptedSize);
		cryptedData = new u8[aligned_len + 0x10];
		memcpy(cryptedData, data_, cryptedSize);

		int decryptMode = 1;
		if(param->key[0] != 0)
		{
			decryptMode = (GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3);
		}

		if(EncryptData(decryptMode, cryptedData, &cryptedSize, &aligned_len, cryptedHash, ((param->key[0] != 0)?param->key:0)) == 0)
		{
		}
		else
		{
			ERROR_LOG(HLE,"Save encryption failed. This save won't work on real PSP");
			delete[] cryptedData;
			cryptedData = 0;
		}
	}

	// SAVE PARAM.SFO
	ParamSFOData sfoFile;
	std::string sfopath = dirPath+"/"+sfoName;
	PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath);
	if(sfoInfo.exists) // Read old sfo if exist
	{
		u8 *sfoData = new u8[(size_t)sfoInfo.size];
		size_t sfoSize = (size_t)sfoInfo.size;
		if(ReadPSPFile(sfopath,&sfoData,sfoSize, NULL))
		{
			sfoFile.ReadSFO(sfoData,sfoSize);
			delete[] sfoData;
		}
	}

	// Update values
	sfoFile.SetValue("TITLE",param->sfoParam.title,128);
	sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128);
	sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.detail,1024);
	sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4);
	sfoFile.SetValue("CATEGORY","MS",4);
	sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64);

	// For each file, 13 bytes for filename, 16 bytes for file hash (0 in PPSSPP), 3 byte for padding
	const int FILE_LIST_ITEM_SIZE = 13 + 16 + 3;
	const int FILE_LIST_COUNT_MAX = 99;
	const int FILE_LIST_TOTAL_SIZE = FILE_LIST_ITEM_SIZE * FILE_LIST_COUNT_MAX;
	u32 tmpDataSize = 0;
	u8* tmpDataOrig = sfoFile.GetValueData("SAVEDATA_FILE_LIST", &tmpDataSize);
	u8* tmpData = new u8[FILE_LIST_TOTAL_SIZE];

	if (tmpDataOrig != NULL)
		memcpy(tmpData, tmpDataOrig, tmpDataSize > FILE_LIST_TOTAL_SIZE ? FILE_LIST_TOTAL_SIZE : tmpDataSize);
	else
		memset(tmpData, 0, FILE_LIST_TOTAL_SIZE);

	if (param->dataBuf != 0)
	{
		char *fName = (char*)tmpData;
		for(int i = 0; i < FILE_LIST_COUNT_MAX; i++)
		{
			if(fName[0] == 0)
				break; // End of list
			if(strncmp(fName,GetFileName(param).c_str(),20) == 0)
				break;
			fName += FILE_LIST_ITEM_SIZE;
		}

		if (fName + 13 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE)
			snprintf(fName, 13, "%s",GetFileName(param).c_str());
		if (fName + 13 + 16 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE)
			memcpy(fName+13, cryptedHash, 16);
	}
	sfoFile.SetValue("SAVEDATA_FILE_LIST", tmpData, FILE_LIST_TOTAL_SIZE, FILE_LIST_TOTAL_SIZE);
	delete[] tmpData;

	// Init param with 0. This will be used to detect crypted save or not on loading
	tmpData = new u8[128];
	memset(tmpData, 0, 128);
	sfoFile.SetValue("SAVEDATA_PARAMS", tmpData, 128, 128);
	delete[] tmpData;

	u8 *sfoData;
	size_t sfoSize;
	sfoFile.WriteSFO(&sfoData,&sfoSize);

	// Calc SFO hash for PSP.
	if(cryptedData != 0)
	{
		int offset = sfoFile.GetDataOffset(sfoData,"SAVEDATA_PARAMS");
		if(offset >= 0)
			UpdateHash(sfoData, sfoSize, offset, (param->key[0]?3:1));
	}
	WritePSPFile(sfopath, sfoData, (SceSize)sfoSize);
	delete[] sfoData;

	if(param->dataBuf != 0)	// Can launch save without save data in mode 13
	{
		std::string filePath = dirPath+"/"+GetFileName(param);
		u8* data_ = 0;
		SceSize saveSize = 0;
		if(cryptedData == 0) // Save decrypted data
		{
			saveSize = param->dataSize;
			if(saveSize == 0 || saveSize > param->dataBufSize)
				saveSize = param->dataBufSize; // fallback, should never use this

			data_ = (u8*)Memory::GetPointer(param->dataBuf);
		}
		else
		{
			data_ = cryptedData;
			saveSize = cryptedSize;
		}

		INFO_LOG(HLE,"Saving file with size %u in %s",saveSize,filePath.c_str());

		// copy back save name in request
		strncpy(param->saveName,GetSaveDirName(param, saveId).c_str(),20);

		if (!WritePSPFile(filePath, data_, saveSize))
		{
			ERROR_LOG(HLE,"Error writing file %s",filePath.c_str());
			if(cryptedData != 0)
			{
				delete[] cryptedData;
			}
			return false;
		}
		delete[] cryptedData;
	}


	// SAVE ICON0
	if (param->icon0FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->icon0FileData.buf);
		std::string icon0path = dirPath+"/"+icon0Name;
		WritePSPFile(icon0path, data_, param->icon0FileData.bufSize);
	}
	// SAVE ICON1
	if (param->icon1FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->icon1FileData.buf);
		std::string icon1path = dirPath+"/"+icon1Name;
		WritePSPFile(icon1path, data_, param->icon1FileData.bufSize);
	}
	// SAVE PIC1
	if (param->pic1FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->pic1FileData.buf);
		std::string pic1path = dirPath+"/"+pic1Name;
		WritePSPFile(pic1path, data_, param->pic1FileData.bufSize);
	}

	// Save SND
	if (param->snd0FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->snd0FileData.buf);
		std::string snd0path = dirPath+"/"+snd0Name;
		WritePSPFile(snd0path, data_, param->snd0FileData.bufSize);
	}

	// Save Encryption Data
	{
		EncryptFileInfo encryptInfo;
		SceSize dataSize = sizeof(encryptInfo); // version + key + sdkVersion
		memset(&encryptInfo,0,dataSize);

		encryptInfo.fileVersion = 1;
		encryptInfo.sdkVersion = sceKernelGetCompiledSdkVersion();
		if(param->size > 1500)
			memcpy(encryptInfo.key,param->key,16);

		std::string encryptInfoPath = dirPath+"/"+"ENCRYPT_INFO.BIN";
		WritePSPFile(encryptInfoPath, (u8*)&encryptInfo, dataSize);
	}
	return true;
}
Exemplo n.º 8
0
void WardenWin::RequestData()
{
    DEBUG_LOG("WARDEN: Request data");

    if (MemCheck.empty())
        MemCheck.assign(WardenDataStorage.MemCheckIds.begin(), WardenDataStorage.MemCheckIds.end());

    ServerTicks = WorldTimer::getMSTime();

    uint32 maxid = WardenDataStorage.InternalDataID;

    uint32 id;
    uint8 type;
    WardenData *wd;

    SendDataId.clear();

    // always! this is SpeedHack on WEH
    SendDataId.push_back(385);

    for (int i = 0; i < 3; ++i)                             // for now include 3 MEM_CHECK's
    {
        if (MemCheck.empty())
            break;
        id = MemCheck.back();
        SendDataId.push_back(id);
        MemCheck.pop_back();
    }

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    int maxSize = 8 - MemCheck.size();
    for (int i = 0; i < maxSize; ++i)                             // for now include 5 random checks
    {
        id = irand(1, maxid - 1);
        wd = WardenDataStorage.GetWardenDataById(id);

        SendDataId.push_back(id);
        switch (wd->Type)
        {
        case MPQ_CHECK:
        case LUA_STR_CHECK:
        case DRIVER_CHECK:
            buff << uint8(wd->str.size());
            buff.append(wd->str.c_str(), wd->str.size());
            break;
        default:
            break;
        }
    }

    uint8 xorByte = InputKey[0];

    buff << uint8(0x00);
    buff << uint8(TIMING_CHECK ^ xorByte);                  // check TIMING_CHECK

    uint8 index = 1;

    for (std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr)
    {
        wd = WardenDataStorage.GetWardenDataById(*itr);

        type = wd->Type;
        buff << uint8(type ^ xorByte);
        switch (type)
        {
        case MEM_CHECK:
        {
            buff << uint8(0x00);
            buff << uint32(wd->Address);
            buff << uint8(wd->Length);
            break;
        }
        case PAGE_CHECK_A:
        case PAGE_CHECK_B:
        {
            buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
            buff << uint32(wd->Address);
            buff << uint8(wd->Length);
            break;
        }
        case MPQ_CHECK:
        case LUA_STR_CHECK:
        {
            buff << uint8(index++);
            break;
        }
        case DRIVER_CHECK:
        {
            buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
            buff << uint8(index++);
            break;
        }
        case MODULE_CHECK:
        {
            uint32 seed = static_cast<uint32>(rand32());
            buff << uint32(seed);
            HMACSHA1 hmac(4, (uint8*)&seed);
            hmac.UpdateData(wd->str);
            hmac.Finalize();
            buff.append(hmac.GetDigest(), hmac.GetLength());
            break;
        }
        /*case PROC_CHECK:
        {
            buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
            buff << uint8(index++);
            buff << uint8(index++);
            buff << uint32(wd->Address);
            buff << uint8(wd->Length);
            break;
        }*/
        default:
            break;                                      // should never happens
        }
    }
    buff << uint8(xorByte);
    buff.hexlike();

    // Encrypt with warden RC4 key.
    EncryptData(const_cast<uint8*>(buff.contents()), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    Client->SendPacket(&pkt);

    m_WardenDataSent = true;

    std::stringstream stream;
    stream << "Sent check id's: ";
    for (std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr)
        stream << *itr << " ";
    DEBUG_LOG("WARDEN: %s",stream.str().c_str());
}
Exemplo n.º 9
0
void WardenWin::RequestData()
{
    sLog->outStaticDebug("Request data");

    if(MemCheck.empty())
        MemCheck.assign(WardenDataStorage.MemCheckIds.begin(), WardenDataStorage.MemCheckIds.end());

    ServerTicks = getMSTime();

    uint32 maxid = WardenDataStorage.InternalDataID;

    uint32 id;
    uint8 type;
    WardenData *wd;

    SendDataId.clear();

    uint8 memcheckAdded = 0;
    for(uint32 i = 1; i <= maxid; ++i)
    {
        if(MemCheck.empty())
            break;

        if(memcheckAdded >= 3)  // for now include 3 MEM_CHECK's
            break;

        id = MemCheck.back();

        if(std::find(SendDataId.begin(), SendDataId.end(), id) != SendDataId.end())
            continue;

        memcheckAdded++;
        SendDataId.push_back(id);
        MemCheck.pop_back();
    }

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    uint8 cheatCheckAdded = 0;
    for(uint32 i = 1; i <= maxid; ++i)                             // for now include 5 random checks
    {
        if(cheatCheckAdded >= 5)
            break;

        id = urand(1, maxid - 1);

        if(std::find(SendDataId.begin(), SendDataId.end(), id) != SendDataId.end())
            continue;

        cheatCheckAdded++;
        wd = WardenDataStorage.GetWardenDataById(id);
        SendDataId.push_back(id);
        switch(wd->Type)
        {
            case MPQ_CHECK:
            case LUA_STR_CHECK:
            case DRIVER_CHECK:
                buff << uint8(wd->str.size());
                buff.append(wd->str.c_str(), wd->str.size());
                break;
            default:
                break;
        }
    }

    uint8 xorByte = InputKey[0];

    buff << uint8(0x00);
    buff << uint8(TIMING_CHECK ^ xorByte);                  // check TIMING_CHECK

    uint8 index = 1;

    for(std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr)
    {
        wd = WardenDataStorage.GetWardenDataById(*itr);

        type = wd->Type;
        buff << uint8(type ^ xorByte);
        switch(type)
        {
            case MEM_CHECK:
            {
                buff << uint8(0x00);
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
            case PAGE_CHECK_A:
            case PAGE_CHECK_B:
            {
                buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
            case MPQ_CHECK:
            case LUA_STR_CHECK:
            {
                buff << uint8(index++);
                break;
            }
            case DRIVER_CHECK:
            {
                buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
                buff << uint8(index++);
                break;
            }
            case MODULE_CHECK:
            {
                uint32 seed = static_cast<uint32>(rand32());
                buff << uint32(seed);
                HmacHash hmac(4, (uint8*)&seed);
                hmac.UpdateData(wd->str);
                hmac.Finalize();
                buff.append(hmac.GetDigest(), hmac.GetLength());
                break;
            }
            default:
                break;                                      // should never happens
        }
    }
    buff << uint8(xorByte);
    buff.hexlike();

    // Encrypt with warden RC4 key.
    EncryptData(const_cast<uint8*>(buff.contents()), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    Client->SendPacket(&pkt);

    m_WardenDataSent = true;

    std::stringstream stream;
    stream << "Sent check id's: ";
    for(std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr)
        stream << *itr << " ";
    sLog->outStaticDebug(stream.str().c_str());
}
Exemplo n.º 10
0
void AppleCSPSession::WrapKey(
		CSSM_CC_HANDLE CCHandle,
		const Context &Context,
        const AccessCredentials &AccessCred,
        const CssmKey &UnwrappedKey,
        const CssmData *DescriptiveData,
        CssmKey &WrappedKey,
		CSSM_PRIVILEGE Privilege)
{
	CssmKey::Header 		&wrappedHdr   = WrappedKey.header();
	bool 					isNullWrap = false;
	CssmKey					*wrappingKey = NULL;
	CSSM_KEYBLOB_FORMAT		wrapFormat;
	
	switch(UnwrappedKey.keyClass()) {
		case CSSM_KEYCLASS_PUBLIC_KEY:
		case CSSM_KEYCLASS_PRIVATE_KEY:
		case CSSM_KEYCLASS_SESSION_KEY:
			break;
		default:
			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
	}

	/* wrapping key only required for non-NULL wrap */
	wrappingKey = Context.get<CssmKey>(CSSM_ATTRIBUTE_KEY);
	if(wrappingKey == NULL) {
		if((Context.algorithm() == CSSM_ALGID_NONE) &&
		   (Context.type() == CSSM_ALGCLASS_SYMMETRIC)) {
				// NULL wrap, OK
				isNullWrap = true;
		}
		else {
			errorLog0("WrapKey: missing wrapping key\n");
			CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_KEY);
		}
	}
	
	/*
	 * Validate misc. params as best we can
	 */
	if(isNullWrap) {
		wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_NONE;
	}
	else {
		/*
		 * Can only wrap session and private keys. 
		 */
		#if		!ALLOW_PUB_KEY_WRAP
		if(UnwrappedKey.keyClass() == CSSM_KEYCLASS_PUBLIC_KEY) {
			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
		}
		#endif	/* ALLOW_PUB_KEY_WRAP */
		cspValidateIntendedKeyUsage(&wrappingKey->KeyHeader, CSSM_KEYUSE_WRAP);
		cspVerifyKeyTimes(wrappingKey->KeyHeader);
		
		/*
		 * make sure wrapping key type matches context
		 */
		CSSM_CONTEXT_TYPE wrapType;
		switch(wrappingKey->KeyHeader.KeyClass) {
			case CSSM_KEYCLASS_PUBLIC_KEY:
			case CSSM_KEYCLASS_PRIVATE_KEY:
				wrapType = CSSM_ALGCLASS_ASYMMETRIC;
				break;
			case CSSM_KEYCLASS_SESSION_KEY:
				wrapType = CSSM_ALGCLASS_SYMMETRIC;
				break;
			default:
				errorLog0("WrapKey: bad class of wrappingKey\n");
				CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_KEY);
		}
		if(wrapType != Context.type()) {
			errorLog0("WrapKey: mismatch wrappingKey/contextType\n");
			CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
		}
		if(Context.algorithm() == CSSM_ALGID_NONE) {
			errorLog0("WrapKey: null wrap alg, non-null key\n");
			CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
		}

		/*
		 * Get optional wrap format, set default per incoming keys
		 * Note: no such atrribute ==> 0 ==> FORMAT_NONE, which we
		 * take to mean "use the default".
		 */
		wrapFormat = Context.getInt(CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT);
		if(wrapFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) {
			/* figure out a default based on unwrapped key */
			switch(UnwrappedKey.keyClass()) {
				case CSSM_KEYCLASS_SESSION_KEY:
					wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7;
					break;
				case CSSM_KEYCLASS_PUBLIC_KEY:
					wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM; 
					break;
				case CSSM_KEYCLASS_PRIVATE_KEY:
					switch(UnwrappedKey.algorithm()) {
						case CSSM_ALGID_FEE:
							wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM; 
							break;
						default:
							wrapFormat = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8; 
							break;
					}
					break;
				default:
					/* NOT REACHED - checked above */
					break;
			}
		}		/* no format present or FORMAT_NONE */
	}
	
	/* make sure we have a valid format here */
	switch(wrapFormat) {
		case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7:
			if(UnwrappedKey.keyClass() != CSSM_KEYCLASS_SESSION_KEY) {
				/* this wrapping style only for symmetric keys */
				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
			}
			break;
		case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8:
		case CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSL:
			if(UnwrappedKey.keyClass() != CSSM_KEYCLASS_PRIVATE_KEY) {
				/* these wrapping styles only for private keys */
				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
			}
			break;
		case CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM:
			/* no restrictions (well AES can't be the wrap alg but that will 
			 * be caught later */
			break;
		case CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1:
			/* RSA private key, reference format, only */
			if(UnwrappedKey.keyClass() != CSSM_KEYCLASS_PRIVATE_KEY) {
				CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
			}
			if(UnwrappedKey.algorithm() != CSSM_ALGID_RSA) {
				CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
			}
			if(UnwrappedKey.blobType() != CSSM_KEYBLOB_REFERENCE) {
				CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
			}
			break;
		case CSSM_KEYBLOB_WRAPPED_FORMAT_NONE:
			if(isNullWrap) {
				/* only time this is OK */
				break;
			}
			/* else fall thru */
		default:
			dprintf1("KeyWrap: invalid wrapFormat (%d)\n", (int)wrapFormat);
			CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT);
	}
	/* get the blob to be wrappped */
	CssmData rawBlob;
	bool allocdRawBlob = false;
	CSSM_KEYBLOB_FORMAT rawFormat;
	
	/* 
	 * Outgoing same as incoming unless a partial key is completed during 
	 * generateKeyBlob()
	 */
	const CssmKey::Header &unwrappedHdr = UnwrappedKey.header();
	CSSM_KEYATTR_FLAGS unwrappedKeyAttrFlags = unwrappedHdr.KeyAttr;
	
	switch(UnwrappedKey.blobType()) {
		case CSSM_KEYBLOB_RAW:
			/* 
			 * Trivial case - we already have the blob.
			 * This op - wrapping a raw key - is not supported for the 
			 * CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1 format since that doesn't
			 * operate on a key blob.
			 */
			rawBlob = CssmData::overlay(UnwrappedKey.KeyData);
			rawFormat = UnwrappedKey.blobFormat();
			break;
		case CSSM_KEYBLOB_REFERENCE:
			/* get binary key, then get blob from it */
			{
				BinaryKey &binKey = lookupRefKey(UnwrappedKey);
				
				/*
				 * Subsequent tests for extractability: don't trust the 
				 * caller's header; use the one in the BinaryKey.
				 */
				CSSM_KEYATTR_FLAGS keyAttr = binKey.mKeyHeader.KeyAttr;
				if(!(keyAttr & CSSM_KEYATTR_EXTRACTABLE)) {
					/* this key not extractable in any form */
					CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
				}
				
				/* 
				 * CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1: we're ready to roll; 
				 * all we need is the reference key.
				 */
				if(wrapFormat == CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1) {
					break;
				}
				
				/*
				 * Null wrap - prevent caller from obtaining 
				 * clear bits if CSSM_KEYATTR_SENSITIVE
				 */
				if(isNullWrap && (keyAttr & CSSM_KEYATTR_SENSITIVE)) {
					CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
				}

				/*
				 * Special case for PKCS8 and openssl: need to get blob of a specific
				 * algorithm-dependent format. Caller can override our 
				 * preference with a 
				 * CSSM_ATTRIBUTE_{PRIVATE,PUBLIC,SESSION}_KEY_FORMAT 
				 * context attribute. 
				 */
				rawFormat = requestedKeyFormat(Context, UnwrappedKey);
				if(rawFormat == CSSM_KEYBLOB_RAW_FORMAT_NONE) {
					CSSM_ALGORITHMS keyAlg = binKey.mKeyHeader.AlgorithmId;
					switch(wrapFormat) {
						case CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS8:
							rawFormat = pkcs8RawKeyFormat(keyAlg);
							break;
						case CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSL:
							rawFormat = opensslRawKeyFormat(keyAlg);
							break;
						default:
							/* punt and take default for key type */
							break;
					}
				}
	
				/* 
				 * DescriptiveData for encoding, currently only used for 
				 * SSH1 keys.
				 */
				if((DescriptiveData != NULL) && (DescriptiveData->Length != 0)) {
					binKey.descData(*DescriptiveData);
				}
				
				/* optional parameter-bearing key */
				CssmKey *paramKey = Context.get<CssmKey>(CSSM_ATTRIBUTE_PARAM_KEY);
				binKey.generateKeyBlob(privAllocator,
					rawBlob,
					rawFormat,
					*this,
					paramKey,
					unwrappedKeyAttrFlags);
			}
			allocdRawBlob = true;		// remember - we need to free
			break;
			
		default:
			errorLog0("WrapKey: bad unwrappedKey BlobType\n");
			CssmError::throwMe(CSSMERR_CSP_INVALID_KEY);
	}

	/*
	 * Prepare outgoing header.
	 */
	setKeyHeader(wrappedHdr,
		plugin.myGuid(),
		unwrappedHdr.algorithm(),		// same as incoming 
		unwrappedHdr.keyClass(),		// same as incoming
		unwrappedKeyAttrFlags,
		unwrappedHdr.KeyUsage);
	wrappedHdr.LogicalKeySizeInBits = unwrappedHdr.LogicalKeySizeInBits;
	wrappedHdr.WrapAlgorithmId = Context.algorithm(); 	// true for null 
														// and non-Null 
	wrappedHdr.StartDate = unwrappedHdr.StartDate;
	wrappedHdr.EndDate = unwrappedHdr.EndDate;
	wrappedHdr.Format = wrapFormat;
	if(isNullWrap) {
		wrappedHdr.BlobType = CSSM_KEYBLOB_RAW;
	}
	else {
		wrappedHdr.BlobType = CSSM_KEYBLOB_WRAPPED;
	}
	
	/* 
	 * special cases - break out here for Apple Custom and OpenSSHv1  
	 */
	if(!isNullWrap) {
		switch(wrapFormat) {
			case CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM:
				try {
					WrapKeyCms(CCHandle,
						Context,
						AccessCred,
						UnwrappedKey,
						rawBlob,
						allocdRawBlob,
						DescriptiveData,
						WrappedKey,
						Privilege);
				}
				catch(...) {
					if(allocdRawBlob) {
						freeCssmData(rawBlob, privAllocator);
					}
					throw;
				}
				if(allocdRawBlob) {
					freeCssmData(rawBlob, privAllocator);
				}
				return;
			case CSSM_KEYBLOB_WRAPPED_FORMAT_OPENSSH1:
			{
				/*
				 * 1. We don't have to worry about allocdRawBlob since this 
				 *    operation only works on reference keys and we did not
				 *    obtain the raw blob from the BinaryKey. 
				 * 2. This is a redundant lookupRefKey, I know, but since
				 *    that returns a reference, it would just be too messy to have
				 *    the previous call be in the same scope as this.
				 */
				BinaryKey &binKey = lookupRefKey(UnwrappedKey);
				WrapKeyOpenSSH1(CCHandle,
					Context,
					AccessCred,
					binKey,
					rawBlob,
					allocdRawBlob,
					DescriptiveData,
					WrappedKey,
					Privilege);
				return;
			}
			default:
				/* proceed to encrypt blob */
				break;
		}
	}	/* !isNullWrap */

	
	/*
	 * Generate wrapped blob. Careful, we need to conditionally free
	 * rawBlob on error.
	 */
	CssmData encryptedBlob;
	CssmData remData;
	WrappedKey.KeyData.Data = NULL;		// ignore possible incoming KeyData
	WrappedKey.KeyData.Length = 0;
	
	try {
		if(isNullWrap) {
			/* copy raw blob to caller's wrappedKey */
			copyCssmData(rawBlob, 
				CssmData::overlay(WrappedKey.KeyData), 
				normAllocator);
			wrappedHdr.Format   = rawFormat; 
		}
		else {
			/* encrypt rawBlob using caller's context, then encode to
			 * WrappedKey.KeyData */
			CSSM_SIZE bytesEncrypted;
			EncryptData(CCHandle,
				Context,
				&rawBlob,			// ClearBufs[]
				1,					// ClearBufCount
				&encryptedBlob,		// CipherBufs[],
				1,					// CipherBufCount,
				bytesEncrypted,
				remData,
				Privilege);
	
			// I'm not 100% sure about this....
			assert(remData.Length == 0);
			encryptedBlob.Length = bytesEncrypted;
			WrappedKey.KeyData = encryptedBlob;
			wrappedHdr.BlobType = CSSM_KEYBLOB_WRAPPED;
			// OK to be zero or not present 
			wrappedHdr.WrapMode = Context.getInt(
				CSSM_ATTRIBUTE_MODE);
		}
	}
	catch (...) {
		errorLog0("WrapKey: EncryptData() threw exception\n");
		if(allocdRawBlob) {
			freeCssmData(rawBlob, privAllocator);
		}
		freeCssmData(remData,normAllocator);
		throw;
	}
	if(allocdRawBlob) {
		freeCssmData(rawBlob, privAllocator);
	}
	freeCssmData(remData, normAllocator);
}
Exemplo n.º 11
0
//src_data为转码前的数据,发送给mas和pas的。
void PasServer::HandleOnePacket(socket_t *sock, const char *data, int len)
{
	if (data == NULL || len < (int) sizeof(Header) + (int) sizeof(Footer))
		return;

	Header *header = (Header *) data;
	unsigned int access_code = ntouv32(header->access_code);
	string str_access_code = uitodecstr(access_code);

	// 针对接入码进行统计处理
	_datastat.AddFlux(access_code, len);

	unsigned int msg_len = ntouv32(header->msg_len);
	if (msg_len != (unsigned int) len) {
		OUT_ERROR( NULL, 0, NULL,
				"PasServer::HandleOnePacket packet len error");
		return;
	}

	// 是否需要加密处理
	if (EncryptData((unsigned char *) data, len, false)) {
		// 将加密标志清空
		header->encrypt_flag = 0;
	}

	unsigned short msg_type = ntouv16(header->msg_type);
	string mac_id = _proto_parse.GetMacId(data, len);

	const char *ip = sock->_szIp;
	unsigned int port = sock->_port;

	OUT_RECV3( ip, port, str_access_code.c_str(), "fd %d, %s", sock->_fd, _proto_parse.Decoder(data,len).c_str() );
//	OUT_HEX( ip, port, str_access_code.c_str(), data, len ) ;

	// 处理车号对应的接入码的关系
	if (!mac_id.empty()) {
		// 记录车号对应的接入码的关系
		_corp_info_handler.update_car_info(mac_id, access_code);
	}

	if (msg_type == UP_CONNECT_REQ) {
		User user = _online_user.GetUserByUserId("U_" + str_access_code);
		UpConnectReq *out_login = (UpConnectReq *) data;
		OUT_RECV(ip, port, str_access_code.c_str(),
				"fd %d, UP_CONNECT_REQ,down-link listen port:%d",
				sock->_fd, ntouv16(out_login->down_link_port));
		//判定是不是同一个socket发上来的UP_CONNECT_REQ。
		if (!user._user_id.empty()) {
			//说明在线列表中已有次用户,
			if (user._fd == sock) {
				OUT_WARNING( ip, port, str_access_code.c_str(), "fd %d, sock already in user queue" , sock->_fd );
				return;
			} else {
				OUT_WARNING(ip, port, str_access_code.c_str(),
						"fd %d, one user already login", sock->_fd);
				CloseSocket(sock);
				return;
			}
		}

		char szuser[128] = { 0 };
		char szpwd[128] = { 0 };
		sprintf(szuser, "%u", ntouv32(out_login->user_id));
		strncpy(szpwd, (const char*) out_login->password,
				sizeof(out_login->password));

		unsigned int flag = 0;
		unsigned char ret = _login_check->CheckUser(access_code, szuser, szpwd,
				ip, flag);
		UpConnectRsp resp;
		resp.header.access_code = ntouv32(access_code);
		resp.header.msg_len = ntouv32(sizeof(UpConnectRsp));
		resp.header.msg_type = ntouv16(UP_CONNECT_RSP);
		resp.header.msg_seq = ntouv32(_proto_parse.get_next_seq());
		resp.verify_code = ntouv32(_verify_code);
		resp.result = ret;

		switch (ret) {
		case 0:
			OUT_INFO(ip, port, str_access_code.c_str(),
					"login check success,access_code:%d  up-link ON_LINE",
					access_code);
			break;
		case 1:
			OUT_WARNING(ip, port, str_access_code.c_str(),
					"login check fail,ip is invalid");
			break;
		case 2:
			OUT_WARNING(ip, port, str_access_code.c_str(),
					"login check fail,%d accesscode is invalid,close it",
					access_code);
			break;
		case 3:
			OUT_WARNING(ip, port, str_access_code.c_str(),
					"login check fail,user_name:%s is invalid,close it",
					szuser);
			break;
		case 4:
			OUT_WARNING(ip, port, str_access_code.c_str(),
					"login check fail,user_password:%s is invalid,close it",
					szpwd);
			break;
		default:
			OUT_WARNING(ip, port, str_access_code.c_str(),
					"login check fail,other error,close it");
			break;
		}
		// 对于登陆的连接的响应处理
		if (SendCrcData(sock, (const char*) &resp, sizeof(resp)))
			OUT_SEND(ip,port,str_access_code.c_str(),"UP_CONNECT_RSP");
		else
			OUT_ERROR(ip,port,str_access_code.c_str(),"UP_CONNECT_RSP");

		// 如果用户认证不通过则直接关闭连接处理
		if (ret != 0) {
			OUT_WARNING( ip, port, str_access_code.c_str(), "result %d, close socket user fd %d", ret , sock->_fd );
			CloseSocket(sock);
			return;
		}

		//睡眠一毫秒等待数据发送出去。
		user._access_code = access_code;
		user._user_name = szuser;
		user._user_id = "U_" + str_access_code; //表明是上行链路
		user._login_time = time(0);
		user._msg_seq = flag; // 处理地市级跨域数据的处理

		user._socket_type = User::TcpClient;
		user._fd = sock;
		user._ip = ip;
		user._port = port;
		user._last_active_time = time(0);

		unsigned short down_link_port = ntouv16( out_login->down_link_port );
		char szdownip[64] = { 0 };
		strncpy(szdownip, (char*) out_login->down_link_ip,
				sizeof(out_login->down_link_ip));

		OUT_CONN( ip, port, str_access_code.c_str() , "fd %d, down connection down ip %s , down port %d", sock->_fd, szdownip, down_link_port );
		if (ret == 0) {
			user._user_state = User::ON_LINE;
			User down_user = _online_user.GetUserByUserId(
					"D_" + str_access_code);
			if (!down_user._user_id.empty()) { // 修正从链接切换地址的BUG
				if (down_user._fd != NULL) { // 如果已建立连接则关闭
					CloseSocket(down_user._fd);
				}
			}
			if (down_link_port > 0 && check_addr(szdownip)) {
				//说明下行链路还没有建立起来。
				down_user._user_id = "D_" + str_access_code;
				down_user._access_code = access_code;
				down_user._user_name = szuser;
				down_user._login_time = time(0);

				down_user._socket_type = User::TcpConnClient;
				down_user._fd = NULL;
				down_user._user_state = User::OFF_LINE;
				down_user._ip = szdownip;
				down_user._port = down_link_port;
				down_user._last_active_time = time(0);
				down_user._msg_seq = flag;

				//下行链路只重连3次。重连三次连不上时就将这个user erase掉。
				down_user._connect_info.keep_alive = ReConnTimes;
				down_user._connect_info.last_reconnect_time = 0;
				down_user._connect_info.timeval = 10;
				down_user._connect_info.reconnect_times = 3;

				if (!_online_user.AddUser(down_user._user_id, down_user)) {
					// 如果已存在则直接替换原来的会话
					_online_user.SetUser(down_user._user_id, down_user);
				}
			}
			// 只登陆成功才添加到用户队列中
			_online_user.AddUser(user._user_id, user);
		} else
			user._user_state = User::OFF_LINE;

		user._last_active_time = time(0);
		_online_user.SetUser(user._user_id, user);

		return;
	}

	User user = _online_user.GetUserBySocket(sock);
	if (user._user_id.empty()) {
		OUT_ERROR(ip, port, str_access_code.c_str(),
				"fd %d, msg type %04x, user havn't login,close it",
				sock->_fd, msg_type);
		CloseSocket(sock);
		return;
	}

	//未登录成功数据上来做单独处理,处理策略
	if (msg_type == UP_DISCONNECT_REQ) {
		OUT_RECV(ip, port, user._user_id.c_str(), "UP_DISCONNECT_REQ");

		//  发送从链路注销请求
		DownDisconnectReq req;
		req.header.msg_type = ntouv16(DOWN_DISCONNECT_REQ);
		req.header.msg_len = ntouv32(sizeof(DownDisconnectReq));
		req.header.msg_seq = ntouv32(_proto_parse.get_next_seq());
		req.header.access_code = header->access_code;
		req.verify_code = ntouv32(_verify_code);

		char buf[200];
		sprintf(buf, "D_%u", user._access_code);
		//  取从链路fd
		User sub_user = _online_user.GetUserByUserId(buf);

		if (!sub_user._user_id.empty()) {
			if (SendCrcData(sub_user._fd, (const char*) &req, sizeof(req))) {
				OUT_SEND(sub_user._ip.c_str(), sub_user._port,
						user._user_id.c_str(), "DOWN_DISCONNECT_REQ");
			} else
				OUT_ERROR(sub_user._ip.c_str(),sub_user._port,user._user_id.c_str(),"DOWN_DISCONNECT_REQ");
		}

		UpDisconnectRsp resp;
		resp.header.msg_seq = ntouv32(_proto_parse.get_next_seq());
		resp.header.access_code = header->access_code;

		if (SendCrcData(sock, (const char*) &resp, sizeof(resp)))
			OUT_SEND(ip, port, user._user_id.c_str(), "UP_DISCONNECT_RSP");
		else
			OUT_ERROR(ip,port,user._user_id.c_str(),"UP_DISCONNECT_RSP");
	} else if (msg_type == UP_LINKTEST_REQ) {
		OUT_RECV(ip, port, user._user_id.c_str(), "UP_LINKTEST_REQ");
		UpLinkTestRsp resp;
		resp.header.access_code = header->access_code;
		resp.header.msg_seq = ntouv32(_proto_parse.get_next_seq());

		if (SendCrcData(sock, (const char*) &resp, sizeof(resp)))
			OUT_SEND(ip, port, user._user_id.c_str(), "UP_LINKTEST_RSP");
		else
			OUT_ERROR(ip,port,user._user_id.c_str(),"UP_LINKTEST_RSP");
	} else if (msg_type == UP_CLOSELINK_INFORM) {
		//  不需要处理,由定时处理流程解决
		OUT_RECV(ip, port, user._user_id.c_str(), "fd %d, UP_CLOSELINK_INFORM",
				sock->_fd);

		char buf[200] = { 0 };
		sprintf(buf, "U_%u", user._access_code);
		//  取主链路fd
		User main_user = _online_user.GetUserByUserId(buf);
		if (!main_user._user_id.empty()) {
			{
				DownDisconnectInform req;
				req.header.access_code = ntouv32(user._access_code);
				req.header.msg_len = ntouv32(sizeof(DownDisconnectInform));
				req.header.msg_type = ntouv16(DOWN_DISCONNECT_INFORM);
				req.header.msg_seq = ntouv32(_proto_parse.get_next_seq());

				if (SendCrcData(main_user._fd, (const char*) &req, sizeof(req)))
					OUT_SEND(ip, port, user._user_id.c_str(),
							"fd %d, DOWN_DISCONNECT_INFORM", sock->_fd);
				else
					OUT_ERROR(ip, port, user._user_id.c_str(),
							"fd %d, DOWN_DISCONNECT_INFORM", sock->_fd);
			}

			{
				DownCloselinkInform req;
				req.header.access_code = ntouv32(user._access_code);
				req.header.msg_len = ntouv32(sizeof(DownCloselinkInform));
				req.header.msg_type = ntouv16(DOWN_CLOSELINK_INFORM);
				req.header.msg_seq = ntouv32(_proto_parse.get_next_seq());

				if (SendCrcData(main_user._fd, (const char*) &req, sizeof(req)))
					OUT_SEND(ip, port, user._user_id.c_str(),
							"fd %d, DOWN_CLOSELINK_INFORM", sock->_fd);
				else
					OUT_ERROR(ip, port, user._user_id.c_str(),
							"fd %d, DOWN_CLOSELINK_INFORM", sock->_fd);
			}

			main_user._last_active_time = time(0);
			_online_user.SetUser(main_user._user_id, main_user);

			user._user_state = User::OFF_LINE;
		}
	} else if (msg_type == UP_DISCONNECT_INFORM) {
		//  不需要处理,由定时处理流程解决
		OUT_RECV(ip, port, user._user_id.c_str(), "fd %d, UP_DISCONNECT_INFORM",
				sock->_fd);
	} else if (msg_type == UP_CLOSELINK_INFORM) {
		//  不需要处理,由定时处理流程解决
		OUT_RECV(ip, port, user._user_id.c_str(), "fd %d, UP_CLOSELINK_INFORM",
				sock->_fd);
		//  取主链路fd
		{
			DownDisconnectInform req;
			req.header.msg_len = ntouv32( sizeof(req) );
			req.header.msg_type = ntouv16( DOWN_DISCONNECT_INFORM );
			req.header.access_code = ntouv32(user._access_code);
			req.header.msg_seq = ntouv32(_proto_parse.get_next_seq());

			if (SendCrcData(sock, (const char*) &req, sizeof(req)))
				OUT_SEND(ip, port, user._user_id.c_str(),
						"fd %d, DOWN_DISCONNECT_INFORM", sock->_fd);
			else
				OUT_ERROR(ip, port, user._user_id.c_str(),
						"fd %d, DOWN_DISCONNECT_INFORM", sock->_fd);
		}

		{
			DownCloselinkInform req;
			req.header.msg_len = ntouv32( sizeof(req) );
			req.header.msg_type = ntouv16( DOWN_CLOSELINK_INFORM );
			req.header.access_code = ntouv32(user._access_code);
			req.header.msg_seq = ntouv32(_proto_parse.get_next_seq());

			if (SendCrcData(sock, (const char*) &req, sizeof(req)))
				OUT_SEND(ip, port, user._user_id.c_str(),
						"fd %d, DOWN_CLOSELINK_INFORM", sock->_fd);
			else
				OUT_ERROR(ip, port, user._user_id.c_str(),
						"fd %d, DOWN_CLOSELINK_INFORM", sock->_fd);
		}
	} else if (msg_type == UP_DISCONNECT_INFORM) {
		//  不需要处理,由定时处理流程解决
		OUT_RECV(ip, port, user._user_id.c_str(), "fd %d, UP_DISCONNECT_INFORM",
				sock->_fd);
	} else if (msg_type == DOWN_CONNECT_RSP) {
		DownConnectRsp *_down_resp = (DownConnectRsp*) data;
		if (_down_resp->result == 0) {
			OUT_RECV(ip, port, user._user_id.c_str(),
					"fd %d, DOWN_CONNECT_RSP,Down-Link ON_LINE", sock->_fd);
			user._connect_info.reconnect_times = 3;
			user._user_state = User::ON_LINE;
		} else {
			OUT_RECV(ip, port, user._user_id.c_str(),
					"fd %d, DOWN_CONNECT_RSP,connect fail,result=%d",
					sock->_fd, _down_resp->result);
		}
	} else if (msg_type == DOWN_LINKTEST_RSP) {
		// 这里处理有些运营商回复下行链路心跳时使用上行来回应
		OUT_RECV(ip, port, user._user_id.c_str(), get_type(msg_type));
		/**
		 if ( user._user_id.at(0) == 'U' ) {
		 User down = _online_user.GetUserByUserId("D_" + str_access_code);
		 if ( ! down._user_id.empty() ) {
		 down._last_active_time = time(0) ;
		 _online_user.SetUser( down._user_id, down ) ;
		 }
		 }*/
	} else if (msg_type == DOWN_DISCONNECT_RSP) {
		OUT_RECV(ip, port, user._user_id.c_str(), get_type(msg_type));
		//	user._user_state = User::OFF_LINE;
		if (user._user_state == User::ON_LINE && user._fd != NULL) {
			CloseSocket(user._fd);
		}
	} else if (msg_type == DOWN_DISCONNECT_INFORM) {
		//不管它,由定时线程来完成。
		OUT_RECV(ip, port, user._user_id.c_str(), get_type(msg_type));
	} else if (msg_type == DOWN_DISCONNECT_RSP) {
		OUT_RECV(ip, port, user._user_id.c_str(), get_type(msg_type));
		user._user_state = User::OFF_LINE;
	} else {
		if (msg_type == UP_EXG_MSG) {
			ExgMsgHeader *msg_header = (ExgMsgHeader*) (data + sizeof(Header));
			if (msg_header->vehicle_no[0] == (char) 0) {
				OUT_ERROR(ip, port, user._user_id.c_str(), "vehicle is null");
				return;
			}

			unsigned short data_type = ntouv16( msg_header->data_type );
			switch (data_type) {
			case UP_EXG_MSG_REAL_LOCATION:
				{
					OUT_RECV3(ip, port, user._user_id.c_str(), "UP_EXG_MSG_REAL_LOCATION:%s", msg_header->vehicle_no);

					CorpInfoHandle::_CorpInfo info = _corp_info_handler.update_corp_map(access_code, 1, _max_send_num);
					if (info.send_num < 1) {
						Header * pHeader = (Header *) (data);

						//给运营商回复DOWN_TOTAL_RECV_BACK_MSG
						DownTotalRecvBackMsg resp;
						resp.header.access_code = pHeader->access_code;
						resp.DynamicInfoTotal = ntouv32(_max_send_num);
						resp.start_time = ntouv64(info.send_time);
						resp.end_time = ntouv64(time(0));
						resp.header.msg_seq = ntouv32(_proto_parse.get_next_seq());

						char buf[200] = { 0 };
						sprintf(buf, "D_%u", user._access_code);
						User sub_user = _online_user.GetUserByUserId(buf);

						socket_t *isock = sock;
						if (!(sub_user._user_id.empty()
								|| sub_user._user_state != User::ON_LINE))
							isock = sub_user._fd;

						if (SendCrcData(isock, (const char*) &resp, sizeof(resp))) {
							OUT_SEND( ip, port, user._user_id.c_str(), "DOWN_TOTAL_RECV_BACK_MSG" );
						} else {
							OUT_ERROR( ip, port, user._user_id.c_str(), "DOWN_TOTAL_RECV_BACK_MSG" );
						}
					}
				}
				break;
			case UP_EXG_MSG_HISTORY_LOCATION:
				{
					OUT_RECV3(ip, port, user._user_id.c_str(), "UP_EXG_MSG_HISTORY_LOCATION:%s", msg_header->vehicle_no);
					UpExgMsgHistoryLocation * pReq = (UpExgMsgHistoryLocation *) (data);
					unsigned int num = pReq->gnss_cnt;

					CorpInfoHandle::_CorpInfo info = _corp_info_handler.update_corp_map(access_code, num, _max_send_num);
					if (info.send_num < num) {
						//给运营商回复DOWN_TOTAL_RECV_BACK_MSG
						DownTotalRecvBackMsg resp;
						resp.header.access_code = pReq->header.header.access_code;
						resp.DynamicInfoTotal = ntouv32(_max_send_num);
						resp.start_time = ntouv64(info.send_time);
						resp.end_time = ntouv64(time(0));
						resp.header.msg_seq = ntouv32(_proto_parse.get_next_seq());

						char buf[200];
						sprintf(buf, "D_%u", user._access_code);
						User sub_user = _online_user.GetUserByUserId(buf);

						socket_t *isock = sock;
						if (!(sub_user._user_id.empty()
								|| sub_user._user_state != User::ON_LINE))
							isock = sub_user._fd;

						if (SendCrcData(isock, (const char*) &resp, sizeof(resp))) {
							OUT_SEND( ip, port, user._user_id.c_str(), "DOWN_TOTAL_RECV_BACK_MSG" );
						} else {
							OUT_ERROR( ip, port, user._user_id.c_str(), "DOWN_TOTAL_RECV_BACK_MSG" );
						}
					}
				}
				break;
			case UP_EXG_MSG_APPLY_HISGNSSDATA_REQ: // 补报数据请求
				{
					if (len < (int) sizeof(UpExgApplyHisGnssDataReq)) {
						OUT_ERROR( ip, port, user._user_id.c_str(), "UP_EXG_MSG_APPLY_HISGNSSDATA_REQ data length errro, len %d" , len );
						return;
					}

					UpExgApplyHisGnssDataReq *req = (UpExgApplyHisGnssDataReq *) data;

					DownExgMsgApplyHisgnssdataAck resp;
					resp.header.msg_len = ntouv32( sizeof(DownExgMsgApplyHisgnssdataAck) );
					resp.header.access_code = req->header.access_code;
					resp.header.msg_type = ntouv16( DOWN_EXG_MSG );
					memcpy(resp.exg_msg_header.vehicle_no, req->exg_msg_header.vehicle_no, sizeof(resp.exg_msg_header.vehicle_no));
					resp.exg_msg_header.vehicle_color = req->exg_msg_header.vehicle_color;
					resp.exg_msg_header.data_type = ntouv16( DOWN_EXG_MSG_APPLY_HISGNSSDATA_ACK );
					resp.exg_msg_header.data_length = ntouv32( sizeof(char) );
					resp.result = 0x00;

					// 补报数据自动应答
					SendCrcData(sock, (const char *) &resp, sizeof(resp));

					// 设置用户为在线处理开始补报数据
					_filecache.Online(user._access_code);
				}
				break;
			default:
				OUT_RECV(ip, port, user._user_id.c_str(), get_type(data_type));
				break;
			}
		} else if (msg_type == UP_PLATFORM_MSG) {

		} else if (msg_type == UP_CTRL_MSG) {

		} else if (msg_type == UP_BASE_MSG) {

		} else if (msg_type == UP_WARN_MSG) {

		} else {
			OUT_ERROR(ip, port, user._user_id.c_str(), "msg_type=%04x,received an invalid message,len %d", msg_type, len);
			OUT_HEX( ip, port, user._user_id.c_str(), data, len );
		}
		_pEnv->GetMasServer()->HandleMasUpData((const char *) data, len);
	}
	user._last_active_time = time(0);
	_online_user.SetUser(user._user_id, user);
}
Exemplo n.º 12
0
STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
{
  _hmac.Update(data, size);
  EncryptData(data, size);
  return size;
}
Exemplo n.º 13
0
UPK_STATUS
NitroPlus::
Pack(
    PCWSTR          InputPath,
    PCWSTR          OutputFile  /* = NULL */,
    PLARGE_INTEGER  PackedFiles /* = NULL */,
    ULONG           Flags       /* = 0 */
)
{
    UNREFERENCED_PARAMETER(OutputFile);
    UNREFERENCED_PARAMETER(Flags);

    ULONG                   PathLength, Length, Hash, Offset;
    ULONG                   Size, CompressedSize, FileBufferSize, CompresseBufferSize;
    WCHAR                   FilePath[MAX_NTPATH];
    PVOID                   NpaEntryBase, FileBuffer, CompresseBuffer;
    PBYTE                   NpaEntryBuffer;
    PWSTR                   FileName;
    NTSTATUS                Status;
    LARGE_INTEGER           FileCount, PackedFileCount;
    NITRO_PLUS_ENTRY       *BaseEntry, *Entry;
    NITRO_PLUS_NPA_HEADER   Header;
    NITRO_PLUS_NPA_ETNRY   *Info;
    NtFileDisk              File;

    if (PackedFiles == NULL)
        PackedFiles = &PackedFileCount;

    PackedFiles->QuadPart = 0;

    if (!EnumDirectoryFiles(
            (PVOID *)&BaseEntry,
            L"*.*",
            sizeof(*BaseEntry),
            InputPath,
            &FileCount,
            (EnumDirectoryFilesCallBackRoutine)QueryFileList,
            0,
            EDF_SUBDIR)
       )
    {
        return STATUS_UNSUCCESSFUL;
    }

    FileBufferSize      = 0;
    CompresseBufferSize = 0;
    FileBuffer          = NULL;
    CompresseBuffer     = NULL;

    *(PULONG)&Header.Signature  = NPA_HEADER_MAGIC;
    Header.Version              = NPA_GCLX_VERSION;
    Header.EntryCount           = FileCount.LowPart;
    Header.FileCount            = FileCount.LowPart;
    Header.DirectoryCount       = 0;
    Header.IsCompressed         = TRUE;
    Header.IsEncrypted          = TRUE;

    RtlRandom(&Header.Hash[0]);
    RtlRandom(&Header.Hash[1]);

    PathLength = StrLengthW(InputPath);

    if (OutputFile != NULL)
    {
        Status = m_File.Create(OutputFile);
    }
    else
    {
        FileName = FilePath + PathLength;
        CopyMemory(FilePath, InputPath, PathLength * sizeof(*FilePath));
        if (FileName[-1] == '\\')
            --FileName;

        *(PULONG64)FileName = TAG4W('.npa');
        FileName[4] = 0;

        Status = m_File.Create(FilePath);
    }

    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    PathLength += InputPath[PathLength - 1] != '\\';

    NpaEntryBase = AllocateMemory(sizeof(*BaseEntry) * FileCount.LowPart);
    if (NpaEntryBase == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto RETURN_POINT;
    }

    NpaEntryBuffer  = (PBYTE)NpaEntryBase;
    Entry           = BaseEntry;

    for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count)
    {
        Length = StrLengthW(Entry->FileName) - PathLength;

        Length = WideCharToMultiByte(
                    CP_SHIFTJIS,
                    0,
                    Entry->FileName + PathLength,
                    Length,
                    (PSTR)NpaEntryBuffer + 4,
                    INT_MAX,
                    NULL,
                    NULL
                 );
//        Nt_UnicodeToAnsi((PSTR)NpaEntryBuffer + 4, INT_MAX, Entry->FileName + PathLength, Length, &Length);
        *(PULONG)NpaEntryBuffer = Length;

        NpaEntryBuffer += 4;

        Entry->DecryptLength    = Length;
        Entry->Seed             = HashBuffer(NpaEntryBuffer, Length);

        EncryptName(NpaEntryBuffer, Length, Index, &Header);

        NpaEntryBuffer += Length;
        NpaEntryBuffer += sizeof(*Info);

        ++Entry;
    }

    Header.EntrySize = PtrOffset(NpaEntryBuffer, NpaEntryBase);

    Hash            = Header.Hash[0] * Header.Hash[1];
    NpaEntryBuffer  = (PBYTE)NpaEntryBase;
    Entry           = BaseEntry;
    Offset          = 0;

    m_File.Seek(Header.EntrySize + sizeof(Header), FILE_BEGIN);

    for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count)
    {
        Status = File.Open(Entry->FileName);
        if (!NT_SUCCESS(Status))
            break;

        Size = File.GetSize32();
        if (FileBufferSize < Size)
        {
            FileBufferSize = Size;
            FileBuffer = ReAllocateMemory(FileBuffer, FileBufferSize);
            if (FileBuffer == NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
        }

        Status = File.Read(FileBuffer, Size);
        if (!NT_SUCCESS(Status))
            break;

        CompressedSize = Size * 4;
        if (CompresseBufferSize < CompressedSize)
        {
            CompresseBufferSize = CompressedSize;
            CompresseBuffer = ReAllocateMemory(CompresseBuffer, CompresseBufferSize);
            if (CompresseBuffer == NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
        }

        CompressedSize = CompresseBufferSize;
        Status = compress2(CompresseBuffer, &CompressedSize, FileBuffer, Size, Z_BEST_COMPRESSION);
        if (Status != Z_OK)
        {
            Status = STATUS_UNSUCCESSFUL;
            break;
        }

        EncryptData(
            CompresseBuffer,
            MY_MIN(CompressedSize, Entry->DecryptLength + 0x1000),
            (Hash + Entry->Seed) * Size
        );

        NpaEntryBuffer += *(PULONG)NpaEntryBuffer + 4;
        Info            = (NITRO_PLUS_NPA_ETNRY *)NpaEntryBuffer;
        NpaEntryBuffer += sizeof(*Info);

        Info->FileType          = NP_FILE_TYPE_FILE;
        Info->CompressedSize    = CompressedSize;
        Info->Offset            = Offset;
        Info->OriginalSize      = Size;
        Info->DirectoryIndex    = 0;

        Status = m_File.Write(CompresseBuffer, CompressedSize);
        if (!NT_SUCCESS(Status))
            break;

        Offset += CompressedSize;
        ++Entry;
    }

    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    m_File.Seek(0, FILE_BEGIN);
    Status = m_File.Write(&Header, sizeof(Header));
    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    Status = m_File.Write(NpaEntryBase, Header.EntrySize);
    if (!NT_SUCCESS(Status))
        goto RETURN_POINT;

    PackedFiles->QuadPart = FileCount.QuadPart;

RETURN_POINT:

    FreeMemory(FileBuffer);
    EnumDirectoryFilesFree(BaseEntry);

    return Status;
}
Exemplo n.º 14
0
void WardenWin::RequestData()
{
    sLog->outWarden("Request data");

    // If all checks were done, fill the todo list again
    if (_memChecksTodo.empty())
        _memChecksTodo.assign(sWardenCheckMgr->MemChecksIdPool.begin(), sWardenCheckMgr->MemChecksIdPool.end());

    if (_otherChecksTodo.empty())
        _otherChecksTodo.assign(sWardenCheckMgr->OtherChecksIdPool.begin(), sWardenCheckMgr->OtherChecksIdPool.end());

    _serverTicks = getMSTime();

    uint32 id;
    uint8 type;
    WardenCheck* wd;
    _currentChecks.clear();

    // Build check request (3 mem checks + 7 other checks)
    for (int i = 0; i < 3; ++i)
    {
        // If todo list is done break loop (will be filled on next Update() run)
        if (_memChecksTodo.empty())
            break;

        // Get check id from the end and remove it from todo
        id = _memChecksTodo.back();
        _memChecksTodo.pop_back();

        // Add the id to the list sent in this cycle
        _currentChecks.push_back(id);
    }

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    for (int i = 0; i < 7; ++i)
    {
        // If todo list is done break loop (will be filled on next Update() run)
        if (_otherChecksTodo.empty())
            break;

        // Get check id from the end and remove it from todo
        id = _otherChecksTodo.back();
        _otherChecksTodo.pop_back();

        // Add the id to the list sent in this cycle
        _currentChecks.push_back(id);

        wd = sWardenCheckMgr->GetWardenDataById(id);

        // Skip if checks aren't in the stores anymore (e.g. by database edit & reload during runtime)
        if (!wd)
            continue;

        switch (wd->Type)
        {
            case MPQ_CHECK:
            case LUA_STR_CHECK:
            case DRIVER_CHECK:
                buff << uint8(wd->Str.size());
                buff.append(wd->Str.c_str(), wd->Str.size());
                break;
            default:
                break;
        }
    }

    uint8 xorByte = _inputKey[0];

    buff << uint8(0x00);
    buff << uint8(TIMING_CHECK ^ xorByte);                  // check TIMING_CHECK

    uint8 index = 1;

    for (std::list<uint32>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
    {
        // Skip if checks aren't in the stores anymore (e.g. by database edit & reload during runtime)
        wd = sWardenCheckMgr->GetWardenDataById(*itr);

        if (!wd)
            continue;

        type = wd->Type;
        buff << uint8(type ^ xorByte);
        switch (type)
        {
            case MEM_CHECK:
            {
                buff << uint8(0x00);
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
            case PAGE_CHECK_A:
            case PAGE_CHECK_B:
            {
                buff.append(wd->Data.AsByteArray(0, false), wd->Data.GetNumBytes());
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
            case MPQ_CHECK:
            case LUA_STR_CHECK:
            {
                buff << uint8(index++);
                break;
            }
            case DRIVER_CHECK:
            {
                buff.append(wd->Data.AsByteArray(0, false), wd->Data.GetNumBytes());
                buff << uint8(index++);
                break;
            }
            case MODULE_CHECK:
            {
                uint32 seed = static_cast<uint32>(rand32());
                buff << uint32(seed);
                HmacHash hmac(4, (uint8*)&seed);
                hmac.UpdateData(wd->Str);
                hmac.Finalize();
                buff.append(hmac.GetDigest(), hmac.GetLength());
                break;
            }
            /*case PROC_CHECK:
            {
                buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
                buff << uint8(index++);
                buff << uint8(index++);
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }*/
            default:
                break;                                      // Should never happen
        }
    }
    buff << uint8(xorByte);
    buff.hexlike();

    // Encrypt with warden RC4 key.
    EncryptData(const_cast<uint8*>(buff.contents()), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    _session->SendPacket(&pkt);

    // DEBUG CODE: Save time the request was sent for later comparison
    _requestSent = time(NULL);

    _dataSent = true;

    std::stringstream stream;
    stream << "Sent check id's: ";
    for (std::list<uint32>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
        stream << *itr << " ";
    sLog->outWarden(stream.str().c_str());
}
Exemplo n.º 15
0
void WardenWin::RequestData()
{
    sLog->outDebug(LOG_FILTER_WARDEN, "Request data");

    // If all checks were done, fill the todo list again
    if (_memChecksTodo.empty())
        _memChecksTodo.assign(sWardenCheckMgr->MemChecksIdPool.begin(), sWardenCheckMgr->MemChecksIdPool.end());

    if (_otherChecksTodo.empty())
        _otherChecksTodo.assign(sWardenCheckMgr->OtherChecksIdPool.begin(), sWardenCheckMgr->OtherChecksIdPool.end());

    _serverTicks = getMSTime();

    uint16 id;
    uint8 type;
    WardenCheck* wd;
    _currentChecks.clear();

    // Build check request
    for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_MEM_CHECKS); ++i)
    {
        // If todo list is done break loop (will be filled on next Update() run)
        if (_memChecksTodo.empty())
            break;

        // Get check id from the end and remove it from todo
        id = _memChecksTodo.back();
        _memChecksTodo.pop_back();

        // Add the id to the list sent in this cycle
        _currentChecks.push_back(id);
    }

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock);

    for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_OTHER_CHECKS); ++i)
    {
        // If todo list is done break loop (will be filled on next Update() run)
        if (_otherChecksTodo.empty())
            break;

        // Get check id from the end and remove it from todo
        id = _otherChecksTodo.back();
        _otherChecksTodo.pop_back();

        // Add the id to the list sent in this cycle
        _currentChecks.push_back(id);

        wd = sWardenCheckMgr->GetWardenDataById(id);

        switch (wd->Type)
        {
            case MPQ_CHECK:
            case LUA_STR_CHECK:
            case DRIVER_CHECK:
                buff << uint8(wd->Str.size());
                buff.append(wd->Str.c_str(), wd->Str.size());
                break;
            default:
                break;
        }
    }

    uint8 xorByte = _inputKey[0];

    // Add TIMING_CHECK
    buff << uint8(0x00);
    buff << uint8(TIMING_CHECK ^ xorByte);

    uint8 index = 1;

    for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
    {
        wd = sWardenCheckMgr->GetWardenDataById(*itr);

        type = wd->Type;
        buff << uint8(type ^ xorByte);
        switch (type)
        {
            case MEM_CHECK:
            {
                buff << uint8(0x00);
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
            case PAGE_CHECK_A:
            case PAGE_CHECK_B:
            {
                buff.append(wd->Data.AsByteArray(0, false), wd->Data.GetNumBytes());
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
            case MPQ_CHECK:
            case LUA_STR_CHECK:
            {
                buff << uint8(index++);
                break;
            }
            case DRIVER_CHECK:
            {
                buff.append(wd->Data.AsByteArray(0, false), wd->Data.GetNumBytes());
                buff << uint8(index++);
                break;
            }
            case MODULE_CHECK:
            {
                uint32 seed = static_cast<uint32>(rand32());
                buff << uint32(seed);
                HmacHash hmac(4, (uint8*)&seed);
                hmac.UpdateData(wd->Str);
                hmac.Finalize();
                buff.append(hmac.GetDigest(), hmac.GetLength());
                break;
            }
            /*case PROC_CHECK:
            {
                buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
                buff << uint8(index++);
                buff << uint8(index++);
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }*/
            default:
                break;                                      // Should never happen
        }
    }
    buff << uint8(xorByte);
    buff.hexlike();

    // Encrypt with warden RC4 key
    EncryptData(buff.contents(), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    _session->SendPacket(&pkt);

    _dataSent = true;

    std::stringstream stream;
    stream << "Sent check id's: ";
    for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
        stream << *itr << " ";

    sLog->outDebug(LOG_FILTER_WARDEN, "%s", stream.str().c_str());
}
Exemplo n.º 16
0
void WardenWin::RequestData()
{
    sLog.outDebug("Request data");

    if (MemCheck.empty())
        MemCheck.assign(WardenDataStorage.MemCheckIds.begin(), WardenDataStorage.MemCheckIds.end());

    ServerTicks = getMSTime();

    uint32 id;
    uint8 type;
    WardenData* wd;

    SendDataId.clear();

    for (uint32 i = 0; i < sWorld.getConfig(CONFIG_WARDEN_NUM_CHECKS); ++i)                             // for now include 3 MEM_CHECK's
    {
        if (MemCheck.empty())
            break;
        id = MemCheck.back();
        SendDataId.push_back(id);
        MemCheck.pop_back();
    }

    ByteBuffer buff;
    buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);

    // This doesn't apply for 2.4.3
    //for (int i = 0; i < 5; ++i)                             // for now include 5 random checks
    //{
    //    id = irand(1, maxid - 1);
    //    wd = WardenDataStorage.GetWardenDataById(id);
    //    SendDataId.push_back(id);
    //    switch (wd->Type)
    //    {
    //        case MPQ_CHECK:
    //        case LUA_STR_CHECK:
    //        case DRIVER_CHECK:
    //            buff << uint8(wd->str.size());
    //            buff.append(wd->str.c_str(), wd->str.size());
    //            break;
    //        default:
    //            break;
    //    }
    //}

    uint8 xorByte = InputKey[0];

    buff << uint8(0x00);
    buff << uint8(TIMING_CHECK ^ xorByte);                  // check TIMING_CHECK

    uint8 index = 1;

    for (std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr)
    {
        wd = WardenDataStorage.GetWardenDataById(*itr);

        type = wd->Type;
        buff << uint8(type ^ xorByte);
        switch (type)
        {
        case MEM_CHECK:
            {
                buff << uint8(0x00);
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
        case PAGE_CHECK_A:
        case PAGE_CHECK_B:
            {
                buff.append(wd->i.AsByteArray(0), wd->i.GetNumBytes());
                buff << uint32(wd->Address);
                buff << uint8(wd->Length);
                break;
            }
        case MPQ_CHECK:
        case LUA_STR_CHECK:
            {
                buff << uint8(index++);
                break;
            }
        case DRIVER_CHECK:
            {
                buff.append(wd->i.AsByteArray(0), wd->i.GetNumBytes());
                buff << uint8(index++);
                break;
            }
        case MODULE_CHECK:
            {
                uint32 seed = rand32();
                buff << uint32(seed);
                HmacHash hmac(4, (uint8*)&seed);
                hmac.UpdateData(wd->str);
                hmac.Finalize();
                buff.append(hmac.GetDigest(), hmac.GetLength());
                break;
            }
        /*case PROC_CHECK:
        {
            buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes());
            buff << uint8(index++);
            buff << uint8(index++);
            buff << uint32(wd->Address);
            buff << uint8(wd->Length);
            break;
        }*/
        default:
            break;                                      // should never happens
        }
    }
    buff << uint8(xorByte);
    buff.hexlike();

    // Encrypt with warden RC4 key.
    EncryptData(const_cast<uint8*>(buff.contents()), buff.size());

    WorldPacket pkt(SMSG_WARDEN_DATA, buff.size());
    pkt.append(buff);
    Client->SendPacket(&pkt);

    m_WardenDataSent = true;

    std::stringstream stream;
    stream << "Sent check id's: ";
    for (std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr)
        stream << *itr << " ";
    sLog.outDebug("%s", stream.str().c_str());
}
Exemplo n.º 17
0
// 处理809协议的数据
void CPccServer::HandleOutData( socket_t *sock, const char *data, int len )
{
	// 处理809
	if (data == NULL || len < (int)sizeof(Header)) {
		OUT_HEX( sock->_szIp, sock->_port, "PccServer" , (const char *)data, len ) ;
		return;
	}

	Header *header = (Header *) data;
	unsigned int access_code = ntouv32(header->access_code);
	string str_access_code = uitodecstr(access_code);

	unsigned short msg_type = ntouv16(header->msg_type);

	const char *ip    = sock->_szIp ;
	unsigned int port = sock->_port ;

	// 处理加解密数据
	EncryptData( (unsigned char*) data , len , false ) ;

	OUT_RECV( ip, port, str_access_code.c_str(), "%s,from pccserver", _proto_parse.Decoder(data,len).c_str() ) ;
	OUT_HEX( ip, port, str_access_code.c_str(), data, len ) ;

	if (msg_type == DOWN_CONNECT_REQ){
		// 连接请求
		User user = _online_user.GetUserByUserId(str_access_code);
		if ( user._fd != NULL && user._fd != sock ) {
			CloseSocket(user._fd) ;
		}

		DownConnectReq* req = (DownConnectReq*) data;

		user._fd          = sock;
		user._ip          = ip ;
		user._port        = port ;
		user._login_time  = time(0);
		user._msg_seq     = 0;
		user._user_id     = str_access_code ;
		user._access_code = access_code ;
		user._user_state  = User::ON_LINE;

		//一定要设置这个,因为在下行链路还没有建立起来的时候,第一次登录的时候上的那个是不能执行的。
		user._last_active_time = time(0);

		// 添加用户
		if ( ! _online_user.AddUser( str_access_code, user ) ){
			_online_user.SetUser( str_access_code, user  ) ;
		}

		DownConnectRsp resp;
		resp.header.msg_seq 	= ntouv16(_proto_parse.get_next_seq());
		resp.header.access_code = req->header.access_code;
		resp.result = 0;

		if ( SendCrcData( sock,(const char *)&resp,sizeof(resp) ) ) {
			OUT_INFO(ip,port,str_access_code.c_str(),"DOWN_CONNECT_REQ: send DOWN_CONNECT_RSP downlink is online");
		} else {
			OUT_ERROR(ip,port,str_access_code.c_str(),"DOWN_CONNECT_REQ: send DOWN_CONNECT_RSP downlink is online failed");
		}
		// 更新连接状态
		_pEnv->GetPasClient()->UpdateSlaveConn( access_code , CONN_CONNECT ) ;

		return;
	}

	User user = _online_user.GetUserBySocket( sock );

	if (user._user_id.empty()){
		OUT_ERROR(ip,port,str_access_code.c_str(),"msg type %04x, user havn't login,close it %d", msg_type, sock->_fd );
		CloseSocket( sock );
		return;
	}

	// 如果为心跳
	if (msg_type == DOWN_LINKTEST_REQ){
		OUT_RECV(ip,port,user._user_id.c_str(),"DOWN_LINKTEST_REQ");
		DownLinkTestRsp resp;
		resp.header.access_code = header->access_code;
		resp.header.msg_seq 	= ntouv32(_proto_parse.get_next_seq());

		if ( SendCrcData( sock, (const char*) &resp, sizeof(resp) ) )
			OUT_SEND(ip,port,user._user_id.c_str(),"DOWN_LINKTEST_RSP");
		else
			OUT_ERROR(ip,port,user._user_id.c_str(),"DOWN_LINKTEST_RSP") ;
	}
	else if (msg_type == DOWN_DISCONNECT_REQ ) {  // 从链路注销请求
		OUT_RECV(ip,port,user._user_id.c_str(),get_type(msg_type));

		DownDisconnectRsp resp ;
		resp.header.msg_len     = ntouv32( sizeof(resp) ) ;
		resp.header.msg_type    = ntouv16( DOWN_DISCONNECT_RSP ) ;
		resp.header.access_code = header->access_code ;
		resp.header.msg_seq     = ntouv32( _proto_parse.get_next_seq() ) ;

		if ( SendCrcData( sock, (const char*) &resp, sizeof(resp) ) )
			OUT_SEND(ip,port,user._user_id.c_str(),"DOWN_DISCONNECT_RSP");
		else
			OUT_ERROR(ip,port,user._user_id.c_str(),"DOWN_DISCONNECT_RSP") ;

		// 这里由主链路来主动关闭连接,置离线状态由线程自动回收链路
		// user._user_state = User::OFF_LINE ;
	}
	else if (msg_type == DOWN_DISCONNECT_INFORM){ // 主链路消息
		//不管它,由定时线程来完成。
		OUT_RECV(ip,port,user._user_id.c_str(),get_type(msg_type));
	}
	else if (msg_type == DOWN_CLOSELINK_INFORM ){ // 来自主链路

	}
	else{
		// 直接到CLIENT处理
		_pEnv->GetPasClient()->HandlePasDownData( access_code, data, len ) ;
	}

	user._last_active_time = time(0);
	_online_user.SetUser(user._user_id,user);
}