Integrate Simplified Privacy essentials library
This commit is contained in:
parent
0ab1ac4168
commit
a3a9fb8843
11 changed files with 25 additions and 176 deletions
|
|
@ -11,7 +11,6 @@ class Constants:
|
|||
|
||||
CONNECTION_RETRY_INTERVAL: Final[int] = int(os.environ.get('CONNECTION_RETRY_INTERVAL', '5'))
|
||||
MAX_CONNECTION_ATTEMPTS: Final[int] = int(os.environ.get('MAX_CONNECTION_ATTEMPTS', '2'))
|
||||
TOR_BOOTSTRAP_TIMEOUT: Final[int] = int(os.environ.get('TOR_BOOTSTRAP_TIMEOUT', '90'))
|
||||
|
||||
HV_CLIENT_PATH: Final[str] = os.environ.get('HV_CLIENT_PATH')
|
||||
HV_CLIENT_VERSION_NUMBER: Final[str] = os.environ.get('HV_CLIENT_VERSION_NUMBER')
|
||||
|
|
@ -48,7 +47,3 @@ class Constants:
|
|||
|
||||
HV_SESSION_STATE_HOME: Final[str] = f'{HV_STATE_HOME}/sessions'
|
||||
HV_TOR_STATE_HOME: Final[str] = f'{HV_STATE_HOME}/tor'
|
||||
|
||||
HV_TOR_CONTROL_SOCKET_PATH: Final[str] = f'{HV_TOR_STATE_HOME}/tor.sock'
|
||||
HV_TOR_PROCESS_IDENTIFIER_PATH: Final[str] = f'{HV_TOR_STATE_HOME}/tor.pid'
|
||||
HV_TOR_INSTANCE_LOCK_PATH: Final[str] = f'{HV_TOR_STATE_HOME}/lock'
|
||||
|
|
|
|||
|
|
@ -26,10 +26,6 @@ class ConnectionTerminationError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class TorServiceInitializationError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class PolicyAssignmentError(Exception):
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from collections.abc import Callable
|
||||
from concurrent.futures import ThreadPoolExecutor, TimeoutError as FutureTimeoutError
|
||||
from core.Constants import Constants
|
||||
from core.Errors import InvalidSubscriptionError, MissingSubscriptionError, ConnectionUnprotectedError, ConnectionTerminationError, CommandNotFoundError, TorServiceInitializationError
|
||||
from core.Errors import InvalidSubscriptionError, MissingSubscriptionError, ConnectionUnprotectedError, ConnectionTerminationError, CommandNotFoundError
|
||||
from core.controllers.ConfigurationController import ConfigurationController
|
||||
from core.controllers.ProfileController import ProfileController
|
||||
from core.controllers.SessionStateController import SessionStateController
|
||||
|
|
@ -9,20 +8,17 @@ from core.controllers.SystemStateController import SystemStateController
|
|||
from core.models.session.SessionProfile import SessionProfile
|
||||
from core.models.system.SystemProfile import SystemProfile
|
||||
from core.models.system.SystemState import SystemState
|
||||
from core.observers import ConnectionObserver
|
||||
from core.observers.ConnectionObserver import ConnectionObserver
|
||||
from core.services.WebServiceApiService import WebServiceApiService
|
||||
from essentials.modules.TorModule import TorModule
|
||||
from pathlib import Path
|
||||
from subprocess import CalledProcessError
|
||||
from typing import Union, Optional, Any
|
||||
import os
|
||||
import psutil
|
||||
import random
|
||||
import re
|
||||
import shutil
|
||||
import socket
|
||||
import stem
|
||||
import stem.control
|
||||
import stem.process
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
|
@ -209,123 +205,34 @@ class ConnectionController:
|
|||
ConnectionController.terminate_tor_connection()
|
||||
time.sleep(1.0)
|
||||
|
||||
@staticmethod
|
||||
def establish_tor_session_connection(port_number: int, connection_observer: Optional[ConnectionObserver] = None):
|
||||
|
||||
try:
|
||||
|
||||
controller = stem.control.Controller.from_socket_file(Constants.HV_TOR_CONTROL_SOCKET_PATH)
|
||||
controller.authenticate()
|
||||
|
||||
except (FileNotFoundError, stem.SocketError, TypeError, IndexError):
|
||||
|
||||
ConnectionController.establish_tor_connection(connection_observer=connection_observer)
|
||||
|
||||
controller = stem.control.Controller.from_socket_file(Constants.HV_TOR_CONTROL_SOCKET_PATH)
|
||||
controller.authenticate()
|
||||
|
||||
socks_port_numbers = [str(port_number) for port_number in controller.get_ports('socks')]
|
||||
socks_port_numbers.append(str(port_number))
|
||||
|
||||
controller.set_conf('SocksPort', socks_port_numbers)
|
||||
|
||||
@staticmethod
|
||||
def terminate_tor_session_connection(port_number: int):
|
||||
|
||||
try:
|
||||
|
||||
controller = stem.control.Controller.from_socket_file(Constants.HV_TOR_CONTROL_SOCKET_PATH)
|
||||
controller.authenticate()
|
||||
|
||||
socks_port_numbers = [str(port_number) for port_number in controller.get_ports('socks')]
|
||||
|
||||
if len(socks_port_numbers) > 1:
|
||||
|
||||
socks_port_numbers = [socks_port_number for socks_port_number in socks_port_numbers if socks_port_number != port_number]
|
||||
controller.set_conf('SocksPort', socks_port_numbers)
|
||||
|
||||
else:
|
||||
controller.set_conf('SocksPort', '0')
|
||||
|
||||
except (FileNotFoundError, stem.SocketError, TypeError, IndexError):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def establish_tor_connection(connection_observer: Optional[ConnectionObserver] = None):
|
||||
|
||||
Path(Constants.HV_TOR_STATE_HOME).mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||
|
||||
ConnectionController.terminate_tor_connection()
|
||||
|
||||
if connection_observer is not None:
|
||||
connection_observer.notify('tor_bootstrapping')
|
||||
|
||||
with ThreadPoolExecutor(max_workers=1) as executor:
|
||||
|
||||
future = executor.submit(
|
||||
stem.process.launch_tor_with_config,
|
||||
config={
|
||||
'DataDirectory': Constants.HV_TOR_STATE_HOME,
|
||||
'ControlSocket': Constants.HV_TOR_CONTROL_SOCKET_PATH,
|
||||
'PIDFile': Constants.HV_TOR_PROCESS_IDENTIFIER_PATH,
|
||||
'SocksPort': '0'
|
||||
},
|
||||
init_msg_handler=lambda contents: ConnectionController.__on_tor_initialization_message(contents, connection_observer)
|
||||
)
|
||||
|
||||
try:
|
||||
future.result(timeout=Constants.TOR_BOOTSTRAP_TIMEOUT)
|
||||
|
||||
except FutureTimeoutError:
|
||||
|
||||
ConnectionController.terminate_tor_connection()
|
||||
raise TorServiceInitializationError('The dedicated Tor service could not be initialized.')
|
||||
|
||||
if connection_observer is not None:
|
||||
connection_observer.notify('tor_bootstrapped')
|
||||
|
||||
try:
|
||||
|
||||
controller = stem.control.Controller.from_socket_file(Constants.HV_TOR_CONTROL_SOCKET_PATH)
|
||||
controller.authenticate()
|
||||
|
||||
except (FileNotFoundError, stem.SocketError, TypeError, IndexError):
|
||||
|
||||
ConnectionController.terminate_tor_connection()
|
||||
raise TorServiceInitializationError('The dedicated Tor service could not be initialized.')
|
||||
tor_module = TorModule(Constants.HV_TOR_STATE_HOME)
|
||||
tor_module.start_service(connection_observer)
|
||||
|
||||
for session_state in SessionStateController.all():
|
||||
|
||||
for port_number in session_state.network_port_numbers.tor:
|
||||
ConnectionController.establish_tor_session_connection(port_number)
|
||||
tor_module.create_session(port_number)
|
||||
|
||||
@staticmethod
|
||||
def terminate_tor_connection():
|
||||
|
||||
control_socket_file = Path(Constants.HV_TOR_CONTROL_SOCKET_PATH)
|
||||
process_identifier_file = Path(Constants.HV_TOR_PROCESS_IDENTIFIER_PATH)
|
||||
instance_lock_file = Path(Constants.HV_TOR_INSTANCE_LOCK_PATH)
|
||||
tor_module = TorModule(Constants.HV_TOR_STATE_HOME)
|
||||
tor_module.stop_service()
|
||||
|
||||
try:
|
||||
process_identifier = int(process_identifier_file.read_text().strip())
|
||||
except (OSError, ValueError):
|
||||
process_identifier = None
|
||||
@staticmethod
|
||||
def establish_tor_session_connection(port_number: int, connection_observer: Optional[ConnectionObserver] = None):
|
||||
|
||||
if process_identifier is not None:
|
||||
tor_module = TorModule(Constants.HV_TOR_STATE_HOME)
|
||||
tor_module.create_session(port_number, connection_observer)
|
||||
|
||||
try:
|
||||
@staticmethod
|
||||
def terminate_tor_session_connection(port_number: int):
|
||||
|
||||
process = psutil.Process(process_identifier)
|
||||
|
||||
if process.is_running():
|
||||
process.terminate()
|
||||
|
||||
except psutil.NoSuchProcess:
|
||||
pass
|
||||
|
||||
control_socket_file.unlink(missing_ok=True)
|
||||
process_identifier_file.unlink(missing_ok=True)
|
||||
instance_lock_file.unlink(missing_ok=True)
|
||||
tor_module = TorModule(Constants.HV_TOR_STATE_HOME)
|
||||
tor_module.destroy_session(port_number)
|
||||
|
||||
@staticmethod
|
||||
def establish_wireguard_session_connection(profile: SessionProfile, session_directory: str, port_number: int):
|
||||
|
|
@ -586,16 +493,3 @@ class ConnectionController:
|
|||
return True
|
||||
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def __on_tor_initialization_message(contents, connection_observer: Optional[ConnectionObserver] = None):
|
||||
|
||||
if connection_observer is not None:
|
||||
|
||||
if 'Bootstrapped ' in contents:
|
||||
|
||||
progress = (m := re.search(r' (\d{1,3})% ', contents)) and int(m.group(1))
|
||||
|
||||
connection_observer.notify('tor_bootstrap_progressing', None, dict(
|
||||
progress=progress
|
||||
))
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
class Event:
|
||||
|
||||
def __init__(self, subject = None, meta = None):
|
||||
|
||||
self.subject = subject
|
||||
self.meta = meta or {}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from core.observers.BaseObserver import BaseObserver
|
||||
from essentials.observers.BaseObserver import BaseObserver
|
||||
|
||||
|
||||
class ApplicationVersionObserver(BaseObserver):
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
from core.models.Event import Event
|
||||
|
||||
|
||||
class BaseObserver:
|
||||
|
||||
def subscribe(self, topic, callback):
|
||||
|
||||
callbacks = getattr(self, f'on_{topic}', None)
|
||||
|
||||
if callbacks is None:
|
||||
return
|
||||
|
||||
callbacks.append(callback)
|
||||
|
||||
def notify(self, topic, subject = None, meta = None):
|
||||
|
||||
callbacks = getattr(self, f'on_{topic}', None)
|
||||
|
||||
if callbacks is None:
|
||||
return
|
||||
|
||||
event = Event(subject, meta)
|
||||
|
||||
for callback in callbacks:
|
||||
callback(event)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from core.observers.BaseObserver import BaseObserver
|
||||
from essentials.observers.BaseObserver import BaseObserver
|
||||
|
||||
|
||||
class ClientObserver(BaseObserver):
|
||||
|
|
|
|||
|
|
@ -1,10 +1,5 @@
|
|||
from core.observers.BaseObserver import BaseObserver
|
||||
from essentials.observers.ConnectionObserver import ConnectionObserver as BaseConnectionObserver
|
||||
|
||||
|
||||
class ConnectionObserver(BaseObserver):
|
||||
|
||||
def __init__(self):
|
||||
self.on_connecting = []
|
||||
self.on_tor_bootstrapping = []
|
||||
self.on_tor_bootstrap_progressing = []
|
||||
self.on_tor_bootstrapped = []
|
||||
class ConnectionObserver(BaseConnectionObserver):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from core.observers.BaseObserver import BaseObserver
|
||||
from essentials.observers.BaseObserver import BaseObserver
|
||||
|
||||
|
||||
class InvoiceObserver(BaseObserver):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from core.observers.BaseObserver import BaseObserver
|
||||
from essentials.observers.BaseObserver import BaseObserver
|
||||
|
||||
|
||||
class ProfileObserver(BaseObserver):
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ dependencies = [
|
|||
"pysocks ~= 1.7.1",
|
||||
"python-dateutil ~= 2.9.0.post0",
|
||||
"requests ~= 2.32.5",
|
||||
"stem ~= 1.8.2",
|
||||
"sp-essentials ~= 1.0.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
|
|||
Loading…
Reference in a new issue