diff --git a/.gitignore b/.gitignore index 672aadb2..cc6624db 100755 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ core .vscode/* venv/* onionr/fs* +onionr/tmp/* *.dll *.exe @@ -35,4 +36,4 @@ onionr/data/*.log onionr-*.pkg.tar.gz pkg/ src/ -spawnnodes.py \ No newline at end of file +spawnnodes.py diff --git a/README.md b/README.md index d0e9116e..014df08f 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ Everyone is welcome to contribute. Help is wanted for the following: * Creation of a shared lib for use from other languages and faster proof-of-work * Android and IOS development * Windows and Mac support (already partially supported, testers needed) - * General bug fixes and development of new features + * Bug fixes and development of new features * Testing * Translations/localizations * UI/UX design diff --git a/onionr/__init__.py b/onionr/__init__.py index c7439429..610e656f 100755 --- a/onionr/__init__.py +++ b/onionr/__init__.py @@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' + # Set the user's locale for encoding reasons import locale locale.setlocale(locale.LC_ALL, '') diff --git a/onionr/config.py b/onionr/config.py index 89298e40..63086a2c 100755 --- a/onionr/config.py +++ b/onionr/config.py @@ -118,7 +118,7 @@ def reload(): try: with open(get_config_file(), 'r', encoding="utf8") as configfile: set_config(json.loads(configfile.read())) - except: + except (FileNotFoundError, json.JSONDecodeError) as e: pass #logger.debug('Failed to parse configuration file.') diff --git a/onionr/coredb/blockmetadb/expiredblocks.py b/onionr/coredb/blockmetadb/expiredblocks.py index 859abc9d..ac66be66 100644 --- a/onionr/coredb/blockmetadb/expiredblocks.py +++ b/onionr/coredb/blockmetadb/expiredblocks.py @@ -26,10 +26,11 @@ def get_expired_blocks(): c = conn.cursor() date = int(epoch.get_epoch()) - execute = 'SELECT hash FROM hashes WHERE expire <= %s ORDER BY dateReceived;' % (date,) + compiled = (date,) + execute = 'SELECT hash FROM hashes WHERE expire <= ? ORDER BY dateReceived;' rows = list() - for row in c.execute(execute): + for row in c.execute(execute, compiled): for i in row: rows.append(i) conn.close() diff --git a/onionr/coredb/blockmetadb/updateblockinfo.py b/onionr/coredb/blockmetadb/updateblockinfo.py index e32c37c8..d79ebece 100644 --- a/onionr/coredb/blockmetadb/updateblockinfo.py +++ b/onionr/coredb/blockmetadb/updateblockinfo.py @@ -34,12 +34,14 @@ def update_block_info(hash, key, data): dateClaimed - timestamp claimed inside the block, only as trustworthy as the block author is expire - expire date for a block ''' - if key not in ('dateReceived', 'decrypted', 'dataType', 'dataFound', 'dataSaved', 'sig', 'author', 'dateClaimed', 'expire'): - return False + if key not in ('dateReceived', 'decrypted', 'dataType', 'dataFound', + 'dataSaved', 'sig', 'author', 'dateClaimed', 'expire'): + raise ValueError('Key must be in the allowed list') conn = sqlite3.connect(dbfiles.block_meta_db, timeout=30) c = conn.cursor() args = (data, hash) + # Unfortunately, not really possible c.execute("UPDATE hashes SET " + key + " = ? where hash = ?;", args) conn.commit() conn.close() diff --git a/onionr/coredb/daemonqueue/__init__.py b/onionr/coredb/daemonqueue/__init__.py index c0480c01..1ad2e6a2 100644 --- a/onionr/coredb/daemonqueue/__init__.py +++ b/onionr/coredb/daemonqueue/__init__.py @@ -86,10 +86,7 @@ def clear_daemon_queue(): conn = sqlite3.connect(dbfiles.daemon_queue_db, timeout=30) c = conn.cursor() - try: - c.execute('DELETE FROM commands;') - conn.commit() - except: - pass + c.execute('DELETE FROM commands;') + conn.commit() - conn.close() \ No newline at end of file + conn.close() diff --git a/onionr/coredb/keydb/transportinfo.py b/onionr/coredb/keydb/transportinfo.py index cd6739dc..442d0c13 100644 --- a/onionr/coredb/keydb/transportinfo.py +++ b/onionr/coredb/keydb/transportinfo.py @@ -66,7 +66,7 @@ def set_address_info(address, key, data): command = (data, address) if key not in ('address', 'type', 'knownPeer', 'speed', 'success', 'failure', 'powValue', 'lastConnect', 'lastConnectAttempt', 'trust', 'introduced'): - raise Exception("Got invalid database key when setting address info") + raise ValueError("Got invalid database key when setting address info, must be in whitelist") else: c.execute('UPDATE adders SET ' + key + ' = ? WHERE address=?', command) conn.commit() diff --git a/onionr/coredb/keydb/userinfo.py b/onionr/coredb/keydb/userinfo.py index 23ee8b7c..c395f493 100644 --- a/onionr/coredb/keydb/userinfo.py +++ b/onionr/coredb/keydb/userinfo.py @@ -61,9 +61,8 @@ def set_peer_info(peer, key, data): command = (data, peer) - # TODO: validate key on whitelist if key not in ('id', 'name', 'pubkey', 'forwardKey', 'dateSeen', 'trust'): - raise Exception("Got invalid database key when setting peer info") + raise ValueError("Got invalid database key when setting peer info") c.execute('UPDATE peers SET ' + key + ' = ? WHERE id=?', command) conn.commit() diff --git a/onionr/httpapi/apiutils/getblockdata.py b/onionr/httpapi/apiutils/getblockdata.py index 1a8f7df0..7de04a29 100644 --- a/onionr/httpapi/apiutils/getblockdata.py +++ b/onionr/httpapi/apiutils/getblockdata.py @@ -1,12 +1,13 @@ import json import onionrblockapi from onionrutils import bytesconverter, stringvalidators +import onionrexceptions class GetBlockData: def __init__(self, client_api_inst=None): return def get_block_data(self, bHash, decrypt=False, raw=False, headerOnly=False): - assert stringvalidators.validate_hash(bHash) + if not stringvalidators.validate_hash(bHash): raise onionrexceptions.InvalidHexHash("block hash not valid hash format") bl = onionrblockapi.Block(bHash) if decrypt: bl.decrypt() diff --git a/onionr/httpapi/apiutils/setbindip.py b/onionr/httpapi/apiutils/setbindip.py index c9c716f5..cca1705b 100644 --- a/onionr/httpapi/apiutils/setbindip.py +++ b/onionr/httpapi/apiutils/setbindip.py @@ -1,11 +1,28 @@ -import random, socket +import gevent +from gevent import socket, sleep +import secrets, random import config, logger +import os + +# Hacky monkey patch so we can bind random localhosts without gevent trying to switch with an empty hub +socket.getfqdn = lambda n: n + +def _get_acceptable_random_number()->int: + """Return a cryptographically random number in the inclusive range (1, 255)""" + number = 0 + while number == 0: + number = secrets.randbelow(0xFF) + return number + def set_bind_IP(filePath=''): '''Set a random localhost IP to a specified file (intended for private or public API localhost IPs)''' - if config.get('general.random_bind_ip', True): - hostOctets = [str(127), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF))] + hostOctets = [] + for i in range(3): + hostOctets.append(str(_get_acceptable_random_number())) + hostOctets = ['127'] + hostOctets data = '.'.join(hostOctets) + # Try to bind IP. Some platforms like Mac block non normal 127.x.x.x s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: