progress removing onionr.py

This commit is contained in:
Kevin Froman 2019-07-30 00:19:22 -05:00
parent 802af58d46
commit 453e8588c5
17 changed files with 164 additions and 64 deletions

1
.gitignore vendored
View File

@ -33,3 +33,4 @@ onionr/data/*.log
onionr-*.pkg.tar.gz onionr-*.pkg.tar.gz
pkg/ pkg/
src/ src/
spawnnodes.py

View File

@ -0,0 +1,63 @@
#!/usr/bin/env python3
'''
Onionr - Private P2P Communication
This file initializes Onionr when ran to be a daemon or with commands
Run with 'help' for usage.
'''
'''
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 <https://www.gnu.org/licenses/>.
'''
# Set the user's locale for encoding reasons
import locale
locale.setlocale(locale.LC_ALL, '')
# Import standard libraries
import sys
# 3rd party lib imports
# Ensure that PySocks is installed
try:
from urllib3.contrib.socks import SOCKSProxyManager
except ImportError:
raise ImportError("You need the PySocks module (for use with socks5 proxy to use Tor)")
# Onionr imports
from etc import onionrvalues # For different Onionr related constants such as versions
from onionr import setup
# Ensure we have at least the minimum python version
if sys.version_info[0] == 2 or sys.version_info[1] < onionrvalues.MIN_PY_VERSION:
sys.stderr.write('Error, Onionr requires Python 3.%s+\n' % (onionrvalues.MIN_PY_VERSION,))
sys.exit(1)
# Ensure Python interpreter is not optimized TODO: Remove asserts and replace with ifs
from utils import detectoptimization
if detectoptimization.detect_optimization():
sys.stderr.write('Error, Onionr cannot be run with an optimized Python interpreter\n')
sys.exit(1)
# Create Onionr data directories, must be done before most imports
from utils import createdirs
createdirs.create_dirs()
setup.setup_config()
setup.setup_default_plugins()
def onionr_main():
return
if __name__ == "__main__":
onionr_main()

View File

@ -19,6 +19,11 @@
''' '''
DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA====" DENIABLE_PEER_ADDRESS = "OVPCZLOXD6DC5JHX4EQ3PSOGAZ3T24F75HQLIUZSDSMYPEOXCPFA===="
PASSWORD_LENGTH = 25 PASSWORD_LENGTH = 25
ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net'
ONIONR_VERSION = '0.0.0' # for debugging and stuff
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
API_VERSION = '0' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
MIN_PY_VERSION = 6
class OnionrValues: class OnionrValues:
def __init__(self): def __init__(self):
self.passwordLength = 20 self.passwordLength = 20

View File

@ -18,7 +18,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import onionrplugins import onionrplugins
API_VERSION = 0
def load_plugin_blueprints(flaskapp, blueprint='flask_blueprint'): def load_plugin_blueprints(flaskapp, blueprint='flask_blueprint'):
'''Iterate enabled plugins and load any http endpoints they have''' '''Iterate enabled plugins and load any http endpoints they have'''
for plugin in onionrplugins.get_enabled_plugins(): for plugin in onionrplugins.get_enabled_plugins():

View File

@ -21,11 +21,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import sys import sys
ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net' from etc import onionrvalues
ONIONR_VERSION = '0.0.0' # for debugging and stuff
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
API_VERSION = '0' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
MIN_PY_VERSION = 6
if sys.version_info[0] == 2 or sys.version_info[1] < MIN_PY_VERSION: if sys.version_info[0] == 2 or sys.version_info[1] < MIN_PY_VERSION:
sys.stderr.write('Error, Onionr requires Python 3.%s+\n' % (MIN_PY_VERSION,)) sys.stderr.write('Error, Onionr requires Python 3.%s+\n' % (MIN_PY_VERSION,))
sys.exit(1) sys.exit(1)
@ -58,7 +54,7 @@ class Onionr:
Main Onionr class. This is for the CLI program, and does not handle much of the logic. Main Onionr class. This is for the CLI program, and does not handle much of the logic.
In general, external programs and plugins should not use this class. In general, external programs and plugins should not use this class.
''' '''
self.API_VERSION = API_VERSION self.API_VERSION = onionrvalues.API_VERSION
self.userRunDir = os.getcwd() # Directory user runs the program from self.userRunDir = os.getcwd() # Directory user runs the program from
self.killed = False self.killed = False
self.config = config self.config = config
@ -118,7 +114,7 @@ class Onionr:
randomPort = netcontroller.get_open_port() randomPort = netcontroller.get_open_port()
config.set('client.public.port', randomPort, savefile=True) config.set('client.public.port', randomPort, savefile=True)
if type(config.get('client.api_version')) is type(None): if type(config.get('client.api_version')) is type(None):
config.set('client.api_version', API_VERSION, savefile=True) config.set('client.api_version', onionrvalues.API_VERSION, savefile=True)
self.cmds = commands.get_commands(self) self.cmds = commands.get_commands(self)
self.cmdhelp = commands.cmd_help self.cmdhelp = commands.cmd_help
@ -140,9 +136,6 @@ class Onionr:
def exitSigterm(self, signum, frame): def exitSigterm(self, signum, frame):
self.killed = True self.killed = True
def setupConfig(self):
return setupconfig.setup_config(self)
def cmdHeader(self): def cmdHeader(self):
if len(sys.argv) >= 3: if len(sys.argv) >= 3:
self.header(logger.colors.fg.pink + sys.argv[2].replace('Onionr', logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink)) self.header(logger.colors.fg.pink + sys.argv[2].replace('Onionr', logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink))
@ -155,15 +148,6 @@ class Onionr:
else: else:
self.header(None) self.header(None)
def header(self, message = logger.colors.fg.pink + logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink + ' has started.'):
if os.path.exists('static-data/header.txt') and logger.get_level() <= logger.LEVEL_INFO:
with open('static-data/header.txt', 'rb') as file:
# only to stdout, not file or log or anything
sys.stderr.write(file.read().decode().replace('P', logger.colors.fg.pink).replace('W', logger.colors.reset + logger.colors.bold).replace('G', logger.colors.fg.green).replace('\n', logger.colors.reset + '\n').replace('B', logger.colors.bold).replace('A', '%s' % API_VERSION).replace('V', ONIONR_VERSION))
if not message is None:
logger.info(logger.colors.fg.lightgreen + '-> ' + str(message) + logger.colors.reset + logger.colors.fg.lightgreen + ' <-\n', terminal=True)
def doExport(self, bHash): def doExport(self, bHash):
exportDir = self.dataDir + 'block-export/' exportDir = self.dataDir + 'block-export/'
if not os.path.exists(exportDir): if not os.path.exists(exportDir):
@ -185,37 +169,10 @@ class Onionr:
except FileNotFoundError: except FileNotFoundError:
pass pass
def get_hostname(self):
try:
with open(self.dataDir + 'hs/hostname', 'r') as hostname:
return hostname.read().strip()
except FileNotFoundError:
return "Not Generated"
except Exception:
return None
def getConsoleWidth(self):
'''
Returns an integer, the width of the terminal/cmd window
'''
columns = 80
try:
columns = int(os.popen('stty size', 'r').read().split()[1])
except:
# if it errors, it's probably windows, so default to 80.
pass
return columns
''' '''
Handle command line commands Handle command line commands
''' '''
def exportBlock(self):
commands.exportblocks.export_block(self)
def showDetails(self): def showDetails(self):
commands.onionrstatistics.show_details(self) commands.onionrstatistics.show_details(self)
@ -303,9 +260,9 @@ class Onionr:
Displays the Onionr version Displays the Onionr version
''' '''
function('Onionr v%s (%s) (API v%s)' % (ONIONR_VERSION, platform.machine(), API_VERSION), terminal=True) function('Onionr v%s (%s) (API v%s)' % (onionrvalues.ONIONR_VERSION, platform.machine(), onionrvalues.API_VERSION), terminal=True)
if verbosity >= 1: if verbosity >= 1:
function(ONIONR_TAGLINE, terminal=True) function(onionrvalues.ONIONR_TAGLINE, terminal=True)
if verbosity >= 2: if verbosity >= 2:
function('Running on %s %s' % (platform.platform(), platform.release()), terminal=True) function('Running on %s %s' % (platform.platform(), platform.release()), terminal=True)
function('Onionr data dir: %s' % self.dataDir) function('Onionr data dir: %s' % self.dataDir)

View File

@ -27,7 +27,7 @@ from onionrutils import localcommand
import filepaths import filepaths
from coredb import daemonqueue from coredb import daemonqueue
from onionrcrypto import getourkeypair from onionrcrypto import getourkeypair
from utils import hastor from utils import hastor, logoheader
def _proper_shutdown(o_inst): def _proper_shutdown(o_inst):
localcommand.local_command('shutdown') localcommand.local_command('shutdown')
@ -62,7 +62,7 @@ def daemon(o_inst):
logger.raw('', terminal=True) logger.raw('', terminal=True)
# print nice header thing :) # print nice header thing :)
if o_inst.config.get('general.display_header', True): if o_inst.config.get('general.display_header', True):
o_inst.header() logoheader.header()
o_inst.version(verbosity = 5, function = logger.info) o_inst.version(verbosity = 5, function = logger.info)
logger.debug('Python version %s' % platform.python_version()) logger.debug('Python version %s' % platform.python_version())

View File

@ -22,14 +22,14 @@ import logger, onionrstorage
from utils import createdirs from utils import createdirs
from onionrutils import stringvalidators from onionrutils import stringvalidators
import filepaths import filepaths
def doExport(o_inst, bHash): def doExport(bHash):
createdirs.create_dirs() createdirs.create_dirs()
data = onionrstorage.getData(bHash) data = onionrstorage.getData(bHash)
with open('%s/%s.dat' % (filepaths.export_location, bHash), 'wb') as exportFile: with open('%s/%s.dat' % (filepaths.export_location, bHash), 'wb') as exportFile:
exportFile.write(data) exportFile.write(data)
logger.info('Block exported as file', terminal=True) logger.info('Block exported as file', terminal=True)
def export_block(o_inst): def export_block():
exportDir = filepaths.export_location exportDir = filepaths.export_location
try: try:
assert stringvalidators.validate_hash(sys.argv[2]) assert stringvalidators.validate_hash(sys.argv[2])
@ -38,4 +38,4 @@ def export_block(o_inst):
sys.exit(1) sys.exit(1)
else: else:
bHash = sys.argv[2] bHash = sys.argv[2]
doExport(o_inst, bHash) doExport(bHash)

View File

@ -22,7 +22,7 @@ import logger
from onionrblockapi import Block from onionrblockapi import Block
import onionr import onionr
from onionrutils import checkcommunicator, mnemonickeys from onionrutils import checkcommunicator, mnemonickeys
from utils import sizeutils from utils import sizeutils, gethostname, getconsolewidth
from coredb import blockmetadb, daemonqueue, keydb from coredb import blockmetadb, daemonqueue, keydb
import onionrcrypto import onionrcrypto
def show_stats(o_inst): def show_stats(o_inst):
@ -60,7 +60,7 @@ def show_stats(o_inst):
# pre-processing # pre-processing
maxlength = 0 maxlength = 0
width = o_inst.getConsoleWidth() width = getconsolewidth.get_console_width()
for key, val in messages.items(): for key, val in messages.items():
if not (type(val) is bool and val is True): if not (type(val) is bool and val is True):
maxlength = max(len(key), maxlength) maxlength = max(len(key), maxlength)
@ -86,7 +86,7 @@ def show_stats(o_inst):
def show_details(o_inst): def show_details(o_inst):
details = { details = {
'Node Address' : o_inst.get_hostname(), 'Node Address' : gethostname.get_hostname(),
'Web Password' : o_inst.getWebPassword(), 'Web Password' : o_inst.getWebPassword(),
'Public Key' : onionrcrypto.pub_key, 'Public Key' : onionrcrypto.pub_key,
'Human-readable Public Key' : mnemonickeys.get_human_readable_ID() 'Human-readable Public Key' : mnemonickeys.get_human_readable_ID()

View File

@ -19,7 +19,7 @@
''' '''
import requests, streamedrequests import requests, streamedrequests
import logger, onionrexceptions import logger, onionrexceptions
import httpapi from etc import onionrvalues
def do_post_request(onionr_inst, url, data={}, port=0, proxyType='tor', max_size=10000): def do_post_request(onionr_inst, url, data={}, port=0, proxyType='tor', max_size=10000):
''' '''
Do a POST request through a local tor or i2p instance Do a POST request through a local tor or i2p instance
@ -49,7 +49,7 @@ def do_get_request(url, port=0, proxyType='tor', ignoreAPI=False, returnHeaders=
''' '''
Do a get request through a local tor or i2p instance Do a get request through a local tor or i2p instance
''' '''
API_VERSION = httpapi.API_VERSION API_VERSION = onionrvalues.API_VERSION
retData = False retData = False
if proxyType == 'tor': if proxyType == 'tor':
if port == 0: if port == 0:

3
onionr/setup/__init__.py Normal file
View File

@ -0,0 +1,3 @@
from . import defaultpluginsetup, setupconfig
setup_default_plugins = defaultpluginsetup.setup_default_plugins
setup_config = setupconfig.setup_config

View File

@ -0,0 +1,21 @@
import os, shutil
import onionrplugins as plugins, logger
def setup_default_plugins():
# Copy default plugins into plugins folder
if not os.path.exists(plugins.get_plugins_folder()):
if os.path.exists('static-data/default-plugins/'):
names = [f for f in os.listdir("static-data/default-plugins/")]
shutil.copytree('static-data/default-plugins/', plugins.get_plugins_folder())
# Enable plugins
for name in names:
if not name in plugins.get_enabled_plugins():
plugins.enable(name)
for name in plugins.get_enabled_plugins():
if not os.path.exists(plugins.get_plugin_data_folder(name)):
try:
os.mkdir(plugins.get_plugin_data_folder(name))
except Exception as e:
#logger.warn('Error enabling plugin: ' + str(e), terminal=True)
plugins.disable(name, stop_event = False)

View File

@ -17,8 +17,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import os, json import os, json, base64
import config, logger import config, logger, netcontroller
from etc import onionrvalues
from logger.settings import * from logger.settings import *
def setup_config(o_inst = None): def setup_config(o_inst = None):
@ -77,4 +78,15 @@ def setup_config(o_inst = None):
if verbosity in map: if verbosity in map:
set_level(map[verbosity]) set_level(map[verbosity])
else: else:
logger.warn('Verbosity level %s is not valid, using default verbosity.' % verbosity) logger.warn('Verbosity level %s is not valid, using default verbosity.' % verbosity)
if type(config.get('client.webpassword')) is type(None):
config.set('client.webpassword', base64.b16encode(os.urandom(32)).decode('utf-8'), savefile=True)
if type(config.get('client.client.port')) is type(None):
randomPort = netcontroller.get_open_port()
config.set('client.client.port', randomPort, savefile=True)
if type(config.get('client.public.port')) is type(None):
randomPort = netcontroller.get_open_port()
config.set('client.public.port', randomPort, savefile=True)
if type(config.get('client.api_version')) is type(None):
config.set('client.api_version', onionrvalues.API_VERSION, savefile=True)

View File

@ -18,7 +18,7 @@ P ::: :::: ::::::: :::: :::: W:: :: :: ::: :: :: :: :: :::: :::::
P ::: ::::: :::::: :::: :::: W:: :: :: ::: :: :: :: :: ::: :: ::: P ::: ::::: :::::: :::: :::: W:: :: :: ::: :: :: :: :: ::: :: :::
P :::: ::::: ::::: ::: W :::: :: :: :: ::::: :: :: :: :: P :::: ::::: ::::: ::: W :::: :: :: :: ::::: :: :: :: ::
P :::: :::::: :::::: :::: P :::: :::::: :::::: ::::
P :::: :::::::::::: :::: GvPBV P :::: :::::::::::: :::: GPB
P ::::: :::::::: :::: P ::::: :::::::: ::::
P ::::: ::::: P ::::: :::::
P :::::::::::::::: P ::::::::::::::::

View File

@ -0,0 +1,15 @@
import os
def get_console_width():
'''
Returns an integer, the width of the terminal/cmd window
'''
columns = 80
try:
columns = int(os.popen('stty size', 'r').read().split()[1])
except:
# if it errors, it's probably windows, so default to 80.
pass
return columns

View File

@ -0,0 +1,10 @@
from . import identifyhome
import filepaths
def get_hostname():
try:
with open(identifyhome.identify_home() + '/hs/hostname', 'r') as hostname:
return hostname.read().strip()
except FileNotFoundError:
return "Not Generated"
except Exception:
return None

View File

@ -0,0 +1,12 @@
import sys, os
from . import readstatic
import logger
def header(message = logger.colors.fg.pink + logger.colors.bold + 'Onionr' + logger.colors.reset + logger.colors.fg.pink + ' has started.'):
header_path = readstatic.get_static_dir() + 'header.txt'
if os.path.exists(header_path) and logger.settings.get_level() <= logger.settings.LEVEL_INFO:
with open(header_path, 'rb') as file:
# only to stdout, not file or log or anything
sys.stderr.write(file.read().decode().replace('P', logger.colors.fg.pink).replace('W', logger.colors.reset + logger.colors.bold).replace('G', logger.colors.fg.green).replace('\n', logger.colors.reset + '\n').replace('B', logger.colors.bold))
if not message is None:
logger.info(logger.colors.fg.lightgreen + '-> ' + str(message) + logger.colors.reset + logger.colors.fg.lightgreen + ' <-\n', terminal=True)

View File

@ -1,6 +1,8 @@
import os import os
def get_static_dir():
return os.path.dirname(os.path.realpath(__file__)) + '/../static-data/'
def read_static(file, ret_bin=False): def read_static(file, ret_bin=False):
static_file = os.path.dirname(os.path.realpath(__file__)) + '/../static-data/' + file static_file = get_static_dir() + file
if ret_bin: if ret_bin:
mode = 'rb' mode = 'rb'