Exemple #1
0
        internal static void EndCheckEncryption(IAsyncResult result, out byte[] initialData)
        {
            EncryptorAsyncResult r = (EncryptorAsyncResult)result;

            if (r == null)
            {
                throw new ArgumentException("Invalid async result");
            }

            if (!r.IsCompleted)
            {
                r.AsyncWaitHandle.WaitOne();
            }

            r.AsyncWaitHandle.Close();

            if (r.SavedException != null)
            {
                throw r.SavedException;
            }

            r.Id.Encryptor = r.Encryptor;
            r.Id.Decryptor = r.Decryptor;
            initialData    = r.InitialData;
        }
        private static void CompletedEncryptedHandshake(IAsyncResult result)
        {
            EncryptorAsyncResult r = (EncryptorAsyncResult)result.AsyncState;

            try
            {
                r.EncSocket.EndHandshake(result);

                r.Decryptor   = r.EncSocket.Decryptor;
                r.Encryptor   = r.EncSocket.Encryptor;
                r.InitialData = r.EncSocket.InitialData;
            }
            catch (Exception ex)
            {
                r.SavedException = ex;
            }

            r.Complete();

#if NETSTANDARD1_5
            result.AsyncWaitHandle.Dispose();
            r.AsyncWaitHandle.Dispose();
#else
            result.AsyncWaitHandle.Close();
            r.AsyncWaitHandle.Close();
#endif
        }
        internal static IAsyncResult BeginCheckEncryption(PeerId id, int bytesToReceive, AsyncCallback callback,
            object state, InfoHash[] sKeys)
        {
            var result = new EncryptorAsyncResult(id, callback, state) {SKeys = sKeys};

            var c = id.Connection;
            ClientEngine.MainLoop.QueueTimeout(TimeSpan.FromSeconds(10), delegate
            {
                if (id.Encryptor == null || id.Decryptor == null)
                    id.CloseConnection();
                return false;
            });

            try
            {
                // If the connection is incoming, receive the handshake before
                // trying to decide what encryption to use
                if (id.Connection.IsIncoming)
                {
                    result.Buffer = new byte[bytesToReceive];
                    NetworkIO.EnqueueReceive(c, result.Buffer, 0, result.Buffer.Length, null, null, null,
                        HandshakeReceivedCallback, result);
                }
                else
                {
                    var usable = CheckRc4(id);
                    var hasPlainText = Toolbox.HasEncryption(usable, EncryptionTypes.PlainText);
                    var hasRc4 = Toolbox.HasEncryption(usable, EncryptionTypes.RC4Full) ||
                                 Toolbox.HasEncryption(usable, EncryptionTypes.RC4Header);
                    if (id.Engine.Settings.PreferEncryption)
                    {
                        if (hasRc4)
                        {
                            result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable);
                            result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
                        }
                        result.Complete();
                    }
                    else
                    {
                        if (hasPlainText)
                        {
                            result.Complete();
                        }
                        else
                        {
                            result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable);
                            result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.Complete(ex);
            }
            return result;
        }
        internal static IAsyncResult BeginCheckEncryption(PeerId id, AsyncCallback callback, object state, byte[][] sKeys)
        {
            EncryptorAsyncResult result = new EncryptorAsyncResult(id, callback, state);
            result.SKeys = sKeys;

            IConnection c = id.Connection;
            try
            {
                // If the connection is incoming, receive the handshake before
                // trying to decide what encryption to use
                if (id.Connection.IsIncoming)
                {
                    result.Buffer = new byte[id.BytesToRecieve];
                    NetworkIO.EnqueueReceive(c, result.Buffer, 0, result.Buffer.Length, HandshakeReceivedCallback, result);
                }
                else
                {
                    EncryptionTypes usable = CheckRC4(id);
                    bool hasPlainText = Toolbox.HasEncryption(usable, EncryptionTypes.PlainText);
                    bool hasRC4 = Toolbox.HasEncryption(usable, EncryptionTypes.RC4Full) || Toolbox.HasEncryption(usable, EncryptionTypes.RC4Header);
                    if (id.Engine.Settings.PreferEncryption)
                    {
                        if (hasRC4)
                        {
                            result.EncSocket = new PeerAEncryption(id.TorrentManager.Torrent.infoHash, usable);
                            result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
                        }
                        else
                        {
                            result.Complete();
                        }
                    }
                    else
                    {
                        if (hasPlainText)
                        {
                            result.Complete();
                        }
                        else
                        {
                            result.EncSocket = new PeerAEncryption(id.TorrentManager.Torrent.infoHash, usable);
                            result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.Complete(ex);
            }
            return result;
        }
Exemple #5
0
        private static void HandshakeReceived(bool succeeded, int count, object state)
        {
            EncryptorAsyncResult result     = (EncryptorAsyncResult)state;
            IConnection          connection = result.Id.Connection;

            try
            {
                if (!succeeded)
                {
                    throw new EncryptionException("Couldn't receive the handshake");
                }

                result.Available += count;
                HandshakeMessage message = new HandshakeMessage();
                message.Decode(result.Buffer, 0, result.Buffer.Length);
                bool            valid  = message.ProtocolString == VersionInfo.ProtocolStringV100;
                EncryptionTypes usable = CheckRC4(result.Id);

                bool canUseRC4 = Toolbox.HasEncryption(usable, EncryptionTypes.RC4Header) || Toolbox.HasEncryption(usable, EncryptionTypes.RC4Full);
                // If encryption is disabled and we received an invalid handshake - abort!
                if (valid)
                {
                    result.InitialData = result.Buffer;
                    result.Complete();
                    return;
                }
                if (!canUseRC4 && !valid)
                {
                    result.Complete(new EncryptionException("Invalid handshake received and no decryption works"));
                    return;
                }
                if (canUseRC4)
                {
                    // The data we just received was part of an encrypted handshake and was *not* the BitTorrent handshake
                    result.EncSocket = new PeerBEncryption(result.SKeys, EncryptionTypes.All);
                    result.EncSocket.BeginHandshake(connection, result.Buffer, 0, result.Buffer.Length, CompletedEncryptedHandshakeCallback, result);
                }
                else
                {
                    result.Complete();
                }
            }
            catch (Exception ex)
            {
                result.Complete(ex);
                return;
            }
        }
Exemple #6
0
        internal static IAsyncResult BeginCheckEncryption(PeerId id, int bytesToReceive, AsyncCallback callback, object state, InfoHash[] sKeys)
        {
            EncryptorAsyncResult result = new EncryptorAsyncResult(id, callback, state);

            result.SKeys = sKeys;

            IConnection c = id.Connection;

            ClientEngine.MainLoop.QueueTimeout(TimeSpan.FromSeconds(10), delegate {
                if (id.Encryptor == null || id.Decryptor == null)
                {
                    id.CloseConnection();
                }
                return(false);
            });

            try
            {
                // If the connection is incoming, receive the handshake before
                // trying to decide what encryption to use
                if (id.Connection.IsIncoming)
                {
                    result.Buffer = new byte[bytesToReceive];
                    NetworkIO.EnqueueReceive(c, result.Buffer, 0, result.Buffer.Length, null, null, null, HandshakeReceivedCallback, result);
                }
                else
                {
                    EncryptionTypes usable       = CheckRC4(id);
                    bool            hasPlainText = Toolbox.HasEncryption(usable, EncryptionTypes.PlainText);
                    bool            hasRC4       = Toolbox.HasEncryption(usable, EncryptionTypes.RC4Full) || Toolbox.HasEncryption(usable, EncryptionTypes.RC4Header);
                    if (id.Engine.Settings.PreferEncryption)
                    {
                        if (hasRC4)
                        {
                            result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable);
                            result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
                        }
                        else
                        {
                            result.Complete();
                        }
                    }
                    else
                    {
                        if (hasPlainText)
                        {
                            result.Complete();
                        }
                        else
                        {
                            result.EncSocket = new PeerAEncryption(id.TorrentManager.InfoHash, usable);
                            result.EncSocket.BeginHandshake(id.Connection, CompletedEncryptedHandshakeCallback, result);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result.Complete(ex);
            }
            return(result);
        }