mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 01:24:18 +00:00
Merge pull request #7564 from Robyt3/HTTP-Download-Check-Sha256
Check SHA256 of downloaded maps and community icons
This commit is contained in:
commit
6a503cf9af
|
@ -1533,6 +1533,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket, int Conn, bool Dummy)
|
|||
m_pMapdownloadTask = HttpGetFile(pMapUrl ? pMapUrl : aUrl, Storage(), m_aMapdownloadFilenameTemp, IStorage::TYPE_SAVE);
|
||||
m_pMapdownloadTask->Timeout(CTimeout{g_Config.m_ClMapDownloadConnectTimeoutMs, 0, g_Config.m_ClMapDownloadLowSpeedLimit, g_Config.m_ClMapDownloadLowSpeedTime});
|
||||
m_pMapdownloadTask->MaxResponseSize(1024 * 1024 * 1024); // 1 GiB
|
||||
m_pMapdownloadTask->ExpectSha256(*pMapSha256);
|
||||
Engine()->AddJob(m_pMapdownloadTask);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -122,6 +122,7 @@ bool HttpHasIpresolveBug()
|
|||
CHttpRequest::CHttpRequest(const char *pUrl)
|
||||
{
|
||||
str_copy(m_aUrl, pUrl);
|
||||
sha256_init(&m_ActualSha256);
|
||||
}
|
||||
|
||||
CHttpRequest::~CHttpRequest()
|
||||
|
@ -311,6 +312,9 @@ size_t CHttpRequest::OnData(char *pData, size_t DataSize)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
sha256_update(&m_ActualSha256, pData, DataSize);
|
||||
|
||||
if(!m_WriteToFile)
|
||||
{
|
||||
if(DataSize == 0)
|
||||
|
@ -358,6 +362,23 @@ int CHttpRequest::OnCompletion(int State)
|
|||
if(m_Abort)
|
||||
State = HTTP_ABORTED;
|
||||
|
||||
if(State == HTTP_DONE && m_ExpectedSha256 != SHA256_ZEROED)
|
||||
{
|
||||
const SHA256_DIGEST ActualSha256 = sha256_finish(&m_ActualSha256);
|
||||
if(ActualSha256 != m_ExpectedSha256)
|
||||
{
|
||||
if(g_Config.m_DbgCurl || m_LogProgress >= HTTPLOG::FAILURE)
|
||||
{
|
||||
char aActualSha256[SHA256_MAXSTRSIZE];
|
||||
sha256_str(ActualSha256, aActualSha256, sizeof(aActualSha256));
|
||||
char aExpectedSha256[SHA256_MAXSTRSIZE];
|
||||
sha256_str(m_ExpectedSha256, aExpectedSha256, sizeof(aExpectedSha256));
|
||||
dbg_msg("http", "SHA256 mismatch: got=%s, expected=%s, url=%s", aActualSha256, aExpectedSha256, m_aUrl);
|
||||
}
|
||||
State = HTTP_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_WriteToFile)
|
||||
{
|
||||
if(m_File && io_close(m_File) != 0)
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#ifndef ENGINE_SHARED_HTTP_H
|
||||
#define ENGINE_SHARED_HTTP_H
|
||||
|
||||
#include <base/hash_ctxt.h>
|
||||
|
||||
#include <engine/shared/jobs.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <engine/shared/jobs.h>
|
||||
|
||||
typedef struct _json_value json_value;
|
||||
class IStorage;
|
||||
|
@ -58,6 +61,9 @@ class CHttpRequest : public IJob
|
|||
int64_t m_MaxResponseSize = -1;
|
||||
REQUEST m_Type = REQUEST::GET;
|
||||
|
||||
SHA256_CTX m_ActualSha256;
|
||||
SHA256_DIGEST m_ExpectedSha256 = SHA256_ZEROED;
|
||||
|
||||
bool m_WriteToFile = false;
|
||||
|
||||
uint64_t m_ResponseLength = 0;
|
||||
|
@ -105,6 +111,7 @@ public:
|
|||
void LogProgress(HTTPLOG LogProgress) { m_LogProgress = LogProgress; }
|
||||
void IpResolve(IPRESOLVE IpResolve) { m_IpResolve = IpResolve; }
|
||||
void WriteToFile(IStorage *pStorage, const char *pDest, int StorageType);
|
||||
void ExpectSha256(const SHA256_DIGEST &Sha256) { m_ExpectedSha256 = Sha256; }
|
||||
void Head() { m_Type = REQUEST::HEAD; }
|
||||
void Post(const unsigned char *pData, size_t DataLength)
|
||||
{
|
||||
|
|
|
@ -542,7 +542,7 @@ protected:
|
|||
int OnCompletion(int State) override;
|
||||
|
||||
public:
|
||||
CCommunityIconDownloadJob(CMenus *pMenus, const char *pCommunityId, const char *pUrl);
|
||||
CCommunityIconDownloadJob(CMenus *pMenus, const char *pCommunityId, const char *pUrl, const SHA256_DIGEST &Sha256);
|
||||
};
|
||||
struct SCommunityIcon
|
||||
{
|
||||
|
|
|
@ -1821,11 +1821,12 @@ int CMenus::CCommunityIconDownloadJob::OnCompletion(int State)
|
|||
return State;
|
||||
}
|
||||
|
||||
CMenus::CCommunityIconDownloadJob::CCommunityIconDownloadJob(CMenus *pMenus, const char *pCommunityId, const char *pUrl) :
|
||||
CMenus::CCommunityIconDownloadJob::CCommunityIconDownloadJob(CMenus *pMenus, const char *pCommunityId, const char *pUrl, const SHA256_DIGEST &Sha256) :
|
||||
CHttpRequest(pUrl),
|
||||
CAbstractCommunityIconJob(pMenus, pCommunityId, IStorage::TYPE_SAVE)
|
||||
{
|
||||
WriteToFile(pMenus->Storage(), m_aPath, IStorage::TYPE_SAVE);
|
||||
ExpectSha256(Sha256);
|
||||
Timeout(CTimeout{0, 0, 0, 0});
|
||||
LogProgress(HTTPLOG::FAILURE);
|
||||
}
|
||||
|
@ -2005,7 +2006,7 @@ void CMenus::UpdateCommunityIcons()
|
|||
});
|
||||
if(pExistingDownload == m_CommunityIconDownloadJobs.end() && (ExistingIcon == m_vCommunityIcons.end() || ExistingIcon->m_Sha256 != Community.IconSha256()))
|
||||
{
|
||||
std::shared_ptr<CCommunityIconDownloadJob> pJob = std::make_shared<CCommunityIconDownloadJob>(this, Community.Id(), Community.IconUrl());
|
||||
std::shared_ptr<CCommunityIconDownloadJob> pJob = std::make_shared<CCommunityIconDownloadJob>(this, Community.Id(), Community.IconUrl(), Community.IconSha256());
|
||||
Engine()->AddJob(pJob);
|
||||
m_CommunityIconDownloadJobs.push_back(pJob);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue