384 lines
12 KiB
Python
Executable File
384 lines
12 KiB
Python
Executable File
""" Classes Method and functions for lx apps """
|
|
|
|
import gettext
|
|
import locale
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import tkinter as tk
|
|
import zipfile
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from subprocess import check_call
|
|
from tkinter import ttk
|
|
|
|
import requests
|
|
|
|
APP = "wirepy"
|
|
LOCALE_DIR = "/usr/share/locale/"
|
|
locale.bindtextdomain(APP, LOCALE_DIR)
|
|
gettext.bindtextdomain(APP, LOCALE_DIR)
|
|
gettext.textdomain(APP)
|
|
_ = gettext.gettext
|
|
|
|
wg_set = Path(Path.home() / ".config/wire_py/settings")
|
|
|
|
|
|
class Create:
|
|
"""
|
|
This class is for the creation of the folders and files
|
|
required by Wire-Py, as well as for decryption
|
|
the tunnel from the user's home directory
|
|
"""
|
|
|
|
@staticmethod
|
|
def dir_and_files():
|
|
|
|
pth = Path.home() / ".config/wire_py"
|
|
pth.mkdir(parents=True, exist_ok=True)
|
|
sett = Path.home() / ".config/wire_py/settings"
|
|
ks = Path.home() / ".config/wire_py/keys"
|
|
|
|
if sett.exists():
|
|
pass
|
|
|
|
else:
|
|
sett.touch()
|
|
sett.write_text(
|
|
"[UPDATES]\non\n[THEME]\nlight\n[TOOLTIP]\nTrue\n[AUTOSTART ON]\noff\n"
|
|
)
|
|
|
|
if ks.exists():
|
|
pass
|
|
|
|
else:
|
|
ks.touch()
|
|
|
|
@staticmethod
|
|
def files_for_autostart():
|
|
|
|
pth2 = Path.home() / ".config/systemd/user"
|
|
pth2.mkdir(parents=True, exist_ok=True)
|
|
wg_ser = Path.home() / ".config/systemd/user/wg_start.service"
|
|
|
|
if wg_ser.exists():
|
|
pass
|
|
|
|
else:
|
|
wg_ser.touch()
|
|
wg_ser.write_text(
|
|
"[Unit]\nDescription=Automatic Tunnel Start\nAfter=network-online.target"
|
|
"\n\n[Service]\nType=oneshot\nExecStartPre=/bin/sleep 5\nExecStart=/usr/"
|
|
"local/bin/start_wg.py\n[Install]\nWantedBy=default.target"
|
|
)
|
|
check_call(["systemctl", "--user", "enable", "wg_start.service"])
|
|
|
|
@staticmethod
|
|
def make_dir():
|
|
"""Dirname "tlecdewg" = Tunnel Encrypt Decrypt Wireguard"""
|
|
|
|
dirname = Path("/tmp/tlecdcwg/")
|
|
if dirname.exists():
|
|
pass
|
|
else:
|
|
dirname.mkdir()
|
|
|
|
@staticmethod
|
|
def decrypt():
|
|
process = subprocess.run(
|
|
["pkexec", "/usr/local/bin/ssl_decrypt.py"],
|
|
stdout=subprocess.PIPE,
|
|
text=True,
|
|
)
|
|
# print(process.stdout)
|
|
if process.returncode == 0:
|
|
print("File successfully decrypted...")
|
|
else:
|
|
print(f"Error with the following code... {process.returncode}")
|
|
|
|
@staticmethod
|
|
def encrypt():
|
|
process = subprocess.run(
|
|
["pkexec", "/usr/local/bin/ssl_encrypt.py"],
|
|
stdout=subprocess.PIPE,
|
|
text=True,
|
|
)
|
|
print(process.stdout)
|
|
if process.returncode == 0:
|
|
print("All Files successfully encrypted...")
|
|
else:
|
|
print(f"Error with the following code... {process.returncode}")
|
|
|
|
|
|
class UOS:
|
|
"""
|
|
The class is only for unixoidal systems "UOS" = UnixOS
|
|
|
|
"""
|
|
|
|
"""
|
|
This method displays the user name of the logged-in user,
|
|
even if you are rooted in a shell
|
|
"""
|
|
|
|
@staticmethod
|
|
def username():
|
|
logname = str(Path.home())[6:]
|
|
file = Path.home() / "/tmp/.loguser"
|
|
with open(file, "w") as f:
|
|
f.write(logname)
|
|
|
|
|
|
class GiteaUpdate:
|
|
"""
|
|
Calling api_down requests the URL and the version of the running script.
|
|
Example: version = 'v. 1.1.1.1' GiteaUpdate.api_down(http://example.de, version)
|
|
|
|
Calling download requests the download URL of the running script,
|
|
the taskbar image for the “Download OK” window, the taskbar image for the
|
|
“Download error” window and the variable res
|
|
"""
|
|
|
|
@staticmethod
|
|
def api_down(update_api_url, version):
|
|
try:
|
|
response = requests.get(update_api_url)
|
|
response_dict = response.json()
|
|
response_dict = response_dict[0]
|
|
with open(wg_set, "r") as set_file:
|
|
set_file = set_file.read()
|
|
if "on\n" in set_file:
|
|
if version[3:] != response_dict["tag_name"]:
|
|
return response_dict["tag_name"]
|
|
else:
|
|
return "No Updates"
|
|
else:
|
|
return "False"
|
|
except requests.exceptions.ConnectionError:
|
|
return "No Internet Connection!"
|
|
|
|
@staticmethod
|
|
def download(urld, down_ok_image, down_not_ok_image, res):
|
|
try:
|
|
to_down = "wget -qP " + str(Path.home()) + " " + urld
|
|
result = subprocess.call(to_down, shell=True)
|
|
if result == 0:
|
|
shutil.chown(str(Path.home()) + f"/{res}.zip", 1000, 1000)
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r"/usr/share/icons/lx-icons/64/info.png"
|
|
ii = down_ok_image
|
|
wt = _("Download Successful")
|
|
msg_t = _("Your zip file is in home directory")
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
else:
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r"/usr/share/icons/lx-icons/64/error.png"
|
|
ii = down_not_ok_image
|
|
wt = _("Download error")
|
|
msg_t = _("Download failed! Please try again")
|
|
msg_window(iw, ii, wt, msg_t)
|
|
except subprocess.CalledProcessError:
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r"/usr/share/icons/lx-icons/64/error.png"
|
|
ii = down_not_ok_image
|
|
wt = _("Download error")
|
|
msg_t = _("Download failed! No internet connection!")
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
|
|
def msg_window(img_w, img_i, w_title, w_txt, txt2=None, com=None):
|
|
"""
|
|
Function for different message windows for the user. with 4 arguments to be passed.
|
|
To create messages with your own images, icons, and titles. As an alternative to Python Messagebox.
|
|
Paths to images must be specified: r'/usr/share/icons/lx-icons/64/info.png'
|
|
img_w = Image for Tk Window
|
|
img_i = Image for Icon
|
|
w_title = Windows Title
|
|
w_txt = Text for Tk Window
|
|
txt2 = Text for Button two
|
|
com = function for Button command
|
|
"""
|
|
msg = tk.Toplevel()
|
|
msg.resizable(width=False, height=False)
|
|
msg.title(w_title)
|
|
msg.configure(pady=15, padx=15)
|
|
msg.img = tk.PhotoImage(file=img_w)
|
|
msg.i_window = tk.Label(msg, image=msg.img)
|
|
|
|
label = tk.Label(msg, text=w_txt)
|
|
|
|
label.grid(column=1, row=0)
|
|
|
|
if txt2 is not None and com is not None:
|
|
label.config(font=("Ubuntu", 11), padx=15, justify="left")
|
|
msg.i_window.grid(column=0, row=0, sticky="nw")
|
|
button2 = ttk.Button(msg, text=f"{txt2}", command=com, padding=4)
|
|
button2.grid(column=0, row=1, sticky="e", columnspan=2)
|
|
button = ttk.Button(msg, text="OK", command=msg.destroy, padding=4)
|
|
button.grid(column=0, row=1, sticky="w", columnspan=2)
|
|
|
|
else:
|
|
label.config(font=("Ubuntu", 11), padx=15)
|
|
msg.i_window.grid(column=0, row=0)
|
|
button = ttk.Button(msg, text="OK", command=msg.destroy, padding=4)
|
|
button.grid(column=0, columnspan=2, row=1)
|
|
|
|
img_i = tk.PhotoImage(file=img_i)
|
|
msg.iconphoto(True, img_i)
|
|
msg.columnconfigure(0, weight=1)
|
|
msg.rowconfigure(0, weight=1)
|
|
msg.winfo_toplevel()
|
|
|
|
|
|
class Tunnel:
|
|
"""
|
|
Class of Methods for Wire-Py
|
|
"""
|
|
|
|
"""
|
|
The config file is packed into a dictionary,
|
|
to display the values Address , DNS and Peer in the labels
|
|
"""
|
|
|
|
@classmethod
|
|
def con_to_dict(cls, file):
|
|
|
|
dictlist = []
|
|
for lines in file.readlines():
|
|
line_plit = lines.split()
|
|
dictlist = dictlist + line_plit
|
|
dictlist.remove("[Interface]")
|
|
dictlist.remove("[Peer]")
|
|
for items in dictlist:
|
|
if items == "=":
|
|
dictlist.remove(items)
|
|
if items == "::/0":
|
|
dictlist.remove(items)
|
|
|
|
""" Here is the beginning (Loop) of convert List to Dictionary """
|
|
for _ in dictlist:
|
|
a = [dictlist[0], dictlist[1]]
|
|
b = [dictlist[2], dictlist[3]]
|
|
c = [dictlist[4], dictlist[5]]
|
|
d = [dictlist[6], dictlist[7]]
|
|
e = [dictlist[8], dictlist[9]]
|
|
f = [dictlist[10], dictlist[11]]
|
|
g = [dictlist[12], dictlist[13]]
|
|
h = [dictlist[14], dictlist[15]]
|
|
new_list = [a, b, c, d, e, f, g, h]
|
|
final_dict = {}
|
|
for elements in new_list:
|
|
final_dict[elements[0]] = elements[1]
|
|
|
|
""" end... result a Dictionary """
|
|
|
|
address = final_dict["Address"]
|
|
dns = final_dict["DNS"]
|
|
if "," in dns:
|
|
dns = dns[:-1]
|
|
endpoint = final_dict["Endpoint"]
|
|
if "PresharedKey" in final_dict:
|
|
pre_key = final_dict["PresharedKey"]
|
|
else:
|
|
pre_key = final_dict["PreSharedKey"]
|
|
return address, dns, endpoint, pre_key
|
|
|
|
"""
|
|
Shows the Active Tunnel
|
|
"""
|
|
|
|
@staticmethod
|
|
def active():
|
|
|
|
active = (
|
|
os.popen('nmcli con show --active | grep -iPo "(.*)(wireguard)"')
|
|
.read()
|
|
.split()
|
|
)
|
|
if not active:
|
|
active = ""
|
|
else:
|
|
active = active[0]
|
|
|
|
return active
|
|
|
|
"""
|
|
Shows all existing Wireguard tunnels a login user
|
|
"""
|
|
|
|
@staticmethod
|
|
def list():
|
|
|
|
dirname = Path("/tmp/tlecdcwg/")
|
|
wg_s = os.listdir(dirname)
|
|
|
|
return wg_s
|
|
|
|
"""
|
|
This will export the tunnels.
|
|
A zipfile with current date and time is created
|
|
in the user's home directory with correct right
|
|
"""
|
|
|
|
@staticmethod
|
|
def export():
|
|
now_time = datetime.now()
|
|
now_datetime = now_time.strftime("wg-exp-" + "%m-%d-%Y" + "-" + "%H:%M")
|
|
tl = Tunnel.list()
|
|
|
|
try:
|
|
if len(tl) != 0:
|
|
wg_tar = str(Path.home()) + "/" + now_datetime
|
|
shutil.copytree("/tmp/tlecdcwg/", "/tmp/wire_py", dirs_exist_ok=True)
|
|
source = Path("/tmp/wire_py")
|
|
shutil.make_archive(wg_tar, "zip", source)
|
|
# shutil.chown(wg_tar + '.zip', 1000, 1000)
|
|
shutil.rmtree(source)
|
|
with zipfile.ZipFile((wg_tar + ".zip"), "r") as zf:
|
|
if len(zf.namelist()) != 0:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r"/usr/share/icons/lx-icons/64/info.png"
|
|
ii = r"/usr/share/icons/lx-icons/48/wg_vpn.png"
|
|
wt = _("Export Successful")
|
|
msg_t = _("Your zip file is in home directory")
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
else:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r"/usr/share/icons/lx-icons/64/error.png"
|
|
ii = r"/usr/share/icons/lx-icons/48/wg_msg.png"
|
|
wt = _("Export error")
|
|
msg_t = _("Export failed! Please try again")
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
else:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r"/usr/share/icons/lx-icons/64/info.png"
|
|
ii = r"/usr/share/icons/lx-icons/48/wg_msg.png"
|
|
wt = _("Select tunnel")
|
|
msg_t = _("Please first import tunnel")
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
except TypeError:
|
|
pass
|
|
|
|
|
|
class Tipi:
|
|
"""
|
|
Class for Tooltip setting write in File
|
|
Calling request path to file
|
|
"""
|
|
|
|
@staticmethod
|
|
def if_tip(path):
|
|
with open(path, "r") as set_file2:
|
|
lines2 = set_file2.readlines()
|
|
if "False\n" in lines2:
|
|
return False
|
|
else:
|
|
return True
|