large update
This commit is contained in:
230
tunnel.py
Normal file
230
tunnel.py
Normal file
@ -0,0 +1,230 @@
|
||||
#!/usr/bin/python3
|
||||
import logging
|
||||
import getpass
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
from subprocess import run, CompletedProcess
|
||||
import secrets
|
||||
from shared_libs.wp_app_config import AppConfig, Msg
|
||||
from shared_libs.common_tools import LxTools, CryptoUtil
|
||||
|
||||
# Translate
|
||||
_ = AppConfig.setup_translations()
|
||||
|
||||
|
||||
class Tunnel:
|
||||
"""
|
||||
Class of Methods for Wire-Py
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def parse_files_to_dictionary(
|
||||
directory: Path = None, filepath: str = None, content: str = None
|
||||
) -> tuple[dict, str] | dict | None:
|
||||
data = {}
|
||||
|
||||
if filepath is not None:
|
||||
filepath = Path(filepath)
|
||||
try:
|
||||
content = filepath.read_text()
|
||||
|
||||
# parse the content
|
||||
address_line = next(
|
||||
line for line in content.splitlines() if line.startswith("Address")
|
||||
)
|
||||
dns_line = next(
|
||||
line for line in content.splitlines() if line.startswith("DNS")
|
||||
)
|
||||
endpoint_line = next(
|
||||
line for line in content.splitlines() if line.startswith("Endpoint")
|
||||
)
|
||||
private_key_line = next(
|
||||
line
|
||||
for line in content.splitlines()
|
||||
if line.startswith("PrivateKey")
|
||||
)
|
||||
|
||||
content = secrets.token_bytes(len(content))
|
||||
|
||||
# extract the values
|
||||
address = address_line.split("=")[1].strip()
|
||||
dns = dns_line.split("=")[1].strip()
|
||||
endpoint = endpoint_line.split("=")[1].strip()
|
||||
private_key = private_key_line.split("=")[1].strip()
|
||||
|
||||
# Shorten the tunnel name to the maximum allowed length if it exceeds 12 characters.
|
||||
original_stem = filepath.stem
|
||||
truncated_stem = (
|
||||
original_stem[-12:] if len(original_stem) > 12 else original_stem
|
||||
)
|
||||
|
||||
# save in the dictionary
|
||||
data[truncated_stem] = {
|
||||
"Address": address,
|
||||
"DNS": dns,
|
||||
"Endpoint": endpoint,
|
||||
"PrivateKey": private_key,
|
||||
}
|
||||
|
||||
content = secrets.token_bytes(len(content))
|
||||
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
elif directory is not None:
|
||||
|
||||
if not directory.exists() or not directory.is_dir():
|
||||
logging.error(
|
||||
"Temp directory does not exist or is not a directory.",
|
||||
exc_info=True,
|
||||
)
|
||||
return None
|
||||
|
||||
# Get a list of all files in the directory
|
||||
files = [file for file in AppConfig.TEMP_DIR.iterdir() if file.is_file()]
|
||||
|
||||
# Search for the string in the files
|
||||
for file in files:
|
||||
try:
|
||||
content = file.read_text()
|
||||
# parse the content
|
||||
address_line = next(
|
||||
line
|
||||
for line in content.splitlines()
|
||||
if line.startswith("Address")
|
||||
)
|
||||
dns_line = next(
|
||||
line for line in content.splitlines() if line.startswith("DNS")
|
||||
)
|
||||
endpoint_line = next(
|
||||
line
|
||||
for line in content.splitlines()
|
||||
if line.startswith("Endpoint")
|
||||
)
|
||||
|
||||
# extract values
|
||||
address = address_line.split("=")[1].strip()
|
||||
dns = dns_line.split("=")[1].strip()
|
||||
endpoint = endpoint_line.split("=")[1].strip()
|
||||
|
||||
# save values to dictionary
|
||||
data[file.stem] = {
|
||||
"Address": address,
|
||||
"DNS": dns,
|
||||
"Endpoint": endpoint,
|
||||
}
|
||||
|
||||
except Exception:
|
||||
# Ignore errors and continue to the next file
|
||||
continue
|
||||
if content is not None:
|
||||
content = secrets.token_bytes(len(content))
|
||||
if filepath is not None:
|
||||
return data, truncated_stem
|
||||
else:
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def get_active() -> str:
|
||||
"""
|
||||
Shows the Active Tunnel
|
||||
"""
|
||||
active = None
|
||||
try:
|
||||
process: CompletedProcess[str] = run(
|
||||
["nmcli", "-t", "-f", "NAME,TYPE", "connection", "show", "--active"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
|
||||
active = next(
|
||||
line.split(":")[0].strip()
|
||||
for line in process.stdout.splitlines()
|
||||
if line.endswith("wireguard")
|
||||
)
|
||||
|
||||
if process.stderr and "error" in process.stderr.lower():
|
||||
logging.error(f"Error output on nmcli: {process.stderr}")
|
||||
|
||||
except StopIteration:
|
||||
active = None
|
||||
except Exception as e:
|
||||
logging.error(f"Error on nmcli: {e}")
|
||||
active = None
|
||||
|
||||
return active if active is not None else ""
|
||||
|
||||
@staticmethod
|
||||
def export() -> bool | None:
|
||||
"""
|
||||
This will export the tunnels.
|
||||
A zipfile with the current date and time is created
|
||||
in the user's home directory with the correct right
|
||||
"""
|
||||
now_time: datetime = datetime.now()
|
||||
now_datetime: str = now_time.strftime("wg-exp-%m-%d-%Y-%H:%M")
|
||||
|
||||
try:
|
||||
AppConfig.ensure_directories()
|
||||
CryptoUtil.decrypt(getpass.getuser())
|
||||
if len([file.name for file in AppConfig.TEMP_DIR.glob("*.conf")]) == 0:
|
||||
|
||||
LxTools.msg_window(
|
||||
AppConfig.IMAGE_PATHS["icon_info"],
|
||||
AppConfig.IMAGE_PATHS["icon_msg"],
|
||||
Msg.STR["sel_tl"],
|
||||
Msg.STR["tl_first"],
|
||||
)
|
||||
return False
|
||||
else:
|
||||
wg_tar: str = f"{AppConfig.BASE_DIR}/{now_datetime}"
|
||||
try:
|
||||
shutil.make_archive(wg_tar, "zip", AppConfig.TEMP_DIR)
|
||||
with zipfile.ZipFile(f"{wg_tar}.zip", "r") as zf:
|
||||
if zf.namelist():
|
||||
|
||||
LxTools.msg_window(
|
||||
AppConfig.IMAGE_PATHS["icon_info"],
|
||||
AppConfig.IMAGE_PATHS["icon_vpn"],
|
||||
Msg.STR["exp_succ"],
|
||||
Msg.STR["exp_in_home"],
|
||||
)
|
||||
else:
|
||||
logging.error(
|
||||
"There was a mistake at creating the Zip file. File is empty."
|
||||
)
|
||||
LxTools.msg_window(
|
||||
AppConfig.IMAGE_PATHS["icon_error"],
|
||||
AppConfig.IMAGE_PATHS["icon_msg"],
|
||||
Msg.STR["exp_err"],
|
||||
Msg.STR["exp_zip"],
|
||||
)
|
||||
return False
|
||||
return True
|
||||
except PermissionError:
|
||||
logging.error(
|
||||
f"Permission denied when creating archive in {wg_tar}"
|
||||
)
|
||||
return False
|
||||
|
||||
except zipfile.BadZipFile as e:
|
||||
logging.error(f"Invalid ZIP file: {e}")
|
||||
return False
|
||||
except TypeError:
|
||||
pass
|
||||
except Exception as e:
|
||||
logging.error(f"Export failed: {str(e)}")
|
||||
LxTools.msg_window(
|
||||
AppConfig.IMAGE_PATHS["icon_error"],
|
||||
AppConfig.IMAGE_PATHS["icon_msg"],
|
||||
Msg.STR["exp_err"],
|
||||
Msg.STR["exp_try"],
|
||||
)
|
||||
return False
|
||||
|
||||
finally:
|
||||
LxTools.clean_files(AppConfig.TEMP_DIR)
|
||||
AppConfig.ensure_directories()
|
Reference in New Issue
Block a user