📄 baseclient.cpp
字号:
{
case US_CONNECTING:
case US_WAITCALLBACK:
if (theApp.uploadqueue->IsDownloading(this))
{
SetUploadState(US_UPLOADING);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__AcceptUploadReq", this);
Packet* packet = new Packet(OP_ACCEPTUPLOADREQ,0);
theStats.AddUpDataOverheadFileRequest(packet->size);
socket->SendPacket(packet,true);
}
}
if (m_iFileListRequested == 1)
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend(m_fSharedDirectories ? "OP__AskSharedDirs" : "OP__AskSharedFiles", this);
Packet* packet = new Packet(m_fSharedDirectories ? OP_ASKSHAREDDIRS : OP_ASKSHAREDFILES,0);
theStats.AddUpDataOverheadOther(packet->size);
socket->SendPacket(packet,true,true);
}
while (!m_WaitingPackets_list.IsEmpty())
{
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("Buffered Packet", this);
socket->SendPacket(m_WaitingPackets_list.RemoveHead());
}
}
void CUpDownClient::ReGetClientSoft()
{
if (m_pszUsername == NULL){
m_clientSoft = SO_UNKNOWN;
return;
}
int iHashType = GetHashType();
if (iHashType == SO_EMULE){
LPCTSTR pszSoftware;
switch(m_byCompatibleClient){
case SO_CDONKEY:
m_clientSoft = SO_CDONKEY;
pszSoftware = _T("cDonkey");
break;
case SO_XMULE:
m_clientSoft = SO_XMULE;
pszSoftware = _T("xMule");
break;
case SO_AMULE:
m_clientSoft = SO_AMULE;
pszSoftware = _T("aMule");
break;
case SO_SHAREAZA:
m_clientSoft = SO_SHAREAZA;
pszSoftware = _T("Shareaza");
break;
case SO_LPHANT:
m_clientSoft = SO_LPHANT;
pszSoftware = _T("lphant");
break;
default:
if (m_bIsML || m_byCompatibleClient == SO_MLDONKEY){
m_clientSoft = SO_MLDONKEY;
pszSoftware = _T("MLdonkey");
}
else if (m_bIsHybrid){
m_clientSoft = SO_EDONKEYHYBRID;
pszSoftware = _T("eDonkeyHybrid");
}
else if (m_byCompatibleClient != 0){
m_clientSoft = SO_XMULE; // means: 'eMule Compatible'
pszSoftware = _T("eMule Compat");
}
else{
m_clientSoft = SO_EMULE;
pszSoftware = _T("eMule");
}
}
int iLen;
TCHAR szSoftware[128];
if (m_byEmuleVersion == 0){
m_nClientVersion = MAKE_CLIENT_VERSION(0, 0, 0);
iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s"), pszSoftware);
}
else if (m_byEmuleVersion != 0x99){
UINT nClientMinVersion = (m_byEmuleVersion >> 4)*10 + (m_byEmuleVersion & 0x0f);
m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0);
iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v0.%u"), pszSoftware, nClientMinVersion);
}
else{
UINT nClientMajVersion = (m_nClientVersion >> 17) & 0x7f;
UINT nClientMinVersion = (m_nClientVersion >> 10) & 0x7f;
UINT nClientUpVersion = (m_nClientVersion >> 7) & 0x07;
m_nClientVersion = MAKE_CLIENT_VERSION(nClientMajVersion, nClientMinVersion, nClientUpVersion);
if (m_clientSoft == SO_EMULE)
iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u%c"), pszSoftware, nClientMajVersion, nClientMinVersion, _T('a') + nClientUpVersion);
else if (m_clientSoft == SO_AMULE || nClientUpVersion != 0)
iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u.%u"), pszSoftware, nClientMajVersion, nClientMinVersion, nClientUpVersion);
else
iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("%s v%u.%u"), pszSoftware, nClientMajVersion, nClientMinVersion);
}
if (iLen > 0){
memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR));
m_strClientSoftware.ReleaseBuffer(iLen);
}
return;
}
if (m_bIsHybrid){
m_clientSoft = SO_EDONKEYHYBRID;
// seen:
// 105010 50.10
// 10501 50.1
// 1051 51.0
// 501 50.1
UINT nClientMajVersion;
UINT nClientMinVersion;
UINT nClientUpVersion;
if (m_nClientVersion > 100000){
UINT uMaj = m_nClientVersion/100000;
nClientMajVersion = uMaj - 1;
nClientMinVersion = (m_nClientVersion - uMaj*100000) / 100;
nClientUpVersion = m_nClientVersion % 100;
}
else if (m_nClientVersion > 10000){
UINT uMaj = m_nClientVersion/10000;
nClientMajVersion = uMaj - 1;
nClientMinVersion = (m_nClientVersion - uMaj*10000) / 10;
nClientUpVersion = m_nClientVersion % 10;
}
else if (m_nClientVersion > 1000){
UINT uMaj = m_nClientVersion/1000;
nClientMajVersion = uMaj - 1;
nClientMinVersion = m_nClientVersion - uMaj*1000;
nClientUpVersion = 0;
}
else if (m_nClientVersion > 100){
UINT uMin = m_nClientVersion/10;
nClientMajVersion = 0;
nClientMinVersion = uMin;
nClientUpVersion = m_nClientVersion - uMin*10;
}
else{
nClientMajVersion = 0;
nClientMinVersion = m_nClientVersion;
nClientUpVersion = 0;
}
m_nClientVersion = MAKE_CLIENT_VERSION(nClientMajVersion, nClientMinVersion, nClientUpVersion);
int iLen;
TCHAR szSoftware[128];
if (nClientUpVersion)
iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("eDonkeyHybrid v%u.%u.%u"), nClientMajVersion, nClientMinVersion, nClientUpVersion);
else
iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("eDonkeyHybrid v%u.%u"), nClientMajVersion, nClientMinVersion);
if (iLen > 0){
memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR));
m_strClientSoftware.ReleaseBuffer(iLen);
}
return;
}
if (m_bIsML || iHashType == SO_MLDONKEY){
m_clientSoft = SO_MLDONKEY;
UINT nClientMinVersion = m_nClientVersion;
m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0);
TCHAR szSoftware[128];
int iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("MLdonkey v0.%u"), nClientMinVersion);
if (iLen > 0){
memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR));
m_strClientSoftware.ReleaseBuffer(iLen);
}
return;
}
if (iHashType == SO_OLDEMULE){
m_clientSoft = SO_OLDEMULE;
UINT nClientMinVersion = m_nClientVersion;
m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0);
TCHAR szSoftware[128];
int iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("Old eMule v0.%u"), nClientMinVersion);
if (iLen > 0){
memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR));
m_strClientSoftware.ReleaseBuffer(iLen);
}
return;
}
m_clientSoft = SO_EDONKEY;
UINT nClientMinVersion = m_nClientVersion;
m_nClientVersion = MAKE_CLIENT_VERSION(0, nClientMinVersion, 0);
TCHAR szSoftware[128];
int iLen = _sntprintf(szSoftware, ARRSIZE(szSoftware), _T("eDonkey v0.%u"), nClientMinVersion);
if (iLen > 0){
memcpy(m_strClientSoftware.GetBuffer(iLen), szSoftware, iLen*sizeof(TCHAR));
m_strClientSoftware.ReleaseBuffer(iLen);
}
}
int CUpDownClient::GetHashType() const
{
if (m_achUserHash[5] == 13 && m_achUserHash[14] == 110)
return SO_OLDEMULE;
else if (m_achUserHash[5] == 14 && m_achUserHash[14] == 111)
return SO_EMULE;
else if (m_achUserHash[5] == 'M' && m_achUserHash[14] == 'L')
return SO_MLDONKEY;
else
return SO_UNKNOWN;
}
void CUpDownClient::SetUserName(LPCTSTR pszNewName)
{
if (m_pszUsername){
free(m_pszUsername);
m_pszUsername = NULL;// needed, in case 'nstrdup' fires an exception!!
}
if( pszNewName )
m_pszUsername = _tcsdup(pszNewName);
}
void CUpDownClient::RequestSharedFileList()
{
if (m_iFileListRequested == 0){
AddLogLine(true,GetResString(IDS_SHAREDFILES_REQUEST),GetUserName());
m_iFileListRequested = 1;
TryToConnect(true);
}
else{
AddLogLine(true,_T("Requesting shared files from user %s (%u) is already in progress"),GetUserName(),GetUserIDHybrid());
}
}
void CUpDownClient::ProcessSharedFileList(char* pachPacket, uint32 nSize, LPCTSTR pszDirectory){
if (m_iFileListRequested > 0){
m_iFileListRequested--;
theApp.searchlist->ProcessSearchanswer(pachPacket,nSize,this,NULL,pszDirectory);
}
}
void CUpDownClient::SetUserHash(const uchar* pucUserHash)
{
if( pucUserHash == NULL ){
md4clr(m_achUserHash);
return;
}
md4cpy(m_achUserHash, pucUserHash);
}
void CUpDownClient::SendPublicKeyPacket(){
///* delete this line later*/ DEBUG_ONLY(AddDebugLogLine(false, "sending public key to '%s'", GetUserName()));
// send our public key to the client who requested it
if (socket == NULL || credits == NULL || m_SecureIdentState != IS_KEYANDSIGNEEDED){
ASSERT ( false );
return;
}
if (!theApp.clientcredits->CryptoAvailable())
return;
Packet* packet = new Packet(OP_PUBLICKEY,theApp.clientcredits->GetPubKeyLen() + 1,OP_EMULEPROT);
theStats.AddUpDataOverheadOther(packet->size);
memcpy(packet->pBuffer+1,theApp.clientcredits->GetPublicKey(), theApp.clientcredits->GetPubKeyLen());
packet->pBuffer[0] = theApp.clientcredits->GetPubKeyLen();
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__PublicKey", this);
socket->SendPacket(packet,true,true);
m_SecureIdentState = IS_SIGNATURENEEDED;
}
void CUpDownClient::SendSignaturePacket(){
// signate the public key of this client and send it
if (socket == NULL || credits == NULL || m_SecureIdentState == 0){
ASSERT ( false );
return;
}
if (!theApp.clientcredits->CryptoAvailable())
return;
if (credits->GetSecIDKeyLen() == 0)
return; // We don't have his public key yet, will be back here later
///* delete this line later*/ DEBUG_ONLY(AddDebugLogLine(false, "sending signature key to '%s'", GetUserName()));
// do we have a challenge value received (actually we should if we are in this function)
if (credits->m_dwCryptRndChallengeFrom == 0){
if (thePrefs.GetLogSecureIdent())
AddDebugLogLine(false, _T("Want to send signature but challenge value is invalid ('%s')"), GetUserName());
return;
}
// v2
// we will use v1 as default, except if only v2 is supported
bool bUseV2;
if ( (m_bySupportSecIdent&1) == 1 )
bUseV2 = false;
else
bUseV2 = true;
uint8 byChaIPKind = 0;
uint32 ChallengeIP = 0;
if (bUseV2){
if (theApp.serverconnect->GetClientID() == 0 || theApp.serverconnect->IsLowID()){
// we cannot do not know for sure our public ip, so use the remote clients one
ChallengeIP = GetIP();
byChaIPKind = CRYPT_CIP_REMOTECLIENT;
}
else{
ChallengeIP = theApp.serverconnect->GetClientID();
byChaIPKind = CRYPT_CIP_LOCALCLIENT;
}
}
//end v2
uchar achBuffer[250];
uint8 siglen = theApp.clientcredits->CreateSignature(credits, achBuffer, 250, ChallengeIP, byChaIPKind );
if (siglen == 0){
ASSERT ( false );
return;
}
Packet* packet = new Packet(OP_SIGNATURE,siglen + 1+ ( (bUseV2)? 1:0 ),OP_EMULEPROT);
theStats.AddUpDataOverheadOther(packet->size);
memcpy(packet->pBuffer+1,achBuffer, siglen);
packet->pBuffer[0] = siglen;
if (bUseV2)
packet->pBuffer[1+siglen] = byChaIPKind;
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__Signature", this);
socket->SendPacket(packet,true,true);
m_SecureIdentState = IS_ALLREQUESTSSEND;
}
void CUpDownClient::ProcessPublicKeyPacket(uchar* pachPacket, uint32 nSize){
theApp.clientlist->AddTrackClient(this);
///* delete this line later*/ DEBUG_ONLY(AddDebugLogLine(false, "recieving public key from '%s'", GetUserName()));
if (socket == NULL || credits == NULL || pachPacket[0] != nSize-1
|| nSize == 0 || nSize > 250){
ASSERT ( false );
return;
}
if (!theApp.clientcredits->CryptoAvailable())
return;
// the function will handle everything (mulitple key etc)
if (credits->SetSecureIdent(pachPacket+1, pachPacket[0])){
// if this client wants a signature, now we can send him one
if (m_SecureIdentState == IS_SIGNATURENEEDED){
SendSignaturePacket();
}
else if(m_SecureIdentState == IS_KEYANDSIGNEEDED)
{
// something is wrong
if (thePrefs.GetLogSecureIdent())
AddDebugLogLine(false, _T("Invalid State error: IS_KEYANDSIGNEEDED in ProcessPublicKeyPacket"));
}
}
else
{
if (thePrefs.GetLogSecureIdent())
AddDebugLogLine(false, _T("Failed to use new received public key"));
}
}
void CUpDownClient::ProcessSignaturePacket(uchar* pachPacket, uint32 nSize){
///* delete this line later*/ DEBUG_ONLY(AddDebugLogLine(false, "receiving signature from '%s'", GetUserName()));
// here we spread the good guys from the bad ones ;)
if (socket == NULL || credits == NULL || nSize == 0 || nSize > 250){
ASSERT ( false );
return;
}
uint8 byChaIPKind;
if (pachPacket[0] == nSize-1)
byChaIPKind = 0;
else if (pachPacket[0] == nSize-2 && (m_bySupportSecIdent & 2) > 0) //v2
byChaIPKind = pachPacket[nSize-1];
else{
ASSERT ( false );
return;
}
if (!theApp.clientcredits->CryptoAvailable())
return;
// we accept only one signature per IP, to avoid floods which need a lot cpu time for cryptfunctions
if (m_dwLastSignatureIP == GetIP())
{
if (thePrefs.GetLogSecureIdent())
AddDebugLogLine(false, _T("received multiple signatures from one client"));
return;
}
// also make sure this client has a public key
if (credits->GetSecIDKeyLen() == 0)
{
if (thePrefs.GetLogSecureIdent())
AddDebugLogLine(false, _T("received signature for client without public key"));
return;
}
// and one more check: did we ask for a signature and sent a challange packet?
if (credits->m_dwCryptRndChallengeFor == 0)
{
if (thePrefs.GetLogSecureIdent())
AddDebugLogLine(false, _T("received signature for client with invalid challenge value ('%s')"), GetUserName());
return;
}
if (theApp.clientcredits->VerifyIdent(credits, pachPacket+1, pachPacket[0], GetIP(), byChaIPKind ) ){
// result is saved in function abouve
//if (thePrefs.GetLogSecureIdent())
// AddDebugLogLine(false, "'%s' has passed the secure identification, V2 State: %i", GetUserName(), byChaIPKind);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -