Compare commits
74 Commits
24-02-2025
...
21-04-2025
Author | SHA1 | Date | |
---|---|---|---|
4eb9d6acd4 | |||
97ea07d34b | |||
cd625d173d | |||
950e04a246 | |||
1a853d4ff1 | |||
f6204c9071 | |||
f9ecd54e0a | |||
67ff24f0b6 | |||
af702f297b | |||
d2a57b329b | |||
87943b2489 | |||
c43c12f961 | |||
3bab0710a4 | |||
aa66f4dc68 | |||
c220951781 | |||
6c0662c62c | |||
5753a35d6c | |||
47bdfbfb17 | |||
2a3bf2bbcb | |||
8896f59efd | |||
c58a630e25 | |||
dc6f8cb094 | |||
dcda647e90 | |||
2a995eabd5 | |||
ea750b0cfc | |||
980ce3c7a7 | |||
28cc423138 | |||
39550b392d | |||
582ef21042 | |||
ca58ac86a4 | |||
177fa1cc34 | |||
ca1a7a6b94 | |||
a49c5b00e1 | |||
75a247797d | |||
4b019b0c1f | |||
ab78eb4f59 | |||
9f3f0246b4 | |||
5302aae807 | |||
13832d916f | |||
1667682c9d | |||
8771be760d | |||
97bf9df041 | |||
1bba45a6c1 | |||
a5eb6293c6 | |||
6e54529c0f | |||
862cc91fa1 | |||
22abe9f8b9 | |||
8754e7ecda | |||
6b75713121 | |||
b68908eaef | |||
66dd27cc64 | |||
03a7e48018 | |||
090842ab28 | |||
9eb99f0859 | |||
feb6217637 | |||
5f6aaa6cf1 | |||
63ed0abc98 | |||
3102c685fd | |||
ec10f912ea | |||
96164eb132 | |||
a19f889950 | |||
de2929896d | |||
f9d4256679 | |||
a0b895438c | |||
4c89488950 | |||
c0ae2d2b75 | |||
e4774abf19 | |||
7b1e543428 | |||
6f83fc7162 | |||
b70400b456 | |||
e25bc154ea | |||
7aa3cd75fe | |||
0b9eec8d1d | |||
b9083d4698 |
3
.idea/dictionaries/project.xml
generated
Normal file
@ -0,0 +1,3 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="project" />
|
||||
</component>
|
2
.idea/misc.xml
generated
@ -3,5 +3,5 @@
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12 (wire-py)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (wire-py)" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
|
||||
</project>
|
2
.idea/wire-py.iml
generated
@ -4,7 +4,7 @@
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.12" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
46
.idea/workspace.xml
generated
@ -5,8 +5,8 @@
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="940e1630-c825-4d4c-be80-bc11f543c122" name="Changes" comment=" - Update Translate Files">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/cls_mth_fc.py" beforeDir="false" afterPath="$PROJECT_DIR$/cls_mth_fc.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/wirepy.py" beforeDir="false" afterPath="$PROJECT_DIR$/wirepy.py" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@ -30,14 +30,13 @@
|
||||
<option name="UPDATE_TYPE" value="REBASE" />
|
||||
</component>
|
||||
<component name="HighlightingSettingsPerFile">
|
||||
<setting file="file://$PROJECT_DIR$/wg_func.py" root0="SKIP_INSPECTION" />
|
||||
<setting file="file://$PROJECT_DIR$/wg_main.py" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file:///usr/local/bin/ssl_decrypt.py" root0="SKIP_INSPECTION" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 3
|
||||
}</component>
|
||||
<component name="ProjectId" id="2kSbZdjOvr0wsVJSNcaMwSfVaxR" />
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="true">
|
||||
<component name="ProjectLevelVcsManager">
|
||||
<ConfirmationsSetting value="2" id="Add" />
|
||||
</component>
|
||||
<component name="ProjectViewState">
|
||||
@ -48,6 +47,7 @@
|
||||
"keyToString": {
|
||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||
"Python.INSTALL.executor": "Run",
|
||||
"Python.cls_mth_fc.executor": "Run",
|
||||
"Python.install.executor": "Run",
|
||||
"Python.main.executor": "Run",
|
||||
"Python.messagebox.executor": "Run",
|
||||
@ -55,12 +55,14 @@
|
||||
"Python.testtheme.executor": "Run",
|
||||
"Python.wg_func.executor": "Run",
|
||||
"Python.wg_main.executor": "Run",
|
||||
"Python.wirepy.executor": "Run",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"Shell Script.install.executor": "Run",
|
||||
"Shell Script.run_as.executor": "Run",
|
||||
"git-widget-placeholder": "1.11.1024",
|
||||
"git-widget-placeholder": "21-04-2025-new-tooltip",
|
||||
"last_opened_file_path": "/home/punix/Pyapps/wire-py",
|
||||
"settings.editor.selected.configurable": "reference.settingsdialog.IDE.editor.colors"
|
||||
"settings.editor.selected.configurable": "ml.llm.LLMConfigurable"
|
||||
}
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
@ -75,7 +77,7 @@
|
||||
<recent name="$PROJECT_DIR$/wire-py" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager" selected="Python.wg_main">
|
||||
<component name="RunManager" selected="Python.wirepy">
|
||||
<configuration name="start_wg" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="wire-py" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
@ -120,8 +122,31 @@
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="wirepy" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="wire-py" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/wirepy.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Python.wirepy" />
|
||||
<item itemvalue="Python.start_wg" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
@ -129,7 +154,7 @@
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-python-sdk-8336bb23522e-31b6be0877a2-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-241.19072.16" />
|
||||
<option value="bundled-python-sdk-348a24fa61fa-5312c7369657-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-251.23774.444" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
@ -600,6 +625,11 @@
|
||||
<line>1128</line>
|
||||
<option name="timeStamp" value="3" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/ssl_decrypt.py</url>
|
||||
<line>3</line>
|
||||
<option name="timeStamp" value="4" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
|
43
Changelog
@ -6,9 +6,46 @@ My standard System: Linux Mint 22 Cinnamon
|
||||
- os import in cls_mth_fc.py replaced by other methods
|
||||
- If Wire-Py already runs, prevent further start
|
||||
- for loops with lists replaced by List Comprehensions
|
||||
- Update search after start of Wire-Py
|
||||
|
||||
|
||||
### Added
|
||||
13-04-0725
|
||||
|
||||
- Installer update for Open Suse Tumbleweed and Leap
|
||||
- add symbolic link wirepy.py
|
||||
|
||||
|
||||
### Added
|
||||
09-04-0725
|
||||
|
||||
- Installer now with query and remove
|
||||
- Icons merged
|
||||
|
||||
|
||||
### Added
|
||||
07-04-0725
|
||||
|
||||
- Installers will support other systems again
|
||||
- Installer is now finished clean with wrong password
|
||||
- Rename wg_main to wirepy
|
||||
|
||||
|
||||
### Added
|
||||
03-03-2025
|
||||
|
||||
- Fixes a new user files create
|
||||
|
||||
|
||||
### Added
|
||||
02-03-2025
|
||||
|
||||
- Fix ipv6 in Config File on import
|
||||
- Wirepy run now as user
|
||||
- settings, keys and Config Files now in ~/.config/wire_py
|
||||
- For new users, the required files are created and autostart service is started.
|
||||
- Tunnels are now read from the directory to view them in the list.
|
||||
To display only own tunnels, and read errors are minimized.
|
||||
|
||||
### Added
|
||||
10-11-2024
|
||||
|
||||
@ -57,7 +94,7 @@ My standard System: Linux Mint 22 Cinnamon
|
||||
### Added
|
||||
27-10-2024
|
||||
|
||||
- Add Autoconnect settings to settings.conf
|
||||
- Add Autoconnect settings to settings
|
||||
|
||||
|
||||
### Added
|
||||
@ -65,7 +102,7 @@ My standard System: Linux Mint 22 Cinnamon
|
||||
|
||||
- Add run_as Bash script and open_gitea.py python script
|
||||
- Add Tooltip disable/enable
|
||||
- Rename settings to settings.conf for theme, updates and tooltip enable in one file
|
||||
- Rename settings to settings for theme, updates and tooltip enable in one file
|
||||
|
||||
|
||||
### Added
|
||||
|
4
Wire-Py.desktop
Executable file → Normal file
@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Wire-Py
|
||||
Exec=/usr/bin/wirepy.py
|
||||
Exec=/usr/local/bin/wirepy.py
|
||||
Terminal=false
|
||||
Categories=Network;
|
||||
Icon=/usr/share/icons/wp-icons/128/wg_vpn.png
|
||||
Icon=/usr/share/icons/lx-icons/128/wg_vpn.png
|
592
cls_mth_fc.py
@ -1,127 +1,329 @@
|
||||
""" Classes Method and functions for lx apps """
|
||||
""" Classes Method and Functions for lx Apps """
|
||||
|
||||
import gettext
|
||||
import locale
|
||||
import os
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import tkinter as tk
|
||||
from typing import Optional, Dict, Any, NoReturn, TextIO, Tuple, List
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from tkinter import ttk
|
||||
from subprocess import check_call, CompletedProcess
|
||||
from tkinter import ttk, Toplevel
|
||||
|
||||
import requests
|
||||
|
||||
APP = 'wirepy'
|
||||
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('/etc/wire_py/settings.conf')
|
||||
_u = Path.read_text(Path('/tmp/_u'))
|
||||
|
||||
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() -> None:
|
||||
"""
|
||||
check and create folders and files if not present
|
||||
"""
|
||||
|
||||
pth: Path = Path.home() / ".config/wire_py"
|
||||
pth.mkdir(parents=True, exist_ok=True)
|
||||
sett: Path = Path.home() / ".config/wire_py/settings"
|
||||
ks: Path = 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() -> None:
|
||||
"""
|
||||
check and create a file for auto start if not present and enable the service
|
||||
"""
|
||||
|
||||
pth2: Path = Path.home() / ".config/systemd/user"
|
||||
pth2.mkdir(parents=True, exist_ok=True)
|
||||
wg_ser: Path = 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]\n"
|
||||
"Type=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() -> None:
|
||||
"""Folder Name "tlecdewg" = Tunnel Encrypt Decrypt Wireguard"""
|
||||
|
||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
||||
if folder_path.exists():
|
||||
pass
|
||||
else:
|
||||
folder_path.mkdir()
|
||||
|
||||
@staticmethod
|
||||
def decrypt() -> None:
|
||||
"""
|
||||
Starts SSL dencrypt
|
||||
"""
|
||||
process: CompletedProcess[str] = subprocess.run(["pkexec", "/usr/local/bin/ssl_decrypt.py"],
|
||||
stdout=subprocess.PIPE, text=True, check=True)
|
||||
path: Path = Path.home() / ".config/wire_py/"
|
||||
file_in_path: list[Path] = list(path.rglob("*.dat"))
|
||||
if file_in_path:
|
||||
if process.returncode == 0:
|
||||
print("File successfully decrypted...")
|
||||
else:
|
||||
print(f"Error with the following code... {process.returncode}")
|
||||
else:
|
||||
print(_("Ready for import"))
|
||||
|
||||
@staticmethod
|
||||
def encrypt() -> None:
|
||||
"""
|
||||
Starts SSL encryption
|
||||
"""
|
||||
process: CompletedProcess[str] = subprocess.run(["pkexec", "/usr/local/bin/ssl_encrypt.py"],
|
||||
stdout=subprocess.PIPE, text=True, check=True)
|
||||
print(process.stdout)
|
||||
if process.returncode == 0:
|
||||
print("All Files successfully encrypted...")
|
||||
else:
|
||||
print(f"Error with the following code... {process.returncode}")
|
||||
|
||||
|
||||
class LxTools(tk.Tk):
|
||||
"""
|
||||
Class LinuxTools methods that can also be used for other apps
|
||||
"""
|
||||
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def uos() -> None:
|
||||
"""
|
||||
uos = LOGIN USERNAME
|
||||
|
||||
This method displays the username of the logged-in user,
|
||||
even if you are rooted in a shell
|
||||
"""
|
||||
log_name: str = f"{Path.home()}"[6:]
|
||||
file: Path = Path.home() / "/tmp/.log_user"
|
||||
with open(file, "w", encoding="utf-8") as f:
|
||||
f.write(log_name)
|
||||
|
||||
@staticmethod
|
||||
def clean_files(folder_path: Path = None, file: Path = None) -> None:
|
||||
"""
|
||||
method that can be added after need to delete a folder and a file when quitting.
|
||||
Args:
|
||||
:param file: default None
|
||||
:param folder_path: default None
|
||||
"""
|
||||
if folder_path is not None:
|
||||
shutil.rmtree(folder_path)
|
||||
if file is not None:
|
||||
Path.unlink(file)
|
||||
|
||||
@staticmethod
|
||||
def if_tip(path: Path) -> bool:
|
||||
"""
|
||||
method that writes in file whether tooltip is displayed or not
|
||||
"""
|
||||
with open(path, "r", encoding="utf-8") as set_f2:
|
||||
lines2 = set_f2.readlines()
|
||||
if "False\n" in lines2:
|
||||
tip = False
|
||||
else:
|
||||
tip = True
|
||||
return tip
|
||||
|
||||
@staticmethod
|
||||
def msg_window(img_w: str, img_i: str, w_title: str, w_txt: str, txt2: Optional[str] = None,
|
||||
com: Optional[str] = None) -> None:
|
||||
"""
|
||||
Creates message windows
|
||||
|
||||
:argument img_w = Image for TK window which is displayed to the left of the text
|
||||
:argument img_i = Image for Task Icon
|
||||
:argument w_title = Windows Title
|
||||
:argument w_txt = Text for Tk Window
|
||||
:argument txt2 = Text for Button two
|
||||
:argument com = function for Button command
|
||||
"""
|
||||
msg: tk.Toplevel = 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 = 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 = ttk.Button(msg, text=f"{txt2}", command=com, padding=4)
|
||||
button2.grid(column=0, row=1, sticky="e", columnspan=2)
|
||||
button: ttk.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 = ttk.Button(msg, text="OK", command=msg.destroy, padding=4)
|
||||
button.grid(column=0, columnspan=2, row=1)
|
||||
|
||||
img_i: tk.PhotoImage = tk.PhotoImage(file=img_i)
|
||||
msg.iconphoto(True, img_i)
|
||||
msg.columnconfigure(0, weight=1)
|
||||
msg.rowconfigure(0, weight=1)
|
||||
msg.winfo_toplevel()
|
||||
|
||||
@staticmethod
|
||||
def sigi(file_path: Optional[Path] = None, file: Optional[Path] = None) -> None:
|
||||
"""
|
||||
Function for cleanup after a program interruption
|
||||
|
||||
:param file: Optional - File to be deleted
|
||||
:param file_path: Optional - Directory to be deleted
|
||||
"""
|
||||
|
||||
def signal_handler(signum: int, frame: Any) -> NoReturn:
|
||||
"""
|
||||
Determines clear text names for signal numbers and handles signals
|
||||
|
||||
Args:
|
||||
signum: The signal number
|
||||
frame: The current stack frame
|
||||
|
||||
Returns:
|
||||
NoReturn since the function either exits the program or continues execution
|
||||
"""
|
||||
|
||||
signals_to_names_dict: Dict[int, str] = dict((getattr(signal, n), n) for n in dir(signal)
|
||||
if n.startswith("SIG") and "_" not in n)
|
||||
|
||||
signal_name: str = signals_to_names_dict.get(signum, f"Unnamed signal: {signum}")
|
||||
|
||||
# End program for certain signals, report to others only reception
|
||||
if signum in (signal.SIGINT, signal.SIGTERM):
|
||||
exit_code: int = 1
|
||||
print(f"\nSignal {signal_name} {signum} received. => Aborting with exit code {exit_code}.")
|
||||
LxTools.clean_files(file_path, file)
|
||||
print("Breakdown by user...")
|
||||
sys.exit(exit_code)
|
||||
else:
|
||||
print(f"Signal {signum} received and ignored.")
|
||||
LxTools.clean_files(file_path, file)
|
||||
print("Process unexpectedly ended...")
|
||||
|
||||
# Register signal handlers for various signals
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
signal.signal(signal.SIGHUP, signal_handler)
|
||||
|
||||
|
||||
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):
|
||||
def api_down(update_api_url: str, version: str, file: Optional[Path] = None) -> str:
|
||||
"""
|
||||
Checks for updates via API
|
||||
|
||||
Args:
|
||||
update_api_url: Update API URL
|
||||
version: Current version
|
||||
file: Optional - Configuration file
|
||||
|
||||
Returns:
|
||||
New version or status message
|
||||
"""
|
||||
try:
|
||||
to_down = 'wget -qP ' + str(_u) + ' ' + urld
|
||||
result = subprocess.call(to_down, shell=True)
|
||||
response: requests.Response = requests.get(update_api_url, timeout=10)
|
||||
response_dict: Any = response.json()
|
||||
response_dict: Dict[str, Any] = response_dict[0]
|
||||
with open(file, "r", encoding="utf-8") as set_f:
|
||||
set_f = set_f.read()
|
||||
if "on\n" in set_f:
|
||||
if version[3:] != response_dict["tag_name"]:
|
||||
req: str = response_dict["tag_name"]
|
||||
else:
|
||||
req: str = "No Updates"
|
||||
else:
|
||||
req: str = "False"
|
||||
return req
|
||||
except requests.exceptions.RequestException:
|
||||
req: str = "No Internet Connection!"
|
||||
return req
|
||||
|
||||
@staticmethod
|
||||
def download(urld: str, res: str, img_w: str = None, img_i: str = None, img_w2: str = None, img_i2: str = None) -> None:
|
||||
"""
|
||||
Downloads new version of wirepy
|
||||
|
||||
Args:
|
||||
urld: Download URL
|
||||
res: Result filename
|
||||
img_w: Image for TK window which is displayed to the left of the text
|
||||
img_i: Image for Task Icon
|
||||
img_w2: Image for TK window which is displayed to the left of the text
|
||||
img_i2: Image for Task Icon
|
||||
"""
|
||||
try:
|
||||
to_down: str = f"wget -qP {Path.home()} {" "} {urld}"
|
||||
result: int = subprocess.call(to_down, shell=True)
|
||||
if result == 0:
|
||||
shutil.chown(str(_u) + 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)
|
||||
shutil.chown(f"{Path.home()}/{res}.zip", 1000, 1000)
|
||||
|
||||
wt: str = _("Download Successful")
|
||||
msg_t: str = _("Your zip file is in home directory")
|
||||
LxTools.msg_window(img_w, img_i, 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)
|
||||
|
||||
wt: str = _("Download error")
|
||||
msg_t: str = _("Download failed! Please try again")
|
||||
LxTools.msg_window(img_w2, img_i2, 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()
|
||||
wt: str = _("Download error")
|
||||
msg_t: str = _("Download failed! No internet connection!")
|
||||
LxTools.msg_window(img_w2, img_i2, wt, msg_t)
|
||||
|
||||
|
||||
class Tunnel:
|
||||
@ -129,144 +331,166 @@ 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):
|
||||
def con_to_dict(cls, file: TextIO) -> Tuple[str, str, str, Optional[str]]:
|
||||
"""
|
||||
Returns tuple of (address, dns, endpoint, pre_key)
|
||||
"""
|
||||
|
||||
dictlist = []
|
||||
dictlist: List[str] = []
|
||||
for lines in file.readlines():
|
||||
line_plit = lines.split()
|
||||
line_plit: List[str] = lines.split()
|
||||
dictlist = dictlist + line_plit
|
||||
dictlist.remove('[Interface]')
|
||||
dictlist.remove('[Peer]')
|
||||
dictlist.remove("[Interface]")
|
||||
dictlist.remove("[Peer]")
|
||||
for items in dictlist:
|
||||
if items == '=':
|
||||
if items == "=":
|
||||
dictlist.remove(items)
|
||||
if items == "::/0":
|
||||
dictlist.remove(items)
|
||||
|
||||
''' Here is the beginning (Loop) of convert List to Dictionary '''
|
||||
# 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 = {}
|
||||
a: List[str] = [dictlist[0], dictlist[1]]
|
||||
b: List[str] = [dictlist[2], dictlist[3]]
|
||||
c: List[str] = [dictlist[4], dictlist[5]]
|
||||
d: List[str] = [dictlist[6], dictlist[7]]
|
||||
e: List[str] = [dictlist[8], dictlist[9]]
|
||||
f: List[str] = [dictlist[10], dictlist[11]]
|
||||
g: List[str] = [dictlist[12], dictlist[13]]
|
||||
h: List[str] = [dictlist[14], dictlist[15]]
|
||||
new_list: List[List[str]] = [a, b, c, d, e, f, g, h]
|
||||
final_dict: Dict[str, str] = {}
|
||||
for elements in new_list:
|
||||
final_dict[elements[0]] = elements[1]
|
||||
|
||||
''' end... result a Dictionary '''
|
||||
# end... result a Dictionary
|
||||
|
||||
address = final_dict['Address']
|
||||
dns = final_dict['DNS']
|
||||
if ',' in dns:
|
||||
address: str = final_dict["Address"]
|
||||
dns: str = 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']
|
||||
endpoint: str = final_dict["Endpoint"]
|
||||
pre_key: Optional[str] = final_dict.get("PresharedKey")
|
||||
if pre_key is None:
|
||||
pre_key: Optional[str] = final_dict.get("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()
|
||||
def active() -> str:
|
||||
"""
|
||||
Shows the Active Tunnel
|
||||
"""
|
||||
active = (os.popen('nmcli con show --active | grep -iPo "(.*)(wireguard)"').read().split())
|
||||
if not active:
|
||||
active = ''
|
||||
active = ""
|
||||
else:
|
||||
active = active[0]
|
||||
|
||||
return active
|
||||
|
||||
"""
|
||||
Shows all existing Wireguard tunnels
|
||||
"""
|
||||
@staticmethod
|
||||
def list():
|
||||
wg_s = os.popen('nmcli con show | grep -iPo "(.*)(wireguard)"').read().split()
|
||||
def list() -> List[str]:
|
||||
"""
|
||||
Returns a list of Wireguard tunnel names
|
||||
"""
|
||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
||||
wg_s: List[str] = os.listdir(folder_path)
|
||||
|
||||
''' tl = Tunnel list # Show of 4.Element in list '''
|
||||
tl = wg_s[::3]
|
||||
return tl
|
||||
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():
|
||||
_u1 = str(_u[6:])
|
||||
now_time = datetime.now()
|
||||
now_datetime = now_time.strftime('wg-exp-' + '%m-%d-%Y' + '-' + '%H:%M')
|
||||
tl = Tunnel.list()
|
||||
def export(img_w: str = None, img_i: str = None, img_w2: str = None, img_i2: str = None, sl: str = None, pfit:str = None) -> 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
|
||||
Args:
|
||||
img_w: Image for TK window which is displayed to the left of the text
|
||||
img_i: Image for Task Icon
|
||||
img_w2: Image for TK window which is displayed to the left of the text
|
||||
img_i2: Image for Task Icon
|
||||
"""
|
||||
now_time: datetime = datetime.now()
|
||||
now_datetime: str = now_time.strftime("wg-exp-%m-%d-%Y-%H:%M")
|
||||
tl: List[str] = Tunnel.list()
|
||||
|
||||
try:
|
||||
if len(tl) != 0:
|
||||
wg_tar = str(_u) + '/' + now_datetime
|
||||
shutil.copytree('/etc/wire_py', '/tmp/wire_py', dirs_exist_ok=True)
|
||||
source = Path('/tmp/wire_py')
|
||||
Path.unlink(Path(source) / 'wg_py', missing_ok=True)
|
||||
Path.unlink(Path(source) / '.keys', missing_ok=True)
|
||||
Path.unlink(Path(source) / 'settings.conf', missing_ok=True)
|
||||
shutil.make_archive(wg_tar, 'zip', source)
|
||||
shutil.chown(wg_tar + '.zip', 1000, 1000)
|
||||
wg_tar: str = f"{Path.home()}/{now_datetime}"
|
||||
shutil.copytree("/tmp/tlecdcwg/", "/tmp/wire_py", dirs_exist_ok=True)
|
||||
source: Path = Path("/tmp/wire_py")
|
||||
shutil.make_archive(wg_tar, "zip", source)
|
||||
shutil.rmtree(source)
|
||||
with zipfile.ZipFile((wg_tar + '.zip'), 'r') as zf:
|
||||
with zipfile.ZipFile(f"{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/wp-icons/48/wg_vpn.png'
|
||||
wt = _('Export Successful')
|
||||
msg_t = _('Your zip file is in home directory')
|
||||
msg_window(iw, ii, wt, msg_t)
|
||||
msg_t: str = _("Your zip file is in home directory")
|
||||
LxTools.msg_window(img_w, img_i, _("Export Successful"), 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/wp-icons/48/wg_msg.png'
|
||||
wt = _('Export error')
|
||||
msg_t = _('Export failed! Please try again')
|
||||
msg_window(iw, ii, wt, msg_t)
|
||||
msg_t: str = _("Export failed! Please try again")
|
||||
LxTools.msg_window(img_w2, img_i2, _("Export error"), 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/wp-icons/48/wg_msg.png'
|
||||
wt = _('Select tunnel')
|
||||
msg_t = _('Please first import tunnel')
|
||||
msg_window(iw, ii, wt, msg_t)
|
||||
LxTools.msg_window(img_w, img_i2, sl, pfit)
|
||||
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
||||
class Tipi:
|
||||
class Tooltip:
|
||||
"""
|
||||
Class for Tooltip setting write in File
|
||||
Calling request path to file
|
||||
class for Tooltip
|
||||
|
||||
import Tooltip
|
||||
|
||||
example: Tooltip(label, "Show tooltip on label")
|
||||
example: Tooltip(button, "Show tooltip on button")
|
||||
info: label and button are parent.
|
||||
"""
|
||||
@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
|
||||
|
||||
def __init__(self, widget: Any, text: str, tips: Optional[bool] = None) -> None:
|
||||
"""
|
||||
Tooltip Class
|
||||
"""
|
||||
|
||||
wg_tips = Tipi.if_tip(wg_set)
|
||||
self.widget: Any = widget
|
||||
self.text: str = text
|
||||
self.tooltip_window: Optional[Toplevel] = None
|
||||
if tips:
|
||||
self.widget.bind("<Enter>", self.show_tooltip)
|
||||
self.widget.bind("<Leave>", self.hide_tooltip)
|
||||
|
||||
def show_tooltip(self, event: Optional[Any] = None) -> None:
|
||||
"""
|
||||
Shows the tooltip
|
||||
"""
|
||||
if self.tooltip_window or not self.text:
|
||||
return
|
||||
|
||||
x: int
|
||||
y: int
|
||||
cx: int
|
||||
cy: int
|
||||
x, y, cx, cy = self.widget.bbox("insert")
|
||||
x += self.widget.winfo_rootx() + 65
|
||||
y += self.widget.winfo_rooty() + 40
|
||||
self.tooltip_window = tw = tk.Toplevel(self.widget)
|
||||
tw.wm_overrideredirect(True)
|
||||
tw.wm_geometry(f"+{x}+{y}")
|
||||
|
||||
label: tk.Label = tk.Label(tw, text=self.text, background="lightgreen", foreground="black", relief="solid",
|
||||
borderwidth=1, padx=5, pady=5)
|
||||
label.grid()
|
||||
|
||||
def hide_tooltip(self, event: Optional[Any] = None) -> None:
|
||||
"""
|
||||
Hides the tooltip
|
||||
"""
|
||||
if self.tooltip_window:
|
||||
self.tooltip_window.destroy()
|
||||
self.tooltip_window = None
|
||||
|
317
install
@ -6,130 +6,223 @@ BLUE='\033[30;1;34m'
|
||||
|
||||
install_file_with(){
|
||||
clear
|
||||
sudo apt install python3-tk && \
|
||||
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
|
||||
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && sudo cp -u settings.conf /etc/wire_py/ && \
|
||||
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
|
||||
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
|
||||
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo cp -u wg_start.service /lib/systemd/system/ && \
|
||||
sudo systemctl enable wg_start.service
|
||||
mkdir -p ~/.config/wire_py && touch ~/.config/wire_py/keys && cp -u settings ~/.config/wire_py/ && \
|
||||
mkdir -p ~/.config/systemd/user && cp -u wg_start.service ~/.config/systemd/user/ && \
|
||||
systemctl --user enable wg_start.service >/dev/null 2>&1
|
||||
sudo cp -f org.sslcrypt.policy /usr/share/polkit-1/actions/
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
systemctl --user disable wg_start.service
|
||||
rm -r ~/.config/wire_py && rm -r ~/.config/systemd
|
||||
exit 0
|
||||
else
|
||||
sudo apt install python3-tk && \
|
||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo ln -sf /usr/local/bin/wirepy.py /usr/local/bin/wirepy
|
||||
sudo mkdir -p /usr/local/etc/ssl
|
||||
if [ ! -f /usr/local/etc/ssl/pwgk.pem ]
|
||||
then
|
||||
sudo openssl genrsa -out /usr/local/etc/ssl/pwgk.pem 4096
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
install_arch_d(){
|
||||
clear
|
||||
sudo pacman -S --noconfirm tk python3 python-requests && \
|
||||
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
|
||||
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && sudo cp -u settings.conf /etc/wire_py/ && \
|
||||
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
|
||||
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
|
||||
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo cp -u wg_start.service /lib/systemd/system/ && \
|
||||
sudo systemctl enable wg_start.service
|
||||
mkdir -p ~/.config/wire_py && touch ~/.config/wire_py/keys && cp -u settings ~/.config/wire_py/ && \
|
||||
mkdir -p ~/.config/systemd/user && cp -u wg_start.service ~/.config/systemd/user/ && \
|
||||
systemctl --user enable wg_start.service >/dev/null 2>&1
|
||||
sudo cp -f org.sslcrypt.policy /usr/share/polkit-1/actions/
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
systemctl --user disable wg_start.service
|
||||
rm -r ~/.config/wire_py && rm -r ~/.config/systemd
|
||||
exit 0
|
||||
else
|
||||
sudo pacman -S --noconfirm tk python3 python-requests && \
|
||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo ln -sf /usr/local/bin/wirepy.py /usr/local/bin/wirepy
|
||||
sudo mkdir -p /usr/local/etc/ssl
|
||||
if [ ! -f /usr/local/etc/ssl/pwgk.pem ]
|
||||
then
|
||||
sudo openssl genrsa -out /usr/local/etc/ssl/pwgk.pem 4096
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
if grep -i 'debian' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
groups > /tmp/isgroup
|
||||
if grep 'sudo' /tmp/isgroup
|
||||
then
|
||||
install(){
|
||||
if grep -i 'debian' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
groups > /tmp/isgroup
|
||||
if grep 'sudo' /tmp/isgroup
|
||||
then
|
||||
install_file_with
|
||||
else
|
||||
echo -e "$BLUE"The installer found that they are not in the group sudo.""
|
||||
echo -e "with "$RED"su -"$BLUE" "they can enter the root shell in which they then""
|
||||
echo -e "enter "$GREEN""usermod -aG sudo $USER.""$BLUE""
|
||||
echo -e ""after logging in from the system, they can then run Wire-Py install again." $NORMAL"
|
||||
read -n 1 -s -r -p $"Press Enter to exit"
|
||||
clear
|
||||
exit 0
|
||||
|
||||
else
|
||||
fi
|
||||
|
||||
elif grep -i 'mint\|ubuntu\|pop|' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
install_file_with
|
||||
|
||||
elif grep -i 'arch' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
groups > /tmp/isgroup
|
||||
clear
|
||||
if grep 'wheel' /tmp/isgroup
|
||||
then
|
||||
install_arch_d
|
||||
else
|
||||
echo "The installer found that they are not in the group sudo."
|
||||
echo "The sudoers file must be edited with"
|
||||
echo -e "$RED""su -""$NORMAL"
|
||||
echo -e "$GREEN"""EDITOR=nano visudo"""$NORMAL"
|
||||
echo "Find the line:"
|
||||
echo "## Uncomment to allow members of group wheel to execute any command"
|
||||
echo "remove '#' on # %wheel ALL=(ALL) ALL and save the file"
|
||||
echo -e "then enter "$GREEN"gpasswd -a $USER wheel.""$NORMAL"
|
||||
echo "after logging in from the system, they can then run Wire-Py install again."
|
||||
read -n 1 -s -r -p $"Press Enter to exit"
|
||||
clear
|
||||
exit 0
|
||||
|
||||
fi
|
||||
|
||||
elif grep -i '|manjaro\|garuda\|endeavour|' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
install_arch_d
|
||||
|
||||
elif grep -i 'fedora' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
clear
|
||||
mkdir -p ~/.config/wire_py && touch ~/.config/wire_py/keys && cp -u settings ~/.config/wire_py/ && \
|
||||
mkdir -p ~/.config/systemd/user && cp -u wg_start.service ~/.config/systemd/user/ && \
|
||||
systemctl --user enable wg_start.service >/dev/null 2>&1
|
||||
sudo cp -f org.sslcrypt.policy /usr/share/polkit-1/actions/
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
systemctl --user disable wg_start.service
|
||||
rm -r ~/.config/wire_py && rm -r ~/.config/systemd
|
||||
exit 0
|
||||
else
|
||||
sudo dnf install python3-tkinter -y
|
||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo ln -sf /usr/local/bin/wirepy.py /usr/local/bin/wirepy
|
||||
sudo mkdir -p /usr/local/etc/ssl
|
||||
if [ ! -f /usr/local/etc/ssl/pwgk.pem ]
|
||||
then
|
||||
sudo openssl genrsa -out /usr/local/etc/ssl/pwgk.pem 4096
|
||||
fi
|
||||
|
||||
fi
|
||||
elif grep -i 'suse' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
clear
|
||||
mkdir -p ~/.config/wire_py && touch ~/.config/wire_py/keys && cp -u settings ~/.config/wire_py/ && \
|
||||
mkdir -p ~/.config/systemd/user && cp -u wg_start.service ~/.config/systemd/user/ && \
|
||||
systemctl --user enable wg_start.service >/dev/null 2>&1
|
||||
sudo cp -f org.sslcrypt.policy /usr/share/polkit-1/actions/
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
systemctl --user disable wg_start.service
|
||||
rm -r ~/.config/wire_py && rm -r ~/.config/systemd
|
||||
exit 0
|
||||
else
|
||||
sudo cp -fv wirepy.py start_wg.py cls_mth_fc.py ssl_encrypt.py ssl_decrypt.py /usr/local/bin/ && \
|
||||
sudo cp -uR lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo cp -fv Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo ln -sf /usr/local/bin/wirepy.py /usr/local/bin/wirepy
|
||||
sudo mkdir -p /usr/local/etc/ssl
|
||||
if [ ! -f /usr/local/etc/ssl/pwgk.pem ]
|
||||
then
|
||||
sudo openssl genrsa -out /usr/local/etc/ssl/pwgk.pem 4096
|
||||
fi
|
||||
if grep -i 'Tumbleweed' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
sudo zypper install python313-tk
|
||||
else
|
||||
sudo zypper install python36-tk
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
clear
|
||||
echo $"Your System could not be determined."
|
||||
echo
|
||||
read -n 1 -s -r -p $"Press Enter to exit"
|
||||
clear
|
||||
exit 0
|
||||
|
||||
fi
|
||||
#clear
|
||||
read -n 1 -s -r -p $"Press Enter to exit"
|
||||
clear
|
||||
|
||||
}
|
||||
|
||||
remove(){
|
||||
sudo rm -f /usr/local/bin/wirepy /usr/local/bin/wirepy.py /usr/local/bin/start_wg.py \
|
||||
/usr/local/bin/cls_mth_fc.py /usr/local/bin/ssl_encrypt.py /usr/local/bin/ssl_decrypt.py
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
exit 0
|
||||
else
|
||||
systemctl --user disable wg_start.service
|
||||
rm -r ~/.config/wire_py && rm -r ~/.config/systemd
|
||||
sudo rm /usr/share/applications/Wire-Py.desktop
|
||||
sudo rm /usr/share/locale/de/LC_MESSAGES/languages/de/wirepy.mo
|
||||
sudo rm -r /usr/local/etc/ssl
|
||||
which syncpy >/dev/null
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
sudo rm -r /usr/share/icons/lx-icons && sudo rm -r /usr/share/TK-Themes
|
||||
|
||||
fi
|
||||
|
||||
echo
|
||||
read -p "Press Enter to exit..."
|
||||
|
||||
echo -e "$BLUE"The installer found that they are not in the group sudo.""
|
||||
echo -e "with "$RED"su -"$BLUE" "they can enter the root shell in which they then""
|
||||
echo -e "enter "$GREEN""usermod -aG sudo $USER.""$BLUE""
|
||||
echo -e ""after logging in from the system, they can then run Wire-Py install again." $NORMAL"
|
||||
read -n 1 -s -r -p $"To close the Window press a button"
|
||||
clear
|
||||
exit 0
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
elif grep -i 'mint\|ubuntu\|pop|' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
install_file_with
|
||||
|
||||
|
||||
elif grep -i 'arch' /etc/os-release > /dev/null 2>&1
|
||||
which wirepy >/dev/null
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
groups > /tmp/isgroup
|
||||
echo "Do you want to update/reinstall or uninstall wirepy?"
|
||||
echo
|
||||
echo "Update/reinstall: press y, uninstall press r"
|
||||
echo
|
||||
read -n 1 -s -r -p "Cancel with any other key..." result
|
||||
case $result in
|
||||
[y]* ) clear; install; exit;;
|
||||
[Y]* ) clear; install; exit;;
|
||||
[j]* ) clear; install; exit;;
|
||||
[J]* ) clear; install; exit;;
|
||||
[r]* ) clear; remove; exit;;
|
||||
[R]* ) clear; remove; exit;;
|
||||
esac
|
||||
clear
|
||||
if grep 'wheel' /tmp/isgroup
|
||||
then
|
||||
install_arch_d
|
||||
else
|
||||
echo "The installer found that they are not in the group sudo."
|
||||
echo "The sudoers file must be edited with"
|
||||
echo -e "$RED""su -""$NORMAL"
|
||||
echo -e "$GREEN"""EDITOR=nano visudo"""$NORMAL"
|
||||
echo "Find the line:"
|
||||
echo "## Uncomment to allow members of group wheel to execute any command"
|
||||
echo "remove '#' on # %wheel ALL=(ALL) ALL and save the file"
|
||||
echo -e "then enter "$GREEN"gpasswd -a $USER wheel.""$NORMAL"
|
||||
echo "after logging in from the system, they can then run Wire-Py install again."
|
||||
read -n 1 -s -r -p $"To close the Window press a button"
|
||||
clear
|
||||
exit 0
|
||||
|
||||
fi
|
||||
|
||||
elif grep -i '|manjaro\|garuda\|endeavour|' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
install_arch_d
|
||||
|
||||
|
||||
elif grep -i 'fedora' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
if ! which python3-tkinter &> /dev/null
|
||||
then sudo dnf install python3-tkinter -y
|
||||
|
||||
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
|
||||
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && \
|
||||
sudo cp -u settings.conf /etc/wire_py/ && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
|
||||
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
|
||||
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
|
||||
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo cp -u wg_start.service /lib/systemd/system/ && \
|
||||
sudo systemctl enable wg_start.service
|
||||
|
||||
fi
|
||||
elif grep -i 'suse' /etc/os-release > /dev/null 2>&1
|
||||
then
|
||||
if ! which python311-tk &> /dev/null
|
||||
then sudo zypper install python311-tk
|
||||
sudo cp -u wg_main.py start_wg.py cls_mth_fc.py wirepy.py run_as open_gitea.py /usr/bin/ && \
|
||||
sudo mkdir -p /etc/wire_py && sudo touch /etc/wire_py/.keys && \
|
||||
sudo cp -u settings.conf /etc/wire_py/ && \
|
||||
sudo cp -u languages/de/*.mo /usr/share/locale/de/LC_MESSAGES/ && \
|
||||
sudo cp -uR wp-icons lx-icons /usr/share/icons/ && sudo cp -uR TK-Themes /usr/share/ && \
|
||||
sudo chown -R root:root /etc/wire_py && sudo chmod 755 /etc/wire_py && \
|
||||
sudo ln -sf /usr/bin/wirepy.py /usr/local/bin/wirepy && \
|
||||
sudo cp -u org.wirepy.policy /usr/share/polkit-1/actions/ && \
|
||||
sudo cp -u Wire-Py.desktop /usr/share/applications/ && \
|
||||
sudo cp -u wg_start.service /lib/systemd/system/ && \
|
||||
sudo systemctl enable wg_start.service
|
||||
fi
|
||||
else
|
||||
clear
|
||||
echo $"Your System could not be determined."
|
||||
echo
|
||||
read -n 1 -s -r -p $"To close the window press a button"
|
||||
clear
|
||||
exit 0
|
||||
fi
|
||||
clear
|
||||
read -n 1 -s -r -p $"To close the Window press a button"
|
||||
clear
|
||||
|
||||
|
||||
install
|
||||
|
||||
fi
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import webbrowser
|
||||
|
||||
webbrowser.open('https://git.ilunix.de/punix/Wire-Py')
|
42
org.sslcrypt.policy
Normal file
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
|
||||
|
||||
<!--
|
||||
Policy definitions for ssl_encrypt and ssl_decrypt
|
||||
|
||||
Copyright (C) 2025 Désiré Werner Menrath <polunga40@unity-mail.de>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<policyconfig>
|
||||
<action id="org.ssl_encrypt">
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.exec.path">/usr/local/bin/ssl_encrypt.py</annotate>
|
||||
</action>
|
||||
|
||||
<action id="org.ssl_decrypt">
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.exec.path">/usr/local/bin/ssl_decrypt.py</annotate>
|
||||
|
||||
</action>
|
||||
</policyconfig>
|
@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
<vendor>Project Wire-Py</vendor>
|
||||
<vendor_url>https://git.ilunix.de/punix/Wire-Py</vendor_url>
|
||||
<icon_name>wg-vpn</icon_name>
|
||||
<action id="org.wirepy">
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.exec.path">/usr/bin/wg_main.py</annotate>
|
||||
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
|
||||
</action>
|
||||
</policyconfig>
|
35
ssl_decrypt.py
Executable file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/python3
|
||||
""" This Script decrypt Wireguard files for Wirepy users """
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from subprocess import check_call
|
||||
|
||||
uname: Path = Path("/tmp/.log_user")
|
||||
|
||||
with open(uname, "r", encoding="utf-8") as f:
|
||||
log_name = f.readline()
|
||||
|
||||
# Folder Name "tlecdewg" = Tunnel Encrypt Decrypt Wireguard
|
||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
||||
keyfile: Path = Path(f"/home/{log_name}/.config/wire_py/pbwgk.pem")
|
||||
PKEYFILE: Path = "/usr/local/etc/ssl/pwgk.pem"
|
||||
|
||||
if not keyfile.is_file():
|
||||
|
||||
check_call(["openssl", "rsa", "-in", PKEYFILE, "-out", keyfile, "-outform", "PEM", "-pubout"])
|
||||
shutil.chown(keyfile, 1000, 1000)
|
||||
|
||||
folder_path2 = f"/home/{log_name}/.config/wire_py/"
|
||||
detl: list[str] = os.listdir(folder_path2)
|
||||
os.chdir(folder_path2)
|
||||
detl.remove("keys")
|
||||
detl.remove("settings")
|
||||
if os.path.exists(f"{folder_path2}pbwgk.pem"):
|
||||
detl.remove("pbwgk.pem")
|
||||
for detunnels in detl:
|
||||
tlname2 = f"{detunnels[:-4]}.conf"
|
||||
extpath = f"{folder_path}/{tlname2}"
|
||||
check_call(["openssl", "pkeyutl", "-decrypt", "-inkey", PKEYFILE, "-in", detunnels, "-out", extpath])
|
||||
shutil.chown(extpath, 1000, 1000)
|
47
ssl_encrypt.py
Executable file
@ -0,0 +1,47 @@
|
||||
#!/usr/bin/python3
|
||||
""" This Script encrypt Wireguardfiles for Wirepy users for more Security """
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from subprocess import check_call
|
||||
|
||||
uname: Path = Path("/tmp/.log_user")
|
||||
|
||||
with open(uname, "r", encoding="utf-8") as f:
|
||||
log_name: str = f.readline()
|
||||
|
||||
keyfile: Path = Path(f"/home/{log_name}/.config/wire_py/pbwgk.pem")
|
||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
||||
PKEYFILE = "/usr/local/etc/ssl/pwgk.pem"
|
||||
|
||||
if not keyfile.is_file():
|
||||
|
||||
check_call(["openssl", "rsa", "-in", PKEYFILE, "-out", keyfile, "-outform", "PEM", "-pubout"])
|
||||
shutil.chown(keyfile, 1000, 1000)
|
||||
|
||||
if folder_path.exists():
|
||||
tl = os.listdir(f"{folder_path}")
|
||||
CPTH: str = f"{keyfile}"
|
||||
CRYPTFILES: str = CPTH[:-9]
|
||||
|
||||
if keyfile.exists() and len(tl) != 0:
|
||||
for tunnels in tl:
|
||||
sourcetl: str = f"{folder_path}/{tunnels}"
|
||||
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
|
||||
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
|
||||
tlname,])
|
||||
|
||||
else:
|
||||
|
||||
if folder_path.exists():
|
||||
tl: list[str] = os.listdir(f"{folder_path}")
|
||||
CPTH: str = f"{keyfile}"
|
||||
CRYPTFILES: str = CPTH[:-9]
|
||||
|
||||
if keyfile.exists() and len(tl) != 0:
|
||||
for tunnels in tl:
|
||||
sourcetl: str = f"{folder_path}/{tunnels}"
|
||||
tlname: str = f"{CRYPTFILES}{tunnels[:-5]}.dat"
|
||||
check_call(["openssl", "pkeyutl", "-encrypt", "-inkey", keyfile, "-pubin", "-in", sourcetl, "-out",
|
||||
tlname])
|
16
start_wg.py
@ -1,14 +1,18 @@
|
||||
#!/usr/bin/python3
|
||||
from subprocess import check_call
|
||||
"""
|
||||
This script belongs to wirepy and is for the auto start of the tunnel
|
||||
"""
|
||||
from pathlib import Path
|
||||
from subprocess import check_call
|
||||
|
||||
path_to_file = Path('/etc/wire_py/settings.conf')
|
||||
path_to_file = Path(Path.home() / ".config/wire_py/settings")
|
||||
|
||||
with open(path_to_file, 'r') as a_con:
|
||||
with open(path_to_file, "r", encoding="utf-8") as a_con:
|
||||
|
||||
# This function is for the independent autostarted of the previously selected tunnel
|
||||
lines = a_con.readlines()
|
||||
a_con = lines[7].strip()
|
||||
if a_con != 'off':
|
||||
check_call(['nmcli', 'connection', 'up', a_con])
|
||||
if a_con != "off":
|
||||
check_call(["nmcli", "connection", "up", a_con])
|
||||
else:
|
||||
pass
|
||||
|
||||
|
1161
wg_main.py
@ -5,6 +5,6 @@ After=network-online.target
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStartPre=/bin/sleep 5
|
||||
ExecStart=/usr/bin/start_wg.py
|
||||
ExecStart=/usr/local/bin/start_wg.py
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy=default.target
|
||||
|
875
wirepy.py
@ -1,6 +1,875 @@
|
||||
#!/usr/bin/python3
|
||||
from subprocess import check_call
|
||||
"""
|
||||
this script is a simple GUI for managing Wireguard Tunnels
|
||||
"""
|
||||
import gettext
|
||||
import locale
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tkinter as tk
|
||||
import webbrowser
|
||||
from pathlib import Path
|
||||
from subprocess import check_call
|
||||
from tkinter import TclError, filedialog, ttk
|
||||
|
||||
Path.write_text(Path('/tmp/_u'), str(Path.home()))
|
||||
check_call(['pkexec', '/usr/bin/wg_main.py'])
|
||||
from cls_mth_fc import (Create, GiteaUpdate, Tooltip, Tunnel, LxTools)
|
||||
|
||||
LxTools.uos()
|
||||
Create.dir_and_files()
|
||||
Create.make_dir()
|
||||
Create.decrypt()
|
||||
|
||||
tcl_path: Path = Path("/usr/share/TK-Themes")
|
||||
set_file: Path = Path(Path.home() / ".config/wire_py/settings")
|
||||
tips = LxTools.if_tip(set_file)
|
||||
folder_path: Path = Path("/tmp/tlecdcwg/")
|
||||
user_file = Path("/tmp/.log_user")
|
||||
|
||||
# 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year
|
||||
VERSION: str = "v. 2.04.1725"
|
||||
|
||||
res = GiteaUpdate.api_down("https://git.ilunix.de/api/v1/repos/punix/Wire-Py/releases", VERSION, set_file)
|
||||
|
||||
# Translate
|
||||
APP = "wirepy"
|
||||
LOCALE_DIR = "/usr/share/locale/"
|
||||
locale.bindtextdomain(APP, LOCALE_DIR)
|
||||
gettext.bindtextdomain(APP, LOCALE_DIR)
|
||||
gettext.textdomain(APP)
|
||||
_ = gettext.gettext
|
||||
|
||||
img_w: str = r"/usr/share/icons/lx-icons/64/info.png"
|
||||
img_i: str = r"/usr/share/icons/lx-icons/48/wg_vpn.png"
|
||||
img_w2: str = r"/usr/share/icons/lx-icons/64/error.png"
|
||||
img_i2: str = r"/usr/share/icons/lx-icons/48/wg_msg.png"
|
||||
sl: str = _("Select tunnel")
|
||||
rnp: str = _("Renaming not possible")
|
||||
ie:str = _("Import Error")
|
||||
pfit: str = _("Please first import tunnel")
|
||||
pstl: str = _("Please select a tunnel from the list")
|
||||
|
||||
LxTools.sigi(folder_path, user_file)
|
||||
|
||||
class Wirepy(tk.Tk):
|
||||
"""
|
||||
Class Wirepy this is the Main Window of wirepy
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.my_tool_tip = None
|
||||
self.x_width = 600
|
||||
self.y_height = 383
|
||||
self.monitor_center_x = int(self.winfo_screenwidth() / 2 - (self.x_width / 2))
|
||||
self.monitor_center_y = int(self.winfo_screenheight() / 2 - (self.y_height / 2))
|
||||
self.resizable(width=False, height=False)
|
||||
self.title("Wire-Py")
|
||||
self.geometry(f"{self.x_width}x{self.y_height}+{self.monitor_center_x}+{self.monitor_center_y}")
|
||||
self.columnconfigure(0, weight=1)
|
||||
self.rowconfigure(0, weight=1)
|
||||
|
||||
self.style = ttk.Style(self)
|
||||
self.tk.call("source", f"{tcl_path}/water.tcl")
|
||||
with open(set_file, "r", encoding="utf-8") as read_file:
|
||||
lines = read_file.readlines()
|
||||
if "light\n" in lines:
|
||||
self.tk.call("set_theme", "light")
|
||||
else:
|
||||
self.tk.call("set_theme", "dark")
|
||||
|
||||
# Load the image file from the disk
|
||||
self.wg_icon = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn.png")
|
||||
|
||||
# Set it as the window icon
|
||||
self.iconphoto(True, self.wg_icon)
|
||||
|
||||
FrameWidgets(self).grid()
|
||||
|
||||
|
||||
class FrameWidgets(ttk.Frame):
|
||||
"""
|
||||
ttk frame class for better structure
|
||||
"""
|
||||
|
||||
def __init__(self, container, **kwargs):
|
||||
super().__init__(container, **kwargs)
|
||||
|
||||
self.lb_tunnel = None
|
||||
self.btn_stst = None
|
||||
self.endpoint = None
|
||||
self.dns = None
|
||||
self.address = None
|
||||
self.auto_con = None
|
||||
self.wg_vpn_start = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn-start.png")
|
||||
self.wg_vpn_stop = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_vpn-stop.png")
|
||||
self.imp_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_import.png")
|
||||
self.tr_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_trash.png")
|
||||
self.exp_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/48/wg_export.png")
|
||||
self.warning_pic = tk.PhotoImage(file=r"/usr/share/icons/lx-icons/64/error.png")
|
||||
|
||||
def update():
|
||||
"""
|
||||
Set on or off in file
|
||||
"""
|
||||
if set_update.get() == 1:
|
||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
||||
lines2 = set_f2.readlines()
|
||||
lines2[1] = "off\n"
|
||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
||||
set_f2.writelines(lines2)
|
||||
|
||||
if set_update.get() == 0:
|
||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
||||
lines2 = set_f2.readlines()
|
||||
lines2[1] = "on\n"
|
||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
||||
set_f2.writelines(lines2)
|
||||
|
||||
def theme_change_light():
|
||||
"""
|
||||
Set a light theme
|
||||
"""
|
||||
if self.tk.call("ttk::style", "theme", "use") == "water-dark":
|
||||
self.tk.call("set_theme", "light")
|
||||
with open(set_file, "r", encoding="utf-8") as theme_set2:
|
||||
lines3 = theme_set2.readlines()
|
||||
lines3[3] = "light\n"
|
||||
with open(set_file, "w", encoding="utf-8") as theme_set2:
|
||||
theme_set2.writelines(lines3)
|
||||
self.color_label()
|
||||
|
||||
def theme_change_dark():
|
||||
"""
|
||||
Set a dark theme
|
||||
"""
|
||||
if not self.tk.call("ttk::style", "theme", "use") == "water-dark":
|
||||
self.tk.call("set_theme", "dark")
|
||||
with open(set_file, "r", encoding="utf-8") as theme_set2:
|
||||
lines4 = theme_set2.readlines()
|
||||
lines4[3] = "dark\n"
|
||||
with open(set_file, "w", encoding="utf-8") as theme_set2:
|
||||
theme_set2.writelines(lines4)
|
||||
self.color_label()
|
||||
|
||||
def tooltip():
|
||||
"""
|
||||
Set True or False in a file
|
||||
"""
|
||||
if set_tip.get():
|
||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
||||
lines2 = set_f2.readlines()
|
||||
lines2[5] = "False\n"
|
||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
||||
set_f2.writelines(lines2)
|
||||
|
||||
else:
|
||||
with open(set_file, "r", encoding="utf-8") as set_f2:
|
||||
lines2 = set_f2.readlines()
|
||||
lines2[5] = "True\n"
|
||||
with open(set_file, "w", encoding="utf-8") as set_f2:
|
||||
set_f2.writelines(lines2)
|
||||
|
||||
def info():
|
||||
def link_btn():
|
||||
webbrowser.open("https://git.ilunix.de/punix/Wire-Py")
|
||||
|
||||
msg_t = _("Wire-Py a simple Wireguard Gui for Linux systems.\n\n"
|
||||
"Wire-Py is open source software written in Python.\n\n"
|
||||
"Email: polunga40@unity-mail.de also likes for donation.\n\n"
|
||||
"Use without warranty!\n")
|
||||
|
||||
LxTools.msg_window(img_i, img_i, _("Info"), msg_t, _("Go to Wire-Py git"), link_btn)
|
||||
|
||||
# Frame for Menu
|
||||
self.menu_frame = ttk.Frame(self)
|
||||
self.menu_frame.configure(relief="flat")
|
||||
self.menu_frame.grid(column=0, row=0, columnspan=4, sticky="w")
|
||||
|
||||
# App Menu
|
||||
self.version_lb = ttk.Label(self.menu_frame, text=VERSION)
|
||||
self.version_lb.config(font=("Ubuntu", 11), foreground="#00c4ff")
|
||||
self.version_lb.grid(column=0, row=0, rowspan=4, padx=10)
|
||||
|
||||
Tooltip(self.version_lb, f"Version: {VERSION[2:]}", tips)
|
||||
|
||||
self.options_btn = ttk.Menubutton(self.menu_frame, text=_("Options"))
|
||||
self.options_btn.grid(column=1, columnspan=1, row=0)
|
||||
|
||||
Tooltip(self.options_btn, _("Click for Settings"), tips)
|
||||
|
||||
set_update = tk.IntVar()
|
||||
set_tip = tk.BooleanVar()
|
||||
self.settings = tk.Menu(self, relief="flat")
|
||||
self.options_btn.configure(menu=self.settings, style="Toolbutton")
|
||||
self.settings.add_checkbutton(label=_("Disable Updates"), command=update, variable=set_update)
|
||||
self.settings.add_checkbutton(label=_("Disable Tooltips"), command=tooltip, variable=set_tip)
|
||||
self.settings.add_command(label=_("Light"), command=theme_change_light)
|
||||
self.settings.add_command(label=_("Dark"), command=theme_change_dark)
|
||||
|
||||
# About BTN Menu / Label
|
||||
self.about_btn = ttk.Button(
|
||||
self.menu_frame, text=_("About"), style="Toolbutton", command=info
|
||||
)
|
||||
self.about_btn.grid(column=2, columnspan=2, row=0)
|
||||
self.readme = tk.Menu(self)
|
||||
|
||||
# Update and Tooltip Label
|
||||
self.updates_lb = ttk.Label(self.menu_frame)
|
||||
self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10)
|
||||
|
||||
# View Checkbox to enable or disable Tooltip
|
||||
if tips:
|
||||
set_tip.set(value=False)
|
||||
else:
|
||||
set_tip.set(value=True)
|
||||
|
||||
# View Checkbox for enable or disable Updates
|
||||
if res == "False":
|
||||
set_update.set(value=1)
|
||||
self.updates_lb.configure(text=_("Update search off"))
|
||||
|
||||
Tooltip(self.updates_lb, _("Updates you have disabled"), tips)
|
||||
|
||||
elif res == "No Internet Connection!":
|
||||
self.updates_lb.configure(text=_("No Server Connection!"), foreground="red")
|
||||
elif res == "No Updates":
|
||||
self.updates_lb.configure(text=_("No Updates"))
|
||||
|
||||
Tooltip(self.updates_lb, _("Congratulations! Wire-Py is up to date"), tips)
|
||||
|
||||
else:
|
||||
set_update.set(value=0)
|
||||
text = f"Update {res} {_("available!")}"
|
||||
|
||||
# Update BTN Menu
|
||||
self.update_btn = ttk.Menubutton(self.menu_frame, text=text)
|
||||
self.update_btn.grid(column=4, columnspan=3, row=0, padx=0)
|
||||
|
||||
Tooltip(self.update_btn, _("Click to download new version"), tips)
|
||||
|
||||
self.download = tk.Menu(self, relief="flat")
|
||||
|
||||
self.update_btn.configure(menu=self.download, style="Toolbutton")
|
||||
self.download.add_command(
|
||||
label=_("Download"),
|
||||
command=lambda: GiteaUpdate.download(f"https://git.ilunix.de/punix/Wire-Py/archive/{res}.zip",
|
||||
res, img_w, img_i, img_w2, img_i2))
|
||||
|
||||
# Show active Tunnel
|
||||
self.a = Tunnel.active()
|
||||
|
||||
# Label Frame 1
|
||||
self.lb_frame_btn_lbox = ttk.Frame(self)
|
||||
self.lb_frame_btn_lbox.configure(relief="flat")
|
||||
self.lb_frame_btn_lbox.grid(column=0, rowspan=3, row=1)
|
||||
|
||||
# Label Frame 2
|
||||
self.lb_frame = ttk.Frame(self)
|
||||
self.lb_frame.configure(relief="solid")
|
||||
self.lb_frame.grid(column=2, row=2, sticky="snew", padx=20, pady=5)
|
||||
|
||||
# Label Frame 3
|
||||
self.lb_frame2 = ttk.Frame(self)
|
||||
self.lb_frame2.configure(relief="solid")
|
||||
self.lb_frame2.grid(column=2, row=3, sticky="snew", padx=20, pady=5)
|
||||
|
||||
# Bottom Frame 4
|
||||
self.lb_frame3 = ttk.Frame(self)
|
||||
self.lb_frame3.configure(relief="flat")
|
||||
self.lb_frame3.grid(column=0, row=5, columnspan=4, sticky="snew", padx=2, pady=2)
|
||||
|
||||
# Bottom Frame 5
|
||||
self.lb_frame4 = ttk.Frame(self)
|
||||
self.lb_frame4.configure(relief="flat")
|
||||
self.lb_frame4.grid(column=2, row=5, columnspan=3, sticky="e", padx=15)
|
||||
|
||||
# Show active Label
|
||||
self.select_tunnel = None
|
||||
self.lb = ttk.Label(self, text=_("Active: "))
|
||||
self.lb.config(font=("Ubuntu", 11, "bold"))
|
||||
self.lb.grid(column=2, row=1, padx=15, pady=4, sticky="w")
|
||||
|
||||
# Label to Show active Tunnel
|
||||
self.str_var = tk.StringVar(value=self.a)
|
||||
self.color_label()
|
||||
|
||||
# Interface Label
|
||||
self.interface = ttk.Label(self.lb_frame, text=_("Interface"))
|
||||
self.interface.grid(column=0, row=3, sticky="we", padx=120)
|
||||
self.interface.config(font=("Ubuntu", 9))
|
||||
|
||||
# Peer Label
|
||||
self.peer = ttk.Label(self.lb_frame2, text=_("Peer"))
|
||||
self.peer.config(font=("Ubuntu", 9))
|
||||
self.peer.grid(column=0, row=4, sticky="we", padx=130)
|
||||
|
||||
def enable_check_box(_):
|
||||
"""
|
||||
checkbox for enable autostart Tunnel
|
||||
"""
|
||||
Create.files_for_autostart()
|
||||
if self.l_box.size() != 0:
|
||||
self.wg_autostart.configure(state="normal")
|
||||
self.lb_rename.config(state="normal")
|
||||
self.lb_rename.delete(0, tk.END)
|
||||
self.btn_rename.config(state="normal")
|
||||
|
||||
# Listbox with Scrollbar
|
||||
self.l_box = tk.Listbox(self.lb_frame_btn_lbox, selectmode="single")
|
||||
self.l_box.config(relief="ridge", font=("Ubuntu", 12, "bold"))
|
||||
self.l_box.grid(column=1, rowspan=4, row=0, sticky="ns")
|
||||
self.l_box.event_add("<<ClickEvent>>", "<Button-1>")
|
||||
self.l_box.bind("<<ClickEvent>>", enable_check_box)
|
||||
self.scrollbar = ttk.Scrollbar(self.lb_frame_btn_lbox, orient="vertical", command=self.l_box.yview)
|
||||
self.scrollbar.grid(column=1, rowspan=4, row=0, sticky="nse")
|
||||
self.l_box.configure(yscrollcommand=self.scrollbar.set)
|
||||
|
||||
# Tunnel List
|
||||
self.tl = Tunnel.list()
|
||||
for tunnels in self.tl:
|
||||
self.l_box.insert("end", tunnels[:-5])
|
||||
self.l_box.update()
|
||||
|
||||
# Button Vpn
|
||||
if self.a != "":
|
||||
self.stop()
|
||||
wg_read = f"/tmp/tlecdcwg/{self.a}.conf"
|
||||
with open(wg_read, "r", encoding="utf-8") as file:
|
||||
data = Tunnel.con_to_dict(file)
|
||||
|
||||
# Address Label
|
||||
self.init_and_report(data)
|
||||
self.show_data()
|
||||
else:
|
||||
self.start()
|
||||
|
||||
# Address Label
|
||||
self.add = tk.StringVar()
|
||||
self.DNS = tk.StringVar()
|
||||
self.enp = tk.StringVar()
|
||||
self.label_empty()
|
||||
self.show_data()
|
||||
|
||||
# Button Import
|
||||
self.btn_i = ttk.Button(self.lb_frame_btn_lbox, image=self.imp_pic, command=self.import_sl, padding=0)
|
||||
self.btn_i.grid(column=0, row=1, padx=15, pady=8)
|
||||
|
||||
Tooltip(self.btn_i, _("Click to import a Wireguard Tunnel"), tips)
|
||||
|
||||
def delete():
|
||||
"""
|
||||
delete Wireguard Tunnel
|
||||
"""
|
||||
try:
|
||||
self.select_tunnel = self.l_box.curselection()
|
||||
select_tl = self.l_box.get(self.select_tunnel[0])
|
||||
with open(f"/tmp/tlecdcwg/{select_tl}.conf", "r+", encoding="utf-8") as file2:
|
||||
key = Tunnel.con_to_dict(file2)
|
||||
pre_key = key[3]
|
||||
check_call(["nmcli", "connection", "delete", select_tl])
|
||||
self.l_box.delete(self.select_tunnel[0])
|
||||
with open(set_file, "r", encoding="utf-8") as set_f6:
|
||||
lines6 = set_f6.readlines()
|
||||
if (
|
||||
select_tl == lines6[7].strip()
|
||||
and "off\n" not in lines6[7].strip()
|
||||
):
|
||||
lines6[7] = "off\n"
|
||||
with open(set_file, "w", encoding="utf-8") as set_f7:
|
||||
set_f7.writelines(lines6)
|
||||
self.selected_option.set(0)
|
||||
self.autoconnect_var.set(_("no Autoconnect"))
|
||||
is_encrypt = Path.home() / f".config/wire_py/{select_tl}.dat"
|
||||
if is_encrypt.is_file():
|
||||
Path.unlink(f"{Path.home()}/.config/wire_py/{select_tl}.dat")
|
||||
Path.unlink(f"/tmp/tlecdcwg/{select_tl}.conf")
|
||||
with open(f"{Path.home()}/.config/wire_py/keys", "r", encoding="utf-8") as readfile:
|
||||
with open(f"{Path.home()}/.config/wire_py/keys2", "w", encoding="utf-8") as writefile:
|
||||
for line in readfile:
|
||||
if pre_key not in line.strip("\n"):
|
||||
writefile.write(line)
|
||||
file_one = Path(f"{Path.home()}/.config/wire_py/keys2")
|
||||
file_two = file_one.with_name("keys")
|
||||
file_one.replace(file_two)
|
||||
self.wg_autostart.configure(state="disabled")
|
||||
|
||||
# for disabling checkbox when Listbox empty
|
||||
if self.l_box.size() == 0:
|
||||
self.wg_autostart.configure(state="disabled")
|
||||
self.lb_rename.configure(state="disabled")
|
||||
Tooltip(self.wg_autostart, _("You must have at least one\ntunnel in the list,to use the autostart")
|
||||
, tips)
|
||||
|
||||
Tooltip(self.btn_exp, _("No Tunnels in List for Export"), tips)
|
||||
Tooltip(self.btn_stst, _("No tunnels to start in the list"), tips)
|
||||
Tooltip(self.lb_rename, _("To rename a tunnel, at least one must be in the list"), tips, )
|
||||
self.lb_rename.insert(0, _("Max. 12 characters!"))
|
||||
|
||||
if self.a != "" and self.a == select_tl:
|
||||
self.str_var.set(value="")
|
||||
self.start()
|
||||
self.l_box.update()
|
||||
|
||||
# Address Label
|
||||
self.add.set("")
|
||||
self.DNS.set("")
|
||||
self.enp.set("")
|
||||
|
||||
except IndexError:
|
||||
|
||||
if self.l_box.size() != 0:
|
||||
|
||||
LxTools.msg_window(img_w, img_i2, sl, pstl)
|
||||
|
||||
else:
|
||||
|
||||
LxTools.msg_window(img_w, img_i2, sl, pfit)
|
||||
|
||||
# Button Trash
|
||||
self.btn_tr = ttk.Button(self.lb_frame_btn_lbox, image=self.tr_pic, command=delete, padding=0,
|
||||
style="CButton.TButton")
|
||||
self.btn_tr.grid(column=0, row=2, padx=15, pady=8)
|
||||
|
||||
if self.l_box.size() == 0:
|
||||
Tooltip(self.btn_tr, _("No tunnels to delete in the list"), tips)
|
||||
else:
|
||||
Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!"), tips)
|
||||
|
||||
# Button Export
|
||||
self.btn_exp = ttk.Button(self.lb_frame_btn_lbox, image=self.exp_pic,
|
||||
command=lambda: Tunnel.export(img_w, img_i, img_w2, img_i2, sl, pfit), padding=0)
|
||||
self.btn_exp.grid(column=0, row=3, padx=15, pady=8)
|
||||
|
||||
if self.l_box.size() == 0:
|
||||
Tooltip(self.btn_exp, _("No Tunnels in List for Export"), tips)
|
||||
else:
|
||||
Tooltip(self.btn_exp, _("Click to export all\nWireguard Tunnel to Zipfile"), tips)
|
||||
|
||||
# Label Entry
|
||||
self.lb_rename = ttk.Entry(self.lb_frame4, width=20)
|
||||
self.lb_rename.grid(column=2, row=0, padx=8, pady=10, sticky="ne")
|
||||
self.lb_rename.insert(0, _("Max. 12 characters!"))
|
||||
self.lb_rename.config(state="disable")
|
||||
|
||||
if self.l_box.size() != 0:
|
||||
Tooltip(self.lb_rename, _("To rename a tunnel, you need to\nselect a tunnel from the list"), tips)
|
||||
else:
|
||||
Tooltip(self.lb_rename, _("To rename a tunnel, at least one must be in the list"), tips)
|
||||
|
||||
def tl_rename():
|
||||
|
||||
special_characters = ["\\", "/", "{", "}", " "]
|
||||
|
||||
if len(self.lb_rename.get()) > 12:
|
||||
|
||||
LxTools.msg_window(img_w, img_i2, rnp, _("The new name may contain only 12 characters"))
|
||||
|
||||
elif len(self.lb_rename.get()) == 0:
|
||||
|
||||
LxTools.msg_window(img_w, img_i2, rnp, _("At least one character must be entered"))
|
||||
|
||||
elif any(ch in special_characters for ch in self.lb_rename.get()):
|
||||
|
||||
msg_t = _("No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n")
|
||||
LxTools.msg_window(img_w, img_i2, rnp, msg_t)
|
||||
|
||||
else:
|
||||
|
||||
try:
|
||||
self.select_tunnel = self.l_box.curselection()
|
||||
select_tl = self.l_box.get(self.select_tunnel[0])
|
||||
|
||||
# nmcli connection modify old connection.id iphone
|
||||
check_call(["nmcli", "connection", "modify", select_tl, "connection.id", self.lb_rename.get()])
|
||||
source = Path(f"/tmp/tlecdcwg/{select_tl}.conf")
|
||||
destination = source.with_name(f"{self.lb_rename.get()}.conf")
|
||||
source.replace(destination)
|
||||
Path.unlink(f"{Path.home()}/.config/wire_py/{select_tl}.dat")
|
||||
|
||||
self.l_box.delete(self.select_tunnel[0])
|
||||
self.l_box.insert("end", self.lb_rename.get())
|
||||
self.l_box.update()
|
||||
new_a_connect = self.lb_rename.get()
|
||||
self.lb_rename.delete(0, tk.END)
|
||||
if self.a != "" and self.a == select_tl:
|
||||
self.a = Tunnel.active()
|
||||
self.str_var.set(value=self.a)
|
||||
with open(set_file, "r", encoding="utf-8") as set_f5:
|
||||
lines5 = set_f5.readlines()
|
||||
if select_tl == lines5[7].strip() and "off\n" not in lines5[7].strip():
|
||||
lines5[7] = new_a_connect
|
||||
with open(set_file, "w", encoding="utf-8") as theme_set5:
|
||||
theme_set5.writelines(lines5)
|
||||
self.autoconnect_var.set(value=new_a_connect)
|
||||
|
||||
Create.encrypt()
|
||||
|
||||
except IndexError:
|
||||
|
||||
LxTools.msg_window(img_w, img_i2, rnp, pstl)
|
||||
|
||||
# Button Rename
|
||||
self.btn_rename = ttk.Button(self.lb_frame4, text=_("Rename"), state="disable", command=tl_rename, padding=4,
|
||||
style="RnButton.TButton")
|
||||
self.btn_rename.grid(column=3, row=0, padx=5, pady=10, sticky="ne")
|
||||
|
||||
# Check Buttons
|
||||
self.selected_option = tk.IntVar()
|
||||
self.autoconnect_var = tk.StringVar()
|
||||
self.autoconnect_var.set(self.auto_con)
|
||||
|
||||
# Frame for Labels, Entry and Button
|
||||
self.autoconnect = ttk.Label(self.lb_frame3, textvariable=self.autoconnect_var, width=15)
|
||||
self.autoconnect.config(font=("Ubuntu", 11))
|
||||
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
|
||||
self.wg_autostart = ttk.Checkbutton(self.lb_frame3, text=_("Autoconnect on:"), variable=self.selected_option,
|
||||
command=self.box_set)
|
||||
self.wg_autostart.grid(column=0, row=0, pady=15, padx=15, sticky="nw")
|
||||
|
||||
if self.l_box.size() >= 1 and len(self.l_box.curselection()) >= 1:
|
||||
Tooltip(self.wg_autostart, _("To use the autostart, enable this Checkbox"), tips)
|
||||
|
||||
if self.l_box.size() == 0:
|
||||
Tooltip(self.wg_autostart, _("You must have at least one\ntunnel in the list,to use the autostart"), tips)
|
||||
|
||||
else:
|
||||
|
||||
Tooltip(self.wg_autostart, _("To use the autostart, a tunnel must be selected from the list"), tips)
|
||||
|
||||
self.on_off()
|
||||
|
||||
def import_sl(self):
|
||||
"""
|
||||
Import Methode for Wireguard config Files.
|
||||
Before importing, it is checked whether PrivateKey and PublicKey are in the file.
|
||||
If True, then it is checked whether the PreSharedKey is already in the key file
|
||||
to avoid an import error so that no double wgconf are imported.
|
||||
Thus, tunnels can be renamed without the problems arising.
|
||||
If False, then the key is written into the file.
|
||||
Furthermore, it is checked whether the name is longer than 12 characters.
|
||||
If True, then the name is automatically shortened to 12 characters
|
||||
and then imported.
|
||||
If in each case false comes out, a corresponding window comes to
|
||||
inform the user that something is wrong.
|
||||
"""
|
||||
|
||||
Create.dir_and_files()
|
||||
|
||||
try:
|
||||
filepath = filedialog.askopenfilename(initialdir=f"{Path.home()}", title=_("Select Wireguard config File"),
|
||||
filetypes=[(_("WG config files"), "*.conf")])
|
||||
|
||||
with open(filepath, "r", encoding="utf-8") as file:
|
||||
read = file.read()
|
||||
path_split = filepath.split("/")
|
||||
path_split1 = path_split[-1]
|
||||
self.a = Tunnel.active()
|
||||
|
||||
if "PrivateKey = " in read and "PublicKey = " in read and "Endpoint =" in read:
|
||||
with open(filepath, "r", encoding="utf-8") as file:
|
||||
key = Tunnel.con_to_dict(file)
|
||||
pre_key = key[3]
|
||||
if len(pre_key) != 0:
|
||||
with open(f"{Path.home()}/.config/wire_py/keys", "r", encoding="utf-8") as readfile:
|
||||
p_key = readfile.readlines()
|
||||
if pre_key in p_key or f"{pre_key}\n" in p_key:
|
||||
|
||||
msg_t = _("Tunnel already available!\nPlease use another file for import")
|
||||
LxTools.msg_window(img_w2, img_i2, ie, msg_t)
|
||||
|
||||
else:
|
||||
|
||||
with open(f"{Path.home()}/.config/wire_py/keys", "a", encoding="utf-8") as keyfile:
|
||||
keyfile.write(f"{pre_key}\r")
|
||||
if len(path_split1) > 17:
|
||||
p1 = shutil.copy(filepath, "/tmp/tlecdcwg/")
|
||||
path_split = path_split1[len(path_split1) - 17:]
|
||||
os.rename(p1, f"/tmp/tlecdcwg/{path_split}")
|
||||
new_conf = f"/tmp/tlecdcwg/{path_split}"
|
||||
if self.a != "":
|
||||
check_call(["nmcli", "connection", "down", Tunnel.active()])
|
||||
self.label_empty()
|
||||
|
||||
subprocess.check_output(["nmcli", "connection", "import", "type",
|
||||
"wireguard", "file", new_conf], text=True)
|
||||
|
||||
Create.encrypt()
|
||||
|
||||
else:
|
||||
shutil.copy(filepath, "/tmp/tlecdcwg/")
|
||||
if self.a != "":
|
||||
check_call(["nmcli", "connection", "down", Tunnel.active()])
|
||||
self.label_empty()
|
||||
|
||||
subprocess.check_output(["nmcli", "connection", "import", "type",
|
||||
"wireguard", "file", filepath], text=True)
|
||||
|
||||
Create.encrypt()
|
||||
|
||||
self.str_var.set("")
|
||||
self.a = Tunnel.active()
|
||||
self.l_box.insert(0, self.a)
|
||||
self.wg_autostart.configure(state="normal")
|
||||
self.l_box.selection_clear(0, tk.END)
|
||||
self.l_box.update()
|
||||
self.l_box.selection_set(0)
|
||||
|
||||
Tooltip(self.wg_autostart, _("To use the autostart, enable this Checkbox"), tips)
|
||||
|
||||
# Tooltip(self.l_box, _("List of available tunnels"))
|
||||
|
||||
Tooltip(self.btn_tr, _("Click to delete a Wireguard Tunnel\nSelect from the list!")
|
||||
, tips,)
|
||||
|
||||
Tooltip(self.btn_exp, _(" Click to export all\nWireguard Tunnel to Zipfile")
|
||||
, tips)
|
||||
|
||||
Tooltip(self.btn_rename, _("To rename a tunnel, you need to\nselect a tunnel from"
|
||||
" the list"), tips)
|
||||
|
||||
self.lb_rename.insert(0, "Max. 12 characters!")
|
||||
self.str_var = tk.StringVar()
|
||||
self.str_var.set(self.a)
|
||||
self.color_label()
|
||||
self.stop()
|
||||
wg_read = f"/tmp/tlecdcwg/{self.a}.conf"
|
||||
with open(wg_read, "r", encoding="utf-8") as file_for_key:
|
||||
data = Tunnel.con_to_dict(file_for_key)
|
||||
|
||||
# Address Label
|
||||
self.init_and_report(data)
|
||||
self.show_data()
|
||||
check_call(["nmcli", "con", "mod", self.a, "connection.autoconnect", "no"])
|
||||
Path.chmod(wg_read, 0o600)
|
||||
|
||||
if ("PrivateKey = " in read) and ("Endpoint = " in read):
|
||||
pass
|
||||
else:
|
||||
|
||||
msg_t = _("Oh... no valid Wireguard File!\nPlease select a valid Wireguard File")
|
||||
LxTools.msg_window(img_w2, img_i2, ie, msg_t)
|
||||
|
||||
except EOFError as e:
|
||||
print(e)
|
||||
except TypeError:
|
||||
print("File import: abort by user...")
|
||||
except FileNotFoundError:
|
||||
print("File import: abort by user...")
|
||||
except subprocess.CalledProcessError:
|
||||
print("Tunnel exist!")
|
||||
|
||||
def box_set(self):
|
||||
"""
|
||||
This Method will display the autostart label which
|
||||
Tunnel is automatically started regardless of the active tunnel.
|
||||
The selected tunnel is written into a file to read it after the start of the system.
|
||||
"""
|
||||
try:
|
||||
select_tunnel = self.l_box.curselection()
|
||||
select_tl = self.l_box.get(select_tunnel[0])
|
||||
|
||||
if self.selected_option.get() == 0:
|
||||
with open(set_file, "r", encoding="utf-8") as set_f3:
|
||||
lines3 = set_f3.readlines()
|
||||
lines3[7] = "off\n"
|
||||
with open(set_file, "w", encoding="utf-8") as set_f3:
|
||||
set_f3.writelines(lines3)
|
||||
|
||||
tl = Tunnel.list()
|
||||
|
||||
if len(tl) == 0:
|
||||
self.wg_autostart.configure(state="disabled")
|
||||
|
||||
if self.selected_option.get() >= 1:
|
||||
with open(set_file, "r", encoding="utf-8") as set_f3:
|
||||
lines3 = set_f3.readlines()
|
||||
lines3[7] = select_tl
|
||||
with open(set_file, "w", encoding="utf-8") as set_f3:
|
||||
set_f3.writelines(lines3)
|
||||
|
||||
except IndexError:
|
||||
self.selected_option.set(1)
|
||||
|
||||
self.on_off()
|
||||
|
||||
def on_off(self):
|
||||
"""
|
||||
Here it is checked whether the path to the file is there, if not, it is created.
|
||||
Set (on), the selected tunnel is displayed in the label.
|
||||
At (off) the label is first emptied then filled with No Autoconnect
|
||||
"""
|
||||
with open(set_file, "r", encoding="utf-8") as set_f4:
|
||||
lines4 = set_f4.readlines()
|
||||
|
||||
if lines4[7] != "off\n":
|
||||
print(f"{lines4[7]} starts automatically when the system starts.")
|
||||
self.selected_option.set(1)
|
||||
self.autoconnect_var.set("")
|
||||
self.auto_con = lines4[7]
|
||||
|
||||
else:
|
||||
self.selected_option.set(0)
|
||||
self.auto_con = _("no Autoconnect")
|
||||
print("Autostart disabled.")
|
||||
self.autoconnect_var.set("")
|
||||
self.autoconnect_var = tk.StringVar()
|
||||
self.autoconnect_var.set(self.auto_con)
|
||||
|
||||
self.autoconnect = ttk.Label(self.lb_frame3, textvariable=self.autoconnect_var, foreground="#0071ff", width=15)
|
||||
self.autoconnect.config(font=("Ubuntu", 11))
|
||||
self.autoconnect.grid(column=1, row=0, sticky="e", pady=19)
|
||||
|
||||
def init_and_report(self, data=None):
|
||||
"""
|
||||
Displays the value address, DNS and peer in the labels
|
||||
or empty it again
|
||||
"""
|
||||
|
||||
# Address Label
|
||||
self.add = tk.StringVar()
|
||||
self.add.set(f"{_("Address: ")}{data[0]}")
|
||||
self.DNS = tk.StringVar()
|
||||
self.DNS.set(f" DNS: {data[1]}")
|
||||
self.enp = tk.StringVar()
|
||||
self.enp.set(f"{_("Endpoint: ")}{data[2]}")
|
||||
|
||||
def label_empty(self):
|
||||
"""
|
||||
empty labels
|
||||
"""
|
||||
self.add.set("")
|
||||
self.DNS.set("")
|
||||
self.enp.set("")
|
||||
|
||||
def show_data(self):
|
||||
"""
|
||||
shows data in the label
|
||||
"""
|
||||
|
||||
# Address Label
|
||||
self.address = ttk.Label(self.lb_frame, textvariable=self.add, foreground="#0071ff")
|
||||
self.address.grid(column=0, row=5, sticky="w", padx=10, pady=6)
|
||||
self.address.config(font=("Ubuntu", 9))
|
||||
|
||||
# DNS Label
|
||||
self.dns = ttk.Label(self.lb_frame, textvariable=self.DNS, foreground="#0071ff")
|
||||
self.dns.grid(column=0, row=7, sticky="w", padx=10, pady=6)
|
||||
self.dns.config(font=("Ubuntu", 9))
|
||||
|
||||
# Endpoint Label
|
||||
self.endpoint = ttk.Label(self.lb_frame2, textvariable=self.enp, foreground="#0071ff")
|
||||
self.endpoint.grid(column=0, row=8, sticky="w", padx=10, pady=20)
|
||||
self.endpoint.config(font=("Ubuntu", 9))
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stop Button
|
||||
"""
|
||||
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_stop, command=self.wg_switch, padding=0)
|
||||
self.btn_stst.grid(column=0, row=0, padx=5, pady=8)
|
||||
|
||||
Tooltip(self.btn_stst, _("Click to stop selected Wireguard Tunnel"), tips)
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Start Button
|
||||
"""
|
||||
self.btn_stst = ttk.Button(self.lb_frame_btn_lbox, image=self.wg_vpn_start, command=self.wg_switch, padding=0)
|
||||
self.btn_stst.grid(column=0, row=0, padx=5, pady=8)
|
||||
|
||||
tl = Tunnel.list()
|
||||
if len(tl) == 0:
|
||||
Tooltip(self.btn_stst, _("No tunnels to start in the list"), tips)
|
||||
else:
|
||||
Tooltip(self.btn_stst, _("Click to start selected Wireguard Tunnel"), tips)
|
||||
|
||||
def color_label(self):
|
||||
"""
|
||||
View activ Tunnel in the color green or yellow
|
||||
"""
|
||||
|
||||
with open(set_file, "r", encoding="utf-8") as read_file:
|
||||
lines = read_file.readlines()
|
||||
if "light\n" in lines:
|
||||
self.lb_tunnel = ttk.Label(self, textvariable=self.str_var, foreground="green")
|
||||
|
||||
else:
|
||||
self.lb_tunnel = ttk.Label(self, textvariable=self.str_var, foreground="yellow")
|
||||
|
||||
self.lb_tunnel.config(font=("Ubuntu", 11, "bold"))
|
||||
self.lb_tunnel.grid(column=2, padx=10, row=1)
|
||||
|
||||
def wg_switch(self):
|
||||
"""
|
||||
switch Tunnel method change from labels and buttons
|
||||
"""
|
||||
self.a = Tunnel.active()
|
||||
try:
|
||||
if self.a == "":
|
||||
|
||||
self.start()
|
||||
self.select_tunnel = self.l_box.curselection()
|
||||
select_tl = self.l_box.get(self.select_tunnel[0])
|
||||
check_call(["nmcli", "connection", "up", select_tl])
|
||||
wg_read = f"/tmp/tlecdcwg/{select_tl}.conf"
|
||||
with open(wg_read, "r", encoding="utf-8") as file:
|
||||
data = Tunnel.con_to_dict(file)
|
||||
|
||||
# Address Label
|
||||
self.init_and_report(data)
|
||||
self.show_data()
|
||||
|
||||
# Button Start/Stop
|
||||
self.stop()
|
||||
self.a = Tunnel.active()
|
||||
self.str_var = tk.StringVar()
|
||||
self.str_var.set(self.a)
|
||||
self.color_label()
|
||||
|
||||
elif self.a != "":
|
||||
|
||||
# Button Start/Stop
|
||||
self.stop()
|
||||
check_call(["nmcli", "connection", "down", self.a])
|
||||
|
||||
# Button Start/Stop
|
||||
self.start()
|
||||
self.a = Tunnel.active()
|
||||
self.str_var.set("")
|
||||
self.color_label()
|
||||
|
||||
# Address Label
|
||||
self.add.set("")
|
||||
self.DNS.set("")
|
||||
self.enp.set("")
|
||||
self.show_data()
|
||||
|
||||
except IndexError:
|
||||
|
||||
if self.l_box.size() != 0:
|
||||
|
||||
LxTools.msg_window(img_w, img_i2, sl, pstl)
|
||||
|
||||
else:
|
||||
|
||||
LxTools.msg_window(img_w, img_i2, sl, pfit)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
window = Wirepy()
|
||||
"""
|
||||
the hidden files are hidden in Filedialog
|
||||
"""
|
||||
try:
|
||||
window.tk.call("tk_getOpenFile", "-foobarbaz")
|
||||
except TclError:
|
||||
pass
|
||||
window.tk.call("set", "::tk::dialog::file::showHiddenBtn", "0")
|
||||
window.tk.call("set", "::tk::dialog::file::showHiddenVar", "0")
|
||||
window.mainloop()
|
||||
|
||||
LxTools.clean_files(folder_path, user_file)
|
||||
sys.exit(0)
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.7 KiB |