Merge pull request 'Remove Panama & Hybrid encryption schemes' (#37) from nightly into master

Reviewed-on: #37
This commit is contained in:
Exynox 2025-04-12 10:31:00 +03:00
commit 5665bde225
14 changed files with 2 additions and 675 deletions

View File

@ -29,7 +29,7 @@ RUN cd build && make -j $(nproc)
FROM ubuntu:22.04 AS app
WORKDIR /app
RUN apt-get update && apt-get install -y gettext python2 libdevil-dev libbsd-dev && apt-get clean
RUN apt-get update && apt-get install -y gettext python2 libdevil1c2 libbsd0 && apt-get clean
# Copy the binaries from the build stage
COPY --from=build /app/build/src/db/db /bin/db

View File

@ -1,219 +0,0 @@
#include "stdafx.h"
#include "ClientPackageCryptInfo.h"
#include <common/stl.h>
CClientPackageCryptInfo::CClientPackageCryptInfo() : m_pSerializedCryptKeyStream(NULL), m_nCryptKeyPackageCnt(0)
{
}
CClientPackageCryptInfo::~CClientPackageCryptInfo()
{
m_vecPackageCryptKeys.clear();
m_mapPackageSDB.clear();
if( m_pSerializedCryptKeyStream )
{
delete[] m_pSerializedCryptKeyStream;
m_pSerializedCryptKeyStream = NULL;
}
}
bool CClientPackageCryptInfo::LoadPackageCryptFile( const char* pCryptFile )
{
FILE * fp = fopen(pCryptFile, "rb");
if (!fp)
return false;
int iSDBDataOffset;
fread(&iSDBDataOffset, sizeof(int), 1, fp);
int iPackageCnt;
fread( &iPackageCnt, sizeof(int), 1, fp );
m_nCryptKeyPackageCnt += iPackageCnt;
int iCryptKeySize = iSDBDataOffset - 2*sizeof(int);
{
if (0 == iCryptKeySize)
{
SPDLOG_WARN("[PackageCryptInfo] failed to load crypt key. (file: {}, key size: {})", pCryptFile, iCryptKeySize);
m_nCryptKeyPackageCnt -= iPackageCnt;
}
else
{
int nCurKeySize = (int)m_vecPackageCryptKeys.size();
m_vecPackageCryptKeys.resize( nCurKeySize + sizeof(int) + iCryptKeySize);
memcpy( &m_vecPackageCryptKeys[nCurKeySize], &iCryptKeySize, sizeof(int));
fread( &m_vecPackageCryptKeys[nCurKeySize + sizeof(int)], sizeof(BYTE), iCryptKeySize, fp );
SPDLOG_WARN("[PackageCryptInfo] {} loaded. (key size: {}, count: {}, total: {})", pCryptFile, iCryptKeySize, iPackageCnt, m_nCryptKeyPackageCnt);
}
}
//about SDB data
//total packagecnt (4byte)
// for packagecnt
// db name hash 4byte( stl.h stringhash ) +child node size(4byte)
//stream to client
// sdb file cnt( 4byte )
// for sdb file cnt
// filename hash ( stl.h stringhash )
// related map name size(4), relate map name
// sdb block size( 1byte )
// sdb blocks
int iSDBPackageCnt;
fread(&iSDBPackageCnt, sizeof(int), 1, fp);
DWORD dwPackageNameHash, dwPackageStreamSize, dwSDBFileCnt, dwFileNameHash, dwMapNameSize;
std::string strRelatedMapName;
if (0 == iCryptKeySize && 0 == iSDBPackageCnt)
return false;
for( int i = 0; i < iSDBPackageCnt; ++i )
{
fread(&dwPackageNameHash, sizeof(DWORD), 1, fp);
fread(&dwPackageStreamSize, sizeof(DWORD), 1, fp);
fread(&dwSDBFileCnt, sizeof(DWORD), 1, fp);
SPDLOG_INFO("[PackageCryptInfo] SDB Loaded. (Name Hash : {}, Stream Size: {}, File Count: {})", dwPackageNameHash,dwPackageStreamSize, dwSDBFileCnt);
for( int j = 0; j < (int)dwSDBFileCnt; ++j )
{
fread(&dwFileNameHash, sizeof(DWORD), 1, fp);
fread(&dwMapNameSize, sizeof(DWORD), 1, fp);
strRelatedMapName.resize( dwMapNameSize );
fread(&strRelatedMapName[0], sizeof(BYTE), dwMapNameSize, fp);
SPDLOG_INFO("[PackageCryptInfo] \t SDB each file info loaded.(MapName: {}, NameHash: {})", strRelatedMapName.c_str(), dwFileNameHash);
BYTE bSDBStreamSize;
std::vector<BYTE> vecSDBStream;
fread(&bSDBStreamSize, sizeof(BYTE), 1, fp);
vecSDBStream.resize(bSDBStreamSize);
fread(&vecSDBStream[0], sizeof(BYTE), bSDBStreamSize, fp);
//reconstruct it
TPackageSDBMap::iterator it = m_mapPackageSDB.find( strRelatedMapName );
if( it == m_mapPackageSDB.end() )
{
TPerFileSDBInfo fileSDBInfo;
m_mapPackageSDB[strRelatedMapName] = fileSDBInfo;
}
TSupplementaryDataBlockInfo SDBInfo;
std::vector<TSupplementaryDataBlockInfo>& rSDBInfos = m_mapPackageSDB[strRelatedMapName].vecSDBInfos;
{
SDBInfo.dwPackageIdentifier = dwPackageNameHash;
SDBInfo.dwFileIdentifier = dwFileNameHash;
SDBInfo.vecSDBStream.resize( bSDBStreamSize );
memcpy(&SDBInfo.vecSDBStream[0], &vecSDBStream[0], bSDBStreamSize );
rSDBInfos.push_back( SDBInfo );
}
}
}
fclose(fp);
return true;
}
bool CClientPackageCryptInfo::LoadPackageCryptInfo( const char* pCryptInfoDir )
{
DIR * pDir = opendir(pCryptInfoDir);
if (!pDir)
return false;
m_nCryptKeyPackageCnt = 0;
if( m_pSerializedCryptKeyStream )
{
delete[] m_pSerializedCryptKeyStream;
m_pSerializedCryptKeyStream = NULL;
}
m_mapPackageSDB.clear();
m_vecPackageCryptKeys.clear();
const char szPrefixCryptInfoFile[] = "cshybridcrypt";
dirent * pDirEnt;
while ((pDirEnt = readdir(pDir)))
{
//if (strncmp( &(pDirEnt->d_name[0]), szPrefixCryptInfoFile, strlen(szPrefixCryptInfoFile)) )
if (std::string::npos == std::string(pDirEnt->d_name).find(szPrefixCryptInfoFile))
{
SPDLOG_DEBUG("[PackageCryptInfo] {} is not crypt file. pass!", pDirEnt->d_name);
continue;
}
std::string strFullPathName = std::string(pCryptInfoDir) + std::string(pDirEnt->d_name);
SPDLOG_DEBUG("[PackageCryptInfo] Try to load crypt file: {}", strFullPathName.c_str());
if (false == LoadPackageCryptFile( strFullPathName.c_str() ))
SPDLOG_DEBUG("[PackageCryptInfo] Failed to load {}", strFullPathName.c_str());
}
closedir(pDir);
return true;
}
void CClientPackageCryptInfo::GetPackageCryptKeys( BYTE** ppData, int& iDataSize )
{
int nCryptKeySize = m_vecPackageCryptKeys.size();
int iStreamSize = sizeof(int)+nCryptKeySize;
//NOTE : Crypt Key Info isn`t updated during runtime. ( in case of file reloading all data is cleared & recreated )
//it`s not safe but due to performance benefit we don`t do re-serialize.
if( m_pSerializedCryptKeyStream )
{
*ppData = m_pSerializedCryptKeyStream;
iDataSize = iStreamSize;
return;
}
if( nCryptKeySize > 0 )
{
m_pSerializedCryptKeyStream = new BYTE[iStreamSize];
memcpy(&m_pSerializedCryptKeyStream[0], &m_nCryptKeyPackageCnt, sizeof(int) );
memcpy(&m_pSerializedCryptKeyStream[sizeof(int)], &m_vecPackageCryptKeys[0], nCryptKeySize );
*ppData = m_pSerializedCryptKeyStream;
iDataSize = iStreamSize;
}
else
{
*ppData = NULL;
iDataSize = 0;
}
}
bool CClientPackageCryptInfo::GetRelatedMapSDBStreams(const char* pMapName, BYTE** ppData, int& iDataSize )
{
std::string strLowerMapName = pMapName;
stl_lowers(strLowerMapName);
TPackageSDBMap::iterator it = m_mapPackageSDB.find( strLowerMapName.c_str() );
if( it == m_mapPackageSDB.end() || it->second.vecSDBInfos.size() == 0 )
{
SPDLOG_ERROR("GetRelatedMapSDBStreams Failed({})", strLowerMapName.c_str());
return false;
}
*ppData = it->second.GetSerializedStream();
iDataSize = it->second.GetSize();
return true;
}

View File

@ -1,117 +0,0 @@
#ifndef __INC_CLIENTPACKAGE_CRYPTINFO_H
#define __INC_CLIENTPACKAGE_CRYPTINFO_H
#include <unordered_map>
#pragma pack(1)
typedef struct SSupplementaryDataBlockInfo
{
DWORD dwPackageIdentifier;
DWORD dwFileIdentifier;
std::vector<BYTE> vecSDBStream;
void Serialize( BYTE* pStream )
{
memcpy(pStream, &dwPackageIdentifier, sizeof(DWORD));
memcpy(pStream+4, &dwFileIdentifier, sizeof(DWORD));
BYTE bSize = vecSDBStream.size();
memcpy(pStream+8, &bSize, sizeof(BYTE));
memcpy(pStream+9, &vecSDBStream[0], bSize);
}
DWORD GetSerializedSize() const
{
return sizeof(DWORD)*2 + sizeof(BYTE) + vecSDBStream.size();
}
} TSupplementaryDataBlockInfo;
#pragma pack()
class CClientPackageCryptInfo
{
public:
CClientPackageCryptInfo();
~CClientPackageCryptInfo();
bool LoadPackageCryptInfo( const char* pCryptInfoDir );
void GetPackageCryptKeys( BYTE** ppData, int& iDataSize );
bool GetRelatedMapSDBStreams(const char* pMapName, BYTE** ppData, int& iDataSize );
private:
bool LoadPackageCryptFile( const char* pCryptFile );
private:
int m_nCryptKeyPackageCnt;
std::vector<BYTE> m_vecPackageCryptKeys;
BYTE* m_pSerializedCryptKeyStream;
typedef struct SPerFileSDBInfo
{
SPerFileSDBInfo() : m_pSerializedStream(NULL) {}
~SPerFileSDBInfo()
{
if(m_pSerializedStream)
{
delete[]m_pSerializedStream;
}
}
DWORD GetSize() const
{
DWORD dwSize = 4; //initial vecSDBInfo count
for(int i = 0; i < (int)vecSDBInfos.size(); ++i)
{
dwSize += vecSDBInfos[i].GetSerializedSize();
}
return dwSize;
}
BYTE* GetSerializedStream()
{
//NOTE : SDB Data isn`t updated during runtime. ( in case of file reloading all data is cleared & recreated )
//it`s not safe but due to performance benefit we don`t do re-serialize.
if(m_pSerializedStream)
return m_pSerializedStream;
m_pSerializedStream = new BYTE[GetSize()];
int iWrittenOffset = 0;
int iSDBInfoSize = vecSDBInfos.size();
//write size
memcpy( m_pSerializedStream, &iSDBInfoSize, sizeof(int) );
iWrittenOffset += sizeof(int);
for(int i = 0; i < iSDBInfoSize; ++i)
{
vecSDBInfos[i].Serialize( m_pSerializedStream + iWrittenOffset );
iWrittenOffset += vecSDBInfos[i].GetSerializedSize();
}
return m_pSerializedStream;
}
std::vector<TSupplementaryDataBlockInfo> vecSDBInfos;
private:
BYTE* m_pSerializedStream;
} TPerFileSDBInfo;
typedef std::unordered_map<std::string, TPerFileSDBInfo > TPackageSDBMap; //key: related map name
TPackageSDBMap m_mapPackageSDB;
};
#endif //__INC_CLIENTPACKAGE_CRYPTINFO_H

View File

@ -5046,24 +5046,6 @@ bool CHARACTER::WarpSet(int x, int y, int lPrivateMapIndex)
return false;
}
//Send Supplementary Data Block if new map requires security packages in loading this map
{
LONG lCurAddr;
int lCurMapIndex = 0;
WORD wCurPort;
CMapLocation::instance().Get(GetX(), GetY(), lCurMapIndex, lCurAddr, wCurPort);
//do not send SDB files if char is in the same map
if( lCurMapIndex != lMapIndex )
{
const TMapRegion * rMapRgn = SECTREE_MANAGER::instance().GetMapRegion(lMapIndex);
{
DESC_MANAGER::instance().SendClientPackageSDBToLoadMap( GetDesc(), rMapRgn->strMapName.c_str() );
}
}
}
if (lPrivateMapIndex >= 10000)
{
if (lPrivateMapIndex / 10000 != lMapIndex)

View File

@ -110,7 +110,6 @@ void DESC::Initialize()
m_pkLoginKey = NULL;
m_dwLoginKey = 0;
m_dwPanamaKey = 0;
m_bCRCMagicCubeIdx = 0;
m_dwProcCRC = 0;

View File

@ -146,9 +146,6 @@ class DESC
unsigned int GetMatrixCols();
bool CheckMatrixTryCount();
void SetPanamaKey(DWORD dwKey) {m_dwPanamaKey = dwKey;}
DWORD GetPanamaKey() const { return m_dwPanamaKey; }
void SetLoginKey(DWORD dwKey);
void SetLoginKey(CLoginKey * pkKey);
DWORD GetLoginKey();
@ -208,7 +205,6 @@ class DESC
CLoginKey * m_pkLoginKey;
DWORD m_dwLoginKey;
DWORD m_dwPanamaKey;
BYTE m_bCRCMagicCubeIdx;
DWORD m_dwProcCRC;

View File

@ -10,7 +10,6 @@
#include "protocol.h"
#include "messenger_manager.h"
#include "p2p.h"
#include "ClientPackageCryptInfo.h"
struct valid_ip
{
@ -53,15 +52,11 @@ int IsValidIP(struct valid_ip* ip_table, const char *host)
DESC_MANAGER::DESC_MANAGER() : m_bDestroyed(false)
{
Initialize();
//NOTE : Destroy 끝에서 Initialize 를 부르는건 또 무슨 짓이냐..-_-; 정말
m_pPackageCrypt = new CClientPackageCryptInfo;
}
DESC_MANAGER::~DESC_MANAGER()
{
Destroy();
delete m_pPackageCrypt;
}
void DESC_MANAGER::Initialize()
@ -479,55 +474,3 @@ void DESC_MANAGER::ProcessExpiredLoginKey()
}
}
}
bool DESC_MANAGER::LoadClientPackageCryptInfo(const char* pDirName)
{
return m_pPackageCrypt->LoadPackageCryptInfo(pDirName);
}
#ifdef __FreeBSD__
void DESC_MANAGER::NotifyClientPackageFileChanged( const std::string& dirName, eFileUpdatedOptions eUpdateOption )
{
Instance().LoadClientPackageCryptInfo(dirName.c_str());
}
#endif
void DESC_MANAGER::SendClientPackageCryptKey( LPDESC desc )
{
if( !desc )
{
return;
}
TPacketGCHybridCryptKeys packet;
{
packet.bHeader = HEADER_GC_HYBRIDCRYPT_KEYS;
m_pPackageCrypt->GetPackageCryptKeys( &(packet.pDataKeyStream), packet.KeyStreamLen );
}
if( packet.KeyStreamLen > 0 )
{
desc->Packet( packet.GetStreamData(), packet.GetStreamSize() );
}
}
void DESC_MANAGER::SendClientPackageSDBToLoadMap( LPDESC desc, const char* pMapName )
{
if( !desc )
{
return;
}
TPacketGCPackageSDB packet;
{
packet.bHeader = HEADER_GC_HYBRIDCRYPT_SDB;
if( !m_pPackageCrypt->GetRelatedMapSDBStreams( pMapName, &(packet.m_pDataSDBStream), packet.iStreamLen ) )
return;
}
if( packet.iStreamLen > 0 )
{
desc->Packet( packet.GetStreamData(), packet.GetStreamSize());
}
}

View File

@ -12,7 +12,6 @@
#include <event2/listener.h>
class CLoginKey;
class CClientPackageCryptInfo;
class DESC_MANAGER : public singleton<DESC_MANAGER>
{
@ -69,14 +68,6 @@ class DESC_MANAGER : public singleton<DESC_MANAGER>
bool IsP2PDescExist(const char * szHost, WORD wPort);
// for C/S hybrid crypt
bool LoadClientPackageCryptInfo(const char* pDirName);
void SendClientPackageCryptKey( LPDESC desc );
void SendClientPackageSDBToLoadMap( LPDESC desc, const char* pMapName );
#ifdef __FreeBSD__
static void NotifyClientPackageFileChanged( const std::string& fileName, eFileUpdatedOptions eUpdateOption );
#endif
private:
bool m_bDisconnectInvalidCRC;
@ -99,8 +90,6 @@ class DESC_MANAGER : public singleton<DESC_MANAGER>
int m_aiEmpireUserCount[EMPIRE_MAX_NUM];
bool m_bDestroyed;
CClientPackageCryptInfo* m_pPackageCrypt;
};
#endif

View File

@ -82,10 +82,8 @@ void CInputAuth::Login(LPDESC d, const char * c_pData)
}
DWORD dwKey = DESC_MANAGER::instance().CreateLoginKey(d);
DWORD dwPanamaKey = dwKey ^ pinfo->adwClientKey[0] ^ pinfo->adwClientKey[1] ^ pinfo->adwClientKey[2] ^ pinfo->adwClientKey[3];
d->SetPanamaKey(dwPanamaKey);
SPDLOG_DEBUG("InputAuth::Login : key {}:{} login {}", dwKey, dwPanamaKey, login);
SPDLOG_DEBUG("InputAuth::Login : key {} login {}", dwKey, login);
TPacketCGLogin3 * p = M2_NEW TPacketCGLogin3;
memcpy(p, pinfo, sizeof(TPacketCGLogin3));

View File

@ -37,7 +37,6 @@
#include "horsename_manager.h"
#include "gm.h"
#include "panama.h"
#include "map_location.h"
#include "DragonSoul.h"
@ -418,14 +417,6 @@ void CInputDB::PlayerLoad(LPDESC d, const char * data)
ch->MainCharacterPacket();
int lPublicMapIndex = lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex;
//Send Supplementary Data Block if new map requires security packages in loading this map
const TMapRegion * rMapRgn = SECTREE_MANAGER::instance().GetMapRegion(lPublicMapIndex);
if( rMapRgn )
{
DESC_MANAGER::instance().SendClientPackageSDBToLoadMap( d, rMapRgn->strMapName.c_str() );
}
//if (!map_allow_find(lMapIndex >= 10000 ? lMapIndex / 10000 : lMapIndex) || !CheckEmpire(ch, lMapIndex))
if (!map_allow_find(lPublicMapIndex))
{
SPDLOG_ERROR("InputDB::PlayerLoad : entering {} map is not allowed here (name: {}, empire {})",
@ -1706,22 +1697,9 @@ void CInputDB::AuthLogin(LPDESC d, const char * c_pData)
ptoc.bHeader = HEADER_GC_AUTH_SUCCESS;
if (bResult)
{
// Panama 암호화 팩에 필요한 키 보내기
SendPanamaList(d);
ptoc.dwLoginKey = d->GetLoginKey();
//NOTE: AuthSucess보다 먼저 보내야지 안그러면 PHASE Close가 되서 보내지지 않는다.-_-
//Send Client Package CryptKey
{
DESC_MANAGER::instance().SendClientPackageCryptKey(d);
DESC_MANAGER::instance().SendClientPackageSDBToLoadMap(d, MAPNAME_DEFAULT);
}
}
else
{
ptoc.dwLoginKey = 0;
}
ptoc.bResult = bResult;

View File

@ -51,7 +51,6 @@
#include "horsename_manager.h"
#include "MarkManager.h"
#include "spam.h"
#include "panama.h"
#include "threeway_war.h"
#include "DragonLair.h"
#include "skill_power.h"
@ -402,20 +401,10 @@ int main(int argc, char **argv)
Cube_init();
Blend_Item_init();
ani_init();
PanamaLoad();
if ( g_bTrafficProfileOn )
TrafficProfiler::instance().Initialize( TRAFFIC_PROFILE_FLUSH_CYCLE, "ProfileLog" );
// Client PackageCrypt
//TODO : make it config
const std::string strPackageCryptInfoDir = "package/";
if( !desc_manager.LoadClientPackageCryptInfo( strPackageCryptInfoDir.c_str() ) )
{
SPDLOG_WARN("Failed to Load ClientPackageCryptInfo Files ({})", strPackageCryptInfoDir);
}
while (idle());
SPDLOG_INFO("<shutdown> Starting...");

View File

@ -260,13 +260,6 @@ enum
HEADER_GC_AUTH_SUCCESS = 150,
HEADER_GC_PANAMA_PACK = 151,
//HYBRID CRYPT
HEADER_GC_HYBRIDCRYPT_KEYS = 152,
HEADER_GC_HYBRIDCRYPT_SDB = 153, // SDB means Supplmentary Data Blocks
//HYBRID CRYPT
// ROULETTE
HEADER_GC_ROULETTE = 200,
// END_ROULETTE
@ -2119,110 +2112,6 @@ typedef struct SPacketGGCheckAwakeness
BYTE bHeader;
} TPacketGGCheckAwakeness;
typedef struct SPacketGCPanamaPack
{
BYTE bHeader;
char szPackName[256];
BYTE abIV[32];
} TPacketGCPanamaPack;
//TODO : 아우 짱나..가변패킷 사이즈 받아들일수 있게 패킷 핸들러 Refactoring 하자.
typedef struct SPacketGCHybridCryptKeys
{
SPacketGCHybridCryptKeys() : m_pStream(NULL) {}
~SPacketGCHybridCryptKeys()
{
//GCC 에선 NULL delete 해도 괜찮나? 일단 안전하게 NULL 체크 하자. ( 근데 이거 C++ 표준아니었나 --a )
if( m_pStream )
{
delete[] m_pStream;
m_pStream = NULL;
}
}
DWORD GetStreamSize()
{
return sizeof(bHeader) + sizeof(WORD) + sizeof(INT) + KeyStreamLen;
}
BYTE* GetStreamData()
{
if( m_pStream )
delete[] m_pStream;
uDynamicPacketSize = (WORD)GetStreamSize();
m_pStream = new BYTE[ uDynamicPacketSize ];
memcpy( m_pStream, &bHeader, 1 );
memcpy( m_pStream+1, &uDynamicPacketSize, 2 );
memcpy( m_pStream+3, &KeyStreamLen, 4 );
if( KeyStreamLen > 0 )
memcpy( m_pStream+7, pDataKeyStream, KeyStreamLen );
return m_pStream;
}
BYTE bHeader;
WORD uDynamicPacketSize; // 빌어먹을 클라 DynamicPacketHeader 구조때문에 맞춰줘야한다 -_-;
INT KeyStreamLen;
BYTE* pDataKeyStream;
private:
BYTE* m_pStream;
} TPacketGCHybridCryptKeys;
typedef struct SPacketGCPackageSDB
{
SPacketGCPackageSDB() : m_pDataSDBStream(NULL), m_pStream(NULL) {}
~SPacketGCPackageSDB()
{
if( m_pStream )
{
delete[] m_pStream;
m_pStream = NULL;
}
}
DWORD GetStreamSize()
{
return sizeof(bHeader) + sizeof(WORD) + sizeof(INT) + iStreamLen;
}
BYTE* GetStreamData()
{
if( m_pStream )
delete[] m_pStream;
uDynamicPacketSize = GetStreamSize();
m_pStream = new BYTE[ uDynamicPacketSize ];
memcpy( m_pStream, &bHeader, 1 );
memcpy( m_pStream+1, &uDynamicPacketSize, 2 );
memcpy( m_pStream+3, &iStreamLen, 4 );
if( iStreamLen > 0 )
memcpy( m_pStream+7, m_pDataSDBStream, iStreamLen );
return m_pStream;
}
BYTE bHeader;
WORD uDynamicPacketSize; // 빌어먹을 클라 DynamicPacketHeader 구조때문에 맞춰줘야한다 -_-;
INT iStreamLen;
BYTE* m_pDataSDBStream;
private:
BYTE* m_pStream;
} TPacketGCPackageSDB;
#define MAX_EFFECT_FILE_NAME 128
typedef struct SPacketGCSpecificEffect
{

View File

@ -1,93 +0,0 @@
#include "stdafx.h"
#include "desc.h"
#include "packet.h"
typedef std::vector<std::pair<std::string, BYTE* > > PanamaVectorType;
static PanamaVectorType s_panamaVector;
size_t PanamaLoad()
{
FILE* fp;
fp = fopen("panama/panama.lst", "r");
if (!fp)
return 0;
char buf[256];
while (fgets(buf, 256, fp))
{
char szPackName[256];
char szIVFileName[512];
char szIVFileNameConfig[256];
sscanf(buf, " %s %s ", szPackName, szIVFileNameConfig);
snprintf(szIVFileName, sizeof(szIVFileName), "panama/%s", szIVFileNameConfig);
FILE * fpIV = fopen(szIVFileName, "rb");
if (!fpIV)
{
SPDLOG_ERROR("cannot open iv file {}", szIVFileName);
continue;
}
BYTE abIV[32];
if (32 != fread(abIV, sizeof(BYTE), 32, fpIV))
SPDLOG_ERROR("IV file format error! {}", szIVFileName);
else
{
char szHex[64 + 1];
for (int i = 0; i < 32; ++i)
snprintf(szHex + i * 2, sizeof(szHex) - i * 2, "%02x", abIV[i]);
SPDLOG_DEBUG("PANAMA: {} {}", szPackName, szHex);
s_panamaVector.push_back(std::make_pair(szPackName, M2_NEW BYTE[32]));
memcpy(s_panamaVector[s_panamaVector.size() - 1].second, abIV, 32);
}
fclose(fpIV);
}
fclose(fp);
return s_panamaVector.size();
}
void PanamaDestroy()
{
PanamaVectorType::iterator it = s_panamaVector.begin();
while (it != s_panamaVector.end()) {
M2_DELETE_ARRAY(it->second);
++it;
}
}
void SendPanamaList(LPDESC d)
{
TPacketGCPanamaPack pack;
pack.bHeader = HEADER_GC_PANAMA_PACK;
PanamaVectorType::iterator it = s_panamaVector.begin();
while (it != s_panamaVector.end())
{
strlcpy(pack.szPackName, it->first.c_str(), sizeof(pack.szPackName));
memcpy(pack.abIV, it->second, sizeof(pack.abIV));
DWORD* ivs = (DWORD*)pack.abIV;
for (int i = 0; i != 32 / sizeof(DWORD); i++)
{
ivs[i] ^= d->GetPanamaKey() + i * 16777619; // 더블워드단위로 변형된 파나마 키를 XOR 해준다
}
++it;
d->Packet(&pack, sizeof(pack));
}
}

View File

@ -1,7 +0,0 @@
#ifndef __INC_METIN_II_PANAMA_H__
#define __INC_METIN_II_PANAMA_H__
extern size_t PanamaLoad();
extern void SendPanamaList(LPDESC d);
#endif