Quote
case OP_FILEREQANSNOFIL:
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_FileReqAnsNoFil", client, (size >= 16) ? packet : NULL);
theStats.AddDownDataOverheadFileRequest(size);
if (size == 16)
{
CPartFile* reqfile = theApp.downloadqueue->GetFileByID(packet);
if (!reqfile){
client->CheckFailedFileIdReqs(packet);
break;
}
else
reqfile->m_DeadSourceList.AddDeadSource(client);
// if that client does not have my file maybe has another different
// we try to swap to another file ignoring no needed parts files
switch (client->GetDownloadState())
{
case DS_CONNECTED:
case DS_ONQUEUE:
case DS_NONEEDEDPARTS:
client->DontSwapTo(client->GetRequestFile()); // ZZ:DownloadManager
if (!client->SwapToAnotherFile(_T("Source says it doesn't have the file. CClientReqSocket::ProcessPacket()"), true, true, true, NULL, false, false)) { // ZZ:DownloadManager
theApp.downloadqueue->RemoveSource(client);
}
break;
}
break;
}
throw GetResString(IDS_ERR_WRONGPACKAGESIZE);
break;
}
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_FileReqAnsNoFil", client, (size >= 16) ? packet : NULL);
theStats.AddDownDataOverheadFileRequest(size);
if (size == 16)
{
CPartFile* reqfile = theApp.downloadqueue->GetFileByID(packet);
if (!reqfile){
client->CheckFailedFileIdReqs(packet);
break;
}
else
reqfile->m_DeadSourceList.AddDeadSource(client);
// if that client does not have my file maybe has another different
// we try to swap to another file ignoring no needed parts files
switch (client->GetDownloadState())
{
case DS_CONNECTED:
case DS_ONQUEUE:
case DS_NONEEDEDPARTS:
client->DontSwapTo(client->GetRequestFile()); // ZZ:DownloadManager
if (!client->SwapToAnotherFile(_T("Source says it doesn't have the file. CClientReqSocket::ProcessPacket()"), true, true, true, NULL, false, false)) { // ZZ:DownloadManager
theApp.downloadqueue->RemoveSource(client);
}
break;
}
break;
}
throw GetResString(IDS_ERR_WRONGPACKAGESIZE);
break;
}
In that codepart we do NOT check if the "correct" file was sent via the packet! That is not only a possible exploit but also not very good in general... I fixed it that way now:
Quote
case OP_FILEREQANSNOFIL:
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_FileReqAnsNoFil", client, (size >= 16) ? packet : NULL);
theStats.AddDownDataOverheadFileRequest(size);
if (size == 16)
{
CPartFile* reqfile = theApp.downloadqueue->GetFileByID(packet);
if (!reqfile){
client->CheckFailedFileIdReqs(packet);
break;
}
//else
//why should he send that for a different file!?
//might happen due to swapping, I guess...
//first check whether he meant his own reqfile
CKnownFile* upreq = theApp.sharedfiles->GetFileByID(client->GetUploadFileID());
if(upreq && upreq == reqfile)
{
DebugLogWarning(_T("Dropped src: (%s) does not seem to have own reqfile (TCP)!"), DbgGetClientInfo());
theApp.uploadqueue->RemoveFromUploadQueue(client, _T("Src says he does not have the file he's dl'ing"));
theApp.uploadqueue->RemoveFromWaitingQueue(client);
}
//now, check if he sent an answer for a wrong file
//if it's not the reqfile, it might be another file we asked for
if(client->GetRequestFile() != reqfile)
{
CString sfind = _T("not found");
bool bFound = false;
POSITION pos = client->m_OtherRequests_list.Find(reqfile);
if(pos)
{
bFound = true;
sfind = _T("m_OtherRequests_list");
client->m_OtherRequests_list.RemoveAt(pos);
pos = reqfile->A4AFsrclist.Find(client);
if(pos)
reqfile->A4AFsrclist.RemoveAt(pos);
theApp.emuledlg->transferwnd->downloadlistctrl.RemoveSource(client, reqfile);
}
else
{
pos = client->m_OtherNoNeeded_list.Find(reqfile);
if(pos)
{
bFound = true;
sfind = _T("m_OtherNoNeeded_list");
client->m_OtherNoNeeded_list.RemoveAt(pos);
pos = reqfile->A4AFsrclist.Find(client);
if(pos)
reqfile->A4AFsrclist.RemoveAt(pos);
theApp.emuledlg->transferwnd->downloadlistctrl.RemoveSource(client, reqfile);
}
}
theApp.QueueDebugLogLineEx(LOG_INFO, _T("DBG: OP_FILEREQANSNOFIL break because of different file (%s)"), sfind);
if(bFound) //add him anyways...? dunno... if we don't want something then there's something wrong!
reqfile->m_DeadSourceList.AddDeadSource(client);
else
client->CheckFailedFileIdReqs(packet);
break;
}
reqfile->m_DeadSourceList.AddDeadSource(client);
// if that client does not have my file maybe has another different
// we try to swap to another file ignoring no needed parts files
switch (client->GetDownloadState())
{
case DS_CONNECTED:
case DS_ONQUEUE:
case DS_NONEEDEDPARTS:
client->DontSwapTo(client->GetRequestFile()); // ZZ:DownloadManager
if (!client->SwapToAnotherFile(_T("Source says it doesn't have the file. CClientReqSocket::ProcessPacket()"), true, true, true, NULL, false, false)) { // ZZ:DownloadManager
theApp.downloadqueue->RemoveSource(client);
}
break;
}
break;
}
throw GetResString(IDS_ERR_WRONGPACKAGESIZE);
break;
}
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugRecv("OP_FileReqAnsNoFil", client, (size >= 16) ? packet : NULL);
theStats.AddDownDataOverheadFileRequest(size);
if (size == 16)
{
CPartFile* reqfile = theApp.downloadqueue->GetFileByID(packet);
if (!reqfile){
client->CheckFailedFileIdReqs(packet);
break;
}
//else
//why should he send that for a different file!?
//might happen due to swapping, I guess...
//first check whether he meant his own reqfile
CKnownFile* upreq = theApp.sharedfiles->GetFileByID(client->GetUploadFileID());
if(upreq && upreq == reqfile)
{
DebugLogWarning(_T("Dropped src: (%s) does not seem to have own reqfile (TCP)!"), DbgGetClientInfo());
theApp.uploadqueue->RemoveFromUploadQueue(client, _T("Src says he does not have the file he's dl'ing"));
theApp.uploadqueue->RemoveFromWaitingQueue(client);
}
//now, check if he sent an answer for a wrong file
//if it's not the reqfile, it might be another file we asked for
if(client->GetRequestFile() != reqfile)
{
CString sfind = _T("not found");
bool bFound = false;
POSITION pos = client->m_OtherRequests_list.Find(reqfile);
if(pos)
{
bFound = true;
sfind = _T("m_OtherRequests_list");
client->m_OtherRequests_list.RemoveAt(pos);
pos = reqfile->A4AFsrclist.Find(client);
if(pos)
reqfile->A4AFsrclist.RemoveAt(pos);
theApp.emuledlg->transferwnd->downloadlistctrl.RemoveSource(client, reqfile);
}
else
{
pos = client->m_OtherNoNeeded_list.Find(reqfile);
if(pos)
{
bFound = true;
sfind = _T("m_OtherNoNeeded_list");
client->m_OtherNoNeeded_list.RemoveAt(pos);
pos = reqfile->A4AFsrclist.Find(client);
if(pos)
reqfile->A4AFsrclist.RemoveAt(pos);
theApp.emuledlg->transferwnd->downloadlistctrl.RemoveSource(client, reqfile);
}
}
theApp.QueueDebugLogLineEx(LOG_INFO, _T("DBG: OP_FILEREQANSNOFIL break because of different file (%s)"), sfind);
if(bFound) //add him anyways...? dunno... if we don't want something then there's something wrong!
reqfile->m_DeadSourceList.AddDeadSource(client);
else
client->CheckFailedFileIdReqs(packet);
break;
}
reqfile->m_DeadSourceList.AddDeadSource(client);
// if that client does not have my file maybe has another different
// we try to swap to another file ignoring no needed parts files
switch (client->GetDownloadState())
{
case DS_CONNECTED:
case DS_ONQUEUE:
case DS_NONEEDEDPARTS:
client->DontSwapTo(client->GetRequestFile()); // ZZ:DownloadManager
if (!client->SwapToAnotherFile(_T("Source says it doesn't have the file. CClientReqSocket::ProcessPacket()"), true, true, true, NULL, false, false)) { // ZZ:DownloadManager
theApp.downloadqueue->RemoveSource(client);
}
break;
}
break;
}
throw GetResString(IDS_ERR_WRONGPACKAGESIZE);
break;
}
And it shows that this happens *pretty* often... maybe something to investigate even further... comments are welcome!
I watched it for a few hours now and the most common part is when they tell me that they don't have their own reqfile, though, it happens with lots of clients, Hybrids, Shareaza and Mules so I doubt that it's intention...
GreetZ,
WiZ