Singbox on disable, checks if wireguard is active, and kills it
This commit is contained in:
parent
732b17fb4a
commit
5dc1463862
8 changed files with 102 additions and 18 deletions
|
|
@ -1,23 +1,24 @@
|
|||
from core.services.profiles.ProfileRepository import ProfileRepository
|
||||
from core.services.networking.systemwide.systemwide_wireguard import terminate_system_connection
|
||||
from core.services.networking.general_connection_tools.testing_evaluating import system_uses_wireguard_interface
|
||||
from core.services.networking.general_connection_tools.connection_enable import establish_connection
|
||||
from core.services.networking.systemwide.systemwide_utils import get_firewall_setting, get_dns_setting
|
||||
from core.services.networking.systemwide.encrypted_proxy.singbox_runner import end_singbox
|
||||
from core.services.networking.systemwide import killswitch
|
||||
# from core.services.networking.systemwide.systemwide_wireguard import terminate_system_connection
|
||||
# from core.services.networking.general_connection_tools.testing_evaluating import system_uses_wireguard_interface
|
||||
# from core.services.networking.general_connection_tools.connection_enable import establish_connection
|
||||
# from core.services.networking.systemwide.systemwide_utils import get_firewall_setting, get_dns_setting
|
||||
# from core.services.networking.systemwide.encrypted_proxy.singbox_runner import end_singbox
|
||||
# from core.services.networking.systemwide import killswitch
|
||||
from core.services.subscriptions import subscriptions
|
||||
from core.errors.exceptions import FirewallError
|
||||
# from core.errors.exceptions import FirewallError
|
||||
from core.models.Result import Result, ResultError
|
||||
from core.observers.TicketObserver import TicketObserver
|
||||
# from core.observers.TicketObserver import TicketObserver
|
||||
# from core.services.assassin.ticket_respawn import respawn_profile
|
||||
# from core.services.assassin import assassin_tools
|
||||
from core.errors.logger import logger
|
||||
|
||||
from core.Errors import InvalidSubscriptionError, MissingSubscriptionError, ConnectionTerminationError, ProfileActivationError, ProfileDeactivationError, MissingLocationError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
|
||||
from core.controllers.ApplicationController import ApplicationController
|
||||
from core.controllers.ApplicationVersionController import ApplicationVersionController
|
||||
from core.controllers.SessionStateController import SessionStateController
|
||||
from core.controllers.SystemStateController import SystemStateController
|
||||
from core.Errors import InvalidSubscriptionError, MissingSubscriptionError
|
||||
#, ConnectionTerminationError, ProfileActivationError, ProfileDeactivationError, MissingLocationError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
|
||||
# from core.controllers.ApplicationController import ApplicationController
|
||||
# from core.controllers.ApplicationVersionController import ApplicationVersionController
|
||||
# from core.controllers.SessionStateController import SessionStateController
|
||||
# from core.controllers.SystemStateController import SystemStateController
|
||||
from core.models.BaseProfile import BaseProfile as Profile
|
||||
from core.models.Subscription import Subscription
|
||||
from core.models.session.SessionProfile import SessionProfile
|
||||
|
|
|
|||
15
core/controllers/profile_state/get_profile_data.py
Normal file
15
core/controllers/profile_state/get_profile_data.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from core.models.enum_models import ProtocolChoice, valid_enum
|
||||
from core.controllers.ProfileController import ProfileController
|
||||
|
||||
|
||||
def get_protocol_enum(profile_id: int) -> ProtocolChoice|bool:
|
||||
"""Return the Enum for a given Profile's Protocol Choice"""
|
||||
|
||||
profile = ProfileController.get(profile_id)
|
||||
|
||||
protocol_string = profile.connection.code
|
||||
|
||||
if not valid_enum(protocol_string, ProtocolChoice):
|
||||
return False
|
||||
else:
|
||||
return ProtocolChoice(protocol_string)
|
||||
|
|
@ -8,6 +8,8 @@ class ProtocolChoice(Enum):
|
|||
SOCK5_PROXY = "proxy"
|
||||
# MASKED_WIREGUARD = "masked_wireguard"
|
||||
|
||||
SINGBOX_PROTOCOLS = [ProtocolChoice.HYSTERIA2, ProtocolChoice.VLESS]
|
||||
|
||||
class Currency(Enum):
|
||||
MONERO = "monero"
|
||||
BITCOIN = "bitcoin"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
from core.models.enum_models import ProtocolChoice
|
||||
from core.Constants import Constants
|
||||
|
||||
# generic
|
||||
from dataclasses import dataclass
|
||||
from dataclasses_json import dataclass_json
|
||||
from pathlib import Path
|
||||
|
|
@ -14,6 +17,7 @@ class SystemState:
|
|||
profile_id: int
|
||||
firewalled: bool
|
||||
dns_set: bool
|
||||
protocol: ProtocolChoice
|
||||
process_id: Optional[int] = None
|
||||
|
||||
def save(self: Self):
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ def launch_encrypted_proxy(
|
|||
tries = tries + 1
|
||||
|
||||
if exists_already:
|
||||
logger.info("The config exists already, attempting to get the IP from it...")
|
||||
server_ip = get_value_from_json_file(filepath=config_path, category="outbounds", key="server")
|
||||
else:
|
||||
server_ip = setup_config_and_return_ip(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
from core.models.enum_models import ProtocolChoice, SINGBOX_PROTOCOLS
|
||||
from core.models.system.SystemState import SystemState
|
||||
from core.utils.type_checker import type_checker
|
||||
from core.models.Result import Result
|
||||
from core.errors.logger import logger
|
||||
|
||||
@type_checker
|
||||
def kill_any_protocol(current_state: SystemState, active_protocol: ProtocolChoice) -> Result:
|
||||
"""Kill any protocol that's currently active"""
|
||||
|
||||
logger.info(f"Killing the external protocol {active_protocol}")
|
||||
|
||||
firewall = current_state.firewalled
|
||||
dns_set = current_state.dns_set
|
||||
|
||||
if active_protocol == ProtocolChoice.WIREGUARD:
|
||||
from core.services.networking.systemwide_wireguard import terminate_system_connection
|
||||
terminate_system_connection(
|
||||
firewall_setting=firewall,
|
||||
dns_setting=dns_set
|
||||
)
|
||||
return Result(valid=True)
|
||||
|
||||
elif active_protocol in SINGBOX_PROTOCOLS:
|
||||
from core.services.networking.systemwide.encrypted_proxy.singbox_runner import end_singbox
|
||||
return end_singbox()
|
||||
|
||||
else:
|
||||
logger.error("Not a supported Systemwide Profile.")
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
from core.controllers.profile_state.get_profile_data import get_protocol_enum
|
||||
from core.models.enum_models import ProtocolChoice
|
||||
from core.services.networking.general_connection_tools.cross_protocol import kill_any_protocol
|
||||
from core.services.networking.systemwide.encrypted_proxy import singbox
|
||||
from core.services.networking.systemwide.encrypted_proxy.close_singbox import orchestrate_closing
|
||||
from core.services.networking.systemwide.general_tools import interface_tools
|
||||
|
|
@ -137,6 +140,9 @@ def end_singbox() -> Result:
|
|||
# get by systemstate:
|
||||
current_state = SystemState.get()
|
||||
|
||||
# ------------------
|
||||
# KILL ZOMBIE SINGBOX NOT TIED TO PROFILES
|
||||
# ------------------
|
||||
if not current_state:
|
||||
# Make sure there's no singbox id:
|
||||
singbox_pid = pid_tools.get_pid_by_app_name(exact_app_name="sing-box")
|
||||
|
|
@ -154,7 +160,18 @@ def end_singbox() -> Result:
|
|||
|
||||
logger.error(f"Critical Issue! State JSON is blank, but Singbox is still running. {singbox_pid}")
|
||||
|
||||
# kill the real singbox
|
||||
|
||||
# ------------------
|
||||
# KILL NON-SINGBOX SUCH AS WIREGUARD
|
||||
# ------------------
|
||||
active_protocol = get_protocol_enum(current_state.profile_id)
|
||||
logger.info(f"State JSON shows there is already an active profile with id {profile_id} and protocol {active_protocol}")
|
||||
if active_protocol not in SINGBOX_PROTOCOLS:
|
||||
return kill_external_protocol(current_state=current_state, active_protocol=active_protocol)
|
||||
|
||||
# ------------------
|
||||
# KILL THE "REAL" KNOWN ACTIVE SINGBOX PROFILE
|
||||
# ------------------
|
||||
try:
|
||||
killed_existing = orchestrate_closing(
|
||||
current_state=current_state,
|
||||
|
|
@ -250,6 +267,7 @@ def start_singbox(
|
|||
# ============= CHECK INTERFACE =============
|
||||
if connection_observer:
|
||||
connection_observer.notify("connecting", "Testing Interface..")
|
||||
print(f"The Constants.SINGBOX_TUN_IF is {Constants.SINGBOX_TUN_IF}")
|
||||
interface_result = interface_tools.get_output(Constants.SINGBOX_TUN_IF)
|
||||
if not interface_result.valid:
|
||||
error_msg = f"We could not get the interface's output, despite having a process id of {process_id}"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from core.models.enum_models import ProtocolChoice, valid_enum
|
||||
from core.controllers.ConnectionController import ConnectionController
|
||||
from core.controllers.ProfileController import ProfileController
|
||||
from core.services.networking.systemwide.systemwide_wireguard import terminate_system_connection
|
||||
|
|
@ -102,7 +103,7 @@ def enable_session_profile(
|
|||
profile_observer.notify('enabled', profile)
|
||||
|
||||
ApplicationController.launch(application_version, profile, port_number, asynchronous=asynchronous, profile_observer=profile_observer, ticket_observer=ticket_observer, connection_observer=connection_observer)
|
||||
return Result(valid=True)
|
||||
return Result(valid=True, data=profile.type)
|
||||
|
||||
|
||||
|
||||
|
|
@ -125,7 +126,7 @@ def enable_profile(
|
|||
if not ProfileStateConflictError in ignore:
|
||||
raise ProfileStateConflictError('The profile is already enabled or its session was not properly terminated.')
|
||||
else:
|
||||
ProfileController.disable(profile)
|
||||
disable_profile(profile)
|
||||
|
||||
# =========== PRISTINE ============
|
||||
if pristine:
|
||||
|
|
@ -155,7 +156,7 @@ def enable_profile(
|
|||
if connection_result.valid:
|
||||
if profile_observer is not None:
|
||||
profile_observer.notify('enabled', profile)
|
||||
return Result(valid=True)
|
||||
return Result(valid=True, data=profile.type)
|
||||
else:
|
||||
logger.error(f"Couldn't enable the profile: {connection_result.error_type}")
|
||||
error_msg = connection_result.message
|
||||
|
|
@ -311,4 +312,17 @@ def destroy_profile(
|
|||
if profile_observer is not None:
|
||||
profile_observer.notify('destroyed', profile)
|
||||
|
||||
return Result(valid=True, message="Deleted Profile")
|
||||
return Result(valid=True, message="Deleted Profile")
|
||||
|
||||
|
||||
def get_protocol_enum(profile_id: int) -> ProtocolChoice|bool:
|
||||
"""Return the Enum for a given Profile's Protocol Choice"""
|
||||
|
||||
profile = ProfileController.get(profile_id)
|
||||
|
||||
protocol_string = profile.connection.code
|
||||
|
||||
if not valid_enum(protocol_string, ProtocolChoice):
|
||||
return False
|
||||
else:
|
||||
return ProtocolChoice(protocol_string)
|
||||
Loading…
Reference in a new issue