work on direct connections
This commit is contained in:
		
							parent
							
								
									225f93106d
								
							
						
					
					
						commit
						9fc6e35fe4
					
				
					 10 changed files with 92 additions and 9 deletions
				
			
		|  | @ -47,10 +47,9 @@ Onionr ships with various application plugins ready for use out of the box: | ||||||
| Currently usable: | Currently usable: | ||||||
| 
 | 
 | ||||||
| * Mail | * Mail | ||||||
| * Public anonymous chat | * Public anonymous chat/message board | ||||||
| * Simple webpage hosting - Will be greatly extended | * Simple webpage hosting - Will be greatly extended | ||||||
| * File sharing (Work in progress) | * File sharing (Work in progress) | ||||||
| * Simple Message board |  | ||||||
| 
 | 
 | ||||||
| Not yet usable: | Not yet usable: | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,11 +17,11 @@ | ||||||
|     You should have received a copy of the GNU General Public License |     You should have received a copy of the GNU General Public License | ||||||
|     along with this program.  If not, see <https://www.gnu.org/licenses/>. |     along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
| ''' | ''' | ||||||
| import threading | import threading # For the client creation thread | ||||||
| 
 | 
 | ||||||
| from flask import Response | from flask import Response # For direct connection management HTTP endpoints | ||||||
| from flask import Blueprint | from flask import Blueprint # To make the direct connection management blueprint in the webUI | ||||||
| from flask import g | from flask import g # Mainly to access the shared toomanyobjs object | ||||||
| import deadsimplekv | import deadsimplekv | ||||||
| 
 | 
 | ||||||
| import filepaths | import filepaths | ||||||
|  | @ -49,12 +49,16 @@ class DirectConnectionManagement: | ||||||
|         def make_new_connection(pubkey): |         def make_new_connection(pubkey): | ||||||
|             communicator = _get_communicator(g) |             communicator = _get_communicator(g) | ||||||
|             resp = "pending" |             resp = "pending" | ||||||
|  |             if pubkey in communicator.shared_state.get_by_string("ServicePool").bootstrap_pending: | ||||||
|  |                 return Response(resp) | ||||||
|  |                  | ||||||
|             if pubkey in communicator.direct_connection_clients: |             if pubkey in communicator.direct_connection_clients: | ||||||
|                 resp = communicator.direct_connection_clients[pubkey] |                 resp = communicator.direct_connection_clients[pubkey] | ||||||
|             else: |             else: | ||||||
|                 """Spawn a thread that will create the client and eventually add it to the |                 """Spawn a thread that will create the client and eventually add it to the | ||||||
|                 communicator.active_services  |                 communicator.active_services  | ||||||
|                 """ |                 """ | ||||||
|                 threading.Thread(target=onionrservices.OnionrServices().create_client, args=[pubkey, communicator], daemon=True).start() |                 threading.Thread(target=onionrservices.OnionrServices().create_client,  | ||||||
|  |                                  args=[pubkey, communicator], daemon=True).start() | ||||||
| 
 | 
 | ||||||
|             return Response(resp) |             return Response(resp) | ||||||
|  | @ -84,6 +84,9 @@ class InvalidAddress(Exception): | ||||||
| class InvalidAPIVersion(Exception): | class InvalidAPIVersion(Exception): | ||||||
|     pass |     pass | ||||||
| 
 | 
 | ||||||
|  | class Timeout(Exception): | ||||||
|  |     pass | ||||||
|  | 
 | ||||||
| # file exceptions | # file exceptions | ||||||
| 
 | 
 | ||||||
| class DiskAllocationReached(Exception): | class DiskAllocationReached(Exception): | ||||||
|  |  | ||||||
|  | @ -31,7 +31,6 @@ class OnionrServices: | ||||||
|         self.servers = {} |         self.servers = {} | ||||||
|         self.clients = {} |         self.clients = {} | ||||||
|         self.shutdown = False |         self.shutdown = False | ||||||
|         return |  | ||||||
|      |      | ||||||
|     def create_server(self, peer, address, comm_inst): |     def create_server(self, peer, address, comm_inst): | ||||||
|         ''' |         ''' | ||||||
|  | @ -55,7 +54,7 @@ class OnionrServices: | ||||||
| 
 | 
 | ||||||
|     @staticmethod |     @staticmethod | ||||||
|     def create_client(peer, comm_inst=None): |     def create_client(peer, comm_inst=None): | ||||||
|         # Create ephemeral onion service to bootstrap connection |         # Create ephemeral onion service to bootstrap connection to server | ||||||
|         if not comm_inst == None: |         if not comm_inst == None: | ||||||
|             try: |             try: | ||||||
|                 return comm_inst.direct_connection_clients[peer] |                 return comm_inst.direct_connection_clients[peer] | ||||||
|  |  | ||||||
|  | @ -25,7 +25,16 @@ from netcontroller import get_open_port | ||||||
| from . import httpheaders | from . import httpheaders | ||||||
| from onionrutils import stringvalidators, epoch | from onionrutils import stringvalidators, epoch | ||||||
| import config, onionrblocks, filepaths | import config, onionrblocks, filepaths | ||||||
|  | import onionrexceptions | ||||||
| import deadsimplekv as simplekv | import deadsimplekv as simplekv | ||||||
|  | import warden | ||||||
|  | from . import pool | ||||||
|  | 
 | ||||||
|  | def __bootstrap_timeout(server: WSGIServer, timeout: int, signal_object): | ||||||
|  |     time.sleep(timeout) | ||||||
|  |     signal_object.timed_out = True | ||||||
|  |     server.stop() | ||||||
|  | 
 | ||||||
| def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300): | def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300): | ||||||
|     ''' |     ''' | ||||||
|         Bootstrap client services |         Bootstrap client services | ||||||
|  | @ -34,8 +43,16 @@ def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300): | ||||||
|     if not stringvalidators.validate_pub_key(peer): |     if not stringvalidators.validate_pub_key(peer): | ||||||
|         raise ValueError('Peer must be valid base32 ed25519 public key') |         raise ValueError('Peer must be valid base32 ed25519 public key') | ||||||
|      |      | ||||||
|  |     connection_pool = None | ||||||
|  | 
 | ||||||
|  |     # here we use a lambda for the timeout thread to set to true | ||||||
|  |     timed_out = lambda: None | ||||||
|  |     timed_out.timed_out = False | ||||||
|  | 
 | ||||||
|     bootstrap_port = get_open_port() |     bootstrap_port = get_open_port() | ||||||
|     bootstrap_app = Flask(__name__) |     bootstrap_app = Flask(__name__) | ||||||
|  |     bootstrap_app.config['MAX_CONTENT_LENGTH'] = 1 * 1024 | ||||||
|  | 
 | ||||||
|     http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None) |     http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None) | ||||||
|     try: |     try: | ||||||
|         assert comm_inst is not None |         assert comm_inst is not None | ||||||
|  | @ -43,6 +60,7 @@ def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300): | ||||||
|         pass |         pass | ||||||
|     else: |     else: | ||||||
|         comm_inst.service_greenlets.append(http_server) |         comm_inst.service_greenlets.append(http_server) | ||||||
|  |         connection_pool = comm_inst.shared_state.get(pool.ServicePool) | ||||||
|      |      | ||||||
|     bootstrap_address = '' |     bootstrap_address = '' | ||||||
|     shutdown = False |     shutdown = False | ||||||
|  | @ -71,12 +89,16 @@ def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300): | ||||||
|             return Response("") |             return Response("") | ||||||
| 
 | 
 | ||||||
|     with Controller.from_port(port=config.get('tor.controlPort')) as controller: |     with Controller.from_port(port=config.get('tor.controlPort')) as controller: | ||||||
|  |         connection_pool.bootstrap_pending.append(peer) | ||||||
|         # Connect to the Tor process for Onionr |         # Connect to the Tor process for Onionr | ||||||
|         controller.authenticate(config.get('tor.controlpassword')) |         controller.authenticate(config.get('tor.controlpassword')) | ||||||
|         # Create the v3 onion service |         # Create the v3 onion service | ||||||
|         response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, key_type = 'NEW', key_content = 'ED25519-V3', await_publication = True) |         response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, key_type = 'NEW', key_content = 'ED25519-V3', await_publication = True) | ||||||
|         onionrblocks.insert(response.service_id, header='con', sign=True, encryptType='asym',  |         onionrblocks.insert(response.service_id, header='con', sign=True, encryptType='asym',  | ||||||
|         asymPeer=peer, disableForward=True, expire=(epoch.get_epoch() + bootstrap_timeout)) |         asymPeer=peer, disableForward=True, expire=(epoch.get_epoch() + bootstrap_timeout)) | ||||||
|  |          | ||||||
|  |         threading.Thread(target=__bootstrap_timeout, args=[http_server, bootstrap_timeout], daemon=True) | ||||||
|  | 
 | ||||||
|         # Run the bootstrap server |         # Run the bootstrap server | ||||||
|         try: |         try: | ||||||
|             http_server.serve_forever() |             http_server.serve_forever() | ||||||
|  | @ -86,5 +108,10 @@ def bootstrap_client_service(peer, comm_inst=None, bootstrap_timeout=300): | ||||||
|     # Add the address to the client pool |     # Add the address to the client pool | ||||||
|     if not comm_inst is None: |     if not comm_inst is None: | ||||||
|         comm_inst.direct_connection_clients[peer] = response.service_id |         comm_inst.direct_connection_clients[peer] = response.service_id | ||||||
|  |      | ||||||
|  |     connection_pool.bootstrap_pending.remove(peer) | ||||||
|  | 
 | ||||||
|  |     if timed_out.timed_out: | ||||||
|  |         raise onionrexceptions.Timeout | ||||||
|     # Now that the bootstrap server has received a server, return the address |     # Now that the bootstrap server has received a server, return the address | ||||||
|     return key_store.get(bs_id) |     return key_store.get(bs_id) | ||||||
|  |  | ||||||
							
								
								
									
										29
									
								
								onionr/onionrservices/pool.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								onionr/onionrservices/pool.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | ''' | ||||||
|  |     Onionr - Private P2P Communication | ||||||
|  | 
 | ||||||
|  |     Holds active onionrservices clients and servers | ||||||
|  | ''' | ||||||
|  | ''' | ||||||
|  |     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 <https://www.gnu.org/licenses/>. | ||||||
|  | ''' | ||||||
|  | from onionrutils import epoch | ||||||
|  | class ServicePool: | ||||||
|  |     def __init__(self): | ||||||
|  |         self.servers = [] | ||||||
|  |         self.clients = [] | ||||||
|  |         self.bootstrap_pending = [] | ||||||
|  |      | ||||||
|  |     def add_server(self, service): | ||||||
|  |         self.servers.append((service, epoch.get_epoch())) | ||||||
|  |          | ||||||
							
								
								
									
										3
									
								
								onionr/onionrservices/warden/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								onionr/onionrservices/warden/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | from . import client # Client connection warden. Monitors & validates connection security. | ||||||
|  | from . import server # Server connection warden. Monitors and validates server security | ||||||
|  | from . import watchdog # Watchdog. Oversees running services for statistic collection and TTL control | ||||||
							
								
								
									
										19
									
								
								onionr/onionrservices/warden/bootstrap.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								onionr/onionrservices/warden/bootstrap.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | ''' | ||||||
|  |     Onionr - Private P2P Communication | ||||||
|  | 
 | ||||||
|  |     Bootstrap warden monitors the bootstrap server | ||||||
|  | ''' | ||||||
|  | ''' | ||||||
|  |     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 <https://www.gnu.org/licenses/>. | ||||||
|  | ''' | ||||||
							
								
								
									
										0
									
								
								onionr/onionrservices/warden/client.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								onionr/onionrservices/warden/client.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								onionr/onionrservices/warden/server.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								onionr/onionrservices/warden/server.py
									
										
									
									
									
										Normal file
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue