Wireguard renegotiation now flows through the new HTTPx modules
This commit is contained in:
parent
320037a2b1
commit
061df01a0d
8 changed files with 91 additions and 78 deletions
20
Untitled Document
Normal file
20
Untitled Document
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
|
from core.services.networking.systemwide.encrypted_proxy.get_proxy_data import post_operator_proxy
|
||||||
|
|
||||||
|
import json
|
||||||
|
observer = ConnectionObserver()
|
||||||
|
observer.subscribe("connecting", lambda msg: print(f"[CONNECT] {msg}"))
|
||||||
|
observer.subscribe("tor_bootstrapping", lambda msg: print(f"[BOOTSTRAP] {msg}"))
|
||||||
|
observer.subscribe("tor_bootstrap_progressing", lambda msg: print(f"[PROGRESS] {msg}"))
|
||||||
|
observer.subscribe("tor_bootstrapped", lambda msg: print(f"[SUCCESS] {msg}"))
|
||||||
|
observer.subscribe("custom_message", lambda msg: print(f"[INFO] {msg}"))
|
||||||
|
|
||||||
|
|
||||||
|
results = post_operator_proxy(
|
||||||
|
billing_code="2UEN-SXAJ-Z1YO-93EJ",
|
||||||
|
location_id=4,
|
||||||
|
protocol="hysteria2",
|
||||||
|
connection_observer=observer
|
||||||
|
)
|
||||||
|
|
||||||
|
print(results)
|
||||||
|
|
@ -81,6 +81,8 @@ class ProfileController:
|
||||||
port_number = establish_connection(profile, ignore=ignore, connection_observer=connection_observer)
|
port_number = establish_connection(profile, ignore=ignore, connection_observer=connection_observer)
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
raise ProfileActivationError('The profile could not be enabled.')
|
raise ProfileActivationError('The profile could not be enabled.')
|
||||||
|
except ValueError:
|
||||||
|
raise ProfileActivationError('The profile could not be enabled.')
|
||||||
|
|
||||||
if profile_observer is not None:
|
if profile_observer is not None:
|
||||||
profile_observer.notify('enabled', profile)
|
profile_observer.notify('enabled', profile)
|
||||||
|
|
@ -99,6 +101,8 @@ class ProfileController:
|
||||||
raise
|
raise
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
raise ProfileActivationError('The profile could not be enabled.')
|
raise ProfileActivationError('The profile could not be enabled.')
|
||||||
|
except ValueError:
|
||||||
|
raise ProfileActivationError('The profile could not be enabled.')
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -163,6 +167,8 @@ class ProfileController:
|
||||||
))
|
))
|
||||||
except ConnectionTerminationError:
|
except ConnectionTerminationError:
|
||||||
raise ProfileDeactivationError('The profile could not be disabled.')
|
raise ProfileDeactivationError('The profile could not be disabled.')
|
||||||
|
except ValueError:
|
||||||
|
raise ProfileDeactivationError('The profile could not be disabled.')
|
||||||
except FirewallError:
|
except FirewallError:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -215,14 +215,14 @@ class WebServiceApiService:
|
||||||
|
|
||||||
return requests.post(Constants.SP_API_BASE_URL + path, headers=headers, json=body, proxies=proxies)
|
return requests.post(Constants.SP_API_BASE_URL + path, headers=headers, json=body, proxies=proxies)
|
||||||
|
|
||||||
@staticmethod
|
# @staticmethod
|
||||||
def get_cached_sync(proxies: Optional[dict] = None):
|
# def get_cached_sync(proxies: Optional[dict] = None):
|
||||||
|
|
||||||
from requests.status_codes import codes as status_codes
|
# from requests.status_codes import codes as status_codes
|
||||||
|
|
||||||
response = WebServiceApiService.__get('/cachedsync', None, proxies)
|
# response = WebServiceApiService.__get('/cachedsync', None, proxies)
|
||||||
|
|
||||||
if response.status_code == status_codes.OK:
|
# if response.status_code == status_codes.OK:
|
||||||
return response.json()
|
# return response.json()
|
||||||
else:
|
# else:
|
||||||
return None
|
# return None
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
|
from core.services.networking.httpx import connect
|
||||||
|
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
||||||
from core.models.session.SessionProfile import SessionProfile
|
from core.models.session.SessionProfile import SessionProfile
|
||||||
from core.models.system.SystemProfile import SystemProfile
|
from core.models.system.SystemProfile import SystemProfile
|
||||||
from core.Errors import MissingSubscriptionError, MissingLocationError, InvalidSubscriptionError
|
from core.Errors import MissingSubscriptionError, MissingLocationError, InvalidSubscriptionError
|
||||||
from core.services.WebServiceApiService import WebServiceApiService
|
from core.services.WebServiceApiService import WebServiceApiService
|
||||||
from core.controllers.ConnectionController import ConnectionController
|
from core.controllers.ConnectionController import ConnectionController
|
||||||
from core.observers.ConnectionObserver import ConnectionObserver
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
|
from core.Constants import Constants
|
||||||
|
|
||||||
from typing import Union, Optional
|
from typing import Union, Optional
|
||||||
import base64
|
import base64
|
||||||
import re
|
import re
|
||||||
|
|
@ -21,16 +25,39 @@ def register_wireguard_session(
|
||||||
raise MissingLocationError()
|
raise MissingLocationError()
|
||||||
|
|
||||||
wireguard_keys = _generate_wireguard_keys()
|
wireguard_keys = _generate_wireguard_keys()
|
||||||
|
public_key = wireguard_keys.get('public', None)
|
||||||
wireguard_configuration = ConnectionController.with_preferred_connection(
|
if not public_key:
|
||||||
profile.location.country_code,
|
logger.error("No Public Key Generated. Raising ValueError")
|
||||||
profile.location.code,
|
raise ValueError("No Public Key Generated.")
|
||||||
profile.subscription.billing_code,
|
|
||||||
wireguard_keys.get('public'),
|
country_code = profile.location.country_code
|
||||||
task=WebServiceApiService.post_wireguard_session,
|
location_code = profile.location.code
|
||||||
connection_observer=connection_observer
|
billing_code = profile.subscription.billing_code
|
||||||
|
url = f'{Constants.SP_API_BASE_URL}/countries/{country_code}/locations/{location_code}/wireguard-sessions'
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'public_key': public_key
|
||||||
|
}
|
||||||
|
|
||||||
|
api_result = connect.single_endpoint(
|
||||||
|
method="post",
|
||||||
|
url=url,
|
||||||
|
observer=connection_observer,
|
||||||
|
payload=payload,
|
||||||
|
billing_code=billing_code
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not api_result.valid:
|
||||||
|
if api_result.error_type == ErrorType.AUTHENTICATION_ERROR:
|
||||||
|
logger.error(f"Server is giving an Authentication error for billing ID: {billing_code}")
|
||||||
|
raise InvalidSubscriptionError(f"Invalid Subscription for {billing_code}")
|
||||||
|
else:
|
||||||
|
error_msg = f"Could Not Connect to API: {api_result.error_type}"
|
||||||
|
logger.error(error_msg)
|
||||||
|
raise ConnectionError(error_msg)
|
||||||
|
|
||||||
|
wireguard_configuration = api_result.data
|
||||||
|
|
||||||
if wireguard_configuration is None:
|
if wireguard_configuration is None:
|
||||||
raise InvalidSubscriptionError()
|
raise InvalidSubscriptionError()
|
||||||
|
|
||||||
|
|
@ -64,3 +91,16 @@ def _inject_private_key(config: str, private_key: str) -> str:
|
||||||
expression = re.compile(r'^(PrivateKey =)\s?$', re.MULTILINE)
|
expression = re.compile(r'^(PrivateKey =)\s?$', re.MULTILINE)
|
||||||
return re.sub(expression, r'\1 ' + private_key, config)
|
return re.sub(expression, r'\1 ' + private_key, config)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# legacy:
|
||||||
|
|
||||||
|
# ConnectionController.with_preferred_connection(
|
||||||
|
# profile.location.country_code,
|
||||||
|
# profile.location.code,
|
||||||
|
# profile.subscription.billing_code,
|
||||||
|
# wireguard_keys.get('public'),
|
||||||
|
# task=WebServiceApiService.post_wireguard_session,
|
||||||
|
# connection_observer=connection_observer
|
||||||
|
# )
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ from core.models.BaseProfile import ProfileType
|
||||||
from core.observers.ConnectionObserver import ConnectionObserver
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
from core.controllers.SystemStateController import SystemStateController
|
from core.controllers.SystemStateController import SystemStateController
|
||||||
|
|
||||||
from core.services.networking.systemwide.encrypted_proxy.ensure_singbox_configured import ensure_singbox_configured
|
|
||||||
|
|
||||||
def establish_connection(
|
def establish_connection(
|
||||||
profile: Union[SessionProfile, SystemProfile],
|
profile: Union[SessionProfile, SystemProfile],
|
||||||
ignore: tuple[type[Exception]] = (),
|
ignore: tuple[type[Exception]] = (),
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,8 @@ def single_endpoint(method: str, url: str, observer: ConnectionObserver, payload
|
||||||
method=method,
|
method=method,
|
||||||
url=url,
|
url=url,
|
||||||
observer=observer,
|
observer=observer,
|
||||||
payload=payload
|
payload=payload,
|
||||||
|
billing_code=billing_code
|
||||||
)
|
)
|
||||||
elif not made_client and connection_type == ConnectionChoice.SYSTEM:
|
elif not made_client and connection_type == ConnectionChoice.SYSTEM:
|
||||||
return ApiResponse(valid=False, error_type=ErrorType.DEVELOPER_ERROR, message="Can't make a local non-Tor HTTPx client. This error should not go off.")
|
return ApiResponse(valid=False, error_type=ErrorType.DEVELOPER_ERROR, message="Can't make a local non-Tor HTTPx client. This error should not go off.")
|
||||||
|
|
@ -92,7 +93,8 @@ def single_endpoint(method: str, url: str, observer: ConnectionObserver, payload
|
||||||
method=method,
|
method=method,
|
||||||
url=url,
|
url=url,
|
||||||
observer=observer,
|
observer=observer,
|
||||||
payload=payload
|
payload=payload,
|
||||||
|
billing_code=billing_code
|
||||||
)
|
)
|
||||||
|
|
||||||
########################################################
|
########################################################
|
||||||
|
|
@ -143,7 +145,7 @@ def _make_client(connection_type: str, observer) -> httpx.Client | ApiResponse:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def bootstrap_and_try_again(method: str, url: str, observer: ConnectionObserver, payload: dict = None):
|
def bootstrap_and_try_again(method: str, url: str, observer: ConnectionObserver, payload: dict = None, billing_code: str = None):
|
||||||
"""
|
"""
|
||||||
Rank:
|
Rank:
|
||||||
Coordinator
|
Coordinator
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ def make_request(
|
||||||
method=method,
|
method=method,
|
||||||
url=url,
|
url=url,
|
||||||
client=client,
|
client=client,
|
||||||
payload=payload
|
payload=payload,
|
||||||
|
billing_code=billing_code
|
||||||
)
|
)
|
||||||
|
|
||||||
if initial_result.valid:
|
if initial_result.valid:
|
||||||
|
|
@ -59,7 +60,8 @@ def make_request(
|
||||||
method=method,
|
method=method,
|
||||||
url=url,
|
url=url,
|
||||||
client=client,
|
client=client,
|
||||||
payload=payload
|
payload=payload,
|
||||||
|
billing_code=billing_code
|
||||||
)
|
)
|
||||||
return second_result
|
return second_result
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -277,58 +277,3 @@ def establish_system_connection(
|
||||||
|
|
||||||
terminate_tor_connection()
|
terminate_tor_connection()
|
||||||
time.sleep(1.0)
|
time.sleep(1.0)
|
||||||
|
|
||||||
|
|
||||||
# legacy version:
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# connection_result = __establish_system_connection(
|
|
||||||
# profile=profile,
|
|
||||||
# firewall_setting=firewall_setting,
|
|
||||||
# dns_setting=dns_setting,
|
|
||||||
# connection_observer=connection_observer
|
|
||||||
# )
|
|
||||||
# evaluate_connection_result(connection_result)
|
|
||||||
|
|
||||||
# except ConnectionError:
|
|
||||||
# # ================= RETRY ON FAILURE =================
|
|
||||||
# try:
|
|
||||||
# terminate_system_connection(firewall_setting, dns_setting)
|
|
||||||
# except ConnectionTerminationError:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# raise ConnectionError('The connection could not be established.')
|
|
||||||
|
|
||||||
# except CalledProcessError:
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# terminate_system_connection(firewall_setting, dns_setting)
|
|
||||||
# except ConnectionTerminationError:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# # trying again..
|
|
||||||
# try:
|
|
||||||
# connection_result = __establish_system_connection(
|
|
||||||
# profile=profile,
|
|
||||||
# firewall_setting=firewall_setting,
|
|
||||||
# dns_setting=dns_setting,
|
|
||||||
# connection_observer=connection_observer
|
|
||||||
# )
|
|
||||||
# evaluate_connection_result(connection_result)
|
|
||||||
|
|
||||||
# except (ConnectionError, CalledProcessError):
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# terminate_system_connection(firewall_setting, dns_setting)
|
|
||||||
# except ConnectionTerminationError:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# raise ConnectionError('The connection could not be established.')
|
|
||||||
|
|
||||||
# def evaluate_connection_result(connection_result: Result):
|
|
||||||
# if not connection_result.valid:
|
|
||||||
# logger.error(f"[SYSTEMWIDE WG] Critical issue, could not establish a connection: {connection_result.message}")
|
|
||||||
# try:
|
|
||||||
# terminate_system_connection(firewall_setting, True)
|
|
||||||
# except ConnectionTerminationError:
|
|
||||||
# pass
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue