diff --git a/onionr/netcontroller.py b/onionr/netcontroller.py index 4f6281c9..49bf46ac 100755 --- a/onionr/netcontroller.py +++ b/onionr/netcontroller.py @@ -17,12 +17,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' - -import subprocess, os, random, sys, logger, time, signal, config, base64, socket -from stem.control import Controller +import subprocess, os, random, sys, time, signal, base64, socket +from shutil import which +import logger, config from onionrblockapi import Block from dependencies import secrets -from shutil import which def getOpenPort(): # taken from (but modified) https://stackoverflow.com/a/2838309 @@ -67,13 +66,6 @@ class NetController: self.torBinary = 'tor' config.reload() - ''' - if os.path.exists(self.torConfigLocation): - torrc = open(self.torConfigLocation, 'r') - if not str(self.hsPort) in torrc.read(): - os.remove(self.torConfigLocation) - torrc.close() - ''' return diff --git a/onionr/onionrservices/__init__.py b/onionr/onionrservices/__init__.py new file mode 100644 index 00000000..68612cf7 --- /dev/null +++ b/onionr/onionrservices/__init__.py @@ -0,0 +1,18 @@ +import stem +import core +from . import connectionserver, connectionclient, bootstrapservice +class OnionrServices: + def __init__(self, onionr_core): + assert isinstance(onionr_core, core.Core) + self._core = onionr_core + self.servers = {} + self.clients = {} + return + + def create_server(self): + return + + def create_client(self, peer): + # Create ephemeral onion service to bootstrap connection + address = bootstrapservice.bootstrap_client_service(peer) + return address \ No newline at end of file diff --git a/onionr/onionrservices/bootstrapservice.py b/onionr/onionrservices/bootstrapservice.py new file mode 100644 index 00000000..7a2c3823 --- /dev/null +++ b/onionr/onionrservices/bootstrapservice.py @@ -0,0 +1,67 @@ +''' + Onionr - P2P Anonymous Storage Network + + Bootstrap onion direct connections for the clients +''' +''' + 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 . +''' +from gevent.pywsgi import WSGIServer, WSGIHandler +from stem.control import Controller +from flask import Flask +import core +from netcontroller import getOpenPort + +def bootstrap_client_service(peer, core_inst=None): + ''' + Bootstrap client services + ''' + if core_inst is None: + core_inst = core.Core() + + if not core_inst._utils.validatePubKey(peer): + raise ValueError('Peer must be valid base32 ed25519 public key') + + http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None) + bootstrap_port = getOpenPort() + bootstrap_app = flask.Flask(__name__) + + bootstrap_address = '' + + @bootstrap_app.route('/ping') + def get_ping(): + return "pong!" + + @bootstrap_app.route('/bs/
', methods=['POST']) + def get_bootstrap(address): + if core_inst._utils.validateID(address): + # Set the bootstrap address then close the server + bootstrap_address = address + http_server.stop() + + with Controller.from_port() as controller: + # Connect to the Tor process for Onionr + controller.authenticate() + # Create the v3 onion service + response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, await_publication = True, key_type='ED25519-V3') + + core_inst.insertBlock(response.hostname, header='con', sign=True, encryptType='asym', + asymPeer=peer, disableForward=True) + + # Run the bootstrap server + http_server.serve_forever() + # This line reached when server is shutdown by being bootstrapped + + # Now that the bootstrap server has received a server, return the address + return bootstrap_address diff --git a/onionr/onionrservices/connectionserver.py b/onionr/onionrservices/connectionserver.py new file mode 100644 index 00000000..d602d8ce --- /dev/null +++ b/onionr/onionrservices/connectionserver.py @@ -0,0 +1,4 @@ +class ConnectionServer: + def __init__(self): + return + \ No newline at end of file diff --git a/onionr/onionrutils.py b/onionr/onionrutils.py index f8fd13af..082b14fb 100755 --- a/onionr/onionrutils.py +++ b/onionr/onionrutils.py @@ -329,7 +329,8 @@ class OnionrUtils: retVal = True return retVal - def validateID(self, id): + @staticmethod + def validateID(id): ''' Validate if an address is a valid tor or i2p hidden service ''' @@ -381,7 +382,8 @@ class OnionrUtils: except: return False - def isIntegerString(self, data): + @staticmethod + def isIntegerString(data): '''Check if a string is a valid base10 integer (also returns true if already an int)''' try: int(data) diff --git a/requirements.in b/requirements.in index 6b1cb663..7bf8ff02 100755 --- a/requirements.in +++ b/requirements.in @@ -5,5 +5,5 @@ gevent==1.3.6 defusedxml==0.5.0 Flask==1.0.2 PySocks==1.6.8 -stem==1.6.0 +stem==1.7.1 deadsimplekv==0.0.1 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b2c93d7c..9bb58ea1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -185,8 +185,8 @@ six==1.12.0 \ --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \ --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 \ # via pynacl -stem==1.6.0 \ - --hash=sha256:d7fe1fb13ed5a94d610b5ad77e9f1b3404db0ca0586ded7a34afd323e3b849ed +stem==1.7.1 \ + --hash=sha256:c9eaf3116cb60c15995cbd3dec3a5cbc50e9bb6e062c4d6d42201e566f498ca2 urllib3==1.23 \ --hash=sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf \ --hash=sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5