From 828c78a569b50ba3ead473b536e93e37fdf9f34e Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Wed, 27 Jan 2021 05:34:31 +0000 Subject: [PATCH] work on torgossip, added base64 code whitelist because of a werid plugin issue with bigbrother --- README.md | 4 +- src/bigbrother/ministry/ofexec.py | 25 ++++++++-- src/blockio/__init__.py | 2 +- src/blockio/load/__init__.py | 18 ++++++++ src/filepaths/__init__.py | 2 + src/onionrcommands/daemonlaunch/__init__.py | 5 +- src/onionrcommands/daemonlaunch/loadsafedb.py | 7 +++ static-data/base64-code-whitelist.txt | 46 +++++++++++++++++++ .../torgossip/commandhandlers.py | 14 ++++++ .../default-plugins/torgossip/commands.py | 27 +++++++++++ .../default-plugins/torgossip/info.json | 5 ++ static-data/default-plugins/torgossip/main.py | 4 +- .../default-plugins/torgossip/server.py | 42 ++++++++++++++--- .../default-plugins/torgossip/server_test.py | 29 ++++++++++++ static-data/default_config.json | 3 ++ tests/test_blockio.py | 19 +++++++- 16 files changed, 235 insertions(+), 17 deletions(-) create mode 100644 src/onionrcommands/daemonlaunch/loadsafedb.py create mode 100644 static-data/base64-code-whitelist.txt create mode 100644 static-data/default-plugins/torgossip/commandhandlers.py create mode 100644 static-data/default-plugins/torgossip/commands.py create mode 100755 static-data/default-plugins/torgossip/info.json create mode 100644 static-data/default-plugins/torgossip/server_test.py diff --git a/README.md b/README.md index 18852ea8..bd5e1d2a 100644 --- a/README.md +++ b/README.md @@ -154,10 +154,12 @@ Donating at least $3 gets you cool Onionr stickers. Get in touch if you want the * Monero: 4B5BA24d1P3R5aWEpkGY5TP7buJJcn2aSGBVRQCHhpiahxeB4aWsu15XwmuTjC6VF62NApZeJGTS248RMVECP8aW73Uj2ax -* USD (Card/Paypal): [Ko-Fi](https://www.ko-fi.com/beardogkf) +* USD (Card/Paypal (no account required)): [Ko-Fi](https://www.ko-fi.com/beardogkf) * [Indiegogo](https://igg.me/at/onionr/x#/) +* Sign up for [privacy.com (refferal link)](https://privacy.com/join/FNNDF) to protect your personal information when contributing or shopping elsewhere, we both get $5 USD. + Note: probably not tax deductible # Security diff --git a/src/bigbrother/ministry/ofexec.py b/src/bigbrother/ministry/ofexec.py index cd4ccef8..7725bc26 100644 --- a/src/bigbrother/ministry/ofexec.py +++ b/src/bigbrother/ministry/ofexec.py @@ -3,11 +3,12 @@ Prevent eval/exec/os.system and log it """ import base64 -import platform +from os import read import logger from utils import identifyhome from onionrexceptions import ArbitraryCodeExec +from utils import readstatic """ 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 @@ -56,14 +57,30 @@ def block_exec(event, info): 'stem/response/mapaddress.py', 'stem/response/protocolinfo.py', 'apport/__init__.py', - 'apport/report.py' + 'apport/report.py', + 'gevent/pool.py', + 'gevent/queue.py', + 'gevent/lock.py', + 'gevent/monkey.py', + 'gevent/_semaphore.py', + 'gevent/_imap.py' ] - whitelisted_source = [] - home = identifyhome.identify_home() + try: + whitelisted_source = readstatic.read_static( + 'base64-code-whitelist.txt') + whitelisted_source = whitelisted_source.splitlines() + except FileNotFoundError: + logger.warn("Failed to read whitelisted code for bigbrother") + whitelisted_source = [] code_b64 = base64.b64encode(info[0].co_code).decode() if code_b64 in whitelisted_source: return + # uncomment when you want to build on the whitelist + else: + with open("../static-data/base64-code-whitelist.txt", "a") as f: + f.write(code_b64 + "\n") + return for source in whitelisted_code: if info[0].co_filename.endswith(source): diff --git a/src/blockio/__init__.py b/src/blockio/__init__.py index 97900e09..df0f8d05 100644 --- a/src/blockio/__init__.py +++ b/src/blockio/__init__.py @@ -3,7 +3,7 @@ Wrap safedb for storing and fetching blocks """ from .store import store_block -from .load import load_block, list_blocks_by_type +from .load import load_block, list_blocks_by_type, list_all_blocks from .clean import clean_expired_blocks, clean_block_list_entries """ This program is free software: you can redistribute it and/or modify diff --git a/src/blockio/load/__init__.py b/src/blockio/load/__init__.py index 684e4ae0..159a1c41 100644 --- a/src/blockio/load/__init__.py +++ b/src/blockio/load/__init__.py @@ -32,5 +32,23 @@ def load_block(block: 'BlockChecksumBytes', safe_db: 'SafeDB') -> Kasten: def list_blocks_by_type( block_type: str, safe_db: 'SafeDB') -> List['BlockChecksumBytes']: + try: + block_type = block_type.decode('utf-8') + except AttributeError: + pass blocks = safe_db.get(f'bl-{block_type}') return zip(*[iter(blocks)]*64) + + +def list_all_blocks(safe_db: 'SafeDB'): + # Builds and return a master list of blocks by identifying all type lists + # and iterating them + key = safe_db.db_conn.firstkey() + master_list = [] + while key: + if key.startswith(b'bl-'): + master_list.extend( + list(list_blocks_by_type(key.replace(b'bl-', b''), safe_db))) + key = safe_db.db_conn.nextkey(key) + return master_list + diff --git a/src/filepaths/__init__.py b/src/filepaths/__init__.py index e37270ed..013c5e93 100644 --- a/src/filepaths/__init__.py +++ b/src/filepaths/__init__.py @@ -20,6 +20,8 @@ config_file = home + 'config.json' daemon_mark_file = home + '/daemon-true.txt' lock_file = home + 'onionr.lock' +main_safedb = home + "main.safe.db" + site_cache = home + 'onionr-sites.txt' tor_hs_loc = home + 'hs/' diff --git a/src/onionrcommands/daemonlaunch/__init__.py b/src/onionrcommands/daemonlaunch/__init__.py index 67d454ea..d86f4d7a 100755 --- a/src/onionrcommands/daemonlaunch/__init__.py +++ b/src/onionrcommands/daemonlaunch/__init__.py @@ -45,6 +45,7 @@ from onionrstatistics.devreporting import statistics_reporter from setupkvvars import setup_kv from communicatorutils.housekeeping import clean_blocks_not_meeting_pow from .spawndaemonthreads import spawn_client_threads +from .loadsafedb import load_safe_db """ 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 @@ -179,6 +180,8 @@ def daemon(): # Create singleton shared_state.get(serializeddata.SerializedData) + shared_state.add(load_safe_db(config)) + shared_state.share_object() # share the parent object to the threads show_logo() @@ -205,7 +208,7 @@ def daemon(): _show_info_messages() logger.info( "Onionr daemon is running under " + str(os.getpid()), terminal=True) - events.event('init', threaded=False) + events.event('init', threaded=False, data=shared_state) events.event('daemon_start') if config.get('transports.lan', True): if not onionrvalues.IS_QUBES: diff --git a/src/onionrcommands/daemonlaunch/loadsafedb.py b/src/onionrcommands/daemonlaunch/loadsafedb.py new file mode 100644 index 00000000..b2258591 --- /dev/null +++ b/src/onionrcommands/daemonlaunch/loadsafedb.py @@ -0,0 +1,7 @@ +import safedb +import filepaths + + +def load_safe_db(config) -> safedb.SafeDB: + return safedb.SafeDB( + filepaths.main_safedb, config.get('security.encrypt_database', False)) diff --git a/static-data/base64-code-whitelist.txt b/static-data/base64-code-whitelist.txt new file mode 100644 index 00000000..2fc433b2 --- /dev/null +++ b/static-data/base64-code-whitelist.txt @@ -0,0 +1,46 @@ +RwBkAGQBhABkAWUAgwNaAUcAZAJkA4QAZANlAYMDWgJHAGQEZAWEAGQFZQGDA1oDRwBkBmQHhABkB2UBgwNaBEcAZAhkCYQAZAllAYMDWgVkClMA +RwBkAGQBhABkAWUAgwNaAUcAZAJkA4QAZANlAYMDWgJHAGQEZAWEAGQFZQGDA1oDRwBkBmQHhABkB2UEZQGDBFoFRwBkCGQJhABkCWUEZQGDBFoGZQRaB0cAZApkC4QAZAtlB4MDWghlAFoJZQRaCmULWgxkDFMA +RwBkAGQBhABkAWUAgwNaAWQCUwA= +ZABaAGQBUwA= +ZABaAGQBZAJkA2QEZAVkBmQHZAhkCWQKZAtkDGQNZA5kD2QQZBFnEVoBZBJkE2wCWgJkEmQTbANaA2QSZBNsBFoEZBJkFGwFbQZaBgEAZBJkFWwHbQhaCAEAZBJkFmwJbQpaCgEAZBJkF2wLbQxaDG0NWg0BAGQSZBhsAm0OWg5tD1oPbRBaEG0RWhFtEloSbRNaE20UWhRtFVoVAQBkEmQZbBZtF1oXAQBkEmQabBhtGVoZAQBHAGQbZAKEAGQCZRqDA1obZGVkHGQdhAFaHGQeZB+EAFodZCBkIYQAWh5kImQjhABaH2QkZCWEAFogZCZkJ4QAWiFkKGQphABaImRmZCtkLIQBWiNkLWQGhABaJGQuZAOEAFolZC9kBIQAWiZkMGQFhABaJ2QxZAeEAFooZDJkCoQAWilkM2QJhABaKmRnZDVkCIQBWitkNmQLhABaLGQ3ZAyEAFotZDhkOWQ6nAJkO2QPhAJaLmRoZDxkPYQBWi9kaWQ+ZBGEAVowZGpkP2QOhAFaMWRrZEBkEIQBWjJkbGRBZA2EAVozZEJkQ4QAWjRHAGREZAGEAGQBgwJaNXoQZBJkRWw2bTRaNAEAVwBuFgQAZTdrCpABctoBAAEAAQBZAG4CWABlOGRGawKQBHKeZBJkR2wCbTlaOQEAZBJkSGwWbTpaOm07WjttPFo8bT1aPQEAZBJkSWwJbT5aPgEAZBJkE2w/Wj9lNWRKZEuDAlpAZTVkTGRNgwJaQWVAZE4UAGROGwBqJGVAaiRrApACc0x0QoIBZUBkThQAZE4bAGoyZUBqMmsCkAJzZnRCggFkT1pDZUCgRGVDoQFaRWVBoERlQ6EBWkZlOmU7ZgJEAF08WkdlSGRQZUdqOJsAZFGdA4MBAQBlSGVHZUBlQYMCgwEBAGVIZTWgSWVKZUdlRWVGgwOhAYMBAQCQAnGGZFJaS2U6ZTtlPGU9ZgREAF1AWkdlSGRQZUdqOJsAZFOdA4MBAQBlSGVHZUBlS4MCgwEBAGVIZTWgSWVKZUdlRWU+ZUuDAYMDoQGDAQEAkAJx1GRUWktlOmU7ZTxmA0QAXUBaR2VIZFVlR2o4mwBkVp0DgwEBAGVIZUdlS2VAgwKDAQEAZUhlNaBJZUplR2U+ZUuDAWVFgwOhAYMBAQCQA3EkZFdkWIQAWkxlNWRZZFqDAlpNZTVkW2RcgwJaTmRdWk9kT1pDZTWgSWReZF+EAGVNoERlQ6EBRACDAaEBWlBlTGVNZU8XAGVQgwIBAGU1oElkYGRfhABlTaBEZUOhAUQAgwGhAVpQZUxlTWVPGABlUIMCAQBlNaBJZGFkX4QAZU2gRGVDoQFEAIMBoQFaUGVMZU1lTxQAZVCDAgEAZTWgSWRiZF+EAGVNoERlQ6EBRACDAaEBWlBlTGVNZU8bAGVQgwIBAGU1oElkY2RfhABlUWVNoERlQ6EBZU6gRGVDoQGDAkQAgwGhAVpQZUxlTWVOFwBlUIMCAQBlNaBJZGRkX4QAZVFlTaBEZUOhAWVOoERlQ6EBgwJEAIMBoQFaUGVMZU1lThgAZVCDAgEAZUhlP6BSoQCDAQEAZBNTAA== +ZABaAGQBZAJsAVQAZANTAA== +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaA2QBZAJsBFoEZAFkA2wFbQZaBgEAZAFkAmwHWgdlAmoIoAlkAWUBagigCmUBagigC2UMoQGhAaECAQBkAWQEbA1tDloOAQBkAWQCbA9aD2QFZAaEAFoQZRFkB2sCcoBlEIMAAQBkAlMA +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaA2QBZAJsBFoEZAFkAmwFWgVkAWQCbAZaBmQBZAJsB1oIZAFkA2wJbQpaCwEAZAFkBGwMbQ1aDW0OWg4BAGQBZAVsD20QWhBtEVoRbRJaEm0TWhMBAGQBZAJsFFoUZAFkAmwVWhVkAWQCbBZaFmUWoBdlFmoYZAahAgEAZAFkAmwZWhlkB1oaRwBkCGQJhABkCYMCWhtkEWQKZAuEAVocZBJkDGQNhAFaHWQOZR1fHmQPZRxfHmQHZBBnAlofZAJTAA== +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaA2QBZAJsBFoFZAFkA2wGbQdaBwEAZAFkBGwIbQlaCQEAZAFkBWwKbQtaCwEAZAFkAmwMWgxkAWQCbA1aDWUBoA5lAWoPZAahAgEAZAdaEGQIWhFlAmoSoBNkAWUDahKgFGUDahKgFWUWoQGhAaECAQBkAWQCbBdaF2QBZAJsGFoYZAFkAmwZWhlkAWQJbBptG1obAQBlGGocWhxkCmQLZwJaHWQMZA2EAFoeaQBmAWQOZA+EAVofZBJkEGQRhAFaIGQCUwA= +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaA2QDZARnAloERwBkBWQEhABkBGUFgwNaBkcAZAZkA4QAZAODAloHZQhkB2sCclRlCWUHgwCDAQEAZAJTAA== +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaA2UDoARlA2oFZAOhAgEAZQFqBqAHZAFlAmoGoAhlAmoGoAllCqEBoQGhAgEAZAFkAmwLWgtlC2oMWgxkBFoNZAVaDmQCUwA= +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaBGQBZANsBW0GWgZtB1oHAQBkAWQEbAVtCFoIAQBkAWQFbAltCloKAQBkAWQGbAttDFoMAQBlB2QHZQ2DAloOZQJqD6AQZQJqD6ARZRKhAaEBWhNlFGUCag+gEGUCag+gEWUSoQGhAWQIFwBkCYMCjyBaFWUVoBahAKAXoQBaGGUEoBllGKEBZAoZAFoaVwA1AFEAUgBYAGUMoBuhAGQLFwBaHGUKZRxkDGQNZA6NA1odZQ5qHmQPZBBkEY0CZBJkE4QAgwFaH2UOah5kFGQVZBGNAmQWZBeEAIMBWiBlDqAeZBihAWQZZBqEAIMBWiFlDqAeZBuhAWQcZB2EAIMBWiJlDqAeZB6hAWQfZCCEAIMBWiNlDmoeZCFkImcBZCONAmQkZCWEAIMBWiRlDqAeZCahAWQnZCiEAIMBWiVkAlMA +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaBGQBZANsBW0GWgZtB1oHAQBkAWQEbAhtCVoJAQBkAWQCbApaCmQBZAJsC1oLZAFkAmwMWgxkAWQFbA1tDloOAQBkAWQCbA9aD2QBZAJsEFoQZAFkBmwRbRJaEm0TWhNtFFoUAQBlDKAVZQxqFmQHoQIBAGUBahegGGQBZQJqF6AZZQJqF6AaZRuhAaEBoQIBAGQBZAJsHFocZRxqHVodZAhkCWcCWh5kClofZAtaIGQMWiFHAGQNZA6EAGQOgwJaImQXZA9kEIQBWiNkGGQRZBKEAVokZBlkE2QUhAFaJWQaZBVkFoQBWiZkAlMA +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQCbANaBGQBZANsBW0GWgZtB1oHbQhaCG0JWgltCloKAQBkAWQEbAVtC1oLAQBkAWQCbAxaDWQBZAVsDm0PWg8BAGQBZAZsEG0RWhEBAGQBZAdsEm0TWhMBAGQBZAhsFG0VWhVtFloWAQBkAWQJbBdtGFoZAQBlAWoaoBtkAWUCahqgHGUCahqgHWUeoQGhAaECAQBkAWQCbB9aH2QBZAJsIFogZQlkCmUhgwJaImUNoCNlFqAkoQBkCxcAoQFaJWUCahqgHGUCahqgHWUeoQGhAVomZQ+DAFonZSJqKGQMZA1kDo0CZA9kEIQAgwFaKWUiaihkEWQSZA6NAmQTZBSEAIMBWiplIqAoZBWhAWQWZBeEAIMBWitlImooZBhkGWcBZBqNAmQbZByEAIMBWixlIqAoZB2hAWQeZB+EAIMBWi1lIqAoZCChAWQhZCKEAIMBWi5lIqAoZCOhAWQkZCWEAIMBWi9kAlMA +ZABaAGQBZAJsAVoBZAFkAmwCWgJkAWQDbANtBFoEAQBkAWQEbAVtBloGbQdaBwEARwBkBWQGhABkBoMCWghkAlMA +ZABaAGQBZAJsAVoBZQGgAmUBagNkA6ECAQBkAWQCbARaBGQBZAJsBVoFZAFkBGwGbQdaBwEAZQRqCKAJZAFlBWoIoAplBWoIoAtlDKEBoQGhAgEAZAVaDWQBZAZsDm0PWg8BAGQJZAdkCIQBWhBkAlMA +ZABaAGQBZAJsAVoCZAFkAmwDWgRkAWQCbAVaBmQBZAJsB1oIZANkBGcCWglkBVoKZQtaDEcAZAZkB4QAZAdlCGoNag6DA1oPZAtkCmQEhAFaEGQCUwA= +ZABaAGQBZAJsAW0CWgIBAEcAZANkBIQAZARlAoMDWgNkBVMA +ZABaAGQBZAJsAW0CWgIBAGQBZANsA1oDZAFkA2wEWgRkAWQDbAVaBWQBZANsBloGZAFkA2wHWgdkBGQFZwJaCGQGZAWEAFoJZAdkCIQAWgplB2oLagxaDWUHagtqDloPZQagEGQJZQZqEWUGahJCAKECWhNHAGQKZASEAGQEZQRqFIMDWhVkA1MA +ZABaAGQBZAJsAW0CWgIBAGQBZANsA20DWgMBAGQBZARsBG0FWgUBAGQBZAVsBm0HWgcBAGQBZAZsCG0JWgkBAGQBZAdsCm0LWgsBAGQNZQxlDWQJZQ5lC2QKnAVkC2QMhAVaD2QIUwA= +ZABaAGQBZAJsAW0CWgIBAGQBZANsA20EWgQBAGQBZARsA1oDZAVkBmwFbQZaBgEAZAVkB2wFbQdaBwEAZAVkCGwIbQlaCQEAZAVkCWwKbQtaCwEARwBkCmQLhABkC4MCWgxkBFMA +ZABaAGQBZAJsAW0CWgIBAGQBZANsA20EWgQBAGQBZARsBVoFZAFkBWwGbQdaBwEAZAFkBmwIbQlaCQEAZAdkCGwKbQtaC20MWgxtDVoNAQBkCVoOZQ9lD2QKnAJkC2QMhARaEGUOZA1mAmUPZRFlEmQOnANkD2QQhAVaE2UOZgFlD2USZRFlFGQRnARkEmQThAVaFWQbZRZkFJwBZBVkFoQFWhdlGGQXawJyzmUZZBiDAQEAZRFlGmQZgwGDAVobZRlkGmUXZRuDAYMCAQBkBFMA +ZABaAGQBZAJsAW0CWgIBAGQBZANsA20EWgQBAGQBZARsBW0GWgYBAGQBZAVsB20IWggBAGUCckRkAWQGbAltCloKAQBkB2QInAFkCWQKhARaC2QLUwA= +ZABaAGQBZAJsAW0CWgIBAGQBZANsA20EWgQBAGQBZARsBW0GWgZtB1oHAQBkAWQFbAhaCWkAWgpkBmQHhABaC2QFUwA= +ZABaAGQBZAJsAW0CWgIBAGQBZANsA20EWgRtBVoFAQBkAWQEbAZtB1oHAQBkAWQFbAZtCFoIAQBkAWQGbAltCloKAQBkB2QIbAttDFoMAQBHAGQJZAqEAGQKgwJaDUcAZAtkDIQAZAyDAloOZA1TAA== +ZABaAGQBZAJsAW0CWgIBAGQBZANsA20EWgRtBVoFbQZaBgEAZAFkBGwHbQhaCG0JWgkBAGQFUwA= +ZABaAGQBZAJsAW0CWgIBAGUCciBkAWQDbANtBFoEAQBkBGQFnAFkBmQHhARaBWQIUwA= +ZABaAGQBZAJsAW0CWgIBAGUCcixkAWQDbANtBFoEAQBkAWQEbAVtBloGAQBkBWQGZAecAmQIZAmEBFoHZApTAA== +ZABaAGQBZAJsAW0CWgJtA1oDAQBkAWQDbARtBVoFAQBlAnI8ZAFkBGwGbQdaBwEAZAFkBWwIbQlaCQEAZAZkB2UFZAicA2QJZAqEBFoKZQtkB2UDZAYZAGQLnANkDGQNhARaDGQHZA6cAWQPZBCEBFoNZBFTAA== +ZABaAGQBZAJsAW0CWgJtA1oDbQRaBAEAZAFkA2wFbQZaBgEAZQNkBGUHgwJaCGUIoAlkBaEBZQJkBpwBZAdkCIQEgwFaCmUIoAlkCaEBZQJkBpwBZApkC4QEgwFaC2QMUwA= +ZABaAHoYZAFkAmwBbQJaAm0DWgMBAGQDWgRXAG4oBABlBWsKckQBAAEAAQBkAWQCbAZtAloCbQNaAwEAZARaBFkAbgJYAGQFUwA= +ZABkAWwAWgBkAGQCbAFtAloCbQNaAwEAZABkA2wEbQVaBW0GWgYBAGQAZARsB20IWggBAGQAZAVsCW0KWgptC1oLAQBkAGQGbAxtDVoNAQBkAGQHbA5tD1oPAQBHAGQIZAmEAGQJZRCDA1oRRwBkCmQLhABkC2UDahKDA1oTZAFTAA== +ZABkAWwAWgBkAmQDhABaAWQBUwA= +ZABkAWwAbQFaAQEAZABkAmwAbQJaAgEAZABkA2wAbQNaAwEARwBkBGQFhABkBWUEgwNaBUcAZAZkB4QAZAdlBIMDWgZkCFMA +ZABkAWwAbQFaAQEAZABkAmwAbQJaAgEAZABkA2wAbQNaAwEAZABkBGwEbQVaBQEAZAVTAA== +ZABkAWwAbQFaAQEAZABkAmwCVABkAGQDbANtBFoEbQVaBQEAZARkBWwGWgZkBGQFbAdaB2UGagigCWQGoQFzTmUHagpkBBkAZAdrAnJkZABkCGwLbQxaDG0NWg1tDloOAQBuQnoYZABkCGwPbQxaDG0NWg1tDloOAQBXAG4oBABlEGsKcqQBAAEAAQBkAGQIbAttDFoMbQ1aDW0OWg4BAFkAbgJYAGQJZAqEAFoRZAtkDIQAWhJkDWQOhABaE2UTWhRlDVoVZRFaFmUSWhdkBVMA +ZABkAWwAbQFaAQEAZABkAmwCWgJkAGQCbANaA2QAZAJsBFoEZQNqBWQAGQBkA2sCWgZlBnJEZQdlCGYCWglkAloKbjZlB1oJegxlAmoLagxaClcAbiQEAGUNawpyeAEAAQABAGUCoAtlAqAOZAChAaEBWgpZAG4CWABHAGQEZAWEAGQFZQFkBWQGgwKDA1oPRwBkB2QIhABkCGUQgwNaEWQCUwA= +ZABkAWwAbQFaAQEAZABkAmwCbQJaAgEAZABkA2wDbQRaBAEAZABkBGwFWgVkBWQGbAZtB1oHAQBkBFMA +ZABkAWwAbQFaAQEAZABkAmwCbQJaAgEAZABkA2wDbQRaBAEAZABkBGwFbQZaBgEAZABkBWwHWgdkBloIZAdaCUcAZAhkCYQAZAllCoMDWgtHAGQKZAuEAGQLZQuDA1oMRwBkDGQNhABkDWULgwNaDUcAZA5kD4QAZA9lC4MDWg5HAGQQZBGEAGQRZQuDA1oPZRBkEmQTnAJkFGQVhARaEWQWZBeEAFoSZAVTAA== +ZABkAWwAbQFaAQEAZABkAmwCbQNaAwEAZABkA2wEbQVaBW0GWgYBAGQAZARsB20IWggBAGQAZAVsCW0KWgptC1oLAQBkAGQGbAxtDVoNAQBkAGQHbA5tD1oPbRBaEAEAZABkCGwRbRJaEm0TWhMBAGQAZAlsFG0VWhUBAEcAZApkC4QAZAtlCmoWgwNaF2QMUwA= +ZABkAWwAbQFaAQEAZABkAmwCbQNaAwEAZANTAA== +ZABkAWwAbQFaAQEAZABkAmwCbQNaAwEAZAZkBGQFhAFaBGQDUwA= +ZABkAWwAbQFaAQEAZABkAmwCbQNaAwEAZQFkA2QEZAVnAoMCWgRlA2QGZQWDAloGZQNkB2UHgwJaCGUDZAhlBYMCWgllA2QJZQqDAloLZQNkCmUKgwJaDGQLUwA= +ZABkAYQAWgBkAlMA +ZABkAWwAWgBkAGQBbAFaAWQCZAOEAFoCZARkBYQAWgNkAVMA +ZABkAWwAWgBlAWQCnAFkA2QEhARaAmQFZAaEAFoDZAFTAA== diff --git a/static-data/default-plugins/torgossip/commandhandlers.py b/static-data/default-plugins/torgossip/commandhandlers.py new file mode 100644 index 00000000..0f9cd2ec --- /dev/null +++ b/static-data/default-plugins/torgossip/commandhandlers.py @@ -0,0 +1,14 @@ +import blockio + + +def list_blocks_by_type(safe_db, block_type) -> bytes: + try: + return safe_db.get(b'bl-' + block_type) + except KeyError: + return b"" + +def handle_check_block(safe_db, block_hash): + if block_hash in blockio.list_all_blocks(safe_db): + return int(1).to_bytes(1, 'little') + else: + return int(2).to_bytes(1, 'little') diff --git a/static-data/default-plugins/torgossip/commands.py b/static-data/default-plugins/torgossip/commands.py new file mode 100644 index 00000000..e38f1311 --- /dev/null +++ b/static-data/default-plugins/torgossip/commands.py @@ -0,0 +1,27 @@ + +""" +Onionr - Private P2P Communication + +Gossip plugin commands +""" +from enum import IntEnum +""" +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. + +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 . +""" + +class GossipCommands(IntEnum): + PING = 1, + CHECK_HAS_BLOCK = 2, + LIST_BLOCKS_BY_TYPE = 3, + EXIT = 4 diff --git a/static-data/default-plugins/torgossip/info.json b/static-data/default-plugins/torgossip/info.json new file mode 100755 index 00000000..e6212e8e --- /dev/null +++ b/static-data/default-plugins/torgossip/info.json @@ -0,0 +1,5 @@ +{ + "name" : "torgossip", + "version" : "0.0.0", + "author" : "onionr" +} diff --git a/static-data/default-plugins/torgossip/main.py b/static-data/default-plugins/torgossip/main.py index 99dfde81..800085c4 100755 --- a/static-data/default-plugins/torgossip/main.py +++ b/static-data/default-plugins/torgossip/main.py @@ -26,8 +26,8 @@ along with this program. If not, see . plugin_name = 'torgossip' from server import start_server - def on_init(api, data=None): + shared_state = data print("starting gossip transport") - Thread(target=start_server, daemon=True).start() + Thread(target=start_server, daemon=True, args=[shared_state]).start() diff --git a/static-data/default-plugins/torgossip/server.py b/static-data/default-plugins/torgossip/server.py index 1fd9cf8d..d96380e1 100644 --- a/static-data/default-plugins/torgossip/server.py +++ b/static-data/default-plugins/torgossip/server.py @@ -4,11 +4,17 @@ Onionr - Private P2P Communication Gossip plugin server, multiplexing using gevent """ import os +import sys + import selectors import socket +from time import sleep import filepaths +sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) +from commands import GossipCommands # noqa +import commandhandlers """ 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 @@ -25,25 +31,47 @@ along with this program. If not, see . """ -def start_server(): +def start_server(shared_state): sel = selectors.DefaultSelector() def accept(sock, mask): conn, addr = sock.accept() # Should be ready - print('accepted', conn, 'from', addr) conn.setblocking(False) sel.register(conn, selectors.EVENT_READ, read) + def do_close(conn, msg=None): + if msg: + conn.sendall(msg) + sleep(0.1) + sel.unregister(conn) + conn.close() + def read(conn, mask): data = conn.recv(1000) # Should be ready + cmd = None if data: - print('echoing', repr(data), 'to', conn) - conn.send(data) # Hope it won't block + try: + cmd = int(int(data[0]).to_bytes(1, 'little')) + data = data[1:] + except IndexError: + do_close(conn, b'MALFORMED COMMAND') + if cmd == GossipCommands.PING: + conn.sendall(b'PONG') + elif cmd == GossipCommands.EXIT: + do_close(conn, b'BYE') + elif cmd == GossipCommands.LIST_BLOCKS_BY_TYPE: + conn.sendall( + commandhandlers.list_blocks_by_type( + shared_state.get_by_string('SafeDB'), data)) + elif cmd == GossipCommands.CHECK_HAS_BLOCK: + conn.sendall( + commandhandlers.handle_check_block( + shared_state.get_by_string('SafeDB'), data)) + else: + conn.sendall(b'Unknown ' + str(cmd).encode('utf-8')) else: - print('closing', conn) - sel.unregister(conn) - conn.close() + do_close(conn) sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) socket_file = filepaths.identifyhome.identify_home() + "torgossip.sock" diff --git a/static-data/default-plugins/torgossip/server_test.py b/static-data/default-plugins/torgossip/server_test.py new file mode 100644 index 00000000..200c2ee1 --- /dev/null +++ b/static-data/default-plugins/torgossip/server_test.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +import socket +import os + +#home = input("Enter Onionr data directory") +home = "/dev/shm/DATA24688" + +def client(data): + with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: + s.connect(f'{home}/torgossip.sock') + s.sendall(data) + resp = s.recv(1024) + print("\n", resp) + +while True: + print("1. ping") + print('2. check block hash') + print('3 list blocks') + print("4. exit") + inp = input() + if inp == "1": + client(b'1') + elif inp == "3": + client(b"3" + input("type: ").encode('utf8')) + elif inp == "2": + client(b'2' + os.urandom(32)) + elif inp == "3": + client(b'3') diff --git a/static-data/default_config.json b/static-data/default_config.json index fe047199..de1d4486 100755 --- a/static-data/default_config.json +++ b/static-data/default_config.json @@ -49,6 +49,9 @@ "disabled": [], "enabled": [] }, + "security": { + "encrypt_database": false + }, "statistics": { "i_dont_want_privacy": false, "server": "" diff --git a/tests/test_blockio.py b/tests/test_blockio.py index 7461df87..3bd1109f 100644 --- a/tests/test_blockio.py +++ b/tests/test_blockio.py @@ -35,6 +35,24 @@ def _remove_db(path): class TestBlockIO(unittest.TestCase): + def test_list_all_blocks(self): + db_file = identifyhome.identify_home() + 'test.db' + db = safedb.SafeDB(db_file) + expected_l = [] + for i in range(5): + bl = blockcreator.create_anonvdf_block(b"hello" + int(i).to_bytes(1, "big"), b"txt" + int(i).to_bytes(1, "big"), 5) + blockio.store_block(bl, db) + expected_l.append(bl.id) + + l = blockio.load.list_all_blocks(db) + self.assertEqual(len(l), 5) + for i in l: + self.assertIn(bytes(i), expected_l) + + + db.close() + _remove_db(db_file) + def test_clean_blocklist_entries(self): db_file = identifyhome.identify_home() + 'test.db' db = safedb.SafeDB(db_file) @@ -91,7 +109,6 @@ class TestBlockIO(unittest.TestCase): bl = blockcreator.create_anonvdf_block(b'test' + int(i).to_bytes(1, 'big'), 'txt', 60) blockio.store_block(bl, db) expected_list.append(bl.id) - #db.db_conn.sync() l = blockio.list_blocks_by_type('txt', db) self.assertEqual(len(list(l)), len(expected_list)) for i in l: