public void AddSubscription(Pubkey pubkey) { if (pubkey.SubscriptionIndex == 0) { pubkey.SubscriptionIndex = 1; pubkey.SaveAsync(DB); lock (_lock4pubkeysCache) _pubkeysCache = null; } }
private void ListenerLoop() { try { NetworkStream ns = _tcpClient.GetStream(); while (ns.CanRead) { #region Read header and payload from network Header header; Payload payload; try { header = new Header(BinaryReader); payload = (header.Length == 0) ? new Payload(header.Command, null) : new Payload(header.Command, BinaryReader.ReadBytes(header.Length)); } catch (Exception e) { string excptionStr = e.ToString(); if ((e is IOException) || (e is SocketException)) excptionStr = ""; Debug.WriteLine("соединение " + NetworkAddress + " потерено " + excptionStr); Bitmessage.NodeIsDisconnected.Set(); break; } #endregion Read header and payload from network bool checksum = header.Checksum.SequenceEqual(payload.Checksum()); if (checksum && payload.IsValid) { debug("Command=" + header.Command); #region Save payload to Inventory if ((header.Command == "msg") || (header.Command == "pubkey") || (header.Command == "broadcast") || (header.Command == "getpubkey")) { _nodeConnectionInventory.Insert(payload.InventoryVector); payload.SaveAsync(Bitmessage); } #endregion Save to Inventory #region VERSION if (header.Command == "version") { var v = new Version(payload); debug("Подключились с " + v.UserAgent); if ((v.Value != 1) && (v.Value != 2)) Stop("Version = " + v.Value); else if (v.Nonce == Version.EightBytesOfRandomDataUsedToDetectConnectionsToSelf) { Bitmessage.DeleteNode(NetworkAddress); Stop("DetectConnectionsToSelf"); } else Send(new Verack()); } #endregion VERSION #region INV else if (header.Command == "inv") { var inputInventory = new Inv(payload.SentData); var buff4GetData = new MemoryInventory(inputInventory.Count); debug("прислали inv. Inventory.Count=" + inputInventory.Count); //lock (Bitmessage.MemoryInventory) //{ foreach (byte[] inventoryVector in inputInventory) { _nodeConnectionInventory.Insert(inventoryVector); if (!Bitmessage.MemoryInventory.Exists(inventoryVector)) { Bitmessage.MemoryInventory.AddWait(inventoryVector); buff4GetData.Insert(inventoryVector); } } //} if (buff4GetData.Count > 0) { debug("SendGetdata count=" + buff4GetData.Count); Send(new GetData(buff4GetData)); } else debug("All know, don't send GetData"); } #endregion #region verack else if (header.Command == "verack") { Send(new Inv(Bitmessage.MemoryInventory)); NetworkAddress.TimeLastSeen = DateTime.UtcNow; NetworkAddress.SaveAsync(Bitmessage.DB); } #endregion #region getpubkey else if (header.Command == "getpubkey") { var getpubkey = new GetPubkey(payload); PrivateKey pk = Bitmessage.FindPrivateKey(getpubkey); if ((pk != null) && (pk.LastPubkeySendTime.ToUnix() < (DateTime.UtcNow.ToUnix() - Payload.LengthOfTimeToHoldOnToAllPubkeys))) { pk.SendAsync(Bitmessage); } } #endregion getpubkey #region pubkey else if (header.Command == "pubkey") { int pos = payload.FirstByteAfterTime; var pubkey = new Pubkey(payload.SentData, ref pos, true); if (pubkey.Status == Status.Valid) { pubkey.SaveAsync(Bitmessage.DB); Bitmessage.OnReceivePubkey(pubkey); } else Bitmessage.OnReceiveInvalidPubkey(pubkey); } #endregion PUBKEY #region msg else if (header.Command == "msg") { var msg = new Msg(Bitmessage, payload); msg.SaveAsync(Bitmessage.DB); if (msg.Status == Status.Valid) Bitmessage.OnReceiveMsg(msg); else Bitmessage.OnReceiveInvalidMsg(msg); } #endregion MSG #region broadcast else if (header.Command == "broadcast") { var broadcast = new Broadcast(Bitmessage, payload); broadcast.SaveAsync(Bitmessage.DB); if (broadcast.Status == Status.Valid) Bitmessage.OnReceiveBroadcast(broadcast); else Bitmessage.OnReceiveInvalidBroadcast(broadcast); } #endregion BROADCAST #region addr else if (header.Command == "addr") { int pos = 0; UInt64 numberOfAddressesIncluded = payload.SentData.ReadVarInt(ref pos); if ((numberOfAddressesIncluded > 0) && (numberOfAddressesIncluded < 1001)) { if (payload.Length != (pos + (38*(int) numberOfAddressesIncluded))) throw new Exception( "addr message does not contain the correct amount of data. Ignoring."); while (pos < payload.Length) { NetworkAddress networkAddress = NetworkAddress.GetFromAddrList(payload.SentData, ref pos); Bitmessage.AddNode(networkAddress); } } } #endregion addr #region getdata else if (header.Command == "getdata") { debug("Load getdata"); var getData = new GetData(payload.SentData); foreach (byte[] hash in getData.Inventory) Payload.SendAsync(this, hash.ToHex(false)); } #endregion getdata #region ping else if (header.Command == "ping") { Send(new Pong()); } #endregion ping #region pong else if (header.Command == "pong") { } #endregion pong else debug("unknown command"); } else debug("checksum error"); } _tcpClient.Close(); } // ReSharper disable EmptyGeneralCatchClause catch(Exception e) { debug("Закрываю соединение " + e); } // ReSharper restore EmptyGeneralCatchClause Bitmessage.NodeIsDisconnected.Set(); }
public void DeleteSubscription(Pubkey pubkey) { if (pubkey.SubscriptionIndex != 0) { pubkey.SubscriptionIndex = 0; pubkey.SaveAsync(DB); lock (_lock4pubkeysCache) _pubkeysCache = null; } }
public Broadcast(Bitmessage bm, Payload payload) { Status = Status.Invalid; try { int pos = payload.FirstByteAfterTime; Version = payload.SentData.ReadVarInt(ref pos); if (Version == 2) { _inventoryVector = payload.InventoryVector; Stream = payload.SentData.ReadVarInt(ref pos); byte[] encrypted = payload.SentData.ReadBytes(ref pos, payload.Length - pos); byte[] decryptedData = null; Pubkey encryptionKey = null; foreach (Pubkey subscriptionKey in bm.Subscriptions(Stream4DB)) { if (subscriptionKey.Stream != _stream) { continue; } try { decryptedData = subscriptionKey.DecryptAes256Cbc4Broadcast(encrypted); encryptionKey = subscriptionKey; } // ReSharper disable EmptyGeneralCatchClause catch { } // ReSharper restore EmptyGeneralCatchClause if (decryptedData != null) { break; } } if ((decryptedData == null) || (encryptionKey == null)) { Status = Status.Encrypted; return; } if (encryptionKey.SubscriptionIndex < int.MaxValue) { encryptionKey.SubscriptionIndex += 1; encryptionKey.SaveAsync(bm.DB).Wait(); } pos = 0; /*var signedBroadcastVersion = */ decryptedData.ReadVarInt(ref pos); Pubkey keyFromMsg = new Pubkey(decryptedData, ref pos); if (!encryptionKey.Hash.SequenceEqual(keyFromMsg.Hash)) { return; } Key = encryptionKey.Name; EncodingType = (EncodingType)decryptedData.ReadVarInt(ref pos); decryptedData.ReadVarStrSubjectAndBody(ref pos, out _subject, out _body); int posOfEndMsg = pos; UInt64 signatureLength = decryptedData.ReadVarInt(ref pos); byte[] signature = decryptedData.ReadBytes(ref pos, (int)signatureLength); byte[] data = new byte[posOfEndMsg]; Buffer.BlockCopy(decryptedData, 0, data, 0, posOfEndMsg); if (data.ECDSAVerify(encryptionKey.SigningKey, signature)) { Status = Status.Valid; } } } catch { Status = Status.Invalid; } }
public Msg(Bitmessage bm, Payload payload) { Status = Status.Invalid; try { int pos = payload.FirstByteAfterTime; _inventoryVector = payload.InventoryVector; Stream = payload.SentData.ReadVarInt(ref pos); byte[] encrypted = payload.SentData.ReadBytes(ref pos, payload.Length - pos); // TODO Check ask data byte[] decryptedData = null; PrivateKey myEncryptionKey = null; foreach (PrivateKey myKey in bm.ListMyAddresses()) { if (myKey.Stream != _stream) { continue; } try { decryptedData = myKey.DecryptAES256CBC4Msg(encrypted); myEncryptionKey = myKey; } // ReSharper disable EmptyGeneralCatchClause catch { } // ReSharper restore EmptyGeneralCatchClause if (decryptedData != null) { break; } } if ((decryptedData == null) || (myEncryptionKey == null)) { Status = Status.Encrypted; return; } pos = 0; Version = decryptedData.ReadVarInt(ref pos); var senderKey = new Pubkey(decryptedData, ref pos); if (!decryptedData.ReadBytes(ref pos, 20).SequenceEqual(myEncryptionKey.Hash)) { //print 'The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.' //print 'See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html' //print 'your toRipe:', toRipe.encode('hex') //print 'embedded destination toRipe:', decryptedData[readPosition:readPosition + 20].encode('hex') return; } KeyTo = myEncryptionKey.Name; KeyFrom = senderKey.Name; EncodingType = (EncodingType)decryptedData.ReadVarInt(ref pos); decryptedData.ReadVarStrSubjectAndBody(ref pos, out _subject, out _body); UInt64 askDataLength = decryptedData.ReadVarInt(ref pos); _askData = decryptedData.ReadBytes(ref pos, (int)askDataLength); int posOfEndMsg = pos; UInt64 signatureLength = decryptedData.ReadVarInt(ref pos); byte[] signature = decryptedData.ReadBytes(ref pos, (int)signatureLength); var data = new byte[posOfEndMsg]; Buffer.BlockCopy(decryptedData, 0, data, 0, posOfEndMsg); if (data.ECDSAVerify(senderKey.SigningKey, signature)) { Status = Status.Valid; senderKey.SaveAsync(bm.DB); } } catch { Status = Status.Invalid; } }
public Msg(Bitmessage bm, Payload payload) { Status = Status.Invalid; try { int pos = payload.FirstByteAfterTime; _inventoryVector = payload.InventoryVector; Stream = payload.SentData.ReadVarInt(ref pos); byte[] encrypted = payload.SentData.ReadBytes(ref pos, payload.Length - pos); // TODO Check ask data byte[] decryptedData = null; PrivateKey myEncryptionKey = null; foreach (PrivateKey myKey in bm.ListMyAddresses()) { if (myKey.Stream != _stream) continue; try { decryptedData = myKey.DecryptAES256CBC4Msg(encrypted); myEncryptionKey = myKey; } // ReSharper disable EmptyGeneralCatchClause catch { } // ReSharper restore EmptyGeneralCatchClause if (decryptedData != null) break; } if ((decryptedData == null) || (myEncryptionKey == null)) { Status = Status.Encrypted; return; } pos = 0; Version = decryptedData.ReadVarInt(ref pos); var senderKey = new Pubkey(decryptedData, ref pos); if (!decryptedData.ReadBytes(ref pos, 20).SequenceEqual(myEncryptionKey.Hash)) //print 'The original sender of this message did not send it to you. Someone is attempting a Surreptitious Forwarding Attack.' //print 'See: http://world.std.com/~dtd/sign_encrypt/sign_encrypt7.html' //print 'your toRipe:', toRipe.encode('hex') //print 'embedded destination toRipe:', decryptedData[readPosition:readPosition + 20].encode('hex') return; KeyTo = myEncryptionKey.Name; KeyFrom = senderKey.Name; EncodingType = (EncodingType) decryptedData.ReadVarInt(ref pos); decryptedData.ReadVarStrSubjectAndBody(ref pos, out _subject, out _body); UInt64 askDataLength = decryptedData.ReadVarInt(ref pos); _askData = decryptedData.ReadBytes(ref pos, (int) askDataLength); int posOfEndMsg = pos; UInt64 signatureLength = decryptedData.ReadVarInt(ref pos); byte[] signature = decryptedData.ReadBytes(ref pos, (int) signatureLength); var data = new byte[posOfEndMsg]; Buffer.BlockCopy(decryptedData, 0, data, 0, posOfEndMsg); if (data.ECDSAVerify(senderKey.SigningKey, signature)) { Status = Status.Valid; senderKey.SaveAsync(bm.DB); } } catch { Status = Status.Invalid; } }