From 6e95acf12e55cf71656b60e33ca10373e51d0552 Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 09:42:14 +0100 Subject: [PATCH 1/8] Fixed KeyError in relay_cell --- ipv8/messaging/anonymization/crypto.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipv8/messaging/anonymization/crypto.py b/ipv8/messaging/anonymization/crypto.py index a3cae11a8..08e7bbc25 100644 --- a/ipv8/messaging/anonymization/crypto.py +++ b/ipv8/messaging/anonymization/crypto.py @@ -199,7 +199,6 @@ def relay_cell(self, cell: CellPayload) -> None: return next_relay = self.relays[cell.circuit_id] - this_relay = self.relays[next_relay.circuit_id] if cell.relay_early and next_relay.relay_early_count >= self.max_relay_early: self.logger.warning('Dropping cell (too many relay_early cells)') @@ -208,6 +207,7 @@ def relay_cell(self, cell: CellPayload) -> None: try: if next_relay.rendezvous_relay: self.decrypt_cell(cell, FORWARD, next_relay.hop) + this_relay = self.relays[next_relay.circuit_id] self.encrypt_cell(cell, BACKWARD, this_relay.hop) cell.relay_early = False else: From 4ab02970f7f44c1bbad855c294b62867fea6cf6b Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 09:45:39 +0100 Subject: [PATCH 2/8] Don't pass DispatcherEndpoint to PythonCryptoEndpoint --- ipv8/messaging/anonymization/community.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ipv8/messaging/anonymization/community.py b/ipv8/messaging/anonymization/community.py index 14b430483..3b4fd6d1e 100644 --- a/ipv8/messaging/anonymization/community.py +++ b/ipv8/messaging/anonymization/community.py @@ -21,6 +21,8 @@ from ...requestcache import RequestCache from ...taskmanager import task from ...types import Address +from ..interfaces.dispatcher.endpoint import DispatcherEndpoint +from ..interfaces.endpoint import Endpoint from .caches import * from .crypto import CryptoEndpoint, PythonCryptoEndpoint, TunnelCrypto from .endpoint import TunnelEndpoint @@ -188,7 +190,14 @@ def __init__(self, settings: TunnelSettings) -> None: self.crypto: TunnelCrypto = TunnelCrypto() self.crypto.initialize(cast(LibNaCLSK, self.my_peer.key)) - self.crypto_endpoint = self.endpoint if isinstance(self.endpoint, + # For now, the TunnelCommunity only supports IPv4 for control messages. + # Data packets can still be sent to IPv6 destinations. + if isinstance(self.endpoint, DispatcherEndpoint): + ipv4_endpoint = cast(Endpoint, self.endpoint.interfaces["UDPIPv4"]) + else: + ipv4_endpoint = self.endpoint + + self.crypto_endpoint = ipv4_endpoint if isinstance(ipv4_endpoint, CryptoEndpoint) else PythonCryptoEndpoint(self.endpoint) self.crypto_endpoint.setup_tunnels(self, self.settings) From 39949e0f1ad41fd30059a3e5edc0f82c45fad7c1 Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 09:46:55 +0100 Subject: [PATCH 3/8] Ensure TunnelExitSockets are shutdown properly --- ipv8/messaging/anonymization/community.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ipv8/messaging/anonymization/community.py b/ipv8/messaging/anonymization/community.py index 3b4fd6d1e..9766db62a 100644 --- a/ipv8/messaging/anonymization/community.py +++ b/ipv8/messaging/anonymization/community.py @@ -790,12 +790,12 @@ def on_created(self, source_address: Address, payload: CreatedPayload, _: int | self.logger.info("Got CREATED message forward as EXTENDED to origin.") - exit_socket = self.exit_sockets.pop(request.from_circuit_id, None) - if exit_socket is None: + if request.from_circuit_id not in self.exit_sockets: self.logger.info("Created for unknown exit socket %s", request.from_circuit_id) return + session_keys = self.exit_sockets[request.from_circuit_id].hop.keys + self.remove_exit_socket(request.from_circuit_id, remove_now=True) - session_keys = exit_socket.hop.keys bw_relay = RelayRoute(request.from_circuit_id, Hop(request.peer, session_keys), BACKWARD) fw_relay = RelayRoute(request.to_circuit_id, Hop(request.to_peer, session_keys), FORWARD) From 24e9f937343d829293606a39d777ffb1f233c8da Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 10:50:18 +0100 Subject: [PATCH 4/8] Fix for peer_flags settings --- ipv8/messaging/anonymization/community.py | 7 +++---- ipv8/test/messaging/anonymization/test_community.py | 3 +++ ipv8/test/messaging/anonymization/test_hiddenservices.py | 3 +++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ipv8/messaging/anonymization/community.py b/ipv8/messaging/anonymization/community.py index 9766db62a..0deb0e780 100644 --- a/ipv8/messaging/anonymization/community.py +++ b/ipv8/messaging/anonymization/community.py @@ -103,7 +103,7 @@ class TunnelSettings(CommunitySettings): # to flow over the circuit (i.e. bandwidth payouts to intermediate nodes in a circuit). remove_tunnel_delay = 5 - _peer_flags: Set[int] + _peer_flags: Set[int] = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST} _max_relay_early = 8 @@ -122,7 +122,7 @@ def max_relay_early(self, value: int) -> None: Set the maximum number of relay_early cells that are allowed to pass a relay. """ self._max_relay_early = value - if hasattr(self.endpoint, 'set_max_relay_early'): + if hasattr(self, 'endpoint') and hasattr(self.endpoint, 'set_max_relay_early'): self.endpoint.set_max_relay_early(value) @property @@ -138,7 +138,7 @@ def peer_flags(self, value: Set[int]) -> None: Set the peer flags. """ self._peer_flags = value - if hasattr(self.endpoint, 'set_peer_flags'): + if hasattr(self, 'endpoint') and hasattr(self.endpoint, 'set_peer_flags'): self.endpoint.set_peer_flags(value) @@ -155,7 +155,6 @@ def __init__(self, settings: TunnelSettings) -> None: """ Create a new TunnelCommunity. """ - settings.peer_flags = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST} self.settings = settings self.dht_provider = settings.dht_provider diff --git a/ipv8/test/messaging/anonymization/test_community.py b/ipv8/test/messaging/anonymization/test_community.py index 1a1499787..25138a09e 100644 --- a/ipv8/test/messaging/anonymization/test_community.py +++ b/ipv8/test/messaging/anonymization/test_community.py @@ -11,6 +11,7 @@ CIRCUIT_STATE_EXTENDING, PEER_FLAG_EXIT_BT, PEER_FLAG_EXIT_IPV8, + PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST, ) from ....messaging.interfaces.udp.endpoint import DomainAddress, UDPEndpoint @@ -74,6 +75,8 @@ def create_node(self, settings: CommunitySettings | None = None, create_dht: boo tunnel_settings.min_circuits = 0 tunnel_settings.max_circuits = 0 tunnel_settings.remove_tunnel_delay = 0 + # For some reason the exit flag set gets remembered across tests, so create a new set here + tunnel_settings.peer_flags = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST} ipv8 = MockIPv8("curve25519", TunnelCommunity, settings=tunnel_settings) # Then kill all automated circuit creation ipv8.overlay.cancel_all_pending_tasks() diff --git a/ipv8/test/messaging/anonymization/test_hiddenservices.py b/ipv8/test/messaging/anonymization/test_hiddenservices.py index ba138ea1e..1cd9d52a1 100644 --- a/ipv8/test/messaging/anonymization/test_hiddenservices.py +++ b/ipv8/test/messaging/anonymization/test_hiddenservices.py @@ -12,6 +12,7 @@ CIRCUIT_TYPE_DATA, CIRCUIT_TYPE_IP_SEEDER, PEER_FLAG_EXIT_BT, + PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST, PEER_SOURCE_DHT, IntroductionPoint, @@ -106,6 +107,8 @@ def create_node(self, settings: None = None, create_dht: bool = False, enable_st tunnel_settings.min_circuits = 0 tunnel_settings.max_circuits = 0 tunnel_settings.remove_tunnel_delay = 0 + # For some reason the exit flag set gets remembered across tests, so create a new set here + tunnel_settings.peer_flags = {PEER_FLAG_RELAY, PEER_FLAG_SPEED_TEST} ipv8 = MockIPv8("curve25519", HiddenTunnelCommunity, settings=tunnel_settings) ipv8.overlay.ipv8 = ipv8 ipv8.overlay.crypto_endpoint.setup_tunnels(ipv8.overlay, tunnel_settings) From 8634b82e6c2b1373d0ba9be038ea4ce884619dc5 Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 10:51:22 +0100 Subject: [PATCH 5/8] Use RustEndpoint for IPv8 exit nodes --- scripts/exitnode_ipv8_only_plugin.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/exitnode_ipv8_only_plugin.py b/scripts/exitnode_ipv8_only_plugin.py index 827f837a5..315053b03 100644 --- a/scripts/exitnode_ipv8_only_plugin.py +++ b/scripts/exitnode_ipv8_only_plugin.py @@ -35,6 +35,7 @@ from ipv8.configuration import get_default_configuration from ipv8.messaging.anonymization.tunnel import PEER_FLAG_EXIT_IPV8 +from ipv8.messaging.interfaces.dispatcher.endpoint import INTERFACES from ipv8.REST.rest_manager import RESTManager from ipv8.util import run_forever from ipv8_service import IPv8 @@ -76,6 +77,13 @@ async def start_ipv8(self, statedir: str | None, listen_port: int, statistics: b overlay['initialize']['settings']['max_joined_circuits'] = 1000 overlay['initialize']['settings']['peer_flags'] = {PEER_FLAG_EXIT_IPV8} + try: + from ipv8_rust_tunnels.endpoint import RustEndpoint as UDPEndpoint + except ImportError: + from ipv8.messaging.interfaces.udp.endpoint import UDPEndpoint + + INTERFACES["UDPIPv4"] = UDPEndpoint + print("Starting IPv8") # noqa: T201 self.ipv8 = IPv8(configuration, enable_statistics=statistics) From a4aed613d0250fbf902ab13bc6b732a69d3518fb Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 10:47:47 +0100 Subject: [PATCH 6/8] Ensure property setters in CommunitySettings are being respected --- ipv8_service.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ipv8_service.py b/ipv8_service.py index f2d86b6dc..b0cfaeadb 100644 --- a/ipv8_service.py +++ b/ipv8_service.py @@ -136,8 +136,9 @@ def __init__(self, # noqa: C901, PLR0912 for overlay in configuration['overlays']: overlay_class = _COMMUNITIES.get(overlay['class'], (extra_communities or {}).get(overlay['class'])) my_peer = self.keys[overlay['key']] - settings = overlay_class.settings_class(my_peer=my_peer, endpoint=self.endpoint, network=self.network, - **overlay['initialize']) + settings = overlay_class.settings_class(my_peer=my_peer, endpoint=self.endpoint, network=self.network) + for k, v in overlay['initialize'].items(): + setattr(settings, k, v) overlay_instance = overlay_class(settings) self.overlays.append(overlay_instance) for walker in overlay['walkers']: From c2423f002112f3fc6702e453df1bc4714fe75992 Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 10:49:31 +0100 Subject: [PATCH 7/8] Fix for tunnel CommunitySettings defaults --- ipv8/configuration.py | 16 +++++++--------- ipv8/test/test_configuration.py | 4 ++-- scripts/exitnode_ipv8_only_plugin.py | 8 ++++---- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/ipv8/configuration.py b/ipv8/configuration.py index b1ec50ac8..b8819cf92 100644 --- a/ipv8/configuration.py +++ b/ipv8/configuration.py @@ -110,15 +110,13 @@ ], 'bootstrappers': [DISPERSY_BOOTSTRAPPER.copy()], 'initialize': { - 'settings': { - 'min_circuits': 1, - 'max_circuits': 1, - 'max_joined_circuits': 100, - 'max_time': 10 * 60, - 'max_time_inactive': 20, - 'max_traffic': 250 * 1024 * 1024, - 'dht_lookup_interval': 30 - } + 'min_circuits': 1, + 'max_circuits': 1, + 'max_joined_circuits': 100, + 'max_time': 10 * 60, + 'max_time_inactive': 20, + 'max_traffic': 250 * 1024 * 1024, + 'dht_lookup_interval': 30 }, 'on_start': [ ('build_tunnels', 1) diff --git a/ipv8/test/test_configuration.py b/ipv8/test/test_configuration.py index c55142280..7dc0543d4 100644 --- a/ipv8/test/test_configuration.py +++ b/ipv8/test/test_configuration.py @@ -385,7 +385,7 @@ def test_default_configuration(self) -> None: [WalkerDefinition(Strategy.RandomWalk, 20, {'timeout': 3.0})], [BootstrapperDefinition(Bootstrapper.DispersyBootstrapper, DISPERSY_BOOTSTRAPPER['init'])], - {'settings': { + { 'min_circuits': 1, 'max_circuits': 1, 'max_joined_circuits': 100, @@ -393,7 +393,7 @@ def test_default_configuration(self) -> None: 'max_time_inactive': 20, 'max_traffic': 250 * 1024 * 1024, 'dht_lookup_interval': 30 - }}, + }, [('build_tunnels', 1)]) \ .add_overlay("DHTDiscoveryCommunity", "anonymous id", diff --git a/scripts/exitnode_ipv8_only_plugin.py b/scripts/exitnode_ipv8_only_plugin.py index 315053b03..1c8267630 100644 --- a/scripts/exitnode_ipv8_only_plugin.py +++ b/scripts/exitnode_ipv8_only_plugin.py @@ -72,10 +72,10 @@ async def start_ipv8(self, statedir: str | None, listen_port: int, statistics: b for overlay in configuration['overlays']: if overlay['class'] == 'HiddenTunnelCommunity': - overlay['initialize']['settings']['min_circuits'] = 0 - overlay['initialize']['settings']['max_circuits'] = 0 - overlay['initialize']['settings']['max_joined_circuits'] = 1000 - overlay['initialize']['settings']['peer_flags'] = {PEER_FLAG_EXIT_IPV8} + overlay['initialize']['min_circuits'] = 0 + overlay['initialize']['max_circuits'] = 0 + overlay['initialize']['max_joined_circuits'] = 1000 + overlay['initialize']['peer_flags'] = {PEER_FLAG_EXIT_IPV8} try: from ipv8_rust_tunnels.endpoint import RustEndpoint as UDPEndpoint From 7fc7b9d3382653546bb437ebfe6ee23afe4b522c Mon Sep 17 00:00:00 2001 From: Egbert Bouman Date: Tue, 23 Jan 2024 15:47:54 +0100 Subject: [PATCH 8/8] Ensure the AttestionCommunity is compatible with the latest cryptography --- ipv8/attestation/wallet/primitives/cryptography_wrapper.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ipv8/attestation/wallet/primitives/cryptography_wrapper.py b/ipv8/attestation/wallet/primitives/cryptography_wrapper.py index 3898238da..a11a8ec6f 100644 --- a/ipv8/attestation/wallet/primitives/cryptography_wrapper.py +++ b/ipv8/attestation/wallet/primitives/cryptography_wrapper.py @@ -28,7 +28,8 @@ def generate_safe_prime(bit_length: int, backend: Backend = default_backend()) - out = int(backend._ffi.string(generated_hex), 16) # Cleanup the memory backend._lib.OPENSSL_free(generated_hex) - backend._lib.BN_clear_free(generated) + backend._lib.BN_set_word(generated, 0) + backend._lib.BN_free(generated) return out @@ -59,5 +60,6 @@ def is_prime(number: int, backend: Backend = default_backend()) -> bool: # noqa raise RuntimeError(msg) result = backend._lib.BN_is_prime_ex(generated, backend._lib.BN_prime_checks_for_size(int(len(bhex_n) * 8)), backend._ffi.NULL, backend._ffi.NULL) - backend._lib.BN_clear_free(generated) + backend._lib.BN_set_word(generated, 0) + backend._lib.BN_free(generated) return result == 1