From 2bcfbf0d796ec310cf07fdd8c283f2f8ab6f44ca Mon Sep 17 00:00:00 2001 From: Kevin F Date: Wed, 16 Feb 2022 00:49:32 -0600 Subject: [PATCH] Tor address generation completed. New system stores the priv key in config as a cleaner method --- src/gossip/commands.py | 9 ++++++ src/gossip/peer.py | 19 +++++++----- src/gossip/server.py | 36 ++++++++++++++++++++-- static-data/default-plugins/tor/main.py | 26 +++++++++++----- static-data/default-plugins/tor/torpeer.py | 15 +++++++++ static-data/default-plugins/tor/torrc | 2 -- 6 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 src/gossip/commands.py create mode 100644 static-data/default-plugins/tor/torpeer.py delete mode 100644 static-data/default-plugins/tor/torrc diff --git a/src/gossip/commands.py b/src/gossip/commands.py new file mode 100644 index 00000000..b7e8a986 --- /dev/null +++ b/src/gossip/commands.py @@ -0,0 +1,9 @@ +from enum import Enum, auto + +class GossipCommands(Enum): + PING = 1 + ANNOUNCE = auto() + PEER_EXCHANGE = auto() + STREAM_BLOCKS = auto() + PUT_BLOCKS = auto() + diff --git a/src/gossip/peer.py b/src/gossip/peer.py index 210bf41b..3b23a548 100644 --- a/src/gossip/peer.py +++ b/src/gossip/peer.py @@ -1,11 +1,16 @@ -class Peer: +from typing import Protocol + + +class Peer(Protocol): + stats = {} + sock = None + id = "" + node_address = "" + def __init__(self): - self.stats = {} - self.sock = None - self.id = "" - def send(self, data: bytes): return + def get_socket(self): + return + def disconnect(self): return - - diff --git a/src/gossip/server.py b/src/gossip/server.py index 0b6b9ff9..bcbb8c50 100644 --- a/src/gossip/server.py +++ b/src/gossip/server.py @@ -1,3 +1,4 @@ +import asyncio from typing import TYPE_CHECKING from typing import Set @@ -8,13 +9,44 @@ if TYPE_CHECKING: from peer import Peer from filepaths import gossip_server_socket_file +from .commands import GossipCommands +""" +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. -import asyncio +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" def gossip_server( peer_set: Set['Peer'], block_queue: Queue['Block'], dandelion_seed: bytes): - return \ No newline at end of file + + async def peer_connected(reader, writer): + while True: + cmd = asyncio.wait_for(await reader.read(1), 30) + match cmd: + case GossipCommands.PING: + writer.write(b'PONG') + + await writer.drain() + + async def main(): + + server = await asyncio.start_unix_server( + peer_connected, gossip_server_socket_file + ) + + async with server: + await server.serve_forever() + + asyncio.run(main()) diff --git a/static-data/default-plugins/tor/main.py b/static-data/default-plugins/tor/main.py index 468ff491..458e425d 100644 --- a/static-data/default-plugins/tor/main.py +++ b/static-data/default-plugins/tor/main.py @@ -9,6 +9,7 @@ import locale from typing import Set, TYPE_CHECKING import base64 +import stem from stem.control import Controller import logger @@ -18,7 +19,6 @@ from filepaths import gossip_server_socket_file from gossip.peer import Peer -import onionrcrypto locale.setlocale(locale.LC_ALL, '') sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) @@ -62,15 +62,17 @@ def on_gossip_start(api, data: Set[Peer] = None): # We don't do gossip logic try: with open(bootstrap_file, 'r') as bootstrap_file_obj: - bootstrap_nodes = bootstrap_file_obj.read().split(',') + bootstrap_nodes = set(bootstrap_file_obj.read().split(',')) except FileNotFoundError: - bootstrap_nodes = [] - #for node in bootstrap_nodes: + bootstrap_nodes = set() + starttor.start_tor() with Controller.from_socket_file(control_socket) as controller: controller.authenticate() - logger.info(f"Tor socks is listening on {controller.get_listeners('SOCKS')}", terminal=True) + logger.info( + "Tor socks is listening on " + + f"{controller.get_listeners('SOCKS')}", terminal=True) key = config.get('tor.key') new_address = '' if not key: @@ -79,10 +81,18 @@ def on_gossip_start(api, data: Set[Peer] = None): key_content='BEST', key_type='NEW') config.set('tor.key', add_onion_resp.private_key, savefile=True) new_address = 'Generated ' + config.set('tor.transport_address', add_onion_resp.service_id) else: - add_onion_resp = controller.create_ephemeral_hidden_service( - {'80': f'unix:{gossip_server_socket_file}'}, - key_content=key, key_type='ED25519-V3') + try: + add_onion_resp = controller.create_ephemeral_hidden_service( + {'80': f'unix:{gossip_server_socket_file}'}, + key_content=key, key_type='ED25519-V3') + except stem.ProtocolError: + logger.error( + "Could not start Tor transport. Try restarting Onionr", + terminal=True) + config.set('tor.key', '', savefile=True) + return logger.info( f'{new_address}Tor transport address {add_onion_resp.service_id}' + '.onion', diff --git a/static-data/default-plugins/tor/torpeer.py b/static-data/default-plugins/tor/torpeer.py new file mode 100644 index 00000000..beb02801 --- /dev/null +++ b/static-data/default-plugins/tor/torpeer.py @@ -0,0 +1,15 @@ +import socks + + +class TorPeer: + + def __init__(self, socks_host, socks_port, onion_address): + self.onion_address = onion_address + self.socks_host = socks_host + self.socks_port = socks_port + + def get_socket(self) -> socks.socksocket: + s = socks.socksocket() + s.set_proxy(socks.SOCKS4, self.socks_host, self.socks_host, rdns=True) + s.connect((self.onion_address, 80)) + return s diff --git a/static-data/default-plugins/tor/torrc b/static-data/default-plugins/tor/torrc deleted file mode 100644 index 29a5cfce..00000000 --- a/static-data/default-plugins/tor/torrc +++ /dev/null @@ -1,2 +0,0 @@ -OnionTrafficOnly 1 -