improved block syncing

master
Kevin Froman 2018-01-27 19:53:24 -06:00
parent f3c1587d51
commit 897f18bbc2
No known key found for this signature in database
GPG Key ID: 0D414D0FE405B63B
5 changed files with 52 additions and 16 deletions

View File

@ -86,6 +86,7 @@ class API:
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'
resp.headers['X-Content-Type-Options'] = "nosniff"
return resp return resp
@app.route('/client/') @app.route('/client/')
@ -105,10 +106,6 @@ class API:
resp = Response('Goodbye') resp = Response('Goodbye')
elif action == 'stats': elif action == 'stats':
resp = Response('me_irl') resp = Response('me_irl')
elif action == 'init':
# generate PGP key
self._core.generateMainPGP()
pass
else: else:
resp = Response('(O_o) Dude what? (invalid command)') resp = Response('(O_o) Dude what? (invalid command)')
endTime = math.floor(time.time()) endTime = math.floor(time.time())

View File

@ -94,6 +94,11 @@ class OnionrCommunicate:
if currentDB != False: if currentDB != False:
if lastDB != currentDB: if lastDB != currentDB:
blocks += self.performGet('getBlockHashes', i) blocks += self.performGet('getBlockHashes', i)
if currentDB != lastDB:
if self._utils.validateHash(currentDB):
self._core.setPeerInfo(i, "blockDBHash", currentDB)
else:
logger.warn("Peer " + i + " returned malformed hash")
blockList = blocks.split('\n') blockList = blocks.split('\n')
for i in blockList: for i in blockList:
if not self._utils.validateHash(i): if not self._utils.validateHash(i):
@ -109,15 +114,16 @@ class OnionrCommunicate:
if not peer.endswith('.onion') and not peer.endswith('.onion/'): if not peer.endswith('.onion') and not peer.endswith('.onion/'):
raise PeerError('Currently only Tor .onion peers are supported. You must manually specify .onion') raise PeerError('Currently only Tor .onion peers are supported. You must manually specify .onion')
socksPort = sys.argv[2] socksPort = sys.argv[2]
proxies = {'http': 'socks5://127.0.0.1:' + str(socksPort), 'https': 'socks5://127.0.0.1:' + str(socksPort)} '''We use socks5h to use tor as DNS'''
proxies = {'http': 'socks5h://127.0.0.1:' + str(socksPort), 'https': 'socks5h://127.0.0.1:' + str(socksPort)}
headers = {'user-agent': 'PyOnionr'} headers = {'user-agent': 'PyOnionr'}
url = 'http://' + peer + '/public/?action=' + action url = 'http://' + peer + '/public/?action=' + action
if data != None: if data != None:
url = url + '&data=' + data url = url + '&data=' + data
try: try:
r = requests.get(url, headers=headers, proxies=proxies) r = requests.get(url, headers=headers, proxies=proxies)
except requests.exceptions.RequestException: except requests.exceptions.RequestException as e:
logger.warn(action + " failed with peer " + peer) logger.warn(action + " failed with peer " + peer + ": " + e)
return False return False
return r.text return r.text

View File

@ -259,11 +259,16 @@ class Core:
key = base64.b64encode(os.urandom(32)) key = base64.b64encode(os.urandom(32))
return key return key
def listPeers(self): def listPeers(self, randomOrder=True):
'''Return a list of peers '''Return a list of peers
randomOrder determines if the list should be in a random order
''' '''
conn = sqlite3.connect(self.peerDB) conn = sqlite3.connect(self.peerDB)
c = conn.cursor() c = conn.cursor()
if randomOrder:
peers = c.execute('SELECT * FROM peers order by RANDOM();')
else:
peers = c.execute('SELECT * FROM peers;') peers = c.execute('SELECT * FROM peers;')
peerList = [] peerList = []
for i in peers: for i in peers:
@ -310,6 +315,14 @@ class Core:
iterCount += 1 iterCount += 1
conn.close() conn.close()
return retVal return retVal
def setPeerInfo(self, peer, key, data):
'''update a peer for a key'''
conn = sqlite3.connect(self.peerDB)
c = conn.cursor()
command = (peer,)
# TODO: validate key on whitelist
c.execute('UPDATE peers SET ' + key + ' = ' + data + ' where id=?', command)
def getBlockList(self, unsaved=False): def getBlockList(self, unsaved=False):
'''get list of our blocks''' '''get list of our blocks'''

View File

@ -38,6 +38,7 @@ class NetController:
''' '''
return return
def generateTorrc(self): def generateTorrc(self):
'''generate a torrc file for our tor instance'''
if os.path.exists(self.torConfigLocation): if os.path.exists(self.torConfigLocation):
os.remove(self.torConfigLocation) os.remove(self.torConfigLocation)
torrcData = '''SocksPort ''' + str(self.socksPort) + ''' torrcData = '''SocksPort ''' + str(self.socksPort) + '''
@ -53,7 +54,15 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
'''Start Tor with onion service on port 80 & socks proxy on random port '''Start Tor with onion service on port 80 & socks proxy on random port
''' '''
self.generateTorrc() self.generateTorrc()
tor = subprocess.Popen(['tor', '-f', self.torConfigLocation], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if os.path.exists('./tor'):
torBinary = './tor'
else:
torBinary = 'tor'
try:
tor = subprocess.Popen([torBinary, '-f', self.torConfigLocation], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except FileNotFoundError:
logger.error("Tor was not found in your path or the Onionr directory. Install Tor and try again.")
sys.exit(1)
# wait for tor to get to 100% bootstrap # wait for tor to get to 100% bootstrap
for line in iter(tor.stdout.readline, b''): for line in iter(tor.stdout.readline, b''):
if 'Bootstrapped 100%: Done' in line.decode(): if 'Bootstrapped 100%: Done' in line.decode():
@ -61,7 +70,8 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
elif 'Opening Socks listener' in line.decode(): elif 'Opening Socks listener' in line.decode():
logger.debug(line.decode()) logger.debug(line.decode())
else: else:
logger.error('Failed to start Tor') logger.error('Failed to start Tor. Try killing any other Tor processes owned by this user.')
return False
logger.info('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')
@ -70,7 +80,7 @@ HiddenServicePort 80 127.0.0.1:''' + str(self.hsPort) + '''
torPidFile = open('data/torPid.txt', 'w') torPidFile = open('data/torPid.txt', 'w')
torPidFile.write(str(tor.pid)) torPidFile.write(str(tor.pid))
torPidFile.close() torPidFile.close()
return return True
def killTor(self): def killTor(self):
'''properly kill tor based on pid saved to file''' '''properly kill tor based on pid saved to file'''
try: try:

View File

@ -25,6 +25,11 @@ import gui, api, core
from onionrutils import OnionrUtils from onionrutils import OnionrUtils
from netcontroller import NetController from netcontroller import NetController
try:
from urllib3.contrib.socks import SOCKSProxyManager
except ImportError:
raise Exception("You need the PySocks module (for use with socks5 proxy to use Tor)")
class Onionr: class Onionr:
def __init__(self): def __init__(self):
'''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.
@ -104,6 +109,12 @@ class Onionr:
os.remove('.onionr-lock') os.remove('.onionr-lock')
elif command == 'stop': elif command == 'stop':
self.killDaemon() self.killDaemon()
elif command in ('addmsg', 'addmessage'):
while True:
messageToAdd = input('Broadcast message to network: ')
if len(messageToAdd) >= 1:
break
self.onionrCore.setData(messageToAdd)
elif command == 'stats': elif command == 'stats':
self.showStats() self.showStats()
elif command == 'help' or command == '--help': elif command == 'help' or command == '--help':
@ -124,7 +135,8 @@ class Onionr:
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'])
logger.info('Tor is starting...') logger.info('Tor is starting...')
net.startTor() if not net.startTor():
sys.exit(1)
logger.info('Started Tor .onion service: ' + logger.colors.underline + net.myID) 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)])
@ -148,6 +160,4 @@ class Onionr:
def showHelp(self): def showHelp(self):
'''Show help for Onionr''' '''Show help for Onionr'''
return return
Onionr() Onionr()