示例#1
0
        public override int Send(byte[] lpBuf, int offset, int nBufLen, SocketFlags nFlags)
        {
            if (!IsEncryptionLayerReady)
            {
                Debug.Assert(false); // must be a bug
                return(0);
            }
            else if (serverCrypt_ &&
                     streamCryptState_ == StreamCryptStateEnum.ECS_ENCRYPTING &&
                     fiSendBuffer_ != null)
            {
                Debug.Assert(negotiatingState_ == NegotiatingStateEnum.ONS_BASIC_SERVER_DELAYEDSENDING);
                // handshakedata was delayed to put it into one frame with the first paypload to the server
                // do so now with the payload attached
                int nRes = SendNegotiatingData(lpBuf, Convert.ToUInt32(nBufLen), Convert.ToUInt32(offset + nBufLen));
                Debug.Assert(nRes != SOCKET_ERROR);
                return(nBufLen); // report a full send, even if we didn't for some reason - the data is know in our buffer and will be handled later
            }
            else if (negotiatingState_ == NegotiatingStateEnum.ONS_BASIC_SERVER_DELAYEDSENDING)
            {
                Debug.Assert(false);
            }

            if (streamCryptState_ == StreamCryptStateEnum.ECS_UNKNOWN)
            {
                //this happens when the encryption option was not set on a outgoing connection
                //or if we try to send before receiving on a incoming connection - both shouldn't happen
                streamCryptState_ = StreamCryptStateEnum.ECS_NONE;
                MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Overwriting State ECS_UNKNOWN with ECS_NONE because of premature Send() (%s)"), DbgGetIPString());
            }

            return(base.Send(lpBuf, offset, nBufLen, nFlags));
        }
示例#2
0
        public void StartUp()
        {
            if (IsRunning)
            {
                return;
            }

            IsRunning = false;

            try
            {
                ServerList.Init();

                UploadBandwidthThrottler.Start();

                DownloadQueue.Init();

                ListenSocket.StartListening();

                ClientUDP.Create();

                if (Preference.DoesAutoConnect)
                {
                    StartConnection();
                }

                IsRunning = true;
            }
            catch (Exception ex)
            {
                MpdUtilities.DebugLogError("MuleApplication StartUp Fail",
                                           ex);
            }
        }
示例#3
0
        protected void InitalizeCrypting()
        {
            publicKeyLen_ = 0;
            Array.Clear(publicKey_, 0, 80); // not really needed; better for debugging tho
            signkey_ = null;
            if (!MuleApplication.Instance.Preference.IsSecureIdentEnabled)
            {
                return;
            }
            // check if keyfile is there
            bool bCreateNewKey = false;

            string filename =
                System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR),
                                       "crytkey.dat");

            if (System.IO.File.Exists(filename))
            {
                FileInfo info = new FileInfo(filename);

                if (info.Length == 0)
                {
                    bCreateNewKey = true;
                }
            }
            else
            {
                bCreateNewKey = true;
            }

            if (bCreateNewKey)
            {
                CreateKeyPair();
            }

            // load key
            try
            {
                string keyText = System.IO.File.ReadAllText(filename);
                byte[] key     = Convert.FromBase64String(keyText);

                // load private key
                signkey_ = MpdObjectManager.CreateRSAPKCS1V15SHA1Signer(key);

                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider((int)MuleConstants.RSAKEYSIZE);
                rsa.ImportCspBlob(key);

                byte[] tmp = rsa.ExportCspBlob(false);
                Array.Copy(tmp, publicKey_, tmp.Length);
                publicKeyLen_ = (byte)tmp.Length;
            }
            catch (Exception ex)
            {
                signkey_ = null;
                MpdUtilities.DebugLogError(ex);
            }
        }
示例#4
0
        public byte CreateSignature(ClientCredits pTarget,
                                    byte[] pachOutput,
                                    byte nMaxSize,
                                    uint ChallengeIP, byte byChaIPKind,
                                    RSAPKCS1SignatureFormatter sigkey)
        {
            // sigkey param is used for debug only
            if (sigkey == null)
            {
                sigkey = signkey_;
            }

            // create a signature of the public key from pTarget
            byte nResult;

            if (!IsCryptoAvailable)
            {
                return(0);
            }
            try
            {
                byte[] abyBuffer = new byte[CreditStruct.MAXPUBKEYSIZE + 9];
                uint   keylen    = pTarget.SecIDKeyLen;
                Array.Copy(pTarget.SecureIdent, abyBuffer, keylen);
                // 4 additional bytes random data send from this client
                uint challenge = pTarget.CryptRndChallengeFrom;
                Array.Copy(BitConverter.GetBytes(challenge), 0,
                           abyBuffer, keylen, 4);
                ushort ChIpLen = 0;
                if (byChaIPKind != 0)
                {
                    ChIpLen = 5;
                    Array.Copy(BitConverter.GetBytes(ChallengeIP), 0,
                               abyBuffer, keylen + 4, 4);
                    abyBuffer[keylen + 4 + 4] = byChaIPKind;
                }

                byte[] tmpBuf = new byte[keylen + 4 + ChIpLen];
                Array.Copy(abyBuffer, tmpBuf, keylen + 4 + ChIpLen);
                byte[] outBuf = sigkey.CreateSignature(tmpBuf);

                nResult = (byte)outBuf.Length;

                if (outBuf.Length > nMaxSize)
                {
                    nResult = nMaxSize;
                }
                Array.Copy(outBuf, pachOutput, nResult);
            }
            catch (Exception ex)
            {
                MpdUtilities.DebugLogError(ex);
                nResult = 0;
            }
            return(nResult);
        }
示例#5
0
        public override bool Connect(string lpszHostAddress, uint nHostPort)
        {
            InitProxySupport();

            try
            {
                base.Connect(lpszHostAddress, nHostPort);
                return(base.Connected);
            }
            catch (Exception ex)
            {
                MpdUtilities.DebugLogError("Connect Fail", ex);
                return(base.Connected);
            }
        }
示例#6
0
 public virtual int Receive(byte[] pBuffer, int offset, int nBufLen, SocketFlags nFlags)
 {
     SocketErrorCode = SocketError.Success;
     try
     {
         return(socket_.Receive(pBuffer, offset, nBufLen, nFlags));
     }
     catch (SocketException ex)
     {
         SocketErrorCode = ex.SocketErrorCode;
         MpdUtilities.DebugLogError(string.Format("Socket Exception:{0},{1}",
                                                  ex.ErrorCode, ex.SocketErrorCode), ex);
         return(SOCKET_ERROR);
     }
 }
示例#7
0
        public AsyncSocket Accept()
        {
            SocketErrorCode = SocketError.Success;

            try
            {
                return(CreateAsyncSocket(socket_.Accept()));
            }
            catch (SocketException ex)
            {
                SocketErrorCode = ex.SocketErrorCode;

                MpdUtilities.DebugLogError(string.Format("Socket Exception:{0},{1}",
                                                         ex.ErrorCode, ex.SocketErrorCode), ex);

                return(null);
            }
        }
示例#8
0
 protected void CryptPrepareSendData(byte[] pBuffer, uint nLen)
 {
     if (!IsEncryptionLayerReady)
     {
         Debug.Assert(false); // must be a bug
         return;
     }
     if (streamCryptState_ == StreamCryptStateEnum.ECS_UNKNOWN)
     {
         //this happens when the encryption option was not set on a outgoing connection
         //or if we try to send before receiving on a incoming connection - both shouldn't happen
         streamCryptState_ = StreamCryptStateEnum.ECS_NONE;
         MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Overwriting State ECS_UNKNOWN with ECS_NONE because of premature Send() (%s)"), DbgGetIPString());
     }
     if (streamCryptState_ == StreamCryptStateEnum.ECS_ENCRYPTING)
     {
         MuleUtilities.RC4Crypt(pBuffer, pBuffer, nLen, rc4SendKey_);
     }
 }
示例#9
0
        public void InitLocalIP()
        {
            LocalIP = 0;

            // Using 'gethostname/gethostbyname' does not solve the problem when we have more than
            // one IP address. Using 'gethostname/gethostbyname' even seems to return the last IP
            // address which we got. e.g. if we already got an IP from our ISP,
            // 'gethostname/gethostbyname' will returned that (primary) IP, but if we add another
            // IP by opening a VPN connection, 'gethostname' will still return the same hostname,
            // but 'gethostbyname' will return the 2nd IP.
            // To weaken that problem at least for users which are binding eMule to a certain IP,
            // we use the explicitly specified bind address as our local IP address.
            if (MuleApplication.Instance.Preference.BindAddr != null)
            {
                IPAddress ulBindAddr = null;

                if (IPAddress.TryParse(MuleApplication.Instance.Preference.BindAddr,
                                       out ulBindAddr))
                {
                    LocalIP = BitConverter.ToUInt32(ulBindAddr.GetAddressBytes(), 0);
                    return;
                }
            }

            // Don't use 'gethostbyname(null)'. The winsock DLL may be replaced by a DLL from a third party
            // which is not fully compatible to the original winsock DLL. ppl reported crash with SCORSOCK.DLL
            // when using 'gethostbyname(null)'.
            try
            {
                string      hostName  = Dns.GetHostName();
                IPHostEntry hostEntry = Dns.GetHostEntry(hostName);

                if (hostEntry.AddressList != null && hostEntry.AddressList.Length > 0)
                {
                    LocalIP = BitConverter.ToUInt32(hostEntry.AddressList[0].GetAddressBytes(), 0);
                }
            }
            catch (Exception ex)
            {
                MpdUtilities.DebugLogError(ex);
            }
        }
示例#10
0
        protected void SaveList()
        {
            lastSaved_ = MpdUtilities.GetTickCount();

            string name =
                System.IO.Path.Combine(MuleApplication.Instance.Preference.GetMuleDirectory(Mule.Preference.DefaultDirectoryEnum.EMULE_CONFIGDIR),
                                       CLIENTS_MET_FILENAME);

            try
            {
                using (FileStream file = new FileStream(name, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    int         count   = clients_.Count;
                    SafeMemFile memfile =
                        MpdObjectManager.CreateSafeMemFile(count * (16 + 5 * 4 + 1 * 2 + 1 + CreditStruct.MAXPUBKEYSIZE));

                    memfile.WriteUInt8((byte)VersionsEnum.CREDITFILE_VERSION);
                    Dictionary <MapCKey, ClientCredits> .Enumerator pos = clients_.GetEnumerator();
                    count = 0;
                    while (pos.MoveNext())
                    {
                        ClientCredits cur_credit = pos.Current.Value;
                        if (cur_credit.GetUploadedTotal() != 0 || cur_credit.GetDownloadedTotal() != 0)
                        {
                            WriteCreditStruct(memfile, cur_credit.DataStruct);
                            count++;
                        }
                    }

                    memfile.WriteUInt32((uint)count);
                    file.Write(memfile.Buffer, 0, (int)memfile.Length);
                    file.Flush();
                    file.Close();
                    memfile.Close();
                }
            }
            catch (Exception error)
            {
                MpdUtilities.DebugLogError(error);
            }
        }
示例#11
0
 private void RetryConnectTimer(object state)
 {
     // NOTE: Always handle all type of MFC exceptions in TimerProcs - otherwise we'll get mem leaks
     try
     {
         StopConnectionTry();
         if (IsConnected)
         {
             return;
         }
         if (startAutoConnectPos_ >= MuleApplication.Instance.ServerList.ServerCount)
         {
             startAutoConnectPos_ = 0;
         }
         ConnectToAnyServer(startAutoConnectPos_, true, true);
     }
     catch (Exception ex)
     {
         MpdUtilities.DebugLogError(ex);
     }
 }
示例#12
0
        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);
            }
        }
示例#13
0
        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);
            }
        }
示例#14
0
        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);
            }
        }
        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
            }
        }
示例#16
0
        public override int Receive(byte[] lpBuf, int offset, int nBufLen, SocketFlags nFlags)
        {
            obfuscationBytesReceived_ = base.Receive(lpBuf, offset, nBufLen, nFlags);

            fullReceive_ = obfuscationBytesReceived_ == (uint)nBufLen;

            if (obfuscationBytesReceived_ == SOCKET_ERROR || obfuscationBytesReceived_ <= 0)
            {
                return(obfuscationBytesReceived_);
            }
            switch (streamCryptState_)
            {
            case StreamCryptStateEnum.ECS_NONE:     // disabled, just pass it through
                return(obfuscationBytesReceived_);

            case StreamCryptStateEnum.ECS_PENDING:
            case StreamCryptStateEnum.ECS_PENDING_SERVER:
                Debug.Assert(false);
                MpdUtilities.DebugLogError(("CEncryptedStreamSocket Received data before sending on outgoing connection"));
                streamCryptState_ = StreamCryptStateEnum.ECS_NONE;
                return(obfuscationBytesReceived_);

            case StreamCryptStateEnum.ECS_UNKNOWN:
            {
                int  nRead         = 1;
                bool bNormalHeader = false;
                switch (lpBuf[offset])
                {
                case MuleConstants.PROTOCOL_EDONKEYPROT:
                case MuleConstants.PROTOCOL_PACKEDPROT:
                case MuleConstants.PROTOCOL_EMULEPROT:
                    bNormalHeader = true;
                    break;
                }
                if (!bNormalHeader)
                {
                    StartNegotiation(false);
                    int nNegRes = Negotiate(lpBuf, offset + nRead, obfuscationBytesReceived_ - nRead);
                    if (nNegRes == (-1))
                    {
                        return(0);
                    }
                    nRead += nNegRes;
                    if (nRead != obfuscationBytesReceived_)
                    {
                        // this means we have more data then the current negotiation step required (or there is a bug) and this should never happen
                        // (note: even if it just finished the handshake here, there still can be no data left, since the other client didnt received our response yet)
                        MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (1)"), DbgGetIPString());
                        OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION));
                    }
                    return(0);
                }
                else
                {
                    // doesn't seems to be encrypted
                    streamCryptState_ = StreamCryptStateEnum.ECS_NONE;

                    // if we require an encrypted connection, cut the connection here. This shouldn't happen that often
                    // at least with other up-to-date eMule clients because they check for incompability before connecting if possible
                    if (MuleApplication.Instance.Preference.IsClientCryptLayerRequired)
                    {
                        // TODO: Remove me when i have been solved
                        // Even if the Require option is enabled, we currently have to accept unencrypted connection which are made
                        // for lowid/firewall checks from servers and other from us selected client. Otherwise, this option would
                        // always result in a lowid/firewalled status. This is of course not nice, but we can't avoid this walkarround
                        // untill servers and kad completely support encryption too, which will at least for kad take a bit
                        // only exception is the .ini option ClientCryptLayerRequiredStrict which will even ignore test connections
                        // Update: New server now support encrypted callbacks

                        IPEndPoint remote  = RemoteEndPoint as IPEndPoint;
                        uint       address = BitConverter.ToUInt32(remote.Address.GetAddressBytes(), 0);

                        if (MuleApplication.Instance.Preference.IsClientCryptLayerRequiredStrict ||
                            (!MuleApplication.Instance.ServerConnect.AwaitingTestFromIP(address) &&
                             !MuleApplication.Instance.ClientList.IsKadFirewallCheckIP(address)))
                        {
                            MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_DEFAULT, false, ("Rejected incoming connection because Obfuscation was required but not used %s"), DbgGetIPString());
                            OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION_NOTALLOWED));
                            return(0);
                        }
                        else
                        {
                            MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_DEFAULT, false, ("Incoming unencrypted firewallcheck connection permitted despite RequireEncryption setting  - %s"), DbgGetIPString());
                        }
                    }

                    return(obfuscationBytesReceived_);        // buffer was unchanged, we can just pass it through
                }
            }

            case StreamCryptStateEnum.ECS_ENCRYPTING:
                // basic obfuscation enabled and set, so decrypt and pass along
                MuleUtilities.RC4Crypt(lpBuf, offset, lpBuf, offset, Convert.ToUInt32(obfuscationBytesReceived_), rc4ReceiveKey_);
                return(obfuscationBytesReceived_);

            case StreamCryptStateEnum.ECS_NEGOTIATING:
            {
                int nRead = Negotiate(lpBuf, offset, obfuscationBytesReceived_);
                if (nRead == (-1))
                {
                    return(0);
                }
                else if (nRead != obfuscationBytesReceived_ &&
                         streamCryptState_ != StreamCryptStateEnum.ECS_ENCRYPTING)
                {
                    // this means we have more data then the current negotiation step required (or there is a bug) and this should never happen
                    MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Client %s sent more data then expected while negotiating, disconnecting (2)"), DbgGetIPString());
                    OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION));
                    return(0);
                }
                else if (nRead != (uint)obfuscationBytesReceived_ && streamCryptState_ == StreamCryptStateEnum.ECS_ENCRYPTING)
                {
                    // we finished the handshake and if we this was an outgoing connection it is allowed (but strange and unlikely) that the client sent payload
                    MpdUtilities.DebugLogWarning(("CEncryptedStreamSocket: Client %s has finished the handshake but also sent payload on a outgoing connection"), DbgGetIPString());
                    Array.Copy(lpBuf, offset + nRead, lpBuf, offset + 0, obfuscationBytesReceived_ - nRead);
                    return(obfuscationBytesReceived_ - nRead);
                }
                else
                {
                    return(0);
                }
            }

            default:
                Debug.Assert(false);
                return(obfuscationBytesReceived_);
            }
        }
示例#17
0
        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();
            }
        }
示例#18
0
        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);
        }
示例#19
0
            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
            }
示例#20
0
        private int Negotiate(byte[] pBuffer, int offset, int nLen)
        {
            int nRead = 0;

            Debug.Assert(receiveBytesWanted_ > 0);
            try
            {
                while (negotiatingState_ != NegotiatingStateEnum.ONS_COMPLETE && receiveBytesWanted_ > 0)
                {
                    if (receiveBytesWanted_ > 512)
                    {
                        Debug.Assert(false);
                        return(0);
                    }

                    if (fiReceiveBuffer_ == null)
                    {
                        byte[] pReceiveBuffer = new byte[512]; // use a fixed size buffer
                        fiReceiveBuffer_ = MpdObjectManager.CreateSafeMemFile(pReceiveBuffer);
                    }
                    int nToRead = Math.Min(Convert.ToInt32(nLen) - nRead, Convert.ToInt32(receiveBytesWanted_));
                    fiReceiveBuffer_.Write(pBuffer, nRead, nToRead);
                    nRead += nToRead;
                    receiveBytesWanted_ -= Convert.ToUInt32(nToRead);
                    if (receiveBytesWanted_ > 0)
                    {
                        return(nRead);
                    }
                    uint nCurrentBytesLen = (uint)fiReceiveBuffer_.Position;

                    if (negotiatingState_ != NegotiatingStateEnum.ONS_BASIC_CLIENTA_RANDOMPART &&
                        negotiatingState_ != NegotiatingStateEnum.ONS_BASIC_SERVER_DHANSWER)
                    { // don't have the keys yet
                        byte[] pCryptBuffer = fiReceiveBuffer_.Buffer;
                        MuleUtilities.RC4Crypt(pCryptBuffer, pCryptBuffer, nCurrentBytesLen, rc4ReceiveKey_);
                    }
                    fiReceiveBuffer_.SeekToBegin();

                    switch (negotiatingState_)
                    {
                    case NegotiatingStateEnum.ONS_NONE:     // would be a bug
                        Debug.Assert(false);
                        return(0);

                    case NegotiatingStateEnum.ONS_BASIC_CLIENTA_RANDOMPART:
                    {
                        Debug.Assert(rc4ReceiveKey_ == null);

                        byte[] achKeyData = new byte[21];
                        MpdUtilities.Md4Cpy(achKeyData, MuleApplication.Instance.Preference.UserHash);
                        achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_REQUESTER);
                        fiReceiveBuffer_.Read(achKeyData, 17, 4);         // random key part sent from remote client

                        MD5 md5 = MD5.Create();
                        rc4ReceiveKey_ =
                            MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16);
                        achKeyData[16] = Convert.ToByte(MuleConstants.MAGICVALUE_SERVER);
                        rc4SendKey_    =
                            MuleUtilities.RC4CreateKey(md5.ComputeHash(achKeyData), 16);

                        negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_CLIENTA_MAGICVALUE;
                        receiveBytesWanted_ = 4;
                        break;
                    }

                    case NegotiatingStateEnum.ONS_BASIC_CLIENTA_MAGICVALUE:
                    {
                        uint dwValue = fiReceiveBuffer_.ReadUInt32();
                        if (dwValue == MuleConstants.MAGICVALUE_SYNC)
                        {
                            // yup, the one or the other way it worked, this is an encrypted stream
                            //DEBUG_ONLY( MpdUtilities.DebugLog(("Received proper magic value, clientIP: %s"), DbgGetIPString()) );
                            // set the receiver key
                            negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_CLIENTA_METHODTAGSPADLEN;
                            receiveBytesWanted_ = 3;
                        }
                        else
                        {
                            MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Received wrong magic value from clientIP %s on a supposly encrytped stream / Wrong Header"), DbgGetIPString());
                            OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION));
                            return(-1);
                        }
                        break;
                    }

                    case NegotiatingStateEnum.ONS_BASIC_CLIENTA_METHODTAGSPADLEN:
                        DbgByEncryptionSupported = fiReceiveBuffer_.ReadUInt8();
                        DbgByEncryptionRequested = fiReceiveBuffer_.ReadUInt8();
                        if (DbgByEncryptionRequested != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION))
                        {
                            MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Client %s preffered unsupported encryption method (%i)"), DbgGetIPString(), DbgByEncryptionRequested);
                        }
                        receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8();
                        negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING;
                        if (receiveBytesWanted_ > 0)
                        {
                            break;
                        }
                        else
                        {
                            goto case NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING;
                        }

                    case NegotiatingStateEnum.ONS_BASIC_CLIENTA_PADDING:
                    {
                        // ignore the random bytes, send the response, set status complete
                        SafeMemFile fileResponse = MpdObjectManager.CreateSafeMemFile(26);
                        fileResponse.WriteUInt32(MuleConstants.MAGICVALUE_SYNC);
                        byte bySelectedEncryptionMethod = Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION);         // we do not support any further encryption in this version, so no need to look which the other client preferred
                        fileResponse.WriteUInt8(bySelectedEncryptionMethod);

                        IPEndPoint remoteEp = RemoteEndPoint as IPEndPoint;

                        byte byPaddingLen =
                            MuleApplication.Instance.ServerConnect.AwaitingTestFromIP(BitConverter.ToUInt32(remoteEp.Address.GetAddressBytes(), 0))
                                        ? Convert.ToByte(16) :
                            Convert.ToByte(MuleApplication.Instance.Preference.CryptTCPPaddingLength + 1);
                        byte byPadding = Convert.ToByte(MpdUtilities.GetRandomUInt8() % byPaddingLen);

                        fileResponse.WriteUInt8(byPadding);
                        for (int i = 0; i < byPadding; i++)
                        {
                            fileResponse.WriteUInt8(MpdUtilities.GetRandomUInt8());
                        }
                        SendNegotiatingData(fileResponse.Buffer, (uint)fileResponse.Length);
                        negotiatingState_ = NegotiatingStateEnum.ONS_COMPLETE;
                        streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING;
                        //DEBUG_ONLY( MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (incoming)"), DbgGetIPString()) );
                        break;
                    }

                    case NegotiatingStateEnum.ONS_BASIC_CLIENTB_MAGICVALUE:
                    {
                        if (fiReceiveBuffer_.ReadUInt32() != MuleConstants.MAGICVALUE_SYNC)
                        {
                            MpdUtilities.DebugLogError(("CEncryptedStreamSocket: EncryptedstreamSyncError: Client sent wrong Magic Value as answer, cannot complete handshake (%s)"), DbgGetIPString());
                            OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION));
                            return(-1);
                        }
                        negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_CLIENTB_METHODTAGSPADLEN;
                        receiveBytesWanted_ = 2;
                        break;
                    }

                    case NegotiatingStateEnum.ONS_BASIC_CLIENTB_METHODTAGSPADLEN:
                    {
                        DbgByEncryptionMethodSet = fiReceiveBuffer_.ReadUInt8();
                        if (DbgByEncryptionMethodSet != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION))
                        {
                            MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Client %s set unsupported encryption method (%i), handshake failed"),
                                                       DbgGetIPString(), DbgByEncryptionMethodSet);
                            OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION));
                            return(-1);
                        }
                        receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8();
                        negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING;
                        if (receiveBytesWanted_ > 0)
                        {
                            break;
                        }
                        else
                        {
                            goto case NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING;
                        }
                    }

                    case NegotiatingStateEnum.ONS_BASIC_CLIENTB_PADDING:
                        // ignore the random bytes, the handshake is complete
                        negotiatingState_ = NegotiatingStateEnum.ONS_COMPLETE;
                        streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING;
                        //DEBUG_ONLY( MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished Obufscation handshake with client %s (outgoing)"), DbgGetIPString()) );
                        break;

                    case NegotiatingStateEnum.ONS_BASIC_SERVER_DHANSWER:
                    {
                        Debug.Assert(cryptDHA_ != new BigInteger(0));
                        byte[] aBuffer = new byte[MuleConstants.PRIMESIZE_BYTES + 1];
                        fiReceiveBuffer_.Read(aBuffer, 0, Convert.ToInt32(MuleConstants.PRIMESIZE_BYTES));
                        BigInteger cryptDHAnswer =
                            new BigInteger(aBuffer, (int)MuleConstants.PRIMESIZE_BYTES);
                        BigInteger cryptDHPrime =
                            new BigInteger(dh768_p_, (int)MuleConstants.PRIMESIZE_BYTES);          // our fixed prime
                        BigInteger cryptResult =
                            cryptDHAnswer.modPow(cryptDHA_, cryptDHPrime);

                        cryptDHA_ = 0;
                        Array.Clear(aBuffer, 0, aBuffer.Length);

                        // create the keys
                        Array.Copy(cryptResult.getBytes(), aBuffer, MuleConstants.PRIMESIZE_BYTES);
                        aBuffer[MuleConstants.PRIMESIZE_BYTES] = Convert.ToByte(MuleConstants.MAGICVALUE_REQUESTER);
                        MD5 md5 = MD5.Create();

                        rc4SendKey_ =
                            MuleUtilities.RC4CreateKey(md5.ComputeHash(aBuffer), 16);
                        aBuffer[MuleConstants.PRIMESIZE_BYTES] = Convert.ToByte(MuleConstants.MAGICVALUE_SERVER);
                        rc4ReceiveKey_ =
                            MuleUtilities.RC4CreateKey(md5.ComputeHash(aBuffer), 16);

                        negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_SERVER_MAGICVALUE;
                        receiveBytesWanted_ = 4;
                        break;
                    }

                    case NegotiatingStateEnum.ONS_BASIC_SERVER_MAGICVALUE:
                    {
                        uint dwValue = fiReceiveBuffer_.ReadUInt32();
                        if (dwValue == MuleConstants.MAGICVALUE_SYNC)
                        {
                            // yup, the one or the other way it worked, this is an encrypted stream
                            MpdUtilities.DebugLog(("Received proper magic value after DH-Agreement from Serverconnection IP: %s"), DbgGetIPString());
                            // set the receiver key
                            negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_SERVER_METHODTAGSPADLEN;
                            receiveBytesWanted_ = 3;
                        }
                        else
                        {
                            MpdUtilities.DebugLogError(("CEncryptedStreamSocket: Received wrong magic value after DH-Agreement from Serverconnection"), DbgGetIPString());
                            OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION));
                            return(-1);
                        }
                        break;
                    }

                    case NegotiatingStateEnum.ONS_BASIC_SERVER_METHODTAGSPADLEN:
                        DbgByEncryptionSupported = fiReceiveBuffer_.ReadUInt8();
                        DbgByEncryptionRequested = fiReceiveBuffer_.ReadUInt8();
                        if (DbgByEncryptionRequested != Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION))
                        {
                            MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Server %s preffered unsupported encryption method (%i)"), DbgGetIPString(), DbgByEncryptionRequested);
                        }
                        receiveBytesWanted_ = fiReceiveBuffer_.ReadUInt8();
                        negotiatingState_   = NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING;
                        if (receiveBytesWanted_ > 16)
                        {
                            MpdUtilities.AddDebugLogLine(EDebugLogPriority.DLP_LOW, false, ("CEncryptedStreamSocket: Server %s sent more than 16 (%i) padding bytes"), DbgGetIPString(), receiveBytesWanted_);
                        }
                        if (receiveBytesWanted_ > 0)
                        {
                            break;
                        }
                        else
                        {
                            goto case NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING;
                        }

                    case NegotiatingStateEnum.ONS_BASIC_SERVER_PADDING:
                    {
                        // ignore the random bytes (they are decrypted already), send the response, set status complete
                        SafeMemFile fileResponse = MpdObjectManager.CreateSafeMemFile(26);
                        fileResponse.WriteUInt32(MuleConstants.MAGICVALUE_SYNC);
                        byte bySelectedEncryptionMethod =
                            Convert.ToByte(EncryptionMethodsEnum.ENM_OBFUSCATION);         // we do not support any further encryption in this version, so no need to look which the other client preferred
                        fileResponse.WriteUInt8(bySelectedEncryptionMethod);
                        byte byPadding = (byte)(MpdUtilities.GetRandomUInt8() % 16);
                        fileResponse.WriteUInt8(byPadding);
                        for (int i = 0; i < byPadding; i++)
                        {
                            fileResponse.WriteUInt8(MpdUtilities.GetRandomUInt8());
                        }

                        negotiatingState_ = NegotiatingStateEnum.ONS_BASIC_SERVER_DELAYEDSENDING;
                        SendNegotiatingData(fileResponse.Buffer, (uint)fileResponse.Length, 0, true);         // don't actually send it right now, store it in our sendbuffer
                        streamCryptState_ = StreamCryptStateEnum.ECS_ENCRYPTING;
                        MpdUtilities.DebugLog(("CEncryptedStreamSocket: Finished DH Obufscation handshake with Server %s"), DbgGetIPString());
                        break;
                    }

                    default:
                        Debug.Assert(false);
                        break;
                    }
                    fiReceiveBuffer_.SeekToBegin();
                }

                fiReceiveBuffer_ = null;
                return(nRead);
            }
            catch (Exception)
            {
                Debug.Assert(false);
                OnError(Convert.ToInt32(EMSocketErrorCodeEnum.ERR_ENCRYPTION));
                fiReceiveBuffer_ = null;
                return(-1);
            }
        }
示例#21
0
        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());
            }
        }
示例#22
0
        protected override void OnReceive(int nErrorCode)
        {
            byte[]   buffer   = new byte[5000];
            EndPoint endPoint = null;

            int        nRealLen   = ReceiveFrom(buffer, ref endPoint);
            IPEndPoint ipEndPoint = endPoint as IPEndPoint;

            uint dwIP = 0;

            if (ipEndPoint != null)
            {
                dwIP = BitConverter.ToUInt32(ipEndPoint.Address.GetAddressBytes(), 0);
            }
            if (ipEndPoint != null &&
                !(MuleApplication.Instance.IPFilter.IsFiltered(dwIP) ||
                  MuleApplication.Instance.ClientList.IsBannedClient(dwIP)))
            {
                byte[] pBuffer;
                uint   nReceiverVerifyKey;
                uint   nSenderVerifyKey;

                int nPacketLen = DecryptReceivedClient(buffer, nRealLen,
                                                       out pBuffer, dwIP,
                                                       out nReceiverVerifyKey, out nSenderVerifyKey);

                if (nPacketLen >= 1)
                {
                    try
                    {
                        switch (pBuffer[0])
                        {
                        case MuleConstants.PROTOCOL_EMULEPROT:
                        {
                            if (nPacketLen >= 2)
                            {
                                ProcessPacket(pBuffer, 2, (uint)nPacketLen - 2,
                                              pBuffer[1], dwIP,
                                              (ushort)IPAddress.NetworkToHostOrder(ipEndPoint.Port));
                            }
                            else
                            {
                                throw new MuleException("eMule packet too short");
                            }
                            break;
                        }

                        case MuleConstants.PROTOCOL_KADEMLIAPACKEDPROT:
                        {
                            MuleApplication.Instance.Statistics.AddDownDataOverheadKad((uint)nPacketLen);
                            if (nPacketLen >= 2)
                            {
                                byte[] unpack    = null;
                                byte[] unpackTmp = null;

                                if (MpdUtilities.Decompress(pBuffer, 2, (uint)nPacketLen - 2, out unpackTmp))
                                {
                                    unpack = new byte[unpackTmp.Length + 2];
                                    Array.Copy(unpackTmp, 0, unpack, 2, unpackTmp.Length);

                                    unpack[0] = MuleConstants.PROTOCOL_KADEMLIAHEADER;
                                    unpack[1] = pBuffer[1];
                                    try
                                    {
                                        MuleApplication.Instance.KadEngine.ProcessPacket(unpack,
                                                                                         (uint)unpack.Length,
                                                                                         dwIP, (ushort)IPAddress.NetworkToHostOrder(ipEndPoint.Port),
                                                                                         MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP) == nReceiverVerifyKey,
                                                                                         MuleApplication.Instance.KadObjectManager.CreateKadUDPKey(nSenderVerifyKey,
                                                                                                                                                   (uint)MuleApplication.Instance.GetPublicIP(false)));
                                    }
                                    catch
                                    {
                                        throw;
                                    }
                                }
                                else
                                {
                                    throw new MuleException("Failed to uncompress Kad packet!");
                                }
                            }
                            else
                            {
                                throw new MuleException("Kad packet (compressed) too short");
                            }
                            break;
                        }

                        case MuleConstants.PROTOCOL_KADEMLIAHEADER:
                        {
                            MuleApplication.Instance.Statistics.AddDownDataOverheadKad((uint)nPacketLen);
                            if (nPacketLen >= 2)
                            {
                                MuleApplication.Instance.KadEngine.ProcessPacket(pBuffer, (uint)nPacketLen,
                                                                                 dwIP, (ushort)ipEndPoint.Port,
                                                                                 MuleApplication.Instance.KadEngine.Preference.GetUDPVerifyKey(dwIP) == nReceiverVerifyKey,
                                                                                 MuleApplication.Instance.KadObjectManager.CreateKadUDPKey(nSenderVerifyKey,
                                                                                                                                           (uint)MuleApplication.Instance.GetPublicIP(false)));
                            }
                            else
                            {
                                throw new MuleException("Kad packet too short");
                            }
                            break;
                        }

                        default:
                        {
                            throw new MuleException(string.Format("Unknown protocol 0x{0}", pBuffer[0]));
                        }
                        }
                    }
                    catch (Exception error)
                    {
                        MpdUtilities.DebugLogError(error);
                    }
                }
            }
        }