Various bug fixes

This commit is contained in:
Arinerron 2018-07-30 21:41:32 -07:00
parent 34b919d324
commit ddb3ce1e35
8 changed files with 60 additions and 31 deletions

View File

@ -24,7 +24,7 @@ from gevent.wsgi import WSGIServer
import sys, random, threading, hmac, hashlib, base64, time, math, os, logger, config
from core import Core
from onionrblockapi import Block
import onionrutils, onionrcrypto, blockimporter
import onionrutils, onionrcrypto, blockimporter, onionrevents as events
class API:
'''
@ -94,6 +94,7 @@ class API:
'''
Simply define the request as not having yet failed, before every request.
'''
self.requestFailed = False
return
@ -119,16 +120,24 @@ class API:
@app.route('/client/ui/<path:path>')
def webUI(path):
startTime = math.floor(time.time())
if request.args.get('timingToken') is None:
timingToken = ''
else:
timingToken = request.args.get('timingToken')
self.validateHost('private')
if not config.get("onionr_ui.run", True):
abort(403)
if config.get("onionr_ui.private_only", True):
self.validateHost('private')
endTime = math.floor(time.time())
elapsed = endTime - startTime
if not hmac.compare_digest(timingToken, self.timeBypassToken):
if elapsed < self._privateDelayTime:
time.sleep(self._privateDelayTime - elapsed)
return send_from_directory('static-data/ui/dist/', path)
@app.route('/client/')
@ -150,6 +159,9 @@ class API:
if not self.validateToken(token):
abort(403)
events.event('webapi_private', onionr = None, data = {'action' : action, 'data' : data, 'timingToken' : timingToken, 'token' : token})
self.validateHost('private')
if action == 'hello':
resp = Response('Hello, World! ' + request.host)
@ -198,12 +210,12 @@ class API:
response['hash'] = hash
response['reason'] = 'Successfully wrote block to file'
else:
response['reason'] = 'Faield to save the block'
response['reason'] = 'Failed to save the block'
except Exception as e:
logger.debug('insertBlock api request failed', error = e)
resp = Response(json.dumps(response))
elif action in callbacks['private']:
elif action in API.callbacks['private']:
resp = Response(str(getCallback(action, scope = 'private')(request)))
else:
resp = Response('(O_o) Dude what? (invalid command)')
@ -257,6 +269,10 @@ class API:
data = data
except:
data = ''
events.event('webapi_public', onionr = None, data = {'action' : action, 'data' : data, 'requestingPeer' : requestingPeer, 'request' : request})
if action == 'firstConnect':
pass
elif action == 'ping':
@ -299,7 +315,7 @@ class API:
peers = self._core.listPeers(getPow=True)
response = ','.join(peers)
resp = Response(response)
elif action in callbacks['public']:
elif action in API.callbacks['public']:
resp = Response(str(getCallback(action, scope = 'public')(request)))
else:
resp = Response("")
@ -373,29 +389,29 @@ class API:
sys.exit(1)
def setCallback(action, callback, scope = 'public'):
if not scope in callbacks:
if not scope in API.callbacks:
return False
callbacks[scope][action] = callback
API.callbacks[scope][action] = callback
return True
def removeCallback(action, scope = 'public'):
if (not scope in callbacks) or (not action in callbacks[scope]):
if (not scope in API.callbacks) or (not action in API.callbacks[scope]):
return False
del callbacks[scope][action]
del API.callbacks[scope][action]
return True
def getCallback(action, scope = 'public'):
if (not scope in callbacks) or (not action in callbacks[scope]):
if (not scope in API.callbacks) or (not action in API.callbacks[scope]):
return None
return callbacks[scope][action]
return API.callbacks[scope][action]
def getCallbacks(scope = None):
if (not scope is None) and (scope in callbacks):
return callbacks[scope]
if (not scope is None) and (scope in API.callbacks):
return API.callbacks[scope]
return callbacks
return API.callbacks

View File

@ -19,8 +19,8 @@
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 sys, os, core, config, json, onionrblockapi as block, requests, time, logger, threading, onionrplugins as plugins, base64, onionr
import onionrexceptions, onionrpeers
import sys, os, core, config, json, requests, time, logger, threading, base64, onionr
import onionrexceptions, onionrpeers, onionrevents as events, onionrplugins as plugins, onionrblockapi as block
from defusedxml import minidom
class OnionrCommunicatorDaemon:
@ -337,6 +337,8 @@ class OnionrCommunicatorDaemon:
cmd = self._core.daemonQueue()
if cmd is not False:
events.event('daemon_command', onionr = None, data = {'cmd' : cmd})
if cmd[0] == 'shutdown':
self.shutdown = True
elif cmd[0] == 'announceNode':
@ -355,6 +357,7 @@ class OnionrCommunicatorDaemon:
threading.Thread(target=self.uploadBlock).start()
else:
logger.info('Recieved daemonQueue command:' + cmd[0])
self.decrementThreadCount('daemonCommands')
def uploadBlock(self):
@ -401,6 +404,7 @@ class OnionrCommunicatorDaemon:
time.sleep(1)
else:
# This executes if the api is NOT detected to be running
events.event('daemon_crash', onionr = None, data = {})
logger.error('Daemon detected API crash (or otherwise unable to reach API after long time), stopping...')
self.shutdown = True
self.decrementThreadCount('detectAPICrash')

View File

@ -100,7 +100,7 @@ DataDirectory data/tordata/
logger.fatal('Failed to start Tor. Try killing any other Tor processes owned by this user.')
return False
except KeyboardInterrupt:
logger.fatal("Got keyboard interrupt")
logger.fatal("Got keyboard interrupt.")
return False
logger.debug('Finished starting Tor.', timestamp=True)

View File

@ -40,9 +40,9 @@ except ImportError:
raise Exception("You need the PySocks module (for use with socks5 proxy to use Tor)")
ONIONR_TAGLINE = 'Anonymous P2P Platform - GPLv3 - https://Onionr.VoidNet.Tech'
ONIONR_VERSION = '0.1.0' # for debugging and stuff
ONIONR_VERSION = '0.1.1' # for debugging and stuff
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
API_VERSION = '4' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes knows how to communicate without learning too much information about you.
API_VERSION = '4' # increments of 1; only change when something fundemental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
class Onionr:
def __init__(self):

View File

@ -33,10 +33,10 @@ def __event_caller(event_name, data = {}, onionr = None):
try:
call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(onionr, data))
except ModuleNotFoundError as e:
logger.warn('Disabling nonexistant plugin \"' + plugin + '\"...')
logger.warn('Disabling nonexistant plugin "%s"...' % plugin)
plugins.disable(plugin, onionr, stop_event = False)
except Exception as e:
logger.warn('Event \"' + event_name + '\" failed for plugin \"' + plugin + '\".')
logger.warn('Event "%s" failed for plugin "%s".' % (event_name, plugin))
logger.debug(str(e))

View File

@ -49,5 +49,6 @@ class InvalidProof(Exception):
# network level exceptions
class MissingPort(Exception):
pass
class InvalidAddress(Exception):
pass

View File

@ -199,7 +199,7 @@ class OnionrUtils:
def getBlockMetadataFromData(self, blockData):
'''
accepts block contents as string, returns a tuple of metadata, meta (meta being internal metadata, which will be returned as an encrypted base64 string if it is encrypted, dict if not).
'''
meta = {}
metadata = {}
@ -208,7 +208,7 @@ class OnionrUtils:
blockData = blockData.encode()
except AttributeError:
pass
try:
metadata = json.loads(blockData[:blockData.find(b'\n')].decode())
except json.decoder.JSONDecodeError:
@ -221,7 +221,7 @@ class OnionrUtils:
meta = json.loads(metadata['meta'])
except KeyError:
pass
meta = metadata['meta']
meta = metadata['meta']
return (metadata, meta, data)
def checkPort(self, port, host=''):
@ -251,7 +251,7 @@ class OnionrUtils:
return False
else:
return True
def processBlockMetadata(self, blockHash):
'''
Read metadata from a block and cache it to the block database
@ -269,7 +269,7 @@ class OnionrUtils:
def escapeAnsi(self, line):
'''
Remove ANSI escape codes from a string with regex
taken or adapted from: https://stackoverflow.com/a/38662876
'''
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
@ -331,12 +331,12 @@ class OnionrUtils:
retVal = False
return retVal
def validateMetadata(self, metadata):
'''Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string'''
# TODO, make this check sane sizes
retData = False
# convert to dict if it is json string
if type(metadata) is str:
try:
@ -382,7 +382,7 @@ class OnionrUtils:
else:
retVal = True
return retVal
def isIntegerString(self, data):
'''Check if a string is a valid base10 integer'''
try:

View File

@ -2,8 +2,16 @@
"general" : {
"dev_mode": true,
"display_header" : true,
"dc_response": true,
"dc_execcallbacks" : true
"direct_connect" : {
"respond" : true,
"execute_callbacks" : true
}
},
"onionr_ui" : {
"run" : true,
"private_only" : true
},
"client" : {