From 9d3e847a68560a650aa4bb2bf5c6779cadfc9b4f Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 21 Jul 2023 14:30:10 -0400 Subject: [PATCH] more punishment cleanup --- veilid-core/src/crypto/envelope.rs | 8 ++++++++ veilid-core/src/crypto/receipt.rs | 5 +++++ veilid-core/src/network_manager/mod.rs | 14 +++++++++----- .../src/network_manager/network_connection.rs | 2 +- veilid-core/src/rpc_processor/destination.rs | 5 +---- veilid-core/src/rpc_processor/mod.rs | 19 ++++--------------- .../rpc_processor/rpc_validate_dial_info.rs | 5 +---- veilid-flutter/lib/routing_context.dart | 7 +++++++ veilid-flutter/lib/veilid_crypto.dart | 4 ++++ 9 files changed, 40 insertions(+), 29 deletions(-) diff --git a/veilid-core/src/crypto/envelope.rs b/veilid-core/src/crypto/envelope.rs index f7116e59..86ecc657 100644 --- a/veilid-core/src/crypto/envelope.rs +++ b/veilid-core/src/crypto/envelope.rs @@ -330,7 +330,15 @@ impl Envelope { self.sender_id } + pub fn get_sender_typed_id(&self) -> TypedKey { + TypedKey::new(self.crypto_kind, self.sender_id) + } + pub fn get_recipient_id(&self) -> PublicKey { self.recipient_id } + + pub fn get_recipient_typed_id(&self) -> TypedKey { + TypedKey::new(self.crypto_kind, self.recipient_id) + } } diff --git a/veilid-core/src/crypto/receipt.rs b/veilid-core/src/crypto/receipt.rs index 4f8d4b15..56bd4c90 100644 --- a/veilid-core/src/crypto/receipt.rs +++ b/veilid-core/src/crypto/receipt.rs @@ -207,6 +207,11 @@ impl Receipt { pub fn get_sender_id(&self) -> PublicKey { self.sender_id } + + pub fn get_sender_typed_id(&self) -> TypedKey { + TypedKey::new(self.crypto_kind, self.sender_id) + } + pub fn get_extra_data(&self) -> &[u8] { &self.extra_data } diff --git a/veilid-core/src/network_manager/mod.rs b/veilid-core/src/network_manager/mod.rs index 3f57f82f..a36569bb 100644 --- a/veilid-core/src/network_manager/mod.rs +++ b/veilid-core/src/network_manager/mod.rs @@ -954,6 +954,7 @@ impl NetworkManager { Ok(v) => v, Err(e) => { log_net!(debug "envelope failed to decode: {}", e); + // safe to punish here because relays also check here to ensure they arent forwarding things that don't decode self.address_filter().punish_ip_addr(remote_addr); return Ok(false); } @@ -1005,12 +1006,12 @@ impl NetworkManager { // Peek at header and see if we need to relay this // If the recipient id is not our node id, then it needs relaying - let sender_id = TypedKey::new(envelope.get_crypto_kind(), envelope.get_sender_id()); + let sender_id = envelope.get_sender_typed_id(); if self.address_filter().is_node_id_punished(sender_id) { return Ok(false); } - let recipient_id = TypedKey::new(envelope.get_crypto_kind(), envelope.get_recipient_id()); + let recipient_id = envelope.get_recipient_typed_id(); if !routing_table.matches_own_node_id(&[recipient_id]) { // See if the source node is allowed to resolve nodes // This is a costly operation, so only outbound-relay permitted @@ -1089,15 +1090,18 @@ impl NetworkManager { ) { Ok(v) => v, Err(e) => { - log_net!(debug "failed to decrypt envelope body: {}",e); - self.address_filter().punish_ip_addr(remote_addr); + log_net!(debug "failed to decrypt envelope body: {}", e); + // Can't punish by ip address here because relaying can't decrypt envelope bodies to check + // But because the envelope was properly signed by the time it gets here, it is safe to + // punish by node id + self.address_filter().punish_node_id(sender_id); return Ok(false); } }; // Cache the envelope information in the routing table let source_noderef = match routing_table.register_node_with_existing_connection( - TypedKey::new(envelope.get_crypto_kind(), envelope.get_sender_id()), + envelope.get_sender_typed_id(), connection_descriptor, ts, ) { diff --git a/veilid-core/src/network_manager/network_connection.rs b/veilid-core/src/network_manager/network_connection.rs index dbda6da2..b96a36e3 100644 --- a/veilid-core/src/network_manager/network_connection.rs +++ b/veilid-core/src/network_manager/network_connection.rs @@ -315,7 +315,7 @@ impl NetworkConnection { return RecvLoopAction::Finish; } - // Punish invalid messages + // Punish invalid framing (tcp framing or websocket framing) if v.is_invalid_message() { address_filter.punish_ip_addr(peer_address.to_socket_addr().ip()); return RecvLoopAction::Finish; diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index 041d41a5..1ba68fec 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -319,10 +319,7 @@ impl RPCProcessor { }; // Reply directly to the request's source - let sender_node_id = TypedKey::new( - detail.envelope.get_crypto_kind(), - detail.envelope.get_sender_id(), - ); + let sender_node_id = detail.envelope.get_sender_typed_id(); // This may be a different node's reference than the 'sender' in the case of a relay let peer_noderef = detail.peer_noderef.clone(); diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 44c07ba8..4d3dee31 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -126,17 +126,9 @@ impl RPCMessageHeader { } pub fn direct_sender_node_id(&self) -> TypedKey { match &self.detail { - RPCMessageHeaderDetail::Direct(d) => { - TypedKey::new(d.envelope.get_crypto_kind(), d.envelope.get_sender_id()) - } - RPCMessageHeaderDetail::SafetyRouted(s) => TypedKey::new( - s.direct.envelope.get_crypto_kind(), - s.direct.envelope.get_sender_id(), - ), - RPCMessageHeaderDetail::PrivateRouted(p) => TypedKey::new( - p.direct.envelope.get_crypto_kind(), - p.direct.envelope.get_sender_id(), - ), + RPCMessageHeaderDetail::Direct(d) => d.envelope.get_sender_typed_id(), + RPCMessageHeaderDetail::SafetyRouted(s) => s.direct.envelope.get_sender_typed_id(), + RPCMessageHeaderDetail::PrivateRouted(p) => p.direct.envelope.get_sender_typed_id(), } } } @@ -1464,10 +1456,7 @@ impl RPCProcessor { let msg = match &encoded_msg.header.detail { RPCMessageHeaderDetail::Direct(detail) => { // Get sender node id - let sender_node_id = TypedKey::new( - detail.envelope.get_crypto_kind(), - detail.envelope.get_sender_id(), - ); + let sender_node_id = detail.envelope.get_sender_typed_id(); // Decode and validate the RPC operation let operation = match self.decode_rpc_operation(&encoded_msg) { diff --git a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs index ab6812e4..bd9823fd 100644 --- a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs +++ b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs @@ -104,10 +104,7 @@ impl RPCProcessor { // We filter on the -outgoing- protocol capability status not the node's dial info // Use the address type though, to ensure we reach an ipv6 capable node if this is // an ipv6 address - let sender_node_id = TypedKey::new( - detail.envelope.get_crypto_kind(), - detail.envelope.get_sender_id(), - ); + let sender_node_id = detail.envelope.get_sender_typed_id(); let routing_domain = detail.routing_domain; let node_count = { let c = self.config.get(); diff --git a/veilid-flutter/lib/routing_context.dart b/veilid-flutter/lib/routing_context.dart index 32d51213..56c2de6a 100644 --- a/veilid-flutter/lib/routing_context.dart +++ b/veilid-flutter/lib/routing_context.dart @@ -91,6 +91,13 @@ extension DHTRecordDescriptorExt on DHTRecordDescriptor { } return KeyPair(key: owner, secret: ownerSecret!); } + + TypedKeyPair? ownerTypedKeyPair() { + if (ownerSecret == null) { + return null; + } + return TypedKeyPair(kind: key.kind, key: owner, secret: ownerSecret!); + } } ////////////////////////////////////// diff --git a/veilid-flutter/lib/veilid_crypto.dart b/veilid-flutter/lib/veilid_crypto.dart index 4a38841f..b41a410d 100644 --- a/veilid-flutter/lib/veilid_crypto.dart +++ b/veilid-flutter/lib/veilid_crypto.dart @@ -21,6 +21,8 @@ String cryptoKindToString(CryptoKind kind) { return "${String.fromCharCode(kind & 0xFF)}${String.fromCharCode((kind >> 8) & 0xFF)}${String.fromCharCode((kind >> 16) & 0xFF)}${String.fromCharCode((kind >> 24) & 0xFF)}"; } +const CryptoKind bestCryptoKind = cryptoKindVLD0; + Uint8List cryptoKindToBytes(CryptoKind kind) { var b = Uint8List(4); b[0] = kind & 0xFF; @@ -140,6 +142,8 @@ class TypedKeyPair extends Equatable { String toJson() => toString(); factory TypedKeyPair.fromJson(dynamic json) => TypedKeyPair.fromString(json as String); + factory TypedKeyPair.fromKeyPair(CryptoKind kind, KeyPair keyPair) => + TypedKeyPair(kind: kind, key: keyPair.key, secret: keyPair.secret); } typedef CryptoKey = FixedEncodedString43;