added tor check and fixed fd exhaustion

This commit is contained in:
Kevin Froman 2019-01-17 23:34:13 -06:00
parent ea5f18d4e1
commit 11d9047548
6 changed files with 29 additions and 6 deletions

View File

@ -99,6 +99,7 @@ class PublicAPI:
resp.headers['X-Frame-Options'] = 'deny' resp.headers['X-Frame-Options'] = 'deny'
resp.headers['X-Content-Type-Options'] = "nosniff" resp.headers['X-Content-Type-Options'] = "nosniff"
resp.headers['X-API'] = onionr.API_VERSION resp.headers['X-API'] = onionr.API_VERSION
resp.headers['Connection'] = "close"
return resp return resp
@app.route('/') @app.route('/')
@ -288,6 +289,7 @@ class API:
resp.headers['X-API'] = onionr.API_VERSION resp.headers['X-API'] = onionr.API_VERSION
resp.headers['Server'] = '' resp.headers['Server'] = ''
resp.headers['Date'] = 'Thu, 1 Jan 1970 00:00:00 GMT' # Clock info is probably useful to attackers. Set to unix epoch. resp.headers['Date'] = 'Thu, 1 Jan 1970 00:00:00 GMT' # Clock info is probably useful to attackers. Set to unix epoch.
resp.headers['Connection'] = "close"
return resp return resp
@app.route('/board/', endpoint='board') @app.route('/board/', endpoint='board')

View File

@ -140,6 +140,9 @@ class OnionrCommunicatorDaemon:
break break
i.processTimer() i.processTimer()
time.sleep(self.delay) time.sleep(self.delay)
# Debug to print out used FDs (regular and net)
#proc = psutil.Process()
#print(proc.open_files(), len(psutil.net_connections()))
except KeyboardInterrupt: except KeyboardInterrupt:
self.shutdown = True self.shutdown = True
pass pass

View File

@ -22,6 +22,7 @@ import subprocess, os, random, sys, logger, time, signal, config, base64, socket
from stem.control import Controller from stem.control import Controller
from onionrblockapi import Block from onionrblockapi import Block
from dependencies import secrets from dependencies import secrets
from shutil import which
def getOpenPort(): def getOpenPort():
# taken from (but modified) https://stackoverflow.com/a/2838309 # taken from (but modified) https://stackoverflow.com/a/2838309
@ -31,6 +32,14 @@ def getOpenPort():
port = s.getsockname()[1] port = s.getsockname()[1]
s.close() s.close()
return port return port
def torBinary():
'''Return tor binary path or none if not exists'''
torPath = './tor'
if not os.path.exists(torPath):
torPath = which('tor')
return torPath
class NetController: class NetController:
''' '''
This class handles hidden service setup on Tor and I2P This class handles hidden service setup on Tor and I2P

View File

@ -68,6 +68,10 @@ class Onionr:
# Load global configuration data # Load global configuration data
data_exists = Onionr.setupConfig(self.dataDir, self = self) data_exists = Onionr.setupConfig(self.dataDir, self = self)
if netcontroller.torBinary() is None:
logger.error('Tor is not installed')
sys.exit(1)
self.onionrCore = core.Core() self.onionrCore = core.Core()
#self.deleteRunFiles() #self.deleteRunFiles()
self.onionrUtils = onionrutils.OnionrUtils(self.onionrCore) self.onionrUtils = onionrutils.OnionrUtils(self.onionrCore)
@ -292,7 +296,8 @@ class Onionr:
newID = self.onionrCore._crypto.keyManager.addKey()[0] newID = self.onionrCore._crypto.keyManager.addKey()[0]
else: else:
logger.warn('Deterministic keys require random and long passphrases.') logger.warn('Deterministic keys require random and long passphrases.')
logger.warn('If a good password is not used, your key can be easily stolen.') logger.warn('If a good passphrase is not used, your key can be easily stolen.')
logger.warn('You should use a series of hard to guess words, see this for reference: https://www.xkcd.com/936/')
pass1 = getpass.getpass(prompt='Enter at least %s characters: ' % (self.onionrCore._crypto.deterministicRequirement,)) pass1 = getpass.getpass(prompt='Enter at least %s characters: ' % (self.onionrCore._crypto.deterministicRequirement,))
pass2 = getpass.getpass(prompt='Confirm entry: ') pass2 = getpass.getpass(prompt='Confirm entry: ')
if self.onionrCore._crypto.safeCompare(pass1, pass2): if self.onionrCore._crypto.safeCompare(pass1, pass2):
@ -760,6 +765,9 @@ class Onionr:
try: try:
while True: while True:
time.sleep(3) time.sleep(3)
# Debug to print out used FDs (regular and net)
#proc = psutil.Process()
#print('api-files:',proc.open_files(), len(psutil.net_connections()))
# Break if communicator process ends, so we don't have left over processes # Break if communicator process ends, so we don't have left over processes
if communicatorProc.poll() is not None: if communicatorProc.poll() is not None:
break break

View File

@ -184,9 +184,9 @@ class OnionrUtils:
payload = 'http://%s/%s%s' % (hostname, command, data) payload = 'http://%s/%s%s' % (hostname, command, data)
try: try:
if post: if post:
retData = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword')}, timeout=(maxWait, 30)).text retData = requests.post(payload, data=postData, headers={'token': config.get('client.webpassword'), 'Connection':'close'}, timeout=(maxWait, 30)).text
else: else:
retData = requests.get(payload, headers={'token': config.get('client.webpassword')}, timeout=(maxWait, 30)).text retData = requests.get(payload, headers={'token': config.get('client.webpassword'), 'Connection':'close'}, timeout=(maxWait, 30)).text
except Exception as error: except Exception as error:
if not silent: if not silent:
logger.error('Failed to make local request (command: %s):%s' % (command, error)) logger.error('Failed to make local request (command: %s):%s' % (command, error))
@ -624,7 +624,7 @@ class OnionrUtils:
proxies = {'http': 'http://127.0.0.1:4444'} proxies = {'http': 'http://127.0.0.1:4444'}
else: else:
return return
headers = {'user-agent': 'PyOnionr'} headers = {'user-agent': 'PyOnionr', 'Connection':'close'}
try: try:
proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)} proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)}
r = requests.post(url, data=data, headers=headers, proxies=proxies, allow_redirects=False, timeout=(15, 30)) r = requests.post(url, data=data, headers=headers, proxies=proxies, allow_redirects=False, timeout=(15, 30))
@ -649,11 +649,11 @@ class OnionrUtils:
proxies = {'http': 'http://127.0.0.1:4444'} proxies = {'http': 'http://127.0.0.1:4444'}
else: else:
return return
headers = {'user-agent': 'PyOnionr'} headers = {'user-agent': 'PyOnionr', 'Connection':'close'}
response_headers = dict() response_headers = dict()
try: try:
proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)} proxies = {'http': 'socks4a://127.0.0.1:' + str(port), 'https': 'socks4a://127.0.0.1:' + str(port)}
r = requests.get(url, headers=headers, proxies=proxies, allow_redirects=False, timeout=(15, 30)) r = requests.get(url, headers=headers, proxies=proxies, allow_redirects=False, timeout=(15, 30), )
# Check server is using same API version as us # Check server is using same API version as us
if not ignoreAPI: if not ignoreAPI:
try: try:

View File

@ -7,6 +7,7 @@
"socket_servers": false, "socket_servers": false,
"security_level": 0, "security_level": 0,
"max_block_age": 2678400, "max_block_age": 2678400,
"bypass_tor_check": false,
"public_key": "" "public_key": ""
}, },