public void CheckForExpiredUDPKeys() { if (!MuleApplication.Instance.Preference.IsServerCryptLayerUDPEnabled) { return; } uint cKeysTotal = 0; uint cKeysExpired = 0; uint cPingDelayed = 0; uint dwIP = (uint)MuleApplication.Instance.PublicIP; uint tNow = (uint)MpdUtilities.Time(); foreach (ED2KServer pServer in servers_) { if (pServer.DoesSupportsObfuscationUDP && pServer.GetServerKeyUDP(true) != 0 && pServer.ServerKeyUDPIP != dwIP) { cKeysTotal++; cKeysExpired++; if (tNow - pServer.RealLastPingedTime < MuleConstants.UDPSERVSTATMINREASKTIME) { cPingDelayed++; // next ping: Now + (MinimumDelay - already elapsed time) pServer.LastPingedTime = (tNow - (uint)MuleConstants.UDPSERVSTATREASKTIME) + (MuleConstants.UDPSERVSTATMINREASKTIME - (tNow - pServer.RealLastPingedTime)); } else { pServer.LastPingedTime = 0; } } else if (pServer.DoesSupportsObfuscationUDP && pServer.GetServerKeyUDP(false) != 0) { cKeysTotal++; } } }
public void TrackBadRequest(UpDownClient upcClient, int nIncreaseCounter) { DeletedClient pResult = null; if (upcClient.IP == 0) { Debug.Assert(false); return; } if (trackedClientsList_.ContainsKey(upcClient.IP)) { pResult = trackedClientsList_[upcClient.IP]; pResult.m_dwInserted = MpdUtilities.GetTickCount(); pResult.m_cBadRequest += (uint)nIncreaseCounter; } else { DeletedClient ccToAdd = new DeletedClient(upcClient); ccToAdd.m_cBadRequest = (uint)nIncreaseCounter; trackedClientsList_[upcClient.IP] = ccToAdd; } }
protected void CleanUpClientList() { // we remove clients which are not needed any more by time // this check is also done on CUpDownClient::Disconnected, however it will not catch all // cases (if a client changes the state without beeing connected // // Adding this check directly to every point where any state changes would be more effective, // is however not compatible with the current code, because there are points where a client has // no state for some code lines and the code is also not prepared that a client object gets // invalid while working with it (aka setting a new state) // so this way is just the easy and safe one to go (as long as emule is basically single threaded) uint cur_tick = MpdUtilities.GetTickCount(); if (lastClientCleanUp_ + MuleConstants.CLIENTLIST_CLEANUP_TIME < cur_tick) { lastClientCleanUp_ = cur_tick; int pos = 0; while (pos < clientList_.Count) { UpDownClient pCurClient = clientList_[pos]; if ((pCurClient.UploadState == UploadStateEnum.US_NONE || pCurClient.UploadState == UploadStateEnum.US_BANNED && !pCurClient.IsBanned) && pCurClient.DownloadState == DownloadStateEnum.DS_NONE && pCurClient.ChatState == ChatStateEnum.MS_NONE && pCurClient.KadState == KadStateEnum.KS_NONE && pCurClient.ClientSocket == null) { pCurClient.CleanUp(); } else { pos++; } } } }
protected void ProcessConnectingClientsList() { // we do check if any connects have timed out by now uint cur_tick = MpdUtilities.GetTickCount(); int pos1 = 0; while (pos1 < connectingClients_.Count) { CONNECTINGCLIENT cc = connectingClients_[pos1]; if (cc.dwInserted + MuleConstants.ONE_SEC_MS * 45 < cur_tick) { connectingClients_.RemoveAt(pos1); if (cc.pClient.Disconnected("Connectiontry Timeout")) { cc.pClient.CleanUp(); } } else { pos1++; } } }
public bool StartListening() { try { if (!base.CreateSocket(new IPEndPoint(0, 0).AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { return(false); } IPAddress address = IPAddress.Any; if (MuleApplication.Instance.Preference.BindAddr != null && MuleApplication.Instance.Preference.BindAddr.Length > 0) { IPAddress.TryParse(MuleApplication.Instance.Preference.BindAddr, out address); } IPEndPoint endpoint = new IPEndPoint(address, MuleApplication.Instance.Preference.Port); Bind(endpoint); Listen(); port_ = MuleApplication.Instance.Preference.Port; bListening_ = true; return(true); } catch (Exception ex) { MpdUtilities.DebugLogError("Start Listening Error", ex); return(false); } }
public bool LoadMD4HashsetFromFile(Mpd.Generic.IO.FileDataIO file, bool bVerifyExistingHash) { byte[] checkid = new byte[16]; file.ReadHash16(checkid); DeleteMD4Hashset(); uint parts = file.ReadUInt16(); //TRACE("Nr. hashs: %u\n", (uint)parts); if (bVerifyExistingHash && (MpdUtilities.Md4Cmp(MD4Hash, checkid) != 0 || parts != TheoreticalMD4PartHashCount)) { return(false); } for (uint i = 0; i < parts; i++) { byte[] cur_hash = new byte[16]; file.ReadHash16(cur_hash); m_aMD4HashSet.Add(cur_hash); } if (!bVerifyExistingHash) { MpdUtilities.Md4Cpy(MD4Hash, checkid); } // Calculate hash out of hashset and compare to existing filehash if (m_aMD4HashSet.Count > 0) { return(CalculateMD4HashByHashSet(true, true)); } else { return(true); } }
public bool InitFromLink(string sLink) { ED2KLink pLink = null; ED2KFileLink pFileLink = null; try { pLink = MuleApplication.Instance.ED2KObjectManager.CreateLinkFromUrl(sLink); if (pLink == null) { throw new Exception("Not a Valid file link:" + sLink); } pFileLink = pLink.FileLink; if (pFileLink == null) { throw new Exception("Not a Valid file link:" + sLink); } } catch (Exception) { //TODO:Log return(false); } tagList_.Add(MpdObjectManager.CreateTag(MuleConstants.FT_FILEHASH, pFileLink.HashKey)); MpdUtilities.Md4Cpy(FileHash, pFileLink.HashKey); tagList_.Add(MpdObjectManager.CreateTag(MuleConstants.FT_FILESIZE, pFileLink.Size, true)); FileSize = pFileLink.Size; tagList_.Add(MpdObjectManager.CreateTag(MuleConstants.FT_FILENAME, pFileLink.Name)); SetFileName(pFileLink.Name, false, false, false); return(true); }
public void PackPacket() { Debug.Assert(!m_bSplitted); byte[] output = null; bool result = MpdUtilities.Compress(Buffer, Size, out output); if (!result || Size <= output.Length) { return; } if (Protocol == MuleConstants.PROTOCOL_KADEMLIAHEADER) { Protocol = MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT; } else { Protocol = MuleConstants.PROTOCOL_PACKEDPROT; } Array.Copy(output, Buffer, output.Length); Size = (uint)output.Length; m_bPacked = true; }
public bool Create() { try { if (!CreateSocket(new IPEndPoint(IPAddress.Any, 0).AddressFamily, SocketType.Dgram, ProtocolType.Udp)) { return(false); } if (MuleApplication.Instance.Preference.UDPPort != 0) { Bind(new IPEndPoint(IPAddress.Parse(MuleApplication.Instance.Preference.BindAddr), MuleApplication.Instance.Preference.UDPPort)); // the default socket size seems to be not enough for this UDP socket // because we tend to drop packets if several flow in at the same time int val = 64 * 1024; SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.ReceiveBuffer, val); } else { return(false); } port_ = MuleApplication.Instance.Preference.UDPPort; return(true); } catch (Exception ex) { MpdUtilities.DebugLogError("ClientUDPSocket Create Fail", ex); return(false); } }
protected bool CreateKeyPair() { try { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider((int)MuleConstants.RSAKEYSIZE); byte[] key = rsa.ExportCspBlob(true); string keyText = Convert.ToBase64String(key); string filename = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), "crytkey.dat"); System.IO.File.WriteAllText(filename, keyText); return(true); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); return(false); } }
public static RC4Key RC4CreateKey(byte[] pachKeyData, uint nLen, ref RC4Key key, bool bSkipDiscard) { byte index1; byte index2; byte[] pabyState; if (key == null) { key = new RC4Key(); } pabyState = key.abyState; for (int i = 0; i < 256; i++) { pabyState[i] = (byte)i; } key.byX = 0; key.byY = 0; index1 = 0; index2 = 0; for (int i = 0; i < 256; i++) { index2 = Convert.ToByte(pachKeyData[index1] + pabyState[i] + index2); MpdUtilities.SwapByte(ref pabyState[i], ref pabyState[index2]); index1 = (byte)((index1 + 1) % nLen); } if (!bSkipDiscard) { RC4Crypt(null, null, 1024, key); } return(key); }
public bool CalculateMD4HashByHashSet(bool bVerifyOnly, bool bDeleteOnVerifyFail) { if (m_aMD4HashSet.Count <= 1) { return(false); } byte[] buffer = new byte[m_aMD4HashSet.Count * 16]; for (int i = 0; i < m_aMD4HashSet.Count; i++) { MpdUtilities.Md4Cpy(buffer, i * 16, m_aMD4HashSet[i], 0, m_aMD4HashSet[i].Length); } byte[] aucResult = new byte[16]; KnownFile knownFile = MuleApplication.Instance.FileObjectManager.CreateKnownFile(); knownFile.CreateHash(buffer, (ulong)m_aMD4HashSet.Count * 16, aucResult); if (bVerifyOnly) { if (MpdUtilities.Md4Cmp(aucResult, MD4Hash) != 0) { if (bDeleteOnVerifyFail) { DeleteMD4Hashset(); } return(false); } else { return(true); } } else { MpdUtilities.Md4Cpy(MD4Hash, aucResult); return(true); } }
public virtual int EncryptSendServer(ref byte[] ppbyBuf, int nBufLen, uint dwBaseKey) { Debug.Assert(MuleApplication.Instance.Preference.IsServerCryptLayerUDPEnabled); Debug.Assert(dwBaseKey != 0); byte byPadLen = 0; // padding disabled for UDP currently int nCryptedLen = nBufLen + byPadLen + CRYPT_HEADER_WITHOUTPADDING; byte[] pachCryptedBuffer = new byte[nCryptedLen]; ushort nRandomKeyPart = MpdUtilities.GetRandomUInt16(); byte[] achKeyData = new byte[7]; Array.Copy(BitConverter.GetBytes(dwBaseKey), achKeyData, 4); achKeyData[4] = MAGICVALUE_UDP_CLIENTSERVER; Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, achKeyData, 5, 2); MD5 md5 = MD5.Create(); byte[] rawHash = md5.ComputeHash(achKeyData); RC4Key keySendKey = null; MuleUtilities.RC4CreateKey(rawHash, 16, ref keySendKey, true); // create the semi random byte encryption header byte bySemiRandomNotProtocolMarker = 0; int i; for (i = 0; i < 128; i++) { bySemiRandomNotProtocolMarker = MpdUtilities.GetRandomUInt8(); if (bySemiRandomNotProtocolMarker != MuleConstants.PROTOCOL_EDONKEYPROT) // not allowed values { break; } } if (i >= 128) { // either we have _real_ bad luck or the randomgenerator is a bit messed up Debug.Assert(false); bySemiRandomNotProtocolMarker = 0x01; } uint dwMagicValue = MAGICVALUE_UDP_SYNC_SERVER; pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker; Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, pachCryptedBuffer, 1, 2); MuleUtilities.RC4Crypt(BitConverter.GetBytes(dwMagicValue), 0, pachCryptedBuffer, 3, 4, keySendKey); MuleUtilities.RC4Crypt(new byte[] { byPadLen }, 0, pachCryptedBuffer, 7, 1, keySendKey); Random rand = new Random(); for (int j = 0; j < byPadLen; j++) { byte byRand = (byte)rand.Next(255); // they actually dont really need to be random, but it doesn't hurts either MuleUtilities.RC4Crypt(new byte[] { byRand }, 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + j, 1, keySendKey); } MuleUtilities.RC4Crypt(ppbyBuf, 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + byPadLen, (uint)nBufLen, keySendKey); ppbyBuf = pachCryptedBuffer; MuleApplication.Instance.Statistics.AddUpDataOverheadCrypt((uint)(nCryptedLen - nBufLen)); return(nCryptedLen); }
public virtual int DecryptReceivedClient(byte[] pbyBufIn, int nBufLen, out byte[] ppbyBufOut, uint dwIP, out uint nReceiverVerifyKey, out uint nSenderVerifyKey) { int nResult = nBufLen; ppbyBufOut = pbyBufIn; nReceiverVerifyKey = 0; nSenderVerifyKey = 0; if (nResult <= CRYPT_HEADER_WITHOUTPADDING /*|| !MuleApplication.Instance.Preference.IsClientCryptLayerSupported()*/) { return(nResult); } switch (pbyBufIn[0]) { case MuleConstants.PROTOCOL_EMULEPROT: case MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT: case MuleConstants.PROTOCOL_KADEMLIAHEADER: case MuleConstants.PROTOCOL_UDPRESERVEDPROT1: case MuleConstants.PROTOCOL_UDPRESERVEDPROT2: case MuleConstants.PROTOCOL_PACKEDPROT: return(nResult); // no encrypted packet (see description on top) } // might be an encrypted packet, try to decrypt RC4Key keyReceiveKey = null; uint dwValue = 0; // check the marker bit which type this packet could be and which key to test first, this is only an indicator since old clients have it set random // see the header for marker bits explanation byte byCurrentTry = (byte)(((pbyBufIn[0] & 0x03) == 3) ? 1 : (pbyBufIn[0] & 0x03)); byte byTries; if (MuleApplication.Instance.KadEngine.Preference == null) { // if kad never run, no point in checking anything except for ed2k encryption byTries = 1; byCurrentTry = 1; } else { byTries = 3; } bool bKadRecvKeyUsed = false; bool bKad = false; do { byTries--; MD5 md5 = MD5.Create(); byte[] rawHash = null; if (byCurrentTry == 0) { // kad packet with NodeID as key bKad = true; bKadRecvKeyUsed = false; if (MuleApplication.Instance.KadEngine.Preference != null) { byte[] achKeyData = new byte[18]; Array.Copy(MuleApplication.Instance.KadEngine.Preference.KadID.Bytes, 0, achKeyData, 0, 16); Array.Copy(pbyBufIn, 1, achKeyData, 16, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } } else if (byCurrentTry == 1) { // ed2k packet bKad = false; bKadRecvKeyUsed = false; byte[] achKeyData = new byte[23]; MpdUtilities.Md4Cpy(achKeyData, MuleApplication.Instance.Preference.UserHash); achKeyData[20] = MAGICVALUE_UDP; Array.Copy(BitConverter.GetBytes(dwIP), 0, achKeyData, 16, 4); Array.Copy(pbyBufIn, 1, achKeyData, 21, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } else if (byCurrentTry == 2) { // kad packet with ReceiverKey as key bKad = true; bKadRecvKeyUsed = true; if (MuleApplication.Instance.KadEngine.Preference != null) { byte[] achKeyData = new byte[6]; Array.Copy(BitConverter.GetBytes(MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP)), achKeyData, 4); Array.Copy(pbyBufIn, 1, achKeyData, 4, 2); // random key part sent from remote client rawHash = md5.ComputeHash(achKeyData); } } else { Debug.Assert(false); } MuleUtilities.RC4CreateKey(rawHash, 16, ref keyReceiveKey, true); byte[] outBuf = new byte[4]; MuleUtilities.RC4Crypt(pbyBufIn, 3, outBuf, 0, 4, keyReceiveKey); dwIP = BitConverter.ToUInt32(outBuf, 0); byCurrentTry = (byte)((byCurrentTry + 1) % 3); } while (dwValue != MAGICVALUE_UDP_SYNC_CLIENT && byTries > 0); // try to decrypt as ed2k as well as kad packet if needed (max 3 rounds) if (dwValue == MAGICVALUE_UDP_SYNC_CLIENT) { // yup this is an encrypted packet // debugoutput notices // the following cases are "allowed" but shouldn't happen given that there is only our implementation yet if (bKad && (pbyBufIn[0] & 0x01) != 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, ed2k bit)", MpdUtilities.IP2String(dwIP))); } else if (bKad && !bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) != 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, nodeid key, recvkey bit)", MpdUtilities.IP2String(dwIP))); } else if (bKad && bKadRecvKeyUsed && (pbyBufIn[0] & 0x02) == 0) { MpdUtilities.DebugLog( string.Format("Received obfuscated UDP packet from clientIP: {0} with wrong key marker bits (kad packet, recvkey key, nodeid bit)", MpdUtilities.IP2String(dwIP))); } byte byPadLen; byte[] outBuf = new byte[1]; MuleUtilities.RC4Crypt(pbyBufIn, 7, outBuf, 0, 1, keyReceiveKey); byPadLen = outBuf[0]; nResult -= CRYPT_HEADER_WITHOUTPADDING; if (nResult <= byPadLen) { MpdUtilities.DebugLogError( string.Format("Invalid obfuscated UDP packet from clientIP: {0}, Paddingsize ({1}) larger than received bytes", MpdUtilities.IP2String(dwIP), byPadLen)); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk } if (byPadLen > 0) { MuleUtilities.RC4Crypt(null, null, byPadLen, keyReceiveKey); } nResult -= byPadLen; if (bKad) { if (nResult <= 8) { MpdUtilities.DebugLogError( string.Format("Obfuscated Kad packet with mismatching size (verify keys missing) received from clientIP: {0}", MpdUtilities.IP2String(dwIP))); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk; } // read the verify keys outBuf = new byte[4]; MuleUtilities.RC4Crypt(pbyBufIn, (int)(CRYPT_HEADER_WITHOUTPADDING + byPadLen), outBuf, 0, 4, keyReceiveKey); nReceiverVerifyKey = BitConverter.ToUInt32(outBuf, 0); MuleUtilities.RC4Crypt(pbyBufIn, (int)(CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4), outBuf, 0, 4, keyReceiveKey); nSenderVerifyKey = BitConverter.ToUInt32(outBuf, 0); nResult -= 8; } ppbyBufOut = new byte[nResult]; Array.Copy(pbyBufIn, (nBufLen - nResult), ppbyBufOut, 0, nResult); MuleUtilities.RC4Crypt(ppbyBufOut, ppbyBufOut, (uint)nResult, keyReceiveKey); MuleApplication.Instance.Statistics.AddDownDataOverheadCrypt((uint)(nBufLen - nResult)); //DEBUG_ONLY( MpdUtilities.DebugLog(("Received obfuscated UDP packet from clientIP: %s, Key: %s, RKey: %u, SKey: %u"), MpdUtilities.IP2String(dwIP), bKad ? (bKadRecvKeyUsed ? ("ReceiverKey") : ("NodeID")) : ("UserHash") // , nReceiverVerifyKey != 0 ? *nReceiverVerifyKey : 0, nSenderVerifyKey != 0 ? *nSenderVerifyKey : 0) ); return(nResult); // done } else { MpdUtilities.DebugLogWarning( string.Format("Obfuscated packet expected but magicvalue mismatch on UDP packet from clientIP: {0}, Possible RecvKey: {1}", MpdUtilities.IP2String(dwIP), MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP))); return(nBufLen); // pass through, let the Receivefunction do the errorhandling on this junk } }
public virtual int EncryptSendClient(ref byte[] ppbyBuf, int nBufLen, byte[] pachClientHashOrKadID, bool bKad, uint nReceiverVerifyKey, uint nSenderVerifyKey) { Debug.Assert(MuleApplication.Instance.PublicIP != 0 || bKad); Debug.Assert(MuleApplication.Instance.Preference.IsClientCryptLayerSupported); Debug.Assert(pachClientHashOrKadID != null || nReceiverVerifyKey != 0); Debug.Assert((nReceiverVerifyKey == 0 && nSenderVerifyKey == 0) || bKad); byte byPadLen = 0; // padding disabled for UDP currently int nCryptHeaderLen = byPadLen + CRYPT_HEADER_WITHOUTPADDING + (bKad ? 8 : 0); int nCryptedLen = nBufLen + nCryptHeaderLen; byte[] pachCryptedBuffer = new byte[nCryptedLen]; bool bKadRecKeyUsed = false; ushort nRandomKeyPart = MpdUtilities.GetRandomUInt16(); MD5 md5 = MD5.Create(); byte[] rawHash = null; if (bKad) { if ((pachClientHashOrKadID == null || MpdUtilities.IsNullMd4(pachClientHashOrKadID)) && nReceiverVerifyKey != 0) { bKadRecKeyUsed = true; byte[] achKeyData = new byte[6]; Array.Copy(BitConverter.GetBytes(nReceiverVerifyKey), achKeyData, 4); Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, achKeyData, 4, 2); rawHash = md5.ComputeHash(achKeyData); //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by ReceiverKey (%u)"), nReceiverVerifyKey) ); } else if (pachClientHashOrKadID != null && !MpdUtilities.IsNullMd4(pachClientHashOrKadID)) { byte[] achKeyData = new byte[18]; MpdUtilities.Md4Cpy(achKeyData, pachClientHashOrKadID); Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, achKeyData, 16, 2); rawHash = md5.ComputeHash(achKeyData); //DEBUG_ONLY( DebugLog(_T("Creating obfuscated Kad packet encrypted by Hash/NodeID %s"), md4str(pachClientHashOrKadID)) ); } else { ppbyBuf = null; Debug.Assert(false); return(nBufLen); } } else { byte[] achKeyData = new byte[23]; MpdUtilities.Md4Cpy(achKeyData, pachClientHashOrKadID); uint dwIP = (uint)MuleApplication.Instance.PublicIP; Array.Copy(BitConverter.GetBytes(dwIP), 0, achKeyData, 16, 4); Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, achKeyData, 21, 2); achKeyData[20] = MAGICVALUE_UDP; rawHash = md5.ComputeHash(achKeyData); } RC4Key keySendKey = null; MuleUtilities.RC4CreateKey(rawHash, 16, ref keySendKey, true); // create the semi random byte encryption header byte bySemiRandomNotProtocolMarker = 0; int i; for (i = 0; i < 128; i++) { bySemiRandomNotProtocolMarker = MpdUtilities.GetRandomUInt8(); bySemiRandomNotProtocolMarker = (byte)(bKad ? (bySemiRandomNotProtocolMarker & 0xFE) : (bySemiRandomNotProtocolMarker | 0x01)); // set the ed2k/kad marker bit if (bKad) { bySemiRandomNotProtocolMarker = (byte)(bKadRecKeyUsed ? ((bySemiRandomNotProtocolMarker & 0xFE) | 0x02) : (bySemiRandomNotProtocolMarker & 0xFC)); // set the ed2k/kad and nodeid/reckey markerbit } else { bySemiRandomNotProtocolMarker = (byte)(bySemiRandomNotProtocolMarker | 0x01); // set the ed2k/kad marker bit } bool bOk = false; switch (bySemiRandomNotProtocolMarker) { // not allowed values case MuleConstants.PROTOCOL_EMULEPROT: case MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT: case MuleConstants.PROTOCOL_KADEMLIAHEADER: case MuleConstants.PROTOCOL_UDPRESERVEDPROT1: case MuleConstants.PROTOCOL_UDPRESERVEDPROT2: case MuleConstants.PROTOCOL_PACKEDPROT: break; default: bOk = true; break; } if (bOk) { break; } } if (i >= 128) { // either we have _really_ bad luck or the randomgenerator is a bit messed up Debug.Assert(false); bySemiRandomNotProtocolMarker = 0x01; } uint dwMagicValue = MAGICVALUE_UDP_SYNC_CLIENT; pachCryptedBuffer[0] = bySemiRandomNotProtocolMarker; Array.Copy(BitConverter.GetBytes(nRandomKeyPart), 0, pachCryptedBuffer, 1, 2); MuleUtilities.RC4Crypt(BitConverter.GetBytes(dwMagicValue), 0, pachCryptedBuffer, 3, 4, keySendKey); MuleUtilities.RC4Crypt(BitConverter.GetBytes(byPadLen), 0, pachCryptedBuffer, 7, 1, keySendKey); Random rand = new Random(); for (int j = 0; j < byPadLen; j++) { byte byRand = (byte)rand.Next(255); // they actually dont really need to be random, but it doesn't hurts either MuleUtilities.RC4Crypt(BitConverter.GetBytes(byRand), 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + j, 1, keySendKey); } if (bKad) { MuleUtilities.RC4Crypt(BitConverter.GetBytes(nReceiverVerifyKey), 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + byPadLen, 4, keySendKey); MuleUtilities.RC4Crypt(BitConverter.GetBytes(nSenderVerifyKey), 0, pachCryptedBuffer, CRYPT_HEADER_WITHOUTPADDING + byPadLen + 4, 4, keySendKey); } MuleUtilities.RC4Crypt(ppbyBuf, 0, pachCryptedBuffer, nCryptHeaderLen, (uint)nBufLen, keySendKey); ppbyBuf = pachCryptedBuffer; MuleApplication.Instance.Statistics.AddUpDataOverheadCrypt((uint)(nCryptedLen - nBufLen)); return(nCryptedLen); }
public static void ConvertED2KTag(ref Tag pTag) { if (pTag.NameID == 0 && pTag.Name != null) { EmuleToED2KMetaTagsMap[] _aEmuleToED2KMetaTagsMap = new EmuleToED2KMetaTagsMap[] { // Artist, Album and Title are disabled because they should be already part of the filename // and would therefore be redundant information sent to the servers.. and the servers count the // amount of sent data! new EmuleToED2KMetaTagsMap(MuleConstants.FT_MEDIA_ARTIST, MuleConstants.TAGTYPE_STRING, MuleConstants.FT_ED2K_MEDIA_ARTIST), new EmuleToED2KMetaTagsMap(MuleConstants.FT_MEDIA_ALBUM, MuleConstants.TAGTYPE_STRING, MuleConstants.FT_ED2K_MEDIA_ALBUM), new EmuleToED2KMetaTagsMap(MuleConstants.FT_MEDIA_TITLE, MuleConstants.TAGTYPE_STRING, MuleConstants.FT_ED2K_MEDIA_TITLE), new EmuleToED2KMetaTagsMap(MuleConstants.FT_MEDIA_LENGTH, MuleConstants.TAGTYPE_STRING, MuleConstants.FT_ED2K_MEDIA_LENGTH), new EmuleToED2KMetaTagsMap(MuleConstants.FT_MEDIA_LENGTH, MuleConstants.TAGTYPE_UINT32, MuleConstants.FT_ED2K_MEDIA_LENGTH), new EmuleToED2KMetaTagsMap(MuleConstants.FT_MEDIA_BITRATE, MuleConstants.TAGTYPE_UINT32, MuleConstants.FT_ED2K_MEDIA_BITRATE), new EmuleToED2KMetaTagsMap(MuleConstants.FT_MEDIA_CODEC, MuleConstants.TAGTYPE_STRING, MuleConstants.FT_ED2K_MEDIA_CODEC) }; for (int j = 0; j < _aEmuleToED2KMetaTagsMap.Length; j++) { if (string.Compare(pTag.Name, _aEmuleToED2KMetaTagsMap[j].pszED2KName) == 0 && ((pTag.IsStr && _aEmuleToED2KMetaTagsMap[j].nED2KType == MuleConstants.TAGTYPE_STRING) || (pTag.IsInt && _aEmuleToED2KMetaTagsMap[j].nED2KType == MuleConstants.TAGTYPE_UINT32))) { if (pTag.IsStr) { if (_aEmuleToED2KMetaTagsMap[j].nID == MuleConstants.FT_MEDIA_LENGTH) { uint nMediaLength = 0; uint hour = 0, min = 0, sec = 0; DateTime dt = DateTime.Now; if (MpdUtilities.Scan3UInt32(pTag.Str, ref hour, ref min, ref sec) == 3) { nMediaLength = hour * 3600 + min * 60 + sec; } else if (MpdUtilities.Scan2UInt32(pTag.Str, ref min, ref sec) == 2) { nMediaLength = min * 60 + sec; } else if (MpdUtilities.ScanUInt32(pTag.Str, ref sec) == 1) { nMediaLength = sec; } if (nMediaLength == 0) { pTag = null; } else { pTag = MpdObjectManager.CreateTag(_aEmuleToED2KMetaTagsMap[j].nID, nMediaLength); } } else { if (!string.IsNullOrEmpty(pTag.Str)) { pTag = MpdObjectManager.CreateTag(_aEmuleToED2KMetaTagsMap[j].nID, pTag.Str); } else { pTag = null; } } } else if (pTag.IsInt) { if (pTag.Int != 0) { pTag = MpdObjectManager.CreateTag(_aEmuleToED2KMetaTagsMap[j].nID, pTag.Int); } else { pTag = null; } } break; } } } }
public void SendPacket(Packet packet, Mule.ED2K.ED2KServer pServer, ushort nSpecialPort, byte[] pInRawPacket, uint nRawLen) { // Create raw UDP packet byte[] pRawPacket; uint uRawPacketSize; ushort nPort = 0; if (packet != null) { pRawPacket = new byte[packet.Size + 2]; Array.Copy(packet.UDPHeader, pRawPacket, 2); Array.Copy(packet.Buffer, 0, pRawPacket, 2, packet.Size); uRawPacketSize = packet.Size + 2; if (MuleApplication.Instance.Preference.IsServerCryptLayerUDPEnabled && pServer.ServerKeyUDP != 0 && pServer.DoesSupportsObfuscationUDP) { uRawPacketSize = (uint)EncryptSendServer(ref pRawPacket, (int)uRawPacketSize, pServer.ServerKeyUDP); nPort = pServer.ObfuscationPortUDP; } else { nPort = (ushort)(pServer.Port + 4); } } else if (pInRawPacket != null) { // we don't encrypt rawpackets (!) pRawPacket = new byte[nRawLen]; Array.Copy(pInRawPacket, pRawPacket, nRawLen); uRawPacketSize = nRawLen; nPort = (ushort)(pServer.Port + 4); } else { Debug.Assert(false); return; } nPort = (nSpecialPort == 0) ? nPort : nSpecialPort; Debug.Assert(nPort != 0); // Do we need to resolve the DN of this server? IPAddress ipAddr = IPAddress.None; IPAddress.TryParse(pServer.Address, out ipAddr); if (ipAddr == IPAddress.None) { IPHostEntry hostEntry = Dns.GetHostEntry(pServer.Address); // Get the IP value uint nIP = 0; if (hostEntry != null && hostEntry.AddressList.Length > 0) { nIP = BitConverter.ToUInt32(hostEntry.AddressList[0].GetAddressBytes(), 0); } if (nIP != 0) { bool bRemoveServer = false; if (!MpdUtilities.IsGoodIP(nIP)) { // However, if we are currently connected to a "not-good-ip", that IP can't // be that bad -- may only happen when debugging in a LAN. ED2KServer pConnectedServer = MuleApplication.Instance.ServerConnect.CurrentServer; if (pConnectedServer != null || pConnectedServer.IP != nIP) { bRemoveServer = true; } } if (!bRemoveServer && MuleApplication.Instance.Preference.IsFilterServerByIP && MuleApplication.Instance.IPFilter.IsFiltered(nIP)) { bRemoveServer = true; } ED2KServer pTempServer = MuleApplication.Instance.ServerList.GetServerByAddress(pServer.Address, pServer.Port); if (pTempServer != null) { pServer.IP = nIP; // If we already have entries in the server list (dynIP-servers without a DN) // with the same IP as this dynIP-server, remove the duplicates. MuleApplication.Instance.ServerList.RemoveDuplicatesByIP(pServer); } if (bRemoveServer) { return; } // Send all of the queued packets for this server. SendBuffer(nIP, nPort, pRawPacket, uRawPacketSize); } } else { // No DNS query needed for this server. Just send the packet. SendBuffer(BitConverter.ToUInt32(ipAddr.GetAddressBytes(), 0), nPort, pRawPacket, uRawPacketSize); } }
private bool ProcessPacket(byte[] buffer, int offset, int size, uint opcode, uint nIP, ushort nUDPPort) { try { MuleApplication.Instance.Statistics.AddDownDataOverheadServer((uint)size); ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByIPUDP(nIP, nUDPPort, true); if (pServer != null) { pServer.ResetFailedCount(); } switch ((OperationCodeEnum)opcode) { case OperationCodeEnum.OP_GLOBSEARCHRES: { SafeMemFile data = MpdObjectManager.CreateSafeMemFile(buffer, size); // process all search result packets int iLeft; do { uint uResultCount = MuleApplication.Instance.SearchList.ProcessUDPSearchAnswer(data, true /*pServer.GetUnicodeSupport()*/, nIP, nUDPPort - 4); // check if there is another source packet iLeft = (int)(data.Length - data.Position); if (iLeft >= 2) { byte protocol = data.ReadUInt8(); iLeft--; if (protocol != MuleConstants.PROTOCOL_EDONKEYPROT) { data.Seek(-1, System.IO.SeekOrigin.Current); iLeft += 1; break; } byte opcode1 = data.ReadUInt8(); iLeft--; if (opcode1 != (byte)OperationCodeEnum.OP_GLOBSEARCHRES) { data.Seek(-2, System.IO.SeekOrigin.Current); iLeft += 2; break; } } }while (iLeft > 0); break; } case OperationCodeEnum.OP_GLOBFOUNDSOURCES: { SafeMemFile data = MpdObjectManager.CreateSafeMemFile(buffer, size); // process all source packets int iLeft; do { byte[] fileid = new byte[16]; data.ReadHash16(fileid); PartFile file = MuleApplication.Instance.DownloadQueue.GetFileByID(fileid); if (file != null) { file.AddSources(data, nIP, (ushort)(nUDPPort - 4), false); } else { // skip sources for that file uint count = data.ReadUInt8(); data.Seek(count * (4 + 2), System.IO.SeekOrigin.Current); } // check if there is another source packet iLeft = (int)(data.Length - data.Position); if (iLeft >= 2) { byte protocol = data.ReadUInt8(); iLeft--; if (protocol != MuleConstants.PROTOCOL_EDONKEYPROT) { data.Seek(-1, System.IO.SeekOrigin.Current); iLeft += 1; break; } byte opcode1 = data.ReadUInt8(); iLeft--; if (opcode1 != (byte)OperationCodeEnum.OP_GLOBFOUNDSOURCES) { data.Seek(-2, System.IO.SeekOrigin.Current); iLeft += 2; break; } } }while (iLeft > 0); break; } case OperationCodeEnum.OP_GLOBSERVSTATRES: { if (size < 12 || pServer == null) { return(true); } uint challenge = BitConverter.ToUInt32(buffer, 0); if (challenge != pServer.Challenge) { return(true); } if (pServer != null) { pServer.Challenge = 0; pServer.CryptPingReplyPending = false; uint tNow = MpdUtilities.Time(); Random rand = new Random(); // if we used Obfuscated ping, we still need to reset the time properly pServer.LastPingedTime = Convert.ToUInt32(tNow - (rand.Next() % MuleConstants.ONE_HOUR_SEC)); } uint cur_user = BitConverter.ToUInt32(buffer, 4); uint cur_files = BitConverter.ToUInt32(buffer, 8); uint cur_maxusers = 0; uint cur_softfiles = 0; uint cur_hardfiles = 0; uint uUDPFlags = 0; uint uLowIDUsers = 0; uint dwServerUDPKey = 0; ushort nTCPObfuscationPort = 0; ushort nUDPObfuscationPort = 0; if (size >= 16) { cur_maxusers = BitConverter.ToUInt32(buffer, 12); } if (size >= 24) { cur_softfiles = BitConverter.ToUInt32(buffer, 16); cur_hardfiles = BitConverter.ToUInt32(buffer, 20); } if (size >= 28) { uUDPFlags = BitConverter.ToUInt32(buffer, 24); } if (size >= 32) { uLowIDUsers = BitConverter.ToUInt32(buffer, 28); } if (size >= 40) { // TODO debug check if this packet was encrypted if it has a key nUDPObfuscationPort = BitConverter.ToUInt16(buffer, 32); nTCPObfuscationPort = BitConverter.ToUInt16(buffer, 34);; dwServerUDPKey = BitConverter.ToUInt32(buffer, 36); } if (pServer != null) { pServer.Ping = MpdUtilities.GetTickCount() - pServer.LastPinged; pServer.UserCount = cur_user; pServer.FileCount = cur_files; pServer.MaxUsers = cur_maxusers; pServer.SoftFiles = cur_softfiles; pServer.HardFiles = cur_hardfiles; pServer.ServerKeyUDP = dwServerUDPKey; pServer.ObfuscationPortTCP = nTCPObfuscationPort; pServer.ObfuscationPortUDP = nUDPObfuscationPort; // if the received UDP flags do not match any already stored UDP flags, // reset the server version string because the version (which was determined by last connecting to // that server) is most likely not accurat any longer. // this may also give 'false' results because we don't know the UDP flags when connecting to a server // with TCP. //if (pServer.GetUDPFlags() != uUDPFlags) // pServer.Version(_T = ""); pServer.UDPFlags = (ED2KServerUdpFlagsEnum)uUDPFlags; pServer.LowIDUsers = uLowIDUsers; pServer.SetLastDescPingedCount(false); if (pServer.LastDescPingedCount < 2) { // eserver 16.45+ supports a new OP_SERVER_DESC_RES answer, if the OP_SERVER_DESC_REQ contains a uint // challenge, the server returns additional info with OP_SERVER_DESC_RES. To properly distinguish the // old and new OP_SERVER_DESC_RES answer, the challenge has to be selected carefully. The first 2 bytes // of the challenge (in network byte order) MUST NOT be a valid string-len-int16! Packet packet1 = MuleApplication.Instance.NetworkObjectManager.CreatePacket(OperationCodeEnum.OP_SERVER_DESC_REQ, 4); uint uDescReqChallenge = ((uint)MpdUtilities.GetRandomUInt16() << 16) + MuleConstants.INV_SERV_DESC_LEN; // 0xF0FF = an 'invalid' string length. pServer.DescReqChallenge = uDescReqChallenge; Array.Copy(BitConverter.GetBytes(uDescReqChallenge), packet1.Buffer, 4); MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet1.Size); MuleApplication.Instance.ServerConnect.SendUDPPacket(packet1, pServer, true); } else { pServer.SetLastDescPingedCount(true); } } break; } case OperationCodeEnum.OP_SERVER_DESC_RES: { if (pServer == null) { return(true); } // old packet: <name_len 2><name name_len><desc_len 2 desc_en> // new packet: <challenge 4><taglist> // // NOTE: To properly distinguish between the two packets which are both useing the same opcode... // the first two bytes of <challenge> (in network byte order) have to be an invalid <name_len> at least. SafeMemFile srvinfo = MpdObjectManager.CreateSafeMemFile(buffer, size); if (size >= 8 && BitConverter.ToUInt16(buffer, 0) == MuleConstants.INV_SERV_DESC_LEN) { if (pServer.DescReqChallenge != 0 && BitConverter.ToUInt32(buffer, 0) == pServer.DescReqChallenge) { pServer.DescReqChallenge = 0; srvinfo.ReadUInt32(); // skip challenge uint uTags = srvinfo.ReadUInt32(); for (uint i = 0; i < uTags; i++) { Tag tag = MpdObjectManager.CreateTag(srvinfo, true /*pServer.GetUnicodeSupport()*/); if (tag.NameID == MuleConstants.ST_SERVERNAME && tag.IsStr) { pServer.ServerName = tag.Str; } else if (tag.NameID == MuleConstants.ST_DESCRIPTION && tag.IsStr) { pServer.Description = tag.Str; } else if (tag.NameID == MuleConstants.ST_DYNIP && tag.IsStr) { // Verify that we really received a DN. IPAddress address; if (!IPAddress.TryParse(tag.Str, out address) || address == IPAddress.None) { string strOldDynIP = pServer.DynIP; pServer.DynIP = tag.Str; // If a dynIP-server changed its address or, if this is the // first time we get the dynIP-address for a server which we // already have as non-dynIP in our list, we need to remove // an already available server with the same 'dynIP:port'. if (string.Compare(strOldDynIP, pServer.DynIP, true) != 0) { MuleApplication.Instance.ServerList.RemoveDuplicatesByAddress(pServer); } } } else if (tag.NameID == MuleConstants.ST_VERSION && tag.IsStr) { pServer.Version = tag.Str; } else if (tag.NameID == MuleConstants.ST_VERSION && tag.IsInt) { pServer.Version = string.Format("{0}.{1}", tag.Int >> 16, tag.Int & 0xFFFF); } } } else { // A server sent us a new server description packet (including a challenge) although we did not // ask for it. This may happen, if there are multiple servers running on the same machine with // multiple IPs. If such a server is asked for a description, the server will answer 2 times, // but with the same IP. } } else { string strName = srvinfo.ReadString(true /*pServer.GetUnicodeSupport()*/); string strDesc = srvinfo.ReadString(true /*pServer.GetUnicodeSupport()*/); pServer.Description = strDesc; pServer.ServerName = strName; } break; } default: return(false); } return(true); } catch (Exception error) { ProcessPacketError((uint)size, (uint)opcode, nIP, nUDPPort, error); if (opcode == (byte)OperationCodeEnum.OP_GLOBSEARCHRES || opcode == (byte)OperationCodeEnum.OP_GLOBFOUNDSOURCES) { return(true); } } return(false); }
public void Process() { /////////////////////////////////////////////////////////////////////////// // Cleanup banned client list // uint cur_tick = MpdUtilities.GetTickCount(); if (lastBannCleanUp_ + MuleConstants.BAN_CLEANUP_TIME < cur_tick) { lastBannCleanUp_ = cur_tick; Dictionary <uint, uint> .Enumerator pos = bannedList_.GetEnumerator(); while (pos.MoveNext()) { if (pos.Current.Value + MuleConstants.CLIENTBANTIME < cur_tick) { RemoveBannedClient(pos.Current.Key); } } } /////////////////////////////////////////////////////////////////////////// // Cleanup tracked client list // if (lastTrackedCleanUp_ + MuleConstants.TRACKED_CLEANUP_TIME < cur_tick) { lastTrackedCleanUp_ = cur_tick; Dictionary <uint, DeletedClient> .Enumerator pos = trackedClientsList_.GetEnumerator(); while (pos.MoveNext()) { if (pos.Current.Value.m_dwInserted + MuleConstants.KEEPTRACK_TIME < cur_tick) { trackedClientsList_.Remove(pos.Current.Key); } } } /////////////////////////////////////////////////////////////////////////// // Process Kad client list // //We need to try to connect to the clients in m_KadList //If connected, remove them from the list and send a message back to Kad so we can send a ACK. //If we don't connect, we need to remove the client.. //The sockets timeout should delete this object. // buddy is just a flag that is used to make sure we are still connected or connecting to a buddy. BuddyStateEnum buddy = BuddyStateEnum.Disconnected; for (int pos1 = 0; pos1 < kadList_.Count; pos1++) { UpDownClient cur_client = kadList_[pos1]; if (!MuleApplication.Instance.KadEngine.IsRunning) { //Clear out this list if we stop running Kad. //Setting the Kad state to KS_NONE causes it to be removed in the switch below. cur_client.KadState = KadStateEnum.KS_NONE; } switch (cur_client.KadState) { case KadStateEnum.KS_QUEUED_FWCHECK: case KadStateEnum.KS_QUEUED_FWCHECK_UDP: //Another client asked us to try to connect to them to check their firewalled status. cur_client.TryToConnect(true, true); break; case KadStateEnum.KS_CONNECTING_FWCHECK: //Ignore this state as we are just waiting for results. break; case KadStateEnum.KS_FWCHECK_UDP: case KadStateEnum.KS_CONNECTING_FWCHECK_UDP: // we want a UDP firewallcheck from this client and are just waiting to get connected to send the request break; case KadStateEnum.KS_CONNECTED_FWCHECK: //We successfully connected to the client. //We now send a ack to let them know. if (cur_client.KadVersion >= (byte)VersionsEnum.KADEMLIA_VERSION7_49a) { // the result is now sent per TCP instead of UDP, because this will fail if our intern UDP port is unreachable. // But we want the TCP testresult regardless if UDP is firewalled, the new UDP state and test takes care of the rest Packet pPacket = MuleApplication.Instance.NetworkObjectManager.CreatePacket(OperationCodeEnum.OP_KAD_FWTCPCHECK_ACK, 0, MuleConstants.PROTOCOL_EMULEPROT); if (!cur_client.SafeConnectAndSendPacket(pPacket)) { cur_client = null; } } else { MuleApplication.Instance.KadEngine.UDPListener.SendNullPacket(KadOperationCodeEnum.KADEMLIA_FIREWALLED_ACK_RES, (uint)IPAddress.NetworkToHostOrder(cur_client.IP), cur_client.KadPort, null, null); } //We are done with this client. Set Kad status to KS_NONE and it will be removed in the next cycle. if (cur_client != null) { cur_client.KadState = KadStateEnum.KS_NONE; } break; case KadStateEnum.KS_INCOMING_BUDDY: //A firewalled client wants us to be his buddy. //If we already have a buddy, we set Kad state to KS_NONE and it's removed in the next cycle. //If not, this client will change to KS_CONNECTED_BUDDY when it connects. if (buddyStatus_ == BuddyStateEnum.Connected) { cur_client.KadState = KadStateEnum.KS_NONE; } break; case KadStateEnum.KS_QUEUED_BUDDY: //We are firewalled and want to request this client to be a buddy. //But first we check to make sure we are not already trying another client. //If we are not already trying. We try to connect to this client. //If we are already connected to a buddy, we set this client to KS_NONE and it's removed next cycle. //If we are trying to connect to a buddy, we just ignore as the one we are trying may fail and we can then try this one. if (buddyStatus_ == BuddyStateEnum.Disconnected) { buddy = BuddyStateEnum.Connecting; buddyStatus_ = BuddyStateEnum.Connecting; cur_client.KadState = KadStateEnum.KS_CONNECTING_BUDDY; cur_client.TryToConnect(true, true); } else if (buddyStatus_ == BuddyStateEnum.Connected) { cur_client.KadState = KadStateEnum.KS_NONE; } break; case KadStateEnum.KS_CONNECTING_BUDDY: //We are trying to connect to this client. //Although it should NOT happen, we make sure we are not already connected to a buddy. //If we are we set to KS_NONE and it's removed next cycle. //But if we are not already connected, make sure we set the flag to connecting so we know //things are working correctly. if (buddyStatus_ == BuddyStateEnum.Connected) { cur_client.KadState = KadStateEnum.KS_NONE; } else { buddy = BuddyStateEnum.Connecting; } break; case KadStateEnum.KS_CONNECTED_BUDDY: //A potential connected buddy client wanting to me in the Kad network //We set our flag to connected to make sure things are still working correctly. buddy = BuddyStateEnum.Connected; //If m_nBuddyStatus is not connected already, we set this client as our buddy! if (buddyStatus_ != BuddyStateEnum.Connected) { buddy_ = cur_client; buddyStatus_ = BuddyStateEnum.Connected; } if (buddy_ == cur_client && MuleApplication.Instance.IsFirewalled && cur_client.SendBuddyPingPong) { Packet buddyPing = MuleApplication.Instance.NetworkObjectManager.CreatePacket(OperationCodeEnum.OP_BUDDYPING, 0, MuleConstants.PROTOCOL_EMULEPROT); MuleApplication.Instance.Statistics.AddUpDataOverheadOther(buddyPing.Size); cur_client.SetLastBuddyPingPongTime(); } break; default: RemoveFromKadList(cur_client); pos1--; break; } } //We either never had a buddy, or lost our buddy.. if (buddy == BuddyStateEnum.Disconnected) { if (buddyStatus_ != BuddyStateEnum.Disconnected || buddy_ != null) { if (MuleApplication.Instance.KadEngine.IsRunning && MuleApplication.Instance.IsFirewalled && MuleApplication.Instance.KadEngine.UDPFirewallTester.IsFirewalledUDP(true)) { //We are a lowID client and we just lost our buddy. //Go ahead and instantly try to find a new buddy. MuleApplication.Instance.KadEngine.Preference.SetFindBuddy(); } buddy_ = null; buddyStatus_ = BuddyStateEnum.Disconnected; } } if (MuleApplication.Instance.KadEngine.IsConnected) { //we only need a buddy if direct callback is not available if (MuleApplication.Instance.KadEngine.IsFirewalled && MuleApplication.Instance.KadEngine.UDPFirewallTester.IsFirewalledUDP(true)) { //TODO 0.49b: Kad buddies won'T work with RequireCrypt, so it is disabled for now but should (and will) //be fixed in later version // Update: Buddy connections itself support obfuscation properly since 0.49a (this makes it work fine if our buddy uses require crypt) // ,however callback requests don't support it yet so we wouldn't be able to answer callback requests with RequireCrypt, protocolchange intended for the next version if (buddyStatus_ == BuddyStateEnum.Disconnected && MuleApplication.Instance.KadEngine.Preference.FindBuddy && !MuleApplication.Instance.Preference.IsClientCryptLayerRequired) { //We are a firewalled client with no buddy. We have also waited a set time //to try to avoid a false firewalled status.. So lets look for a buddy.. if (null == MuleApplication.Instance.KadEngine.SearchManager.PrepareLookup(KadSearchTypeEnum.FINDBUDDY, true, MuleApplication.Instance.KadObjectManager.CreateUInt128(true).Xor(MuleApplication.Instance.KadEngine.Preference.KadID))) { //This search ID was already going. Most likely reason is that //we found and lost our buddy very quickly and the last search hadn't //had time to be removed yet. Go ahead and set this to happen again //next time around. MuleApplication.Instance.KadEngine.Preference.SetFindBuddy(); } } } else { if (buddy_ != null) { //Lets make sure that if we have a buddy, they are firewalled! //If they are also not firewalled, then someone must have fixed their firewall or stopped saturating their line.. //We just set the state of this buddy to KS_NONE and things will be cleared up with the next cycle. if (!buddy_.HasLowID) { buddy_.KadState = KadStateEnum.KS_NONE; } } } } else { if (buddy_ != null) { //We are not connected anymore. Just set this buddy to KS_NONE and things will be cleared out on next cycle. buddy_.KadState = KadStateEnum.KS_NONE; } } /////////////////////////////////////////////////////////////////////////// // Cleanup client list // CleanUpClientList(); /////////////////////////////////////////////////////////////////////////// // Process Direct Callbacks for Timeouts // ProcessConnectingClientsList(); }
public bool VerifyIdent(ClientCredits pTarget, byte[] pachSignature, byte nInputSize, uint dwForIP, byte byChaIPKind) { if (!IsCryptoAvailable) { pTarget.IdentState = IdentStateEnum.IS_NOTAVAILABLE; return(false); } bool bResult; try { RSAPKCS1SignatureDeformatter pubkey = MpdObjectManager.CreateRSAPKCS1V15SHA1Verifier(pTarget.SecureIdent, pTarget.SecIDKeyLen); // 4 additional bytes random data send from this client +5 bytes v2 byte[] abyBuffer = new byte[CreditStruct.MAXPUBKEYSIZE + 9]; Array.Copy(publicKey_, abyBuffer, publicKeyLen_); uint challenge = pTarget.CryptRndChallengeFor; Array.Copy(BitConverter.GetBytes(challenge), 0, abyBuffer, publicKeyLen_, 4); // v2 security improvments (not supported by 29b, not used as default by 29c) byte nChIpSize = 0; if (byChaIPKind != 0) { nChIpSize = 5; uint ChallengeIP = 0; switch (byChaIPKind) { case CRYPT_CIP_LOCALCLIENT: ChallengeIP = dwForIP; break; case CRYPT_CIP_REMOTECLIENT: if (MuleApplication.Instance.ServerConnect.ClientID == 0 || MuleApplication.Instance.ServerConnect.IsLowID) { ChallengeIP = MuleApplication.Instance.ServerConnect.LocalIP; } else { ChallengeIP = MuleApplication.Instance.ServerConnect.ClientID; } break; case CRYPT_CIP_NONECLIENT: // maybe not supported in future versions ChallengeIP = 0; break; } Array.Copy(BitConverter.GetBytes(ChallengeIP), 0, abyBuffer, publicKeyLen_ + 4, 4); abyBuffer[publicKeyLen_ + 4 + 4] = byChaIPKind; } //v2 end byte[] hash = new byte[publicKeyLen_ + 4 + nChIpSize]; Array.Copy(abyBuffer, hash, publicKeyLen_ + 4 + nChIpSize); byte[] sign = new byte[nInputSize]; Array.Copy(pachSignature, sign, nInputSize); bResult = pubkey.VerifySignature(hash, sign); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); bResult = false; } if (!bResult) { if (pTarget.IdentState == IdentStateEnum.IS_IDNEEDED) { pTarget.IdentState = IdentStateEnum.IS_IDFAILED; } } else { pTarget.Verified(dwForIP); } return(bResult); }
protected void LoadList() { string strFileName = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), CLIENTS_MET_FILENAME); if (!System.IO.File.Exists(strFileName)) { return; } SafeBufferedFile file = null; try { file = MpdObjectManager.CreateSafeBufferedFile(strFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None); byte version = file.ReadUInt8(); if (version != (byte)VersionsEnum.CREDITFILE_VERSION && version != (byte)VersionsEnum.CREDITFILE_VERSION_29) { file.Close(); return; } // everything is ok, lets see if the backup exist... string strBakFileName = System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR), string.Format("{0}{1}", CLIENTS_MET_FILENAME, ".bak")); uint dwBakFileSize = 0; bool bCreateBackup = true; if (System.IO.File.Exists(strBakFileName)) { FileInfo fInfo = new FileInfo(strBakFileName); dwBakFileSize = (uint)fInfo.Length; if (dwBakFileSize > (uint)file.Length) { // the size of the backup was larger then the org. file, something is wrong here, don't overwrite old backup.. bCreateBackup = false; } } //else: the backup doesn't exist, create it if (bCreateBackup) { file.Close(); // close the file before copying System.IO.File.Copy(strFileName, strBakFileName, true); file = MpdObjectManager.CreateSafeBufferedFile(strFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None); file.Seek(1, SeekOrigin.Begin); //set filepointer behind file version byte } uint count = file.ReadUInt32(); uint dwExpired = MpdUtilities.Time() - 12960000; // today - 150 day uint cDeleted = 0; for (uint i = 0; i < count; i++) { CreditStruct newcstruct = new CreditStruct(); if (version == (byte)VersionsEnum.CREDITFILE_VERSION_29) { ReadCreditStruct29a(file, newcstruct); } else { ReadCreditStruct(file, newcstruct); } if (newcstruct.nLastSeen < dwExpired) { cDeleted++; continue; } ClientCredits newcredits = MuleApplication.Instance.CoreObjectManager.CreateClientCredits(newcstruct); clients_[new MapCKey(newcredits.Key)] = newcredits; } file.Close(); } catch (Exception error) { MpdUtilities.DebugLogError(error); file.Close(); } }
public void ConnectionEstablished(Mule.Network.ServerSocket sender) { if (!IsConnecting) { // we are already IsConnected to another server DestroySocket(sender); return; } InitLocalIP(); if (sender.ConnectionState == ConnectionStateEnum.CS_WAITFORLOGIN) { ED2KServer pServer = MuleApplication.Instance.ServerList.GetServerByAddress(sender.CurrentServer.Address, sender.CurrentServer.Port); if (pServer != null) { pServer.ResetFailedCount(); } // Send login packet SafeMemFile data = MpdObjectManager.CreateSafeMemFile(256); data.WriteHash16(MuleApplication.Instance.Preference.UserHash); data.WriteUInt32(ClientID); data.WriteUInt16(MuleApplication.Instance.Preference.Port); uint tagcount = 4; data.WriteUInt32(tagcount); Tag tagName = MpdObjectManager.CreateTag(TagTypeEnum.CT_NAME, MuleApplication.Instance.Preference.UserNick); tagName.WriteTagToFile(data); Tag tagVersion = MpdObjectManager.CreateTag(TagTypeEnum.CT_VERSION, VersionsEnum.EDONKEYVERSION); tagVersion.WriteTagToFile(data); ServerFlagsEnum dwCryptFlags = 0; if (MuleApplication.Instance.Preference.IsClientCryptLayerSupported) { dwCryptFlags |= ServerFlagsEnum.SRVCAP_SUPPORTCRYPT; } if (MuleApplication.Instance.Preference.IsClientCryptLayerRequested) { dwCryptFlags |= ServerFlagsEnum.SRVCAP_REQUESTCRYPT; } if (MuleApplication.Instance.Preference.IsClientCryptLayerRequired) { dwCryptFlags |= ServerFlagsEnum.SRVCAP_REQUIRECRYPT; } Tag tagFlags = MpdObjectManager.CreateTag(TagTypeEnum.CT_SERVER_FLAGS, ServerFlagsEnum.SRVCAP_ZLIB | ServerFlagsEnum.SRVCAP_NEWTAGS | ServerFlagsEnum.SRVCAP_LARGEFILES | ServerFlagsEnum.SRVCAP_UNICODE | dwCryptFlags); tagFlags.WriteTagToFile(data); // eMule Version (14-Mar-2004: requested by lugdunummaster (need for LowID clients which have no chance // to send an Hello packet to the server during the callback test)) Tag tagMuleVersion = MpdObjectManager.CreateTag(TagTypeEnum.CT_EMULE_VERSION, (MuleApplication.Instance.Version.Major << 17) | (MuleApplication.Instance.Version.Minor << 10) | (MuleApplication.Instance.Version.Build << 7)); tagMuleVersion.WriteTagToFile(data); Packet packet = MuleApplication.Instance.NetworkObjectManager.CreatePacket(data); packet.OperationCode = OperationCodeEnum.OP_LOGINREQUEST; MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet.Size); SendPacket(packet, true, sender); } else if (sender.ConnectionState == ConnectionStateEnum.CS_CONNECTED) { MuleApplication.Instance.Statistics.Reconnects++; MuleApplication.Instance.Statistics.ServerConnectTime = MpdUtilities.GetTickCount(); IsConnected = true; connectedSocket_ = sender; StopConnectionTry(); MuleApplication.Instance.SharedFiles.ClearED2KPublishInfo(); MuleApplication.Instance.SharedFiles.SendListToServer(); if (MuleApplication.Instance.Preference.DoesAddServersFromServer) { Packet packet = MuleApplication.Instance.NetworkObjectManager.CreatePacket( OperationCodeEnum.OP_GETSERVERLIST, 0); MuleApplication.Instance.Statistics.AddUpDataOverheadServer(packet.Size); SendPacket(packet, true); } } }
private void SocketManagerThreadFunc() { while (!shutDown_) { List <Socket> readSockets = new List <Socket>(); List <Socket> writeSockets = new List <Socket>(); List <Socket> errorSockets = new List <Socket>(); lock (locker_) { sockets_.Keys.ToList().ForEach(s => { readSockets.Add(s); writeSockets.Add(s); errorSockets.Add(s); }); } if (readSockets.Count == 0) { Thread.Sleep(TIMEOUT); continue; } try { Socket.Select(readSockets, writeSockets, errorSockets, TIMEOUT * 1000); if (shutDown_) { return; } lock (locker_) { readSockets.ForEach(s => { if (!sockets_.ContainsKey(s)) { return; } AsyncSocketImpl socket = sockets_[s]; if (socket.listen_called_) { socket.FireOnAcceptEvent(); } else { socket.FireOnReceiveEvent(); } }); writeSockets.ForEach(s => { if (!sockets_.ContainsKey(s)) { return; } AsyncSocketImpl socket = sockets_[s]; if (socket.Connected && socket.connect_event_fired_) { socket.FireOnSendEvent(); } else { socket.connect_event_fired_ = true; socket.FireOnConnectEvent(); } }); errorSockets.ForEach(s => { if (!sockets_.ContainsKey(s)) { return; } AsyncSocketImpl socket = sockets_[s]; socket.FireOnErrorEvent(10061); }); } } catch (SocketException ex) { MpdUtilities.DebugLogError(string.Format("Socket Exception:{0},{1}", ex.ErrorCode, ex.SocketErrorCode), ex); } catch (Exception ex) { MpdUtilities.DebugLogError(ex); } }//while }
public void Stop() { try { CloseConnection(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ServerConnect.Stop(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ClientUDP.Close(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ListenSocket.StopListening(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { LastCommonRouteFinder.StopFinder(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { UploadBandwidthThrottler.Stop(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { Preference.Save(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } try { ClientCredits.CleanUp(); } catch (Exception ex) { MpdUtilities.DebugLogError("MuleApplication Stop Fail", ex); } if (ShutDownMuleApplication != null) { ShutDownMuleApplication(this, new EventArgs()); } }
public MapSKey(MapSKey key) { MpdUtilities.Md4Cpy(key_, key.key_); }
public void AddBannedClient(uint dwIP) { bannedList_[dwIP] = MpdUtilities.GetTickCount(); }
public void SetFileRating(byte[] hash, uint rating) { lock (locker_) { if (FileComments == null) { FileComments = new List <FileComments>(); } bool found = false; foreach (FileComments comments in FileComments) { if (string.Compare(comments.Name, MpdUtilities.EncodeHexString(hash)) == 0) { if (comments.Comments != null && comments.Comments.Count > 0) { comments.Comments[0].Rate = rating; } else { if (comments.Comments == null) { comments.Comments = new List <FileComment>(); } FileComment comment = MuleApplication.Instance.PreferenceObjectManager.CreateFileComment(); comment.Rate = rating; comments.Comments.Add(comment); } found = true; break; } } if (!found) { FileComments comments = MuleApplication.Instance.PreferenceObjectManager.CreateFileComments(MpdUtilities.EncodeHexString(hash)); if (comments.Comments == null) { comments.Comments = new List <FileComment>(); } FileComment comment = MuleApplication.Instance.PreferenceObjectManager.CreateFileComment(); comment.Rate = rating; comments.Comments.Add(comment); FileComments.Add(comments); } } }
public void SetLastSeen() { credits_.nLastSeen = MpdUtilities.Time(); }
private void ResetTimeOutTimer() { timeout_timer_ = MpdUtilities.GetTickCount(); }
public void SetSecWaitStartTime(uint dwForIP) { unSecureWaitTime_ = MpdUtilities.GetTickCount() - 1; secureWaitTime_ = MpdUtilities.GetTickCount() - 1; waitTimeIP_ = dwForIP; }