commit
3667ae0e68
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@ __pycache__/
|
|||||||
onionr/data/config.ini
|
onionr/data/config.ini
|
||||||
onionr/data/*.db
|
onionr/data/*.db
|
||||||
onionr/data-old/*
|
onionr/data-old/*
|
||||||
|
onionr/*.pyc
|
||||||
|
onionr/*.log
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import flask
|
import flask
|
||||||
from flask import request, Response, abort
|
from flask import request, Response, abort
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
import configparser, sys, random, threading, hmac, hashlib, base64, time, math, gnupg, os
|
import configparser, sys, random, threading, hmac, hashlib, base64, time, math, gnupg, os, logging
|
||||||
|
|
||||||
from core import Core
|
from core import Core
|
||||||
import onionrutils
|
import onionrutils
|
||||||
@ -42,10 +42,13 @@ class API:
|
|||||||
This also saves the used host (random localhost IP address) to the data folder in host.txt
|
This also saves the used host (random localhost IP address) to the data folder in host.txt
|
||||||
'''
|
'''
|
||||||
if os.path.exists('dev-enabled'):
|
if os.path.exists('dev-enabled'):
|
||||||
print('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
|
|
||||||
self._developmentMode = True
|
self._developmentMode = True
|
||||||
|
logger.set_level(logger.LEVEL_DEBUG)
|
||||||
|
logger.warn('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
|
||||||
else:
|
else:
|
||||||
self._developmentMode = False
|
self._developmentMode = False
|
||||||
|
logger.set_level(logger.LEVEL_INFO)
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self._privateDelayTime = 3
|
self._privateDelayTime = 3
|
||||||
@ -55,13 +58,13 @@ class API:
|
|||||||
bindPort = int(self.config['CLIENT']['PORT'])
|
bindPort = int(self.config['CLIENT']['PORT'])
|
||||||
self.bindPort = bindPort
|
self.bindPort = bindPort
|
||||||
self.clientToken = self.config['CLIENT']['CLIENT HMAC']
|
self.clientToken = self.config['CLIENT']['CLIENT HMAC']
|
||||||
print(self.clientToken)
|
logger.debug('Your HMAC token: ' + logger.colors.underline + self.clientToken)
|
||||||
|
|
||||||
if not debug and not self._developmentMode:
|
if not debug and not self._developmentMode:
|
||||||
hostNums = [random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)]
|
hostNums = [random.randint(1, 255), random.randint(1, 255), random.randint(1, 255)]
|
||||||
self.host = '127.' + str(hostNums[0]) + '.' + str(hostNums[1]) + '.' + str(hostNums[2])
|
self.host = '127.' + str(hostNums[0]) + '.' + str(hostNums[1]) + '.' + str(hostNums[2])
|
||||||
else:
|
else:
|
||||||
self.host = '127.0.0.1'
|
self.host = '127.0.0.1'
|
||||||
hostFile = open('data/host.txt', 'w')
|
hostFile = open('data/host.txt', 'w')
|
||||||
hostFile.write(self.host)
|
hostFile.write(self.host)
|
||||||
hostFile.close()
|
hostFile.close()
|
||||||
@ -80,11 +83,11 @@ class API:
|
|||||||
resp.headers['Access-Control-Allow-Origin'] = '*'
|
resp.headers['Access-Control-Allow-Origin'] = '*'
|
||||||
else:
|
else:
|
||||||
resp.headers['server'] = 'Onionr'
|
resp.headers['server'] = 'Onionr'
|
||||||
resp.headers['content-type'] = 'text/plain'
|
resp.headers['Content-Type'] = 'text/plain'
|
||||||
resp.headers["Content-Security-Policy"] = "default-src 'none'"
|
resp.headers["Content-Security-Policy"] = "default-src 'none'"
|
||||||
resp.headers['x-frame-options'] = 'deny'
|
resp.headers['X-Frame-Options'] = 'deny'
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
@app.route('/client/')
|
@app.route('/client/')
|
||||||
def private_handler():
|
def private_handler():
|
||||||
startTime = math.floor(time.time())
|
startTime = math.floor(time.time())
|
||||||
@ -101,7 +104,7 @@ class API:
|
|||||||
request.environ.get('werkzeug.server.shutdown')()
|
request.environ.get('werkzeug.server.shutdown')()
|
||||||
resp = Response('Goodbye')
|
resp = Response('Goodbye')
|
||||||
elif action == 'stats':
|
elif action == 'stats':
|
||||||
resp = Response('something')
|
resp = Response('me_irl')
|
||||||
elif action == 'init':
|
elif action == 'init':
|
||||||
# generate PGP key
|
# generate PGP key
|
||||||
self._core.generateMainPGP()
|
self._core.generateMainPGP()
|
||||||
@ -156,17 +159,17 @@ class API:
|
|||||||
resp = Response("Invalid request")
|
resp = Response("Invalid request")
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
print('Starting client on ' + self.host + ':' + str(bindPort))
|
logger.info('Starting client on ' + self.host + ':' + str(bindPort) + '...')
|
||||||
print('Client token:', self.clientToken)
|
logger.debug('Client token: ' + logger.colors.underline + self.clientToken)
|
||||||
|
|
||||||
app.run(host=self.host, port=bindPort, debug=True, threaded=True)
|
app.run(host=self.host, port=bindPort, debug=True, threaded=True)
|
||||||
|
|
||||||
def validateHost(self, hostType):
|
def validateHost(self, hostType):
|
||||||
''' Validate various features of the request including:
|
''' Validate various features of the request including:
|
||||||
If private (/client/), is the host header local?
|
If private (/client/), is the host header local?
|
||||||
If public (/public/), is the host header onion or i2p?
|
If public (/public/), is the host header onion or i2p?
|
||||||
|
|
||||||
Was x-request-with used?
|
Was X-Request-With used?
|
||||||
'''
|
'''
|
||||||
if self.debug:
|
if self.debug:
|
||||||
return
|
return
|
||||||
@ -181,7 +184,8 @@ class API:
|
|||||||
# Validate x-requested-with, to protect against CSRF/metadata leaks
|
# Validate x-requested-with, to protect against CSRF/metadata leaks
|
||||||
if not self._developmentMode:
|
if not self._developmentMode:
|
||||||
try:
|
try:
|
||||||
request.headers['x-requested-with']
|
request.headers['X-Requested-With']
|
||||||
except:
|
except:
|
||||||
# we exit rather than abort to avoid fingerprinting
|
# we exit rather than abort to avoid fingerprinting
|
||||||
sys.exit(1)
|
logger.debug('Avoiding fingerprinting, exiting...')
|
||||||
|
sys.exit(1)
|
||||||
|
@ -19,7 +19,7 @@ and code to operate as a daemon, getting commands from the command queue databas
|
|||||||
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 sqlite3, requests, hmac, hashlib, time, sys, os
|
import sqlite3, requests, hmac, hashlib, time, sys, os, logger
|
||||||
import core
|
import core
|
||||||
class OnionrCommunicate:
|
class OnionrCommunicate:
|
||||||
def __init__(self, debug, developmentMode):
|
def __init__(self, debug, developmentMode):
|
||||||
@ -30,8 +30,7 @@ class OnionrCommunicate:
|
|||||||
self._core = core.Core()
|
self._core = core.Core()
|
||||||
blockProcessTimer = 0
|
blockProcessTimer = 0
|
||||||
blockProcessAmount = 5
|
blockProcessAmount = 5
|
||||||
if debug:
|
logger.debug('Communicator debugging enabled.')
|
||||||
print('Communicator debugging enabled')
|
|
||||||
torID = open('data/hs/hostname').read()
|
torID = open('data/hs/hostname').read()
|
||||||
|
|
||||||
# get our own PGP fingerprint
|
# get our own PGP fingerprint
|
||||||
@ -40,7 +39,7 @@ class OnionrCommunicate:
|
|||||||
self._core.generateMainPGP(torID)
|
self._core.generateMainPGP(torID)
|
||||||
with open(fingerprintFile,'r') as f:
|
with open(fingerprintFile,'r') as f:
|
||||||
self.pgpOwnFingerprint = f.read()
|
self.pgpOwnFingerprint = f.read()
|
||||||
print('My PGP fingerprint is ' + self.pgpOwnFingerprint)
|
logger.info('My PGP fingerprint is ' + logger.colors.underline + self.pgpOwnFingerprint + logger.colors.reset + logger.colors.fg.green + '.')
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
command = self._core.daemonQueue()
|
command = self._core.daemonQueue()
|
||||||
@ -51,11 +50,10 @@ class OnionrCommunicate:
|
|||||||
self.lookupBlocks()
|
self.lookupBlocks()
|
||||||
self._core.processBlocks()
|
self._core.processBlocks()
|
||||||
blockProcessTimer = 0
|
blockProcessTimer = 0
|
||||||
if debug:
|
logger.debug('Communicator daemon heartbeat')
|
||||||
print('Communicator daemon heartbeat')
|
|
||||||
if command != False:
|
if command != False:
|
||||||
if command[0] == 'shutdown':
|
if command[0] == 'shutdown':
|
||||||
print('Daemon recieved exit command.')
|
logger.warn('Daemon recieved exit command.')
|
||||||
break
|
break
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return
|
return
|
||||||
@ -94,11 +92,11 @@ class OnionrCommunicate:
|
|||||||
# skip hash if it isn't valid
|
# skip hash if it isn't valid
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
print('adding', i, 'to hash database')
|
logger.debug('Adding ' + i + ' to hash database...')
|
||||||
self._core.addToBlockDB(i)
|
self._core.addToBlockDB(i)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def performGet(self, action, peer, data=None, type='tor'):
|
def performGet(self, action, peer, data=None, type='tor'):
|
||||||
'''performs a request to a peer through Tor or i2p (currently only tor)'''
|
'''performs a request to a peer through Tor or i2p (currently only tor)'''
|
||||||
if not peer.endswith('.onion') and not peer.endswith('.onion/'):
|
if not peer.endswith('.onion') and not peer.endswith('.onion/'):
|
||||||
@ -114,7 +112,7 @@ class OnionrCommunicate:
|
|||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
return False
|
return False
|
||||||
return r.text
|
return r.text
|
||||||
|
|
||||||
|
|
||||||
shouldRun = False
|
shouldRun = False
|
||||||
debug = False
|
debug = False
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
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 sqlite3, os, sys, time, math, gnupg, base64, tarfile, getpass, simplecrypt, hashlib, nacl
|
import sqlite3, os, sys, time, math, gnupg, base64, tarfile, getpass, simplecrypt, hashlib, nacl, logger
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
from Crypto import Random
|
from Crypto import Random
|
||||||
import netcontroller
|
import netcontroller
|
||||||
@ -26,7 +26,7 @@ if sys.version_info < (3, 6):
|
|||||||
try:
|
try:
|
||||||
import sha3
|
import sha3
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
sys.stderr.write('On Python 3 versions prior to 3.6.x, you need the sha3 module')
|
logger.fatal('On Python 3 versions prior to 3.6.x, you need the sha3 module')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
@ -66,7 +66,7 @@ class Core:
|
|||||||
conn = sqlite3.connect(self.peerDB)
|
conn = sqlite3.connect(self.peerDB)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
t = (peerID, name, 'unknown')
|
t = (peerID, name, 'unknown')
|
||||||
c.execute('Insert into peers (id, name, dateSeen) values(?, ?, ?);', t)
|
c.execute('insert into peers (id, name, dateSeen) values(?, ?, ?);', t)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
return True
|
return True
|
||||||
@ -295,4 +295,3 @@ class Core:
|
|||||||
for i in row:
|
for i in row:
|
||||||
retData += i
|
retData += i
|
||||||
return retData
|
return retData
|
||||||
|
|
153
onionr/logger.py
Normal file
153
onionr/logger.py
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
'''
|
||||||
|
Onionr - P2P Microblogging Platform & Social network
|
||||||
|
|
||||||
|
This file handles all operations involving logging
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
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/>.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
class colors:
|
||||||
|
'''
|
||||||
|
This class allows you to set the color if ANSI codes are supported
|
||||||
|
'''
|
||||||
|
reset='\033[0m'
|
||||||
|
bold='\033[01m'
|
||||||
|
disable='\033[02m'
|
||||||
|
underline='\033[04m'
|
||||||
|
reverse='\033[07m'
|
||||||
|
strikethrough='\033[09m'
|
||||||
|
invisible='\033[08m'
|
||||||
|
italics='\033[3m'
|
||||||
|
class fg:
|
||||||
|
black='\033[30m'
|
||||||
|
red='\033[31m'
|
||||||
|
green='\033[32m'
|
||||||
|
orange='\033[33m'
|
||||||
|
blue='\033[34m'
|
||||||
|
purple='\033[35m'
|
||||||
|
cyan='\033[36m'
|
||||||
|
lightgrey='\033[37m'
|
||||||
|
darkgrey='\033[90m'
|
||||||
|
lightred='\033[91m'
|
||||||
|
lightgreen='\033[92m'
|
||||||
|
yellow='\033[93m'
|
||||||
|
lightblue='\033[94m'
|
||||||
|
pink='\033[95m'
|
||||||
|
lightcyan='\033[96m'
|
||||||
|
class bg:
|
||||||
|
black='\033[40m'
|
||||||
|
red='\033[41m'
|
||||||
|
green='\033[42m'
|
||||||
|
orange='\033[43m'
|
||||||
|
blue='\033[44m'
|
||||||
|
purple='\033[45m'
|
||||||
|
cyan='\033[46m'
|
||||||
|
lightgrey='\033[47m'
|
||||||
|
@staticmethod
|
||||||
|
def filter(data):
|
||||||
|
return re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]').sub('', str(data))
|
||||||
|
|
||||||
|
'''
|
||||||
|
Use the bitwise operators to merge these settings
|
||||||
|
'''
|
||||||
|
USE_ANSI = 0b100
|
||||||
|
OUTPUT_TO_CONSOLE = 0b010
|
||||||
|
OUTPUT_TO_FILE = 0b001
|
||||||
|
|
||||||
|
LEVEL_DEBUG = 1
|
||||||
|
LEVEL_INFO = 2
|
||||||
|
LEVEL_WARN = 3
|
||||||
|
LEVEL_ERROR = 4
|
||||||
|
LEVEL_FATAL = 5
|
||||||
|
|
||||||
|
_type = OUTPUT_TO_CONSOLE | USE_ANSI # the default settings for logging
|
||||||
|
_level = LEVEL_DEBUG # the lowest level to log
|
||||||
|
_outputfile = './output.log' # the file to log to
|
||||||
|
|
||||||
|
'''
|
||||||
|
Set the settings for the logger using bitwise operators
|
||||||
|
'''
|
||||||
|
def set_settings(type):
|
||||||
|
global _type
|
||||||
|
_type = type
|
||||||
|
|
||||||
|
'''
|
||||||
|
Get settings from the logger
|
||||||
|
'''
|
||||||
|
def get_settings():
|
||||||
|
return _type
|
||||||
|
|
||||||
|
'''
|
||||||
|
Set the lowest log level to output
|
||||||
|
'''
|
||||||
|
def set_level(level):
|
||||||
|
global _level
|
||||||
|
_level = level
|
||||||
|
|
||||||
|
'''
|
||||||
|
Get the lowest log level currently being outputted
|
||||||
|
'''
|
||||||
|
def get_level():
|
||||||
|
return _level
|
||||||
|
|
||||||
|
'''
|
||||||
|
Outputs raw data to console without formatting
|
||||||
|
'''
|
||||||
|
def raw(data):
|
||||||
|
if get_settings() & OUTPUT_TO_CONSOLE:
|
||||||
|
print(data)
|
||||||
|
if get_settings() & OUTPUT_TO_FILE:
|
||||||
|
with open(_outputfile, "a+") as f:
|
||||||
|
f.write(colors.filter(data) + '\n')
|
||||||
|
|
||||||
|
'''
|
||||||
|
Logs the data
|
||||||
|
prefix : The prefix to the output
|
||||||
|
data : The actual data to output
|
||||||
|
color : The color to output before the data
|
||||||
|
'''
|
||||||
|
def log(prefix, data, color = ''):
|
||||||
|
output = colors.reset + str(color) + '[' + colors.bold + str(prefix) + colors.reset + str(color) + '] ' + str(data) + colors.reset
|
||||||
|
if not get_settings() & USE_ANSI:
|
||||||
|
output = colors.filter(output)
|
||||||
|
|
||||||
|
raw(output)
|
||||||
|
|
||||||
|
# debug: when there is info that could be useful for debugging purposes only
|
||||||
|
def debug(data):
|
||||||
|
if get_level() <= LEVEL_DEBUG:
|
||||||
|
log('/', data)
|
||||||
|
|
||||||
|
# info: when there is something to notify the user of, such as the success of a process
|
||||||
|
def info(data):
|
||||||
|
if get_level() <= LEVEL_INFO:
|
||||||
|
log('+', data, colors.fg.green)
|
||||||
|
|
||||||
|
# warn: when there is a potential for something bad to happen
|
||||||
|
def warn(data):
|
||||||
|
if get_level() <= LEVEL_WARN:
|
||||||
|
log('!', data, colors.fg.orange)
|
||||||
|
|
||||||
|
# error: when only one function, module, or process of the program encountered a problem and must stop
|
||||||
|
def error(data):
|
||||||
|
if get_level() <= LEVEL_ERROR:
|
||||||
|
log('-', data, colors.fg.red)
|
||||||
|
|
||||||
|
# fatal: when the something so bad has happened that the prorgam must stop
|
||||||
|
def fatal(data):
|
||||||
|
if get_level() <= LEVEL_FATAL:
|
||||||
|
log('#', data, colors.bg.red + colors.fg.black)
|
@ -17,7 +17,7 @@
|
|||||||
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 subprocess, os, random, sys
|
import subprocess, os, random, sys, logger
|
||||||
class NetController:
|
class NetController:
|
||||||
'''NetController
|
'''NetController
|
||||||
This class handles hidden service setup on Tor and I2P
|
This class handles hidden service setup on Tor and I2P
|
||||||
@ -56,10 +56,10 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
|
|||||||
if 'Bootstrapped 100%: Done' in line.decode():
|
if 'Bootstrapped 100%: Done' in line.decode():
|
||||||
break
|
break
|
||||||
elif 'Opening Socks listener' in line.decode():
|
elif 'Opening Socks listener' in line.decode():
|
||||||
print(line.decode())
|
logger.debug(line.decode())
|
||||||
print('Finished starting Tor')
|
logger.info('Finished starting Tor')
|
||||||
self.readyState = True
|
self.readyState = True
|
||||||
myID = open('data/hs/hostname', 'r')
|
myID = open('data/hs/hostname', 'r')
|
||||||
self.myID = myID.read()
|
self.myID = myID.read()
|
||||||
myID.close()
|
myID.close()
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
'''
|
'''
|
||||||
Onionr - P2P Microblogging Platform & Social network.
|
Onionr - P2P Microblogging Platform & Social network.
|
||||||
|
|
||||||
Onionr is the name for both the protocol and the original/reference software.
|
Onionr is the name for both the protocol and the original/reference software.
|
||||||
|
|
||||||
@ -20,10 +20,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 sys, os, configparser, base64, random, getpass, shutil, subprocess, requests, time
|
import sys, os, configparser, base64, random, getpass, shutil, subprocess, requests, time, logger
|
||||||
import gui, api, colors, core
|
import gui, api, core
|
||||||
from onionrutils import OnionrUtils
|
from onionrutils import OnionrUtils
|
||||||
from colors import Colors
|
|
||||||
from netcontroller import NetController
|
from netcontroller import NetController
|
||||||
|
|
||||||
class Onionr:
|
class Onionr:
|
||||||
@ -37,18 +36,18 @@ class Onionr:
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
if os.path.exists('dev-enabled'):
|
if os.path.exists('dev-enabled'):
|
||||||
print('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
|
|
||||||
self._developmentMode = True
|
self._developmentMode = True
|
||||||
|
logger.set_level(logger.LEVEL_DEBUG)
|
||||||
|
logger.warn('DEVELOPMENT MODE ENABLED (THIS IS LESS SECURE!)')
|
||||||
else:
|
else:
|
||||||
self._developmentMode = False
|
self._developmentMode = False
|
||||||
|
logger.set_level(logger.LEVEL_INFO)
|
||||||
colors = Colors()
|
|
||||||
|
|
||||||
self.onionrCore = core.Core()
|
self.onionrCore = core.Core()
|
||||||
self.onionrUtils = OnionrUtils(self.onionrCore)
|
self.onionrUtils = OnionrUtils(self.onionrCore)
|
||||||
|
|
||||||
# Get configuration and Handle commands
|
# Get configuration and Handle commands
|
||||||
|
|
||||||
self.debug = False # Whole application debugging
|
self.debug = False # Whole application debugging
|
||||||
|
|
||||||
if os.path.exists('data-encrypted.dat'):
|
if os.path.exists('data-encrypted.dat'):
|
||||||
@ -59,12 +58,12 @@ class Onionr:
|
|||||||
if os.path.exists('data/'):
|
if os.path.exists('data/'):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print('Failed to decrypt: ' + result[1])
|
logger.error('Failed to decrypt: ' + result[1])
|
||||||
else:
|
else:
|
||||||
if not os.path.exists('data/'):
|
if not os.path.exists('data/'):
|
||||||
os.mkdir('data/')
|
os.mkdir('data/')
|
||||||
os.mkdir('data/blocks/')
|
os.mkdir('data/blocks/')
|
||||||
|
|
||||||
if not os.path.exists('data/peers.db'):
|
if not os.path.exists('data/peers.db'):
|
||||||
self.onionrCore.createPeerDB()
|
self.onionrCore.createPeerDB()
|
||||||
pass
|
pass
|
||||||
@ -94,7 +93,7 @@ class Onionr:
|
|||||||
finally:
|
finally:
|
||||||
if command == 'start':
|
if command == 'start':
|
||||||
if os.path.exists('.onionr-lock'):
|
if os.path.exists('.onionr-lock'):
|
||||||
self.onionrUtils.printErr('Cannot start. Daemon is already running, or it did not exit cleanly.\n(if you are sure that there is not a daemon running, delete .onionr-lock & try again).')
|
logger.fatal('Cannot start. Daemon is already running, or it did not exit cleanly.\n(if you are sure that there is not a daemon running, delete .onionr-lock & try again).')
|
||||||
else:
|
else:
|
||||||
if not self.debug and not self._developmentMode:
|
if not self.debug and not self._developmentMode:
|
||||||
lockFile = open('.onionr-lock', 'w')
|
lockFile = open('.onionr-lock', 'w')
|
||||||
@ -110,32 +109,31 @@ class Onionr:
|
|||||||
elif command == 'help' or command == '--help':
|
elif command == 'help' or command == '--help':
|
||||||
self.showHelp()
|
self.showHelp()
|
||||||
elif command == '':
|
elif command == '':
|
||||||
print('Do', sys.argv[0], ' --help for Onionr help.')
|
logger.info('Do ' + logger.colors.bold + sys.argv[0] + ' --help' + logger.colors.reset + logger.colors.fg.green + ' for Onionr help.')
|
||||||
else:
|
else:
|
||||||
print(colors.RED, 'Invalid Command', colors.RESET)
|
logger.error('Invalid command.')
|
||||||
|
|
||||||
if not self._developmentMode:
|
if not self._developmentMode:
|
||||||
encryptionPassword = self.onionrUtils.getPassword('Enter password to encrypt directory.')
|
encryptionPassword = self.onionrUtils.getPassword('Enter password to encrypt directory: ')
|
||||||
self.onionrCore.dataDirEncrypt(encryptionPassword)
|
self.onionrCore.dataDirEncrypt(encryptionPassword)
|
||||||
shutil.rmtree('data/')
|
shutil.rmtree('data/')
|
||||||
return
|
return
|
||||||
def daemon(self):
|
def daemon(self):
|
||||||
''' Start the Onionr communication daemon
|
''' Start the Onionr communication daemon
|
||||||
'''
|
'''
|
||||||
colors = Colors()
|
|
||||||
if not os.environ.get("WERKZEUG_RUN_MAIN") == "true":
|
if not os.environ.get("WERKZEUG_RUN_MAIN") == "true":
|
||||||
net = NetController(self.config['CLIENT']['PORT'])
|
net = NetController(self.config['CLIENT']['PORT'])
|
||||||
print('Tor is starting...')
|
logger.info('Tor is starting...')
|
||||||
net.startTor()
|
net.startTor()
|
||||||
print(colors.GREEN + 'Started Tor .onion service: ' + colors.UNDERLINE + net.myID + colors.RESET)
|
logger.info('Started Tor .onion service: ' + logger.colors.underline + net.myID)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
subprocess.Popen(["./communicator.py", "run", str(net.socksPort)])
|
subprocess.Popen(["./communicator.py", "run", str(net.socksPort)])
|
||||||
print('Started communicator')
|
logger.debug('Started communicator')
|
||||||
api.API(self.config, self.debug)
|
api.API(self.config, self.debug)
|
||||||
return
|
return
|
||||||
def killDaemon(self):
|
def killDaemon(self):
|
||||||
'''Shutdown the Onionr Daemon'''
|
'''Shutdown the Onionr Daemon'''
|
||||||
print('Killing the running daemon')
|
logger.warn('Killing the running daemon')
|
||||||
try:
|
try:
|
||||||
self.onionrUtils.localCommand('shutdown')
|
self.onionrUtils.localCommand('shutdown')
|
||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
@ -149,6 +147,6 @@ class Onionr:
|
|||||||
def showHelp(self):
|
def showHelp(self):
|
||||||
'''Show help for Onionr'''
|
'''Show help for Onionr'''
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
Onionr()
|
|
||||||
|
Onionr()
|
||||||
|
@ -18,12 +18,12 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
'''
|
'''
|
||||||
# Misc functions that do not fit in the main api, but are useful
|
# Misc functions that do not fit in the main api, but are useful
|
||||||
import getpass, sys, requests, configparser, os, socket, gnupg, hashlib
|
import getpass, sys, requests, configparser, os, socket, gnupg, hashlib, logger
|
||||||
if sys.version_info < (3, 6):
|
if sys.version_info < (3, 6):
|
||||||
try:
|
try:
|
||||||
import sha3
|
import sha3
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
sys.stderr.write('On Python 3 versions prior to 3.6.x, you need the sha3 module')
|
logger.fatal('On Python 3 versions prior to 3.6.x, you need the sha3 module')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
class OnionrUtils:
|
class OnionrUtils:
|
||||||
'''Various useful functions'''
|
'''Various useful functions'''
|
||||||
@ -33,7 +33,7 @@ class OnionrUtils:
|
|||||||
return
|
return
|
||||||
def printErr(self, text='an error occured'):
|
def printErr(self, text='an error occured'):
|
||||||
'''Print an error message to stderr with a new line'''
|
'''Print an error message to stderr with a new line'''
|
||||||
sys.stderr.write(text + '\n')
|
logger.error(text)
|
||||||
def localCommand(self, command):
|
def localCommand(self, command):
|
||||||
'''Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers.'''
|
'''Send a command to the local http API server, securely. Intended for local clients, DO NOT USE for remote peers.'''
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
@ -51,7 +51,7 @@ class OnionrUtils:
|
|||||||
print('Confirm password: ')
|
print('Confirm password: ')
|
||||||
pass2 = getpass.getpass()
|
pass2 = getpass.getpass()
|
||||||
if pass1 != pass2:
|
if pass1 != pass2:
|
||||||
print("Passwords do not match.")
|
logger.error("Passwords do not match.")
|
||||||
input()
|
input()
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
@ -101,4 +101,4 @@ class OnionrUtils:
|
|||||||
int(data, 16)
|
int(data, 16)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
retVal = False
|
retVal = False
|
||||||
return retVal
|
return retVal
|
||||||
|
@ -14,18 +14,18 @@
|
|||||||
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 unittest, sys, os, base64, tarfile, shutil, simplecrypt
|
import unittest, sys, os, base64, tarfile, shutil, simplecrypt, logger
|
||||||
|
|
||||||
class OnionrTests(unittest.TestCase):
|
class OnionrTests(unittest.TestCase):
|
||||||
def testPython3(self):
|
def testPython3(self):
|
||||||
if sys.version_info.major != 3:
|
if sys.version_info.major != 3:
|
||||||
print(sys.version_info.major)
|
logger.debug('Python version: ' + sys.version_info.major)
|
||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
else:
|
else:
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
def testNone(self):
|
def testNone(self):
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('Running simple program run test')
|
logger.info('Running simple program run test...')
|
||||||
# Test just running ./onionr with no arguments
|
# Test just running ./onionr with no arguments
|
||||||
blank = os.system('./onionr.py')
|
blank = os.system('./onionr.py')
|
||||||
if blank != 0:
|
if blank != 0:
|
||||||
@ -33,8 +33,8 @@ class OnionrTests(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
def testPeer_a_DBCreation(self):
|
def testPeer_a_DBCreation(self):
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('Running peer db creation test')
|
logger.info('Running peer db creation test...')
|
||||||
if os.path.exists('data/peers.db'):
|
if os.path.exists('data/peers.db'):
|
||||||
os.remove('data/peers.db')
|
os.remove('data/peers.db')
|
||||||
import core
|
import core
|
||||||
@ -45,8 +45,8 @@ class OnionrTests(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
def testPeer_b_addPeerToDB(self):
|
def testPeer_b_addPeerToDB(self):
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('Running peer db insertion test')
|
logger.info('Running peer db insertion test...')
|
||||||
import core
|
import core
|
||||||
myCore = core.Core()
|
myCore = core.Core()
|
||||||
if not os.path.exists('data/peers.db'):
|
if not os.path.exists('data/peers.db'):
|
||||||
@ -58,8 +58,8 @@ class OnionrTests(unittest.TestCase):
|
|||||||
def testData_b_Encrypt(self):
|
def testData_b_Encrypt(self):
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
return
|
return
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('Running data dir encrypt test')
|
logger.info('Running data dir encrypt test...')
|
||||||
import core
|
import core
|
||||||
myCore = core.Core()
|
myCore = core.Core()
|
||||||
myCore.dataDirEncrypt('password')
|
myCore.dataDirEncrypt('password')
|
||||||
@ -70,8 +70,8 @@ class OnionrTests(unittest.TestCase):
|
|||||||
def testData_a_Decrypt(self):
|
def testData_a_Decrypt(self):
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
return
|
return
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('Running data dir decrypt test')
|
logger.info('Running data dir decrypt test...')
|
||||||
import core
|
import core
|
||||||
myCore = core.Core()
|
myCore = core.Core()
|
||||||
myCore.dataDirDecrypt('password')
|
myCore.dataDirDecrypt('password')
|
||||||
@ -80,8 +80,8 @@ class OnionrTests(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
def testPGPGen(self):
|
def testPGPGen(self):
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('Testing PGP key generation')
|
logger.info('Running PGP key generation test...')
|
||||||
if os.path.exists('data/pgp/'):
|
if os.path.exists('data/pgp/'):
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
else:
|
else:
|
||||||
@ -94,8 +94,8 @@ class OnionrTests(unittest.TestCase):
|
|||||||
if os.path.exists('data/pgp/'):
|
if os.path.exists('data/pgp/'):
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
def testHMACGen(self):
|
def testHMACGen(self):
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('running daemon queue test')
|
logger.info('Running HMAC generation test...')
|
||||||
# Test if hmac key generation is working
|
# Test if hmac key generation is working
|
||||||
import core
|
import core
|
||||||
myCore = core.Core()
|
myCore = core.Core()
|
||||||
@ -105,8 +105,8 @@ class OnionrTests(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
self.assertTrue(False)
|
self.assertTrue(False)
|
||||||
def testQueue(self):
|
def testQueue(self):
|
||||||
print('--------------------------')
|
logger.debug('--------------------------')
|
||||||
print('running daemon queue test')
|
logger.info('Running daemon queue test...')
|
||||||
# test if the daemon queue can read/write data
|
# test if the daemon queue can read/write data
|
||||||
import core
|
import core
|
||||||
myCore = core.Core()
|
myCore = core.Core()
|
||||||
|
Loading…
Reference in New Issue
Block a user