Verbose tor output, colorful integration
This commit is contained in:
@@ -1,18 +1,32 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
from dragonion_server.utils.onion import Onion
|
from dragonion_server.utils.onion import Onion
|
||||||
from dragonion_server.utils.generated_auth.db import AuthFile
|
from dragonion_server.utils.generated_auth.db import AuthFile
|
||||||
from dragonion_server.utils.config.db import services
|
from dragonion_server.utils.config.db import services
|
||||||
|
|
||||||
|
from rich import print
|
||||||
|
|
||||||
|
|
||||||
def integrate_onion(port: int, name: str) -> Onion:
|
def integrate_onion(port: int, name: str) -> Onion:
|
||||||
onion = Onion()
|
onion = Onion()
|
||||||
|
|
||||||
|
try:
|
||||||
onion.connect()
|
onion.connect()
|
||||||
onion.write_onion_service(name, port)
|
onion.write_onion_service(name, port)
|
||||||
print(f'Available on {(onion_host := onion.start_onion_service(name))}')
|
finally:
|
||||||
|
if not onion.connected_to_tor:
|
||||||
|
onion.cleanup()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f'[green]Available on[/] '
|
||||||
|
f'{(onion_host := onion.start_onion_service(name))}.onion')
|
||||||
|
|
||||||
auth = AuthFile(name)
|
auth = AuthFile(name)
|
||||||
auth['host'] = onion_host
|
auth['host'] = f'{onion_host}.onion'
|
||||||
auth['auth'] = onion.auth_string
|
auth['auth'] = onion.auth_string
|
||||||
print(f'To connect to server share .onion host and auth string (next line), '
|
print(f'To connect to server just share [green]{auth.filename}[/] file')
|
||||||
f'also you can just share {auth.filename} file')
|
print(f'Or use [#ff901b]service id[/] and [#564ec3]auth string[/]: \n'
|
||||||
print(onion.auth_string)
|
f'[#ff901b]{onion_host}[/] \n'
|
||||||
print(f'Raw url auth string: {services[name].client_auth_priv_key}')
|
f'[#564ec3]{services[name].client_auth_priv_key}[/]')
|
||||||
|
|
||||||
return onion
|
return onion
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
from stem.control import Controller
|
from stem.control import Controller
|
||||||
from stem import SocketClosed, ProtocolError
|
from stem import ProtocolError
|
||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
import socket
|
import socket
|
||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
import psutil
|
import psutil
|
||||||
import shlex
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
import platform
|
import platform
|
||||||
@@ -113,7 +112,7 @@ class Onion(object):
|
|||||||
with open(self.tor_torrc, "w") as f:
|
with open(self.tor_torrc, "w") as f:
|
||||||
f.write(torrc_template)
|
f.write(torrc_template)
|
||||||
|
|
||||||
def connect(self, connect_timeout=60):
|
def connect(self):
|
||||||
self.tor_data_directory = tempfile.TemporaryDirectory(
|
self.tor_data_directory = tempfile.TemporaryDirectory(
|
||||||
dir=dirs.build_tmp_dir()
|
dir=dirs.build_tmp_dir()
|
||||||
)
|
)
|
||||||
@@ -121,14 +120,12 @@ class Onion(object):
|
|||||||
|
|
||||||
self.fill_torrc(self.tor_data_directory_name)
|
self.fill_torrc(self.tor_data_directory_name)
|
||||||
|
|
||||||
start_ts = time.time()
|
time.time()
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
startupinfo = subprocess.STARTUPINFO()
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||||
self.tor_proc = subprocess.Popen(
|
self.tor_proc = subprocess.Popen(
|
||||||
[self.tor_path, "-f", self.tor_torrc],
|
[self.tor_path, "-f", self.tor_torrc],
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE,
|
|
||||||
startupinfo=startupinfo,
|
startupinfo=startupinfo,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -136,8 +133,6 @@ class Onion(object):
|
|||||||
|
|
||||||
self.tor_proc = subprocess.Popen(
|
self.tor_proc = subprocess.Popen(
|
||||||
[self.tor_path, "-f", self.tor_torrc],
|
[self.tor_path, "-f", self.tor_torrc],
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.PIPE,
|
|
||||||
env=env,
|
env=env,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -150,40 +145,6 @@ class Onion(object):
|
|||||||
self.c = Controller.from_socket_file(path=self.tor_control_socket)
|
self.c = Controller.from_socket_file(path=self.tor_control_socket)
|
||||||
self.c.authenticate()
|
self.c.authenticate()
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
res = self.c.get_info("status/bootstrap-phase")
|
|
||||||
except SocketClosed:
|
|
||||||
raise
|
|
||||||
|
|
||||||
res_parts = shlex.split(res)
|
|
||||||
progress = res_parts[2].split("=")[1]
|
|
||||||
summary = res_parts[4].split("=")[1]
|
|
||||||
|
|
||||||
print(
|
|
||||||
f"\rConnecting to the Tor network: {progress}% - {summary}\033[K",
|
|
||||||
end="",
|
|
||||||
)
|
|
||||||
|
|
||||||
if summary == "Done":
|
|
||||||
print("")
|
|
||||||
break
|
|
||||||
time.sleep(0.2)
|
|
||||||
|
|
||||||
if time.time() - start_ts > connect_timeout:
|
|
||||||
print("")
|
|
||||||
try:
|
|
||||||
self.tor_proc.terminate()
|
|
||||||
print(
|
|
||||||
"Taking too long to connect to Tor. Maybe you aren't "
|
|
||||||
"connected to the Internet, or have an inaccurate "
|
|
||||||
"system clock?"
|
|
||||||
)
|
|
||||||
self.cleanup()
|
|
||||||
raise
|
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.connected_to_tor = True
|
self.connected_to_tor = True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -231,7 +192,7 @@ class Onion(object):
|
|||||||
print("Tor error: {}".format(e.args[0]))
|
print("Tor error: {}".format(e.args[0]))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
onion_host = res.service_id + ".onion"
|
onion_id = res.service_id
|
||||||
|
|
||||||
self.graceful_close_onions.append(res.service_id)
|
self.graceful_close_onions.append(res.service_id)
|
||||||
|
|
||||||
@@ -240,13 +201,12 @@ class Onion(object):
|
|||||||
service.key_type = "ED25519-V3"
|
service.key_type = "ED25519-V3"
|
||||||
service.key_content = res.private_key
|
service.key_content = res.private_key
|
||||||
|
|
||||||
self.auth_string = \
|
self.auth_string = f'{res.service_id}:descriptor:' \
|
||||||
base64.b64encode(f'{res.service_id}:descriptor:x25519:'
|
f'x25519:{service.client_auth_priv_key}'
|
||||||
f'{service.client_auth_priv_key}'.encode()).decode()
|
|
||||||
|
|
||||||
services[name] = service
|
services[name] = service
|
||||||
|
|
||||||
return onion_host
|
return onion_id
|
||||||
|
|
||||||
def stop_onion_service(self, name):
|
def stop_onion_service(self, name):
|
||||||
service: config.models.ServiceModel = services[name]
|
service: config.models.ServiceModel = services[name]
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ sqlitedict = "^2.1.0"
|
|||||||
cleo = "^2.0.1"
|
cleo = "^2.0.1"
|
||||||
fastapi = "^0.98.0"
|
fastapi = "^0.98.0"
|
||||||
uvicorn = "^0.22.0"
|
uvicorn = "^0.22.0"
|
||||||
|
rich = "^13.4.2"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
dragonion-server = "dragonion_server:main"
|
dragonion-server = "dragonion_server:main"
|
||||||
|
|||||||
Reference in New Issue
Block a user