📄 baseclient.cpp
字号:
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;
}
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{
LogWarning(LOG_STATUSBAR, _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::SetBuddyID(const uchar* pucBuddyID)
{
if( pucBuddyID == NULL ){
md4clr(m_achBuddyID);
m_bBuddyIDValid = false;
return;
}
m_bBuddyIDValid = true;
md4cpy(m_achBuddyID, pucBuddyID);
}
void CUpDownClient::SendPublicKeyPacket(){
// 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
// 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);
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){
// 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, _T("'%s' has passed the secure identification, V2 State: %i"), GetUserName(), byChaIPKind);
}
else
{
if (thePrefs.GetLogSecureIdent())
AddDebugLogLine(false, _T("'%s' has failed the secure identification, V2 State: %i"), GetUserName(), byChaIPKind);
}
m_dwLastSignatureIP = GetIP();
}
void CUpDownClient::SendSecIdentStatePacket(){
// check if we need public key and signature
uint8 nValue = 0;
if (credits){
if (theApp.clientcredits->CryptoAvailable()){
if (credits->GetSecIDKeyLen() == 0)
nValue = IS_KEYANDSIGNEEDED;
else if (m_dwLastSignatureIP != GetIP())
nValue = IS_SIGNATURENEEDED;
}
if (nValue == 0){
//if (thePrefs.GetLogSecureIdent())
// AddDebugLogLine(false, _T("Not sending SecIdentState Packet, because State is Zero"));
return;
}
// crypt: send random data to sign
uint32 dwRandom = rand()+1;
credits->m_dwCryptRndChallengeFor = dwRandom;
Packet* packet = new Packet(OP_SECIDENTSTATE,5,OP_EMULEPROT);
theStats.AddUpDataOverheadOther(packet->size);
packet->pBuffer[0] = nValue;
PokeUInt32(packet->pBuffer+1, dwRandom);
if (thePrefs.GetDebugClientTCPLevel() > 0)
DebugSend("OP__SecIdentState", this);
socket->SendPacket(packet,true,true);
}
else
ASSERT ( false );
}
void CUpDownClient::ProcessSecIdentStatePacket(uchar* pachPacket, uint32 nSize){
if (nSize != 5)
return;
if (!credits){
ASSERT ( false );
return;
}
switch(pachPacket[0]){
case 0:
m_SecureIdentState = IS_UNAVAILABLE;
break;
case 1:
m_SecureIdentState = IS_SIGNATURENEEDED;
break;
case 2:
m_SecureIdentState = IS_KEYANDSIGNEEDED;
break;
}
credits->m_dwCryptRndChallengeFrom = PeekUInt32(pachPacket+1);
}
void CUpDownClient::InfoPacketsReceived(){
// indicates that both Information Packets has been received
// needed for actions, which process data from both packets
ASSERT ( m_byInfopacketsReceived == IP_BOTH );
m_byInfopacketsReceived = IP_NONE;
if (m_bySupportSecIdent){
SendSecIdentStatePacket();
}
}
void CUpDownClient::ResetFileStatusInfo()
{
if (m_abyPartStatus){
delete[] m_abyPartStatus;
m_abyPartStatus = NULL;
}
m_nRemoteQueueRank = 0;
m_nPartCount = 0;
m_strClientFilename.Empty();
m_bCompleteSource = false;
m_uFileRating = 0;
m_strFileComment.Empty();
if (m_pReqFileAICHHash != NULL){
delete m_pReqFileAICHHash;
m_pReqFileAICHHash = NULL;
}
}
bool CUpDownClient::IsBanned() const
{
return theApp.clientlist->IsBannedClient(GetIP());
}
void CUpDownClient::SendPreviewRequest(const CAbstractFile* pForFile)
{
if (m_fPreviewReqPending == 0){
m_fPreviewReqPending = 1;
Packet* packet = new Packet(OP_REQUESTPREVIEW,16,OP_EMULEPROT);
md4cpy(packet->pBuffer,pForFile->GetFileHash());
theStats.AddUpDataOverheadOther(packet->size);
SafeSendPacket(packet);
}
else{
LogWarning(LOG_STATUSBAR, GetResString(IDS_ERR_PREVIEWALREADY));
}
}
void CUpDownClient::SendPreviewAnswer(const CKnownFile* pForFile, CxImage** imgFrames, uint8 nCount)
{
m_fPreviewAnsPending = 0;
CSafeMemFile data(1024);
if (pForFile){
data.WriteHash16(pForFile->GetFileHash());
}
else{
static const uchar _aucZeroHash[16] = {0};
data.WriteHash16(_aucZeroHash);
}
data.WriteUInt8(nCount);
for (int i = 0; i != nCount; i++){
if (imgFrames == NULL){
ASSERT ( false );
return;
}
CxImage* cur_frame = imgFrames[i];
if (cur_frame == NULL){
ASSERT ( false );
return;
}
BYTE* abyResultBuffer = NULL;
long nResultSize = 0;
if (!cur_frame->Encode(abyResultBuffer, nResultSize, CXIMAGE_FORMAT_PNG)){
ASSERT ( false );
return;
}
data.WriteUInt32(nResultSize);
data.Write(abyResultBuffer, nResultSize);
free(abyResultBuffer);
}
Packet* packet = new Packet(&data, OP_EMULEPROT);
packet->opcode = OP_PREVIEWANSWER;
theStats.AddUpDataOverheadOther(packet->size);
SafeSendPacket(packet);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -