Esempio n. 1
0
        public async Task <byte[]> GetHashAsync(TorrentManager manager, int pieceIndex)
        {
            await IOLoop;

            // We want to be sure we've actually written everything so when we go to hash the
            // piece it will be returned to us in our Read call. If the write were still pending
            // we could accidentally end up reporting the piece was corrupt.
            await WaitForBufferedWrites();

            long startOffset = (long)manager.Torrent.PieceLength * pieceIndex;
            long endOffset   = Math.Min(startOffset + manager.Torrent.PieceLength, manager.Torrent.Size);

            byte[] hashBuffer = BufferManager.EmptyBuffer;
            ClientEngine.BufferManager.GetBuffer(ref hashBuffer, Piece.BlockSize);

            SHA1 hasher = HashAlgoFactory.Create <SHA1>();

            hasher.Initialize();

            while (startOffset != endOffset)
            {
                int count = (int)Math.Min(Piece.BlockSize, endOffset - startOffset);
                if (!await ReadAsync(manager, startOffset, hashBuffer, count).ConfigureAwait(false))
                {
                    ClientEngine.BufferManager.FreeBuffer(ref hashBuffer);
                    return(null);
                }
                startOffset += count;
                hasher.TransformBlock(hashBuffer, 0, count, hashBuffer, 0);
            }

            hasher.TransformFinalBlock(hashBuffer, 0, 0);
            ClientEngine.BufferManager.FreeBuffer(ref hashBuffer);
            return(hasher.Hash);
        }
        public EncryptedSocket(EncryptionTypes allowedEncryption)
        {
#if NETSTANDARD1_5
            random = RandomNumberGenerator.Create();
            hasher = SHA1.Create();
#else
            random = RNGCryptoServiceProvider.Create();
            hasher = HashAlgoFactory.Create <SHA1>();
#endif

            GenerateX();
            GenerateY();

            InitialPayload       = BufferManager.EmptyBuffer;
            RemoteInitialPayload = BufferManager.EmptyBuffer;

            doneSendCallback             = doneSend;
            doneReceiveCallback          = doneReceive;
            doneReceiveYCallback         = delegate { doneReceiveY(); };
            doneSynchronizeCallback      = delegate { doneSynchronize(); };
            fillSynchronizeBytesCallback = fillSynchronizeBytes;

            bytesReceived = 0;

            SetMinCryptoAllowed(allowedEncryption);
        }
Esempio n. 3
0
        internal void BeginGetHash(TorrentManager manager, int pieceIndex, MainLoopResult callback)
        {
            int  count     = 0;
            long offset    = (long)manager.Torrent.PieceLength * pieceIndex;
            long endOffset = Math.Min(offset + manager.Torrent.PieceLength, manager.Torrent.Size);

            byte[] hashBuffer = BufferManager.EmptyBuffer;
            ClientEngine.BufferManager.GetBuffer(ref hashBuffer, Piece.BlockSize);

#if NETSTANDARD1_5
            SHA1 hasher = SHA1.Create();
#else
            SHA1 hasher = HashAlgoFactory.Create <SHA1>();
#endif
            hasher.Initialize();

            DiskIOCallback readCallback = null;
            readCallback = delegate(bool successful) {
                if (successful)
                {
#if NETSTANDARD1_5
                    var h = hasher.ComputeHash(hashBuffer, 0, count);
                    h.CopyTo(hashBuffer, 0);
#else
                    hasher.TransformBlock(hashBuffer, 0, count, hashBuffer, 0);
#endif
                }
                offset += count;

                if (!successful || offset == endOffset)
                {
                    object hash = null;
                    if (successful)
                    {
#if NETSTANDARD1_5
                        hash = hasher.ComputeHash(hashBuffer, 0, 0);
#else
                        hasher.TransformFinalBlock(hashBuffer, 0, 0);
                        hash = hasher.Hash;
#endif
                    }
                    ((IDisposable)hasher).Dispose();
                    ClientEngine.BufferManager.FreeBuffer(ref hashBuffer);
                    ClientEngine.MainLoop.Queue(delegate {
                        callback(hash);
                    });
                }
                else
                {
                    count = (int)Math.Min(Piece.BlockSize, endOffset - offset);
                    QueueRead(manager, offset, hashBuffer, count, readCallback);
                }
            };

            count = (int)Math.Min(Piece.BlockSize, endOffset - offset);
            QueueRead(manager, offset, hashBuffer, count, readCallback);
        }
Esempio n. 4
0
 public TokenManager()
 {
     sha1           = HashAlgoFactory.Create <SHA1>();
     random         = new RNGCryptoServiceProvider();
     currentSecret  = new byte[10];
     previousSecret = new byte[10];
     random.GetNonZeroBytes(currentSecret);
     random.GetNonZeroBytes(previousSecret);
 }
Esempio n. 5
0
 public TokenManager()
 {
     sha1   = HashAlgoFactory.Create <SHA1>();
     random = new RNGCryptoServiceProvider();
     LastSecretGeneration = DateTime.MinValue; //in order to force the update
     secret         = new byte[10];
     previousSecret = new byte[10];
     random.GetNonZeroBytes(secret);
     random.GetNonZeroBytes(previousSecret);
 }
Esempio n. 6
0
        protected EncryptedSocket(EncryptionTypes allowedEncryption)
        {
            random = RandomNumberGenerator.Create();
            hasher = HashAlgoFactory.Create <SHA1> ();

            X = new byte[20];
            random.GetBytes(X);
            Y = ModuloCalculator.Calculate(ModuloCalculator.TWO, X);

            SetMinCryptoAllowed(allowedEncryption);
        }
Esempio n. 7
0
        private string HashFilePiece(string path, ulong start, ulong length)
        {
            var        sha1       = HashAlgoFactory.Create <SHA1>();
            FileStream fileStream =
                File.OpenRead(path);
            var buffer = new byte[length];

            fileStream.Position = (long)start;
            fileStream.Read(buffer, 0, buffer.Length);
            byte[] hash = sha1.ComputeHash(buffer);
            fileStream.Close();
            return(Convert.ToBase64String(hash));
        }
Esempio n. 8
0
        internal Torrent GetTorrent()
        {
            byte[] calculatedInfoHash;
            using (SHA1 sha = HashAlgoFactory.Create<SHA1>())
                calculatedInfoHash = sha.ComputeHash(stream.ToArray());
            if (!Manager.InfoHash.Equals (calculatedInfoHash))
                throw new Exception("invalid metadata");//restart ?

            BEncodedValue d = BEncodedValue.Decode(stream);
            BEncodedDictionary dict = new BEncodedDictionary();
            dict.Add("info", d);

            return Torrent.LoadCore(dict);
        }
Esempio n. 9
0
        public EncryptedSocket(EncryptionTypes allowedEncryption)
        {
            random = RNGCryptoServiceProvider.Create();
            hasher = HashAlgoFactory.Create <SHA1>();

            GenerateX();
            GenerateY();

            InitialPayload       = BufferManager.EmptyBuffer;
            RemoteInitialPayload = BufferManager.EmptyBuffer;

            bytesReceived = 0;

            SetMinCryptoAllowed(allowedEncryption);
        }
Esempio n. 10
0
        internal Torrent GetTorrent()
        {
            byte[] calculatedInfoHash;
            using (var sha = HashAlgoFactory.Create <SHA1>())
                calculatedInfoHash = sha.ComputeHash(Stream.ToArray());
            if (!Manager.InfoHash.Equals(calculatedInfoHash))
            {
                throw new Exception("invalid metadata"); //restart ?
            }
            var d    = BEncodedValue.Decode(Stream);
            var dict = new BEncodedDictionary {
                { "info", d }
            };

            return(Torrent.LoadCore(dict));
        }
Esempio n. 11
0
        internal void BeginGetHash(TorrentManager manager, int pieceIndex, MainLoopResult callback)
        {
            var count     = 0;
            var offset    = (long)manager.Torrent.PieceLength * pieceIndex;
            var endOffset = Math.Min(offset + manager.Torrent.PieceLength, manager.Torrent.Size);

            var hashBuffer = BufferManager.EmptyBuffer;

            ClientEngine.BufferManager.GetBuffer(ref hashBuffer, Piece.BlockSize);

            var hasher = HashAlgoFactory.Create <SHA1>();

            hasher.Initialize();

            DiskIOCallback readCallback = null;

            readCallback = successful =>
            {
                if (successful)
                {
                    hasher.TransformBlock(hashBuffer, 0, count, hashBuffer, 0);
                }
                offset += count;

                if (!successful || offset == endOffset)
                {
                    object hash = null;
                    if (successful)
                    {
                        hasher.TransformFinalBlock(hashBuffer, 0, 0);
                        hash = hasher.Hash;
                    }
                    ((IDisposable)hasher).Dispose();
                    ClientEngine.BufferManager.FreeBuffer(ref hashBuffer);
                    ClientEngine.MainLoop.Queue(() => callback(hash));
                }
                else
                {
                    count = (int)Math.Min(Piece.BlockSize, endOffset - offset);
                    QueueRead(manager, offset, hashBuffer, count, readCallback);
                }
            };

            count = (int)Math.Min(Piece.BlockSize, endOffset - offset);
            QueueRead(manager, offset, hashBuffer, count, readCallback);
        }
        internal System.Net.BitTorrent.Common.Torrent GetTorrent()
        {
            byte[] calculatedInfoHash;
#if NETSTANDARD1_5
            using (SHA1 sha = SHA1.Create())
#else
            using (SHA1 sha = HashAlgoFactory.Create <SHA1>())
#endif
                calculatedInfoHash = sha.ComputeHash(stream.ToArray());
            if (!Manager.InfoHash.Equals(calculatedInfoHash))
            {
                throw new Exception("invalid metadata");//restart ?
            }
            BEncodedValue      d    = BEncodedValue.Decode(stream);
            BEncodedDictionary dict = new BEncodedDictionary();
            dict.Add("info", d);

            return(System.Net.BitTorrent.Common.Torrent.LoadCore(dict));
        }
Esempio n. 13
0
        private void Run(int index, string pattern)
        {
            if (this._result == 1)
            {
                return;
            }
            if (index < this._fileLinkPieces.Count)
            {
                for (int i = 0; i < this._cleanedFileInfos[index].Count; i++)
                {
                    string nextPattern = pattern + i + ',';
                    int    nextIndex   = index + 1;
                    Run(nextIndex, nextPattern);
                }
            }
            else
            {
                using (var pieceStream = new MemoryStream(this._torrent.PieceLength))
                {
                    for (int i = 0; i < this._fileLinkPieces.Count; i++)
                    {
                        int fileIndex = int.Parse(pattern.Split(',')[i]);
                        using (FileStream fileStream =
                                   File.OpenRead(this._cleanedFileInfos[i][fileIndex].FilePath))
                        {
                            var buffer = new byte[this._fileLinkPieces[i].ReadLength];
                            fileStream.Position = (long)this._fileLinkPieces[i].StartPos;
                            fileStream.Read(buffer, 0, buffer.Length);
                            pieceStream.Write(buffer, 0, buffer.Length);
                        }
                    }

                    var    sha1 = HashAlgoFactory.Create <SHA1>();
                    byte[] hash = sha1.ComputeHash(pieceStream.ToArray());
                    if (this._torrent.Pieces.IsValid(hash, this._pieceIndex))
                    {
                        this._validPattern = pattern;
                        this._result       = 1;
                    }
                }
            }
        }
        public TokenManager()
        {
#if NETSTANDARD1_5
            sha1   = SHA1.Create();
            random = RandomNumberGenerator.Create();
            LastSecretGeneration = DateTime.MinValue; //in order to force the update
            secret         = new byte[10];
            previousSecret = new byte[10];
            random.GetBytes(secret);
            random.GetBytes(previousSecret);
#else
            sha1   = HashAlgoFactory.Create <SHA1>();
            random = new RNGCryptoServiceProvider();
            LastSecretGeneration = DateTime.MinValue; //in order to force the update
            secret         = new byte[10];
            previousSecret = new byte[10];
            random.GetNonZeroBytes(secret);
            random.GetNonZeroBytes(previousSecret);
#endif
        }
Esempio n. 15
0
        public EncryptedSocket(EncryptionTypes allowedEncryption)
        {
            _random = RandomNumberGenerator.Create();
            _hasher = HashAlgoFactory.Create <SHA1>();

            GenerateX();
            GenerateY();

            InitialPayload       = BufferManager.EmptyBuffer;
            RemoteInitialPayload = BufferManager.EmptyBuffer;

            _doneSendCallback             = DoneSend;
            _doneReceiveCallback          = DoneReceive;
            _doneReceiveYCallback         = delegate { doneReceiveY(); };
            _doneSynchronizeCallback      = delegate { DoneSynchronize(); };
            _fillSynchronizeBytesCallback = fillSynchronizeBytes;

            _bytesReceived = 0;

            SetMinCryptoAllowed(allowedEncryption);
        }
Esempio n. 16
0
        protected override void HandleLtMetadataMessage(PeerId id, LTMetadata message)
        {
            base.HandleLtMetadataMessage(id, message);

            switch (message.MetadataMessageType)
            {
            case LTMetadata.eMessageType.Data:
                if (stream == null)
                {
                    throw new Exception("Need extention handshake before ut_metadata message.");
                }

                stream.Seek(message.Piece * LTMetadata.BlockSize, SeekOrigin.Begin);
                stream.Write(message.MetadataPiece, 0, message.MetadataPiece.Length);
                bitField[message.Piece] = true;
                if (bitField.AllTrue)
                {
                    byte[] hash;
                    stream.Position = 0;
                    using (SHA1 hasher = HashAlgoFactory.Create <SHA1>())
                        hash = hasher.ComputeHash(stream);

                    if (!Manager.InfoHash.Equals(hash))
                    {
                        bitField.SetAll(false);
                    }
                    else
                    {
                        Torrent t;
                        stream.Position = 0;
                        BEncodedDictionary dict = new BEncodedDictionary();
                        dict.Add("info", BEncodedValue.Decode(stream));
                        // FIXME: Add the trackers too
                        if (Torrent.TryLoad(dict.Encode(), out t))
                        {
                            try
                            {
                                if (Directory.Exists(savePath))
                                {
                                    savePath = Path.Combine(savePath, Manager.InfoHash.ToHex() + ".torrent");
                                }
                                File.Delete(savePath);
                                File.WriteAllBytes(savePath, dict.Encode());
                            }
                            catch (Exception ex)
                            {
                                Logger.Log(null, "*METADATA EXCEPTION* - Can not write in {0} : {1}", savePath, ex);
                                Manager.Error = new Error(Reason.WriteFailure, ex);
                                Manager.Mode  = new ErrorMode(Manager);
                                return;
                            }
                            t.TorrentPath   = savePath;
                            Manager.Torrent = t;
                            SwitchToRegular();
                        }
                        else
                        {
                            bitField.SetAll(false);
                        }
                    }
                }
                //Double test because we can change the bitfield in the other block
                if (!bitField.AllTrue)
                {
                    RequestNextNeededPiece(id);
                }
                break;

            case LTMetadata.eMessageType.Reject:
                //TODO
                //Think to what we do in this situation
                //for moment nothing ;)
                //reject or flood?
                break;

            case LTMetadata.eMessageType.Request:    //ever done in base class but needed to avoid default
                break;

            default:
                throw new MessageException(string.Format("Invalid messagetype in LTMetadata: {0}", message.MetadataMessageType));
            }
        }
Esempio n. 17
0
 public IncrementalHashData()
 {
     Hasher = HashAlgoFactory.Create <SHA1> ();
     Initialise();
 }
        private byte[] CalcPiecesHash(byte[][] files, int pieceSize)
        {
            byte[]      buffer        = new byte[pieceSize];
            int         bufferRead    = 0;
            long        fileRead      = 0;
            long        overallRead   = 0;
            long        overallTotal  = files.LongLength;
            MD5         md5Hasher     = HashAlgoFactory.Create <MD5>();
            SHA1        shaHasher     = HashAlgoFactory.Create <SHA1>();
            List <byte> torrentHashes = new List <byte>();

            try
            {
                foreach (byte[] file in files)
                {
                    fileRead = 0;
                    if (md5Hasher != null)
                    {
                        md5Hasher.Initialize();
                    }

                    while (fileRead < file.Length)
                    {
                        int toRead = (int)Math.Min(buffer.Length - bufferRead, file.Length - fileRead);
                        int read   = Read(file, fileRead, buffer, bufferRead, toRead);

                        if (md5Hasher != null)
                        {
                            md5Hasher.TransformBlock(buffer, bufferRead, read, buffer, bufferRead);
                        }
                        shaHasher.TransformBlock(buffer, bufferRead, read, buffer, bufferRead);

                        bufferRead  += read;
                        fileRead    += read;
                        overallRead += read;

                        if (bufferRead == buffer.Length)
                        {
                            bufferRead = 0;
                            shaHasher.TransformFinalBlock(buffer, 0, 0);
                            torrentHashes.AddRange(shaHasher.Hash);
                            shaHasher.Initialize();
                        }
                    }
                    if (md5Hasher != null)
                    {
                        md5Hasher.TransformFinalBlock(buffer, 0, 0);
                        md5Hasher.Initialize();
                        //file.MD5 = md5Hasher.Hash;
                    }
                }
                if (bufferRead > 0)
                {
                    shaHasher.TransformFinalBlock(buffer, 0, 0);
                    torrentHashes.AddRange(shaHasher.Hash);
                }
            }
            finally
            {
                if (shaHasher != null)
                {
                    shaHasher.Clear();
                }
                if (md5Hasher != null)
                {
                    md5Hasher.Clear();
                }
            }
            return(torrentHashes.ToArray());
        }
Esempio n. 19
0
        protected override void HandleLtMetadataMessage(PeerId id, LTMetadata message)
        {
            base.HandleLtMetadataMessage(id, message);

            switch (message.MetadataMessageType)
            {
            case LTMetadata.eMessageType.Data:
                if (Stream == null)
                {
                    throw new Exception("Need extention handshake before ut_metadata message.");
                }

                Stream.Seek(message.Piece * LTMetadata.BlockSize, SeekOrigin.Begin);
                Stream.Write(message.MetadataPiece, 0, message.MetadataPiece.Length);
                bitField[message.Piece] = true;
                if (bitField.AllTrue)
                {
                    byte[] hash;
                    Stream.Position = 0;
                    using (SHA1 hasher = HashAlgoFactory.Create <SHA1> ())
                        hash = hasher.ComputeHash(Stream);

                    if (!Manager.InfoHash.Equals(hash))
                    {
                        bitField.SetAll(false);
                    }
                    else
                    {
                        Stream.Position = 0;
                        BEncodedDictionary dict = new BEncodedDictionary();
                        dict.Add("info", BEncodedValue.Decode(Stream));

                        if (Manager.TrackerManager.Tiers != null && Manager.TrackerManager.Tiers.Count > 0)
                        {
                            BEncodedList announceTrackers = new BEncodedList();
                            foreach (var tier in Manager.TrackerManager.Tiers)
                            {
                                BEncodedList announceUrls = new BEncodedList();

                                foreach (var tracker in tier.Trackers)
                                {
                                    announceUrls.Add(new BEncodedString(tracker.Uri.OriginalString));
                                }

                                announceTrackers.Add(announceUrls);
                            }

                            dict.Add("announce-list", announceTrackers);
                        }
                        if (Torrent.TryLoad(dict.Encode(), out Torrent t))
                        {
                            Manager.RaiseMetadataReceived(t, dict);
                            if (stopWhenDone)
                            {
                                return;
                            }

                            try {
                                if (Directory.Exists(savePath))
                                {
                                    savePath = Path.Combine(savePath, $"{Manager.InfoHash.ToHex ()}.torrent");
                                }
                                File.Delete(savePath);
                                File.WriteAllBytes(savePath, dict.Encode());
                            } catch (Exception ex) {
                                Logger.Log(null, "*METADATA EXCEPTION* - Can not write in {0} : {1}", savePath, ex);
                                Manager.TrySetError(Reason.WriteFailure, ex);
                                return;
                            }
                            t.TorrentPath   = savePath;
                            Manager.Torrent = t;
                            SwitchToRegular();
                        }
                        else
                        {
                            bitField.SetAll(false);
                        }
                    }
                }
                //Double test because we can change the bitfield in the other block
                if (!bitField.AllTrue)
                {
                    RequestNextNeededPiece(id);
                }
                break;

            case LTMetadata.eMessageType.Reject:
                //TODO
                //Think to what we do in this situation
                //for moment nothing ;)
                //reject or flood?
                break;

            case LTMetadata.eMessageType.Request:    //ever done in base class but needed to avoid default
                break;

            default:
                throw new MessageException($"Invalid messagetype in LTMetadata: {message.MetadataMessageType}");
            }
        }