punix
cf94bf3d1d
Install further adapted and with colored text if user is not in group sudo or wheel. Added to install Opensuse for installation
411 lines
17 KiB
Python
Executable File
411 lines
17 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
import tkinter as tk
|
|
from subprocess import check_call
|
|
from tkinter import *
|
|
from pathlib import Path
|
|
from tkinter import ttk
|
|
|
|
from wg_func import (TunnelActiv, ListTunnels, ImportTunnel, ConToDict, GreenLabel, StartStopBTN, ShowAddress,
|
|
FileHandle, ExportTunnels, OnOff, msg_window)
|
|
|
|
font_color = '#4011a7'
|
|
dk_theme = '#2e2e2e'
|
|
''' 1 = 1. Year, 09 = Month of the Year, 2924 = Day and Year of the Year '''
|
|
version = 'v. 1.10.0424'
|
|
|
|
|
|
class MainWindow(tk.Tk):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.switch_on = None
|
|
self.switch_off = None
|
|
self.x_width = 600
|
|
self.y_height = 340
|
|
self.monitor_center_x = self.winfo_screenwidth() / 2 - (self.x_width / 2)
|
|
self.monitor_center_y = self.winfo_screenheight() / 2 - (self.y_height / 2)
|
|
self.resizable(width=False, height=False)
|
|
self.title('Wire-Py')
|
|
self.configure()
|
|
self.geometry('%dx%d+%d+%d' % (self.x_width, 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.style.theme_use('clam')
|
|
|
|
''' Load the image file from disk. '''
|
|
self.wg_icon = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn.png')
|
|
# Set it as the window icon.
|
|
self.iconphoto(True, self.wg_icon)
|
|
|
|
# App Menu
|
|
self.app_menu = tk.Menu(self, borderwidth=0)
|
|
|
|
self.configure(menu=self.app_menu)
|
|
self.app_menu.add_cascade(label=version)
|
|
self.app_menu.add_cascade(label='Options')
|
|
self.app_menu.add_cascade(label='?')
|
|
|
|
FrameWidgets(self).grid()
|
|
|
|
|
|
class FrameWidgets(ttk.Frame):
|
|
def __init__(self, container, **kwargs):
|
|
super().__init__(container, **kwargs)
|
|
|
|
self.auto_con = None
|
|
self.enp = None
|
|
self.DNS = None
|
|
self.add = None
|
|
self.data = None
|
|
self.peer = None
|
|
self.lb_tunnel = None
|
|
self.wg_read = None
|
|
self.wg_vpn_start = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-start.png')
|
|
self.wg_vpn_stop = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_vpn-stop.png')
|
|
self.imp_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_import.png')
|
|
self.tr_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_trash.png')
|
|
self.exp_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/48/wg_export.png')
|
|
self.warning_pic = tk.PhotoImage(file=r'/usr/share/icons/wp-icons/64/error.png')
|
|
|
|
''' Show active Tunnel '''
|
|
self.a = TunnelActiv.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=4, row=0)
|
|
self.columnconfigure(0, weight=1)
|
|
self.rowconfigure(0, weight=1)
|
|
|
|
''' Label Frame 2 '''
|
|
self.lb_frame = ttk.Frame(self)
|
|
self.lb_frame.configure(relief='solid')
|
|
self.lb_frame.grid(column=2, row=1, sticky='snew', padx=20, pady=5)
|
|
self.columnconfigure(2, weight=1)
|
|
self.rowconfigure(1, weight=1)
|
|
|
|
''' Label Frame 3 '''
|
|
self.lb_frame2 = ttk.Frame(self)
|
|
self.lb_frame2.configure(relief='solid')
|
|
self.lb_frame2.grid(column=2, row=2, sticky='snew', padx=20, pady=5)
|
|
self.columnconfigure(2, weight=1)
|
|
self.rowconfigure(2, weight=1)
|
|
|
|
''' Show active Label '''
|
|
self.select_tunnel = None
|
|
self.lb = tk.Label(self, text='Active: ')
|
|
self.lb.config(font=('Ubuntu', 11, 'bold'))
|
|
self.lb.grid(column=2, row=0, padx=15, sticky='w')
|
|
self.columnconfigure(2, weight=1)
|
|
self.rowconfigure(0, weight=1)
|
|
|
|
''' Label to Show active Tunnel '''
|
|
self.StrVar = tk.StringVar(value=self.a)
|
|
GreenLabel.green_show_label(self)
|
|
|
|
''' Interface Label '''
|
|
self.interface = tk.Label(self.lb_frame, text='Interface', fg=font_color)
|
|
self.interface.grid(column=0, row=2, sticky='we', padx=120)
|
|
self.interface.config(font=('Ubuntu', 9))
|
|
|
|
''' Peer Label '''
|
|
self.peer = tk.Label(self.lb_frame2, text='Peer', fg=font_color)
|
|
self.peer.config(font=('Ubuntu', 9))
|
|
self.peer.grid(column=0, row=3, sticky='we', padx=130)
|
|
|
|
''' Listbox with Scrollbar '''
|
|
def enable_check_box(event):
|
|
tl = ListTunnels.tl_list()
|
|
if len(tl) != 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')
|
|
|
|
self.l_box = tk.Listbox(self.lb_frame_btn_lbox, fg='#606060', selectmode='single')
|
|
self.l_box.config(highlightthickness=0, relief='ridge')
|
|
self.l_box.config(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)
|
|
self.rowconfigure(0, weight=1)
|
|
|
|
''' Tunnel List '''
|
|
self.tl = ListTunnels.tl_list()
|
|
for tunnels in self.tl:
|
|
self.l_box.insert("end", tunnels)
|
|
self.l_box.update()
|
|
|
|
''' Button Vpn '''
|
|
if self.a != '':
|
|
StartStopBTN.button_stop(self)
|
|
wg_read = Path('/etc/wire_py') / str(self.a + '.conf')
|
|
with open(wg_read, 'r') as file:
|
|
data = ConToDict.covert_to_dict(file)
|
|
|
|
''' Address Label '''
|
|
ShowAddress.init_and_report(self, data)
|
|
ShowAddress.show_data(self)
|
|
else:
|
|
StartStopBTN.button_start(self)
|
|
|
|
''' Address Label '''
|
|
self.add = tk.StringVar()
|
|
self.DNS = tk.StringVar()
|
|
self.enp = tk.StringVar()
|
|
ShowAddress.label_empty(self)
|
|
ShowAddress.show_data(self)
|
|
|
|
''' Button Import '''
|
|
self.btn_i = tk.Button(self.lb_frame_btn_lbox,
|
|
image=self.imp_pic, bd=0,
|
|
command=lambda: ImportTunnel.wg_import_select(self))
|
|
self.btn_i.grid(column=0, row=1, padx=15, pady=8)
|
|
|
|
def delete():
|
|
|
|
try:
|
|
self.select_tunnel = self.l_box.curselection()
|
|
select_tl = self.l_box.get(self.select_tunnel[0])
|
|
with open('/etc/wire_py/' + select_tl + '.conf', 'r+') as file2:
|
|
key = ConToDict.covert_to_dict(file2)
|
|
pre_key = key[3]
|
|
check_call(['nmcli', 'connection', 'delete', select_tl])
|
|
self.l_box.delete(self.select_tunnel[0])
|
|
if Path.is_file(Path('/etc/wire_py/wg_py')):
|
|
path_to_file = Path('/etc/wire_py') / 'wg_py'
|
|
a_con = Path.read_text(path_to_file)
|
|
if select_tl == a_con:
|
|
self.selected_option.set(0)
|
|
self.autoconnect_var.set('no Autoconnect')
|
|
self.wg_autostart.configure(state='disabled')
|
|
Path.unlink(path_to_file)
|
|
Path.unlink(Path('/etc/wire_py') / str(select_tl + '.conf'))
|
|
with open('/etc/wire_py/.keys', 'r') as readfile:
|
|
with open('/etc/wire_py/.keys2', 'w') as writefile:
|
|
for line in readfile:
|
|
if pre_key not in line.strip("\n"):
|
|
writefile.write(line)
|
|
file_one = Path('/etc/wire_py/.keys2')
|
|
file_two = file_one.with_name('.keys')
|
|
file_one.replace(file_two)
|
|
|
|
''' for disable checkbox when Listbox empty '''
|
|
tl = ListTunnels.tl_list()
|
|
if len(tl) == 0:
|
|
self.wg_autostart.configure(state='disabled')
|
|
if self.a != '' and self.a == select_tl:
|
|
self.StrVar.set(value='')
|
|
StartStopBTN.button_start(self)
|
|
self.l_box.update()
|
|
|
|
''' Address Label '''
|
|
self.add.set('')
|
|
self.DNS.set('')
|
|
self.enp.set('')
|
|
return select_tl
|
|
except IndexError:
|
|
tl = ListTunnels.tl_list()
|
|
if len(tl) != 0:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-icons/64/info.png'
|
|
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
|
|
wt = 'Select tunnel'
|
|
msg_t = 'Please select a tunnel from the list.'
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
else:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-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)
|
|
|
|
''' Button Trash '''
|
|
self.btn_tr = tk.Button(self.lb_frame_btn_lbox, image=self.tr_pic, bd=0, command=delete)
|
|
self.btn_tr.grid(column=0, row=2, padx=15, pady=8)
|
|
|
|
''' Button Export '''
|
|
self.btn_exp = tk.Button(self.lb_frame_btn_lbox, image=self.exp_pic, bd=0, command=ExportTunnels.wg_export)
|
|
self.btn_exp.grid(column=0, row=3, padx=15, pady=8)
|
|
|
|
''' Label Entry '''
|
|
self.lb_rename = ttk.Entry(self, width=20)
|
|
self.lb_rename.grid(column=2, row=4, padx=30, pady=5, sticky='w')
|
|
self.lb_rename.insert(0, 'Max. 12 characters!')
|
|
self.lb_rename.config(state='disable')
|
|
|
|
def tl_rename():
|
|
special_characters = ['\\', '/', '{', '}', ' ']
|
|
|
|
if len(self.lb_rename.get()) > 12:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-icons/64/info.png'
|
|
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
|
|
wt = 'Renaming not possible'
|
|
msg_t = 'The new name may contain only 12 characters.'
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
elif len(self.lb_rename.get()) == 0:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-icons/64/info.png'
|
|
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
|
|
wt = 'Renaming not possible'
|
|
msg_t = 'At least one character must be entered.'
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
elif any(ch in special_characters for ch in self.lb_rename.get()):
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-icons/64/info.png'
|
|
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
|
|
wt = 'Renaming not possible'
|
|
msg_t = 'No valid sign. These must not be used.\nBlank, Slash, Backslash and { }\n'
|
|
msg_window(iw, ii, wt, 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('/etc/wire_py') / str(select_tl + '.conf')
|
|
destination = source.with_name(str(self.lb_rename.get() + '.conf'))
|
|
source.replace(destination)
|
|
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 = TunnelActiv.active()
|
|
self.StrVar.set(value=self.a)
|
|
if Path.is_file(Path('/etc/wire_py/wg_py')):
|
|
path_to_file = Path('/etc/wire_py') / 'wg_py'
|
|
a_con = Path.read_text(path_to_file)
|
|
if select_tl == a_con:
|
|
self.autoconnect_var.set(value=new_a_connect)
|
|
Path.write_text(path_to_file, new_a_connect)
|
|
return select_tl
|
|
|
|
except IndexError:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-icons/64/info.png'
|
|
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
|
|
wt = 'Renaming not possible'
|
|
msg_t = 'Please select a tunnel from the list.'
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
''' Button Rename '''
|
|
self.btn_rename = ttk.Button(self, text='Rename', state='disable', command=tl_rename)
|
|
self.btn_rename.grid(column=2, row=4, padx=20, pady=10, sticky='e')
|
|
|
|
''' Check Buttons '''
|
|
self.selected_option = tk.IntVar()
|
|
self.autoconnect_var = tk.StringVar()
|
|
self.autoconnect_var.set(self.auto_con)
|
|
self.autoconnect = tk.Label(self, textvariable=self.autoconnect_var, fg='blue', padx=5)
|
|
self.autoconnect.config(font=('Ubuntu', 11))
|
|
self.autoconnect.grid(column=0, row=4, sticky='ne', pady=10)
|
|
self.wg_autostart = tk.Checkbutton(self,
|
|
text='Autoconnect on:',
|
|
variable=self.selected_option,
|
|
command=lambda: FileHandle.box_set(self))
|
|
self.wg_autostart.grid(column=0, row=4, pady=19, padx=15, sticky='nw')
|
|
|
|
OnOff.on_off(self)
|
|
|
|
#self.wg_update = tk.Checkbutton(self, tex='Search automatically for\nWire-Py updates')
|
|
#self.wg_update.grid(column=1, rowspan=3, row=5)
|
|
|
|
def wg_switch(self):
|
|
self.a = TunnelActiv.active()
|
|
try:
|
|
if self.a == '':
|
|
|
|
StartStopBTN.button_start(self)
|
|
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 = Path('/etc/wire_py') / str(select_tl + '.conf')
|
|
with open(wg_read, 'r') as file:
|
|
data = ConToDict.covert_to_dict(file)
|
|
|
|
''' Address Label '''
|
|
ShowAddress.init_and_report(self, data)
|
|
ShowAddress.show_data(self)
|
|
|
|
''' Button Start/Stop '''
|
|
StartStopBTN.button_stop(self)
|
|
self.a = TunnelActiv.active()
|
|
self.StrVar = tk.StringVar()
|
|
self.StrVar.set(self.a)
|
|
GreenLabel.green_show_label(self)
|
|
|
|
elif self.a != '':
|
|
|
|
''' Button Start/Stop '''
|
|
StartStopBTN.button_stop(self)
|
|
check_call(['nmcli', 'connection', 'down', self.a])
|
|
|
|
''' Button Start/Stop '''
|
|
StartStopBTN.button_start(self)
|
|
self.a = TunnelActiv.active()
|
|
self.StrVar.set('')
|
|
GreenLabel.green_show_label(self)
|
|
|
|
''' Address Label '''
|
|
self.add.set('')
|
|
self.DNS.set('')
|
|
self.enp.set('')
|
|
ShowAddress.show_data(self)
|
|
|
|
except IndexError:
|
|
|
|
tl = ListTunnels.tl_list()
|
|
if len(tl) != 0:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-icons/64/info.png'
|
|
ii = r'/usr/share/icons/wp-icons/48/wg_msg.png'
|
|
wt = 'Select tunnel'
|
|
msg_t = 'Please select a tunnel from the list.'
|
|
msg_window(iw, ii, wt, msg_t)
|
|
|
|
else:
|
|
|
|
"""img_w, img_i, w_title, w_txt hand over"""
|
|
iw = r'/usr/share/icons/wp-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)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
window = MainWindow()
|
|
"""
|
|
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()
|