fixed config and other bugs, improved connection server
parent
4e3ad27485
commit
b582377c8c
|
@ -27,10 +27,12 @@ Users are identified by ed25519/curve25519 public keys, which can be used to sig
|
|||
|
||||
Onionr can be used for mail, as a social network, instant messenger, file sharing software, or for encrypted group discussion.
|
||||
|
||||
The whitepaper (subject to change prior to first alpha release) is available [here](docs/whitepaper.md).
|
||||
The whitepaper (subject to change prior to alpha release) is available [here](docs/whitepaper.md).
|
||||
|
||||
![node web illustration](docs/onionr-web.png)
|
||||
|
||||
![Tor stinks slide image](docs/tor-stinks-02.png)
|
||||
|
||||
## Main Features
|
||||
|
||||
* [X] 🌐 Fully p2p/decentralized, no trackers or other single points of failure
|
||||
|
@ -117,6 +119,4 @@ The 'open source badge' is by Maik Ellerbrock and is licensed under a Creative C
|
|||
|
||||
The Onionr logo was created by [Anhar Ismail](https://github.com/anharismail) under the [Creative Commons Attribution 4.0 International License](https://creativecommons.org/licenses/by/4.0/).
|
||||
|
||||
If you modify and redistribute our code ("forking"), please use a different logo and project name to avoid confusion. Please do not use our logo in a way that makes it seem like we endorse you without our permission.
|
||||
|
||||
![Tor stinks slide image](docs/tor-stinks-02.png)
|
||||
If you modify and redistribute our code ("forking"), please use a different logo and project name to avoid confusion. Please do not use our logo in a way that makes it seem like we endorse you without our permission.
|
|
@ -81,7 +81,7 @@ class PublicAPI:
|
|||
def validateRequest():
|
||||
'''Validate request has the correct hostname'''
|
||||
# If high security level, deny requests to public (HS should be disabled anyway for Tor, but might not be for I2P)
|
||||
if config.get('general.security_level', default=0) > 0:
|
||||
if config.get('general.security_level', default=1) > 0:
|
||||
abort(403)
|
||||
if type(self.torAdder) is None and type(self.i2pAdder) is None:
|
||||
# abort if our hs addresses are not known
|
||||
|
|
|
@ -33,6 +33,7 @@ OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
|
|||
config.reload()
|
||||
class OnionrCommunicatorDaemon:
|
||||
def __init__(self, onionrInst, proxyPort, developmentMode=config.get('general.dev_mode', False)):
|
||||
config.reload()
|
||||
onionrInst.communicatorInst = self
|
||||
# configure logger and stuff
|
||||
onionr.Onionr.setupConfig('data/', self = self)
|
||||
|
|
|
@ -18,11 +18,13 @@
|
|||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
'''
|
||||
import communicator, onionrexceptions
|
||||
import logger
|
||||
import logger, onionrpeers
|
||||
|
||||
def download_blocks_from_communicator(comm_inst):
|
||||
assert isinstance(comm_inst, communicator.OnionrCommunicatorDaemon)
|
||||
for blockHash in list(comm_inst.blockQueue):
|
||||
if len(comm_inst.onlinePeers) == 0:
|
||||
break
|
||||
triedQueuePeers = [] # List of peers we've tried for a block
|
||||
try:
|
||||
blockPeers = list(comm_inst.blockQueue[blockHash])
|
||||
|
|
|
@ -98,9 +98,6 @@ def check():
|
|||
|
||||
if not os.path.exists(os.path.dirname(get_config_file())):
|
||||
os.makedirs(os.path.dirname(get_config_file()))
|
||||
if not os.path.isfile(get_config_file()):
|
||||
open(get_config_file(), 'a', encoding="utf8").close()
|
||||
save()
|
||||
|
||||
def save():
|
||||
'''
|
||||
|
|
|
@ -103,7 +103,7 @@ CookieAuthentication 1
|
|||
ControlPort ''' + str(controlPort) + '''
|
||||
HashedControlPassword ''' + str(password) + '''
|
||||
'''
|
||||
if config.get('general.security_level') == 0:
|
||||
if config.get('general.security_level', 1) == 0:
|
||||
torrcData += '''\nHiddenServiceDir ''' + self.dataDir + '''hs/
|
||||
\n''' + hsVer + '''\n
|
||||
HiddenServicePort 80 ''' + self.apiServerIP + ''':''' + str(self.hsPort)
|
||||
|
|
|
@ -71,7 +71,7 @@ class Onionr:
|
|||
logger.set_file(os.environ.get('LOG_DIR', 'data') + '/onionr.log')
|
||||
|
||||
# Load global configuration data
|
||||
data_exists = Onionr.setupConfig(self.dataDir, self = self)
|
||||
data_exists = Onionr.setupConfig(self.dataDir, self)
|
||||
|
||||
if netcontroller.torBinary() is None:
|
||||
logger.error('Tor is not installed')
|
||||
|
@ -122,7 +122,6 @@ class Onionr:
|
|||
config.set('client.client.port', randomPort, savefile=True)
|
||||
if type(config.get('client.public.port')) is type(None):
|
||||
randomPort = netcontroller.getOpenPort()
|
||||
print(randomPort)
|
||||
config.set('client.public.port', randomPort, savefile=True)
|
||||
if type(config.get('client.participate')) is type(None):
|
||||
config.set('client.participate', True, savefile=True)
|
||||
|
|
|
@ -50,7 +50,7 @@ def daemon(o_inst):
|
|||
except FileNotFoundError:
|
||||
pass
|
||||
time.sleep(0.5)
|
||||
onionr.Onionr.setupConfig('data/', self = o_inst)
|
||||
#onionr.Onionr.setupConfig('data/', self = o_inst)
|
||||
|
||||
if o_inst._developmentMode:
|
||||
logger.warn('DEVELOPMENT MODE ENABLED (NOT RECOMMENDED)', timestamp = False)
|
||||
|
@ -59,7 +59,7 @@ def daemon(o_inst):
|
|||
if not net.startTor():
|
||||
o_inst.onionrUtils.localCommand('shutdown')
|
||||
sys.exit(1)
|
||||
if len(net.myID) > 0 and o_inst.onionrCore.config.get('general.security_level') == 0:
|
||||
if len(net.myID) > 0 and o_inst.onionrCore.config.get('general.security_level', 1) == 0:
|
||||
logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID))
|
||||
else:
|
||||
logger.debug('.onion service disabled')
|
||||
|
|
|
@ -23,6 +23,9 @@ import core
|
|||
from . import connectionserver, bootstrapservice
|
||||
|
||||
class OnionrServices:
|
||||
'''
|
||||
Create a client or server for connecting to peer interfaces
|
||||
'''
|
||||
def __init__(self, onionr_core):
|
||||
assert isinstance(onionr_core, core.Core)
|
||||
self._core = onionr_core
|
||||
|
@ -32,13 +35,19 @@ class OnionrServices:
|
|||
return
|
||||
|
||||
def create_server(self, peer, address):
|
||||
'''
|
||||
When a client wants to connect, contact their bootstrap address and tell them our
|
||||
ephemeral address for our service by creating a new ConnectionServer instance
|
||||
'''
|
||||
assert self._core._utils.validateID(address)
|
||||
BOOTSTRAP_TRIES = 10
|
||||
TRY_WAIT = 3
|
||||
BOOTSTRAP_TRIES = 10 # How many times to attempt contacting the bootstrap server
|
||||
TRY_WAIT = 3 # Seconds to wait before trying bootstrap again
|
||||
# HTTP is fine because .onion/i2p is encrypted/authenticated
|
||||
base_url = 'http://%s/' % (address,)
|
||||
socks = self._core.config.get('tor.socksport')
|
||||
for x in range(BOOTSTRAP_TRIES):
|
||||
if self._core._utils.doGetRequest(base_url + 'ping', port=socks, ignoreAPI=True) == 'pong!':
|
||||
# if bootstrap sever is online, tell them our service address
|
||||
connectionserver.ConnectionServer(peer, address, core_inst=self._core)
|
||||
else:
|
||||
time.sleep(TRY_WAIT)
|
||||
|
|
|
@ -22,6 +22,7 @@ from gevent.pywsgi import WSGIServer, WSGIHandler
|
|||
from stem.control import Controller
|
||||
from flask import Flask
|
||||
import core, logger, httpapi
|
||||
import onionrexceptions
|
||||
from netcontroller import getOpenPort
|
||||
import api
|
||||
from . import httpheaders
|
||||
|
@ -66,11 +67,23 @@ class ConnectionServer:
|
|||
with Controller.from_port(port=core_inst.config.get('tor.controlPort')) as controller:
|
||||
# Connect to the Tor process for Onionr
|
||||
controller.authenticate(core_inst.config.get('tor.controlpassword'))
|
||||
# Create the v3 onion service
|
||||
# Create the v3 onion service for the peer to connect to
|
||||
response = controller.create_ephemeral_hidden_service({80: service_port}, await_publication = True, key_type='NEW', key_content = 'ED25519-V3')
|
||||
self.core_inst.keyStore.put('dc-' + response.service_id, self.core_inst._utils.bytesToStr(peer))
|
||||
self.core_inst._utils.doPostRequest('http://' + address + '/bs/' + response.service_id, port=socks)
|
||||
logger.info('hosting on %s with %s' % (response.service_id, peer))
|
||||
http_server.serve_forever()
|
||||
self.core_inst.keyStore.delete('dc-' + response.service_id)
|
||||
http_server.stop()
|
||||
|
||||
try:
|
||||
for x in range(3):
|
||||
attempt = self.core_inst._utils.doPostRequest('http://' + address + '/bs/' + response.service_id, port=socks)
|
||||
if attempt == 'success':
|
||||
break
|
||||
else:
|
||||
raise ConnectionError
|
||||
except ConnectionError:
|
||||
# Re-raise
|
||||
raise ConnectionError('Could not reach %s bootstrap address %s' % (peer, address))
|
||||
else:
|
||||
# If no connection error, create the service and save it to local global key store
|
||||
self.core_inst.keyStore.put('dc-' + response.service_id, self.core_inst._utils.bytesToStr(peer))
|
||||
logger.info('hosting on %s with %s' % (response.service_id, peer))
|
||||
http_server.serve_forever()
|
||||
http_server.stop()
|
||||
self.core_inst.keyStore.delete('dc-' + response.service_id)
|
|
@ -3,21 +3,22 @@ import config, logger
|
|||
|
||||
def setup_config(dataDir, o_inst = None):
|
||||
data_exists = os.path.exists(dataDir)
|
||||
|
||||
if not data_exists:
|
||||
os.mkdir(dataDir)
|
||||
config.reload()
|
||||
|
||||
|
||||
if not os.path.exists(config._configfile):
|
||||
if os.path.exists('static-data/default_config.json'):
|
||||
# this is the default config, it will be overwritten if a config file already exists. Else, it saves it
|
||||
with open('static-data/default_config.json', 'r') as configReadIn:
|
||||
config.set_config(json.loads(configReadIn.read()))
|
||||
else:
|
||||
# the default config file doesn't exist, try hardcoded config
|
||||
logger.warn('Default configuration file does not exist, switching to hardcoded fallback configuration!')
|
||||
config.set_config({'dev_mode': True, 'log': {'file': {'output': True, 'path': dataDir + 'output.log'}, 'console': {'output': True, 'color': True}}})
|
||||
|
||||
if os.path.exists('static-data/default_config.json'):
|
||||
# this is the default config, it will be overwritten if a config file already exists. Else, it saves it
|
||||
with open('static-data/default_config.json', 'r') as configReadIn:
|
||||
config.set_config(json.loads(configReadIn.read()))
|
||||
else:
|
||||
# the default config file doesn't exist, try hardcoded config
|
||||
logger.warn('Default configuration file does not exist, switching to hardcoded fallback configuration!')
|
||||
config.set_config({'dev_mode': True, 'log': {'file': {'output': True, 'path': dataDir + 'output.log'}, 'console': {'output': True, 'color': True}}})
|
||||
if not data_exists:
|
||||
config.save()
|
||||
config.reload() # this will read the configuration file into memory
|
||||
|
||||
settings = 0b000
|
||||
if config.get('log.console.color', True):
|
||||
|
|
Loading…
Reference in New Issue