Compare commits

..

No commits in common. "main" and "0.0.1" have entirely different histories.
main ... 0.0.1

30 changed files with 491 additions and 296 deletions

View file

@ -1,43 +1,23 @@
# WireGUIde # WireGUIde
WireGUIde is a free and open source graphical user interface for WireGuard: https://www.wireguard.com/. Using WireGUIde you will be able to easily manage you Wireguard client connections on GNU/Linux without the need to use the terminal. WireGUIde uses NetworkManager as a backend, so it is compatible with connections set up with nmcli. WireGUIde is a graphical user interface for WireGuard: https://www.wireguard.com/
It makes use of: It makes use of:
* libnm (https://developer.gnome.org/libnm/stable/usage.html) * libnm (https://developer.gnome.org/libnm/stable/usage.html)
* wxPython (https://wxpython.org/) * wxPython (https://wxpython.org/)
* GObject Introspection (https://gi.readthedocs.io/en/latest/) * GObject Introspection (https://gi.readthedocs.io/en/latest/)
For packaging a debian package you can use these dependencies:
* libnm0
* wxpython
* gir1.2-nm-1.0
Thanks to Jan Bodnar of zetcode.com for the valuable tutorial on wxPython dialogs: Thanks to Jan Bodnar of zetcode.com for the valuable tutorial on wxPython dialogs:
* http://zetcode.com/wxpython/dialogs/ * http://zetcode.com/wxpython/dialogs/
Thanks to CoreUI for providing a free and open source WireGuard Icon:
* https://github.com/coreui/coreui-icons
## Prerequisites
WireGUIde requires a fairly recent version of network-manager, and of course wireguard support. For example, while wireguard is available from buster-backports, network-manager for Debian Buster is too old (1.14.6). WireGUIde is known to work on Debian, Ubuntu and Fedora versions with network-manager >= 1.22.10. That means that it will work on Debian Bullseye, Ubuntu Focal, Ubuntu Groovy and Fedora 33 or later.
## Installation ## Installation
Please use supplied debian and rpm repos. Packages are signed with gpg.
### DEB
``` ```
curl https://repo.mic.ke/PUBLIC.KEY | sudo apt-key add - pip install wireguide
curl https://repo.mic.ke/debian/debian-micke-unstable.list | sudo tee /etc/apt/sources.list.d/debian-micke-unstable.list
sudo apt update && sudo apt install wireguide
``` ```
Unless you are using resolvconf and systemd-resolvd, NetworkManager might empty /etc/resolv.conf when you remove the last tunnel. This step is optional, but recommended:
```
sudo apt install resolvconf
sudo systemctl restart systemd-resolved.service
```
### RPM
```
wget https://repo.mic.ke/PUBLIC.KEY
sudo rpm --import PUBLIC.KEY
sudo dnf config-manager --add-repo https://repo.mic.ke/rpm/rpm-micke.repo
sudo dnf install wireguide
```
## Screenshots ## Screenshots
![No config](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot0.png) ![No config](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot0.png)
![Open dialog](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot1.png) ![Open dialog](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot1.png)

View file

392
build/scripts-3.8/wireguide Executable file
View file

@ -0,0 +1,392 @@
#!python
"""
This is a program that can manage Wireguard Configuration graphically
"""
import configparser
import os
import re
import sys
import uuid
from socket import AF_INET
import gi
import wx
import wx.adv
gi.require_version("NM", "1.0")
from gi.repository import NM # pylint: disable=wrong-import-position
class WireFrame(wx.Frame): # pylint: disable=too-many-ancestors,too-many-instance-attributes
"""
The WireGUIde wx.Frame
"""
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
self.version = 0.1
# Get active conns from NetworkManager
self.client = NM.Client.new(None)
self.conns = self.get_wg_conns()
self.active_conns = self.get_wg_aconns()
# Set up for loaded configs
self.inactive_conns = get_inactive_conns()
# create a panel in the frame
self.pnl = wx.Panel(self)
# and create a sizer to manage the layout of child widgets
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.write_to_sizer()
self.pnl.SetSizer(self.sizer)
# create a menu bar
self.make_menu_bar()
# and a status bar
self.statusbar = self.CreateStatusBar(style=wx.BORDER_NONE)
self.set_status()
self.timer = wx.Timer(self)
self.count = 0
self.Bind(wx.EVT_TIMER, self.do_on_timer)
self.Bind(wx.EVT_PAINT, self.timing)
self.Show()
def about_clicked(self, event): # pylint: disable=unused-argument
"""Display an About Dialog"""
about = "WireGUIde is a GUI for WireGuard."
lic_text = """
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>."""
#wx.MessageBox(about, "About WireGUIde" ,wx.OK | wx.ICON_INFORMATION)
info = wx.adv.AboutDialogInfo()
info.SetIcon(wx.Icon('logo.png', wx.BITMAP_TYPE_PNG))
info.SetName('WireGUIde')
info.SetVersion(str(self.version))
info.SetDescription(about)
info.SetCopyright('(C) 2020 Mikael Nordin')
info.SetWebSite('https://github.com/mickenordin')
info.SetLicence(lic_text)
info.AddDeveloper('Mikael Nordin')
info.AddDocWriter('Mikael Nordin')
info.AddArtist('Mikael Nordin')
wx.adv.AboutBox(info)
def activate_button_clicked(self, event, conn): # pylint: disable=unused-argument
"""
This activates an imported config
"""
print(conn.get_id())
self.client.add_connection_async(conn, False, None, self.add_callback,
None)
self.remove_inactive(conn)
def add_callback(self, client, result, data): # pylint: disable=unused-argument
"""
This is here to let us know if the connection was successful or not
"""
try:
client.add_connection_finish(result)
print(
"The connection profile has been successfully added to NetworkManager."
)
except Exception as exception: # pylint: disable=broad-except
sys.stderr.write("Error: %s\n" % exception)
self.active_conns = self.get_wg_aconns()
self.conns = self.get_wg_conns()
self.write_to_sizer()
def create_conn_from_file(self, pathname):
"""
Read a WireGuardUI config file and convert it in to
an object that can be user by NetworkManager
"""
filename = os.path.basename(pathname)
try:
config = configparser.ConfigParser()
config.read(pathname)
iname = self.get_next_int_name()
profile = NM.SimpleConnection.new()
s_con = NM.SettingConnection.new()
s_con.set_property(NM.SETTING_CONNECTION_ID, iname)
s_con.set_property(NM.SETTING_CONNECTION_INTERFACE_NAME, iname)
s_con.set_property(NM.SETTING_CONNECTION_UUID, str(uuid.uuid4()))
s_con.set_property(NM.SETTING_CONNECTION_TYPE,
NM.SETTING_WIREGUARD_SETTING_NAME)
s_wireguard = NM.SettingWireGuard.new()
s_wireguard.set_property(NM.SETTING_WIREGUARD_PRIVATE_KEY,
config['Interface']['PrivateKey'])
s_peer = NM.WireGuardPeer.new()
s_peer.set_endpoint(config['Peer']['Endpoint'], False)
s_peer.set_public_key(config['Peer']['PublicKey'], False)
s_peer.append_allowed_ip(config['Peer']['AllowedIPs'], False)
s_wireguard.append_peer(s_peer)
s_ip4 = NM.SettingIP4Config.new()
s_ip4_address = NM.IPAddress(AF_INET,
config['Interface']['Address'],
int(32))
s_ip4.set_property(NM.SETTING_IP_CONFIG_METHOD, "manual")
s_ip4.add_address(s_ip4_address)
s_ip4.add_dns(config['Interface']['DNS'])
profile.add_setting(s_con)
profile.add_setting(s_ip4)
profile.add_setting(s_wireguard)
return profile
except IOError:
wx.LogError("Cannot open file '%s'." % filename)
return None
def deactivate_button_clicked(self, event, conn): # pylint: disable=unused-argument
"""
This deactivates an active config
"""
print(conn.get_id())
self.client.deactivate_connection_async(conn, None, self.de_callback,
conn)
conn.get_connection().delete_async(None, None, None)
def de_callback(self, client, result, data): # pylint: disable=unused-argument
"""
This is here to let us know if the deactivation was successful or not
"""
try:
client.deactivate_connection_finish(result)
print(
"The connection profile has been successfully removed from NetworkManager."
)
except Exception as exception: # pylint: disable=broad-except
sys.stderr.write("Error: %s\n" % exception)
self.active_conns = self.get_wg_aconns()
self.conns = self.get_wg_conns()
self.write_to_sizer()
def do_on_timer(self, event): # pylint: disable=unused-argument
"""
Do stuff to redraw the window when the timer times out
Ths is because connections might change outside of WireGUIde
"""
self.count += 1
if self.count == 5:
self.client.reload_connections_async()
self.active_conns = self.get_wg_aconns()
self.conns = self.get_wg_conns()
self.set_status()
self.write_to_sizer()
self.count = 0
def exit_clicked(self, event): # pylint: disable=unused-argument
"""
Close the frame, terminating the application.
"""
self.Close(True)
def file_chooser_clicked(self, event): # pylint: disable=unused-argument
"""
This is what happens when you click on the file chooser
"""
with wx.FileDialog(self,
"Open WireGuard config file",
wildcard="WireGuard files (*.conf)|*.conf",
style=wx.FD_OPEN
| wx.FD_FILE_MUST_EXIST) as file_dialog:
if file_dialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind
# Proceed loading the file chosen by the user
pathname = file_dialog.GetPath()
new_conn = self.create_conn_from_file(pathname)
self.inactive_conns.append(new_conn)
self.write_to_sizer()
def get_next_int_name(self):
"""
Determins what we should call the next interface
"""
temp = []
for conn in self.conns:
temp.append(re.findall(r'\d+', conn.get_interface_name()))
for conn in self.inactive_conns:
temp.append(re.findall(r'\d+', conn.get_interface_name()))
numbers = [int(item) for sublist in temp for item in sublist]
if not numbers:
num = 0
else:
numbers.sort(reverse=True)
num = numbers[0] + 1
return "wg" + str(num)
def get_wg_aconns(self):
"""
Reads all active wireguard connections from NetworkManager
and returns them as objects in an array
"""
mconns = []
wgconns = self.client.get_active_connections()
for conn in wgconns:
if conn.get_connection_type() == NM.SETTING_WIREGUARD_SETTING_NAME:
mconns.append(conn)
return mconns
def get_wg_conns(self):
"""
Reads all current wireguard connections from NetworkManager
and returns them as objects in an array
"""
mconns = []
wgconns = self.client.get_connections()
for conn in wgconns:
if conn.get_connection_type() == NM.SETTING_WIREGUARD_SETTING_NAME:
mconns.append(conn)
return mconns
def make_menu_bar(self):
"""
A menu bar is composed of menus, which are composed of menu items.
This method builds a set of menus and binds handlers to be called
when the menu item is selected.
"""
file_menu = wx.Menu()
file_chooser_item = file_menu.Append(-1, "&Open...\tCtrl-O",
"Select WireGuard config file")
file_menu.AppendSeparator()
exit_item = file_menu.Append(wx.ID_EXIT)
help_menu = wx.Menu()
about_item = help_menu.Append(wx.ID_ABOUT)
menu_bar = wx.MenuBar()
menu_bar.Append(file_menu, "&File")
menu_bar.Append(help_menu, "&Help")
self.SetMenuBar(menu_bar)
self.Bind(wx.EVT_MENU, self.file_chooser_clicked, file_chooser_item)
self.Bind(wx.EVT_MENU, self.exit_clicked, exit_item)
self.Bind(wx.EVT_MENU, self.about_clicked, about_item)
def remove_inactive(self, conn):
"""
Remove the inactive connection from the array
"""
for i in range(len(self.inactive_conns)):
if self.inactive_conns[i].get_id() == conn.get_id():
self.inactive_conns.pop(i)
def set_status(self):
"""
Update the status bar
"""
status = str(len(self.active_conns)) + " active connection(s)"
self.statusbar.SetStatusText(status)
def timing(self, event): # pylint: disable=unused-argument
"""
Start a timer
"""
self.timer.Start(20)
def write_to_sizer(self):
"""
We use the BoxSizer to hold our configs
This method redraws the sizer
"""
self.sizer.Clear(delete_windows=True)
if len(self.active_conns) > 0:
hd1 = wx.StaticText(self.pnl)
hd1.SetLabelMarkup("<b>Active connections</b>")
self.sizer.Add(hd1, 0, wx.ALIGN_CENTER)
for conn in self.active_conns:
statstr = wx.StaticText(self.pnl)
info = get_info_as_text(conn)
statstr.SetLabelMarkup(info)
self.sizer.Add(statstr,
wx.SizerFlags().Border(wx.TOP | wx.LEFT, 25))
dbtn = wx.Button(self.pnl, -1, "Deactivate")
self.sizer.Add(dbtn, 0, wx.ALIGN_CENTER)
self.Bind(wx.EVT_BUTTON,
lambda event, mconn=conn: self.
deactivate_button_clicked(event, mconn),
dbtn)
if len(self.inactive_conns) > 0:
hd2 = wx.StaticText(self.pnl)
hd2.SetLabelMarkup("<b>Imported configs</b>")
self.sizer.Add(hd2, 0, wx.ALIGN_CENTER)
if self.inactive_conns:
for conn in self.inactive_conns:
statstr = wx.StaticText(self.pnl)
info = get_info_as_text(conn)
statstr.SetLabelMarkup(info)
self.sizer.Add(
statstr,
wx.SizerFlags().Border(wx.TOP | wx.LEFT, 25))
btn = wx.Button(self.pnl, -1, "Activate")
self.sizer.Add(btn, 0, wx.ALIGN_CENTER)
self.Bind(wx.EVT_BUTTON,
lambda event, mconn=conn: self.
activate_button_clicked(event, mconn),
btn)
if (len(self.active_conns) == 0) and (len(self.inactive_conns) == 0):
hd0 = wx.StaticText(self.pnl)
hd0.SetLabelMarkup("<b>No configs available</b>")
missingstr = wx.StaticText(self.pnl)
missingstr.SetLabelMarkup(
"Please choose a config file from the file menu (CTRL+O).")
self.sizer.Add(hd0, 0, wx.ALIGN_CENTER)
self.sizer.Add(missingstr, 0, wx.ALIGN_LEFT)
self.sizer.Layout()
def get_inactive_conns():
"""
TODO: Not implemented yet
"""
minactive_conns = []
#return empty array for now, we cant read configs from stash yet
return minactive_conns
def get_info_as_text(aconn):
"""
Returns info about a connection as text
"""
try:
conn = aconn.get_connection()
except Exception: # pylint: disable=broad-except
conn = aconn
mid = conn.get_id()
miname = conn.get_interface_name()
muuid = conn.get_uuid()
info = "id: " + mid + '\n'
info += "interface name: " + miname + '\n'
info += "uuid: " + muuid + '\n'
return info
if __name__ == '__main__':
# When this module is run (not imported) then create the app, the
# frame, show it, and start the event loop.
app = wx.App()
frm = WireFrame(None, title='WireGUIde')
frm.Show()
app.MainLoop()

11
debian/changelog vendored
View file

@ -1,11 +0,0 @@
wireguide (0.2.1) unstable; urgency=low
* Adding desktop file.
-- Micke Nordin <hej@mic.ke> Thu, 17 Dec 2020 18:11:29 +0100
wireguide (0.2.0) unstable; urgency=low
* Initial Debian packaging.
-- Micke Nordin <hej@mic.ke> Thu, 17 Dec 2020 14:35:39 +0100

1
debian/compat vendored
View file

@ -1 +0,0 @@
10

16
debian/control vendored
View file

@ -1,16 +0,0 @@
Source: wireguide
Section: net
Priority: optional
Maintainer: Micke Nordin <hej@mic.ke>
Build-Depends: debhelper (>=10)
Standards-Version: 4.0.0
Homepage: https://github.com/mickenordin/wireguide
Package: wireguide
Section: net
Priority: optional
Architecture: all
Depends: gir1.2-nm-1.0, libnm0, network-manager, python3-wxgtk4.0, wireguard
Recommends: resolvconf
Essential: no
Description: WireGUIde is a graphical user interface for WireGuard

63
debian/copyright vendored
View file

@ -1,63 +0,0 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: wireguide
Upstream-Contact: Micke Nordin <hej@mic.ke>
Source: https://github.com/mickenordin/wireguide
Files: src/wireguide
Copyright: 2020 Micke Nordin <hej@mic.ke>
License: GPL-3+
Files: debian/*
Copyright: 2020 Micke Nordin <hej@mic.ke>
License: GPL-3+
Files: src/ke.mic.wireguide.png
Copyright: https://github.com/coreui/coreui-icons
License: CC0-1.0
License: GPL-3+
Copyright (C) 2020 Micke Nordin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
On Debian systems, the full text of the GNU General Public
License version 3 can be found in the file
'/usr/share/common-licenses/GPL-3'.
License: CC0-1.0
No Copyright
The person who associated a work with this deed has dedicated the
work to the public domain by waiving all of his or her rights to the
work worldwide under copyright law, including all related and
neighboring rights, to the extent allowed by law.
You can copy, modify, distribute and perform the work, even for
commercial purposes, all without asking permission. See Other
Information below.
This license is acceptable for Free Cultural Works.
Other Information
In no way are the patent or trademark rights of any person affected by
CC0, nor are the rights that other persons may have in the work or in
how the work is used, such as publicity or privacy rights.
Unless expressly stated otherwise, the person who associated a work
with this deed makes no warranties about the work, and disclaims
liability for all uses of the work, to the fullest extent permitted
by applicable law.
When using or citing the work, you should not imply endorsement by the
author or the affirmer.
On Debian systems, the full text of the Creative Commons 0 License
version 1 can be found in the file
'/usr/share/common-licenses/CC0-1.0'.

3
debian/install vendored
View file

@ -1,3 +0,0 @@
src/wireguide /usr/bin
src/wireguide.desktop /usr/share/applications
src/ke.mic.wireguide.png /usr/share/icons/hicolor/256x256

17
debian/rules vendored
View file

@ -1,17 +0,0 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
#DH_VERBOSE = 1
# see FEATURE AREAS in dpkg-buildflags(1)
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
# see ENVIRONMENT in dpkg-buildflags(1)
# package maintainers to append CFLAGS
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
# package maintainers to append LDFLAGS
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
%:
dh $@

View file

@ -1 +0,0 @@
3.0 (git)

BIN
dist/wireguide-0.0.1-py3-none-any.whl vendored Normal file

Binary file not shown.

BIN
dist/wireguide-0.0.1.tar.gz vendored Normal file

Binary file not shown.

BIN
logo.xcf Normal file

Binary file not shown.

View file

@ -1,30 +0,0 @@
#!/usr/bin/env bash
# This is where I keep my sources
BASEDIR=~/sources
# Version of wireguide
VERSION=$(awk -F '"' '/self.version =/ {print $2}' ${BASEDIR}/wireguide/src/wireguide)
cd ${BASEDIR}
# Import signing key
sudo rpm --import ${BASEDIR}/repo/PUBLIC.KEY
# Convert deb to rpm
sudo alien -g -r ${BASEDIR}/wireguide_${VERSION}_all.deb
# Remove generated specfile
sudo rm ${BASEDIR}/wireguide-${VERSION}/wireguide-*.spec
# Replace with our own
sed "s/##VERSION##/${VERSION}/" ${BASEDIR}/wireguide/rpm/wireguide-TEMPLATE.spec | sudo tee ${BASEDIR}/wireguide-${VERSION}/wireguide-${VERSION}.spec
# Change to build dir
cd wireguide-${VERSION}
# Build rpm and put in repo
cp ${BASEDIR}/wireguide/rpm/macros ~/.rpmmacros
sudo rpmbuild --buildroot=$(pwd) -bb wireguide-${VERSION}.spec
sudo chown ${USER}:${USER} ${BASEDIR}/wireguide-${VERSION}.noarch.rpm
rpm --addsign ${BASEDIR}/wireguide-${VERSION}.noarch.rpm
cp ${BASEDIR}/wireguide-${VERSION}.noarch.rpm ${BASEDIR}/repo/rpm/
createrepo_c ${BASEDIR}/repo/rpm/

View file

@ -1,15 +0,0 @@
#!/usr/bin/env bash
# Where I keep the sources
BASEDIR=~/sources
# Version of wireguide
VERSION=$(awk -F '"' '/self.version =/ {print $2}' ${BASEDIR}/wireguide/src/wireguide)
# Change to source dir
cd ${BASEDIR}/wireguide
# Build deb
dpkg-buildpackage -us -uc
# Add binary and source to repo
reprepro --basedir ${BASEDIR}/debian includedeb unstable ${BASEDIR}/wireguide_${VERSION}_all.deb
reprepro --basedir ${BASEDIR}/debian -S net --priority optional includedsc unstable ${BASEDIR}/wireguide_${VERSION}.dsc

View file

@ -1,5 +0,0 @@
#!/usr/bin/env bash
BASEDIR=~/sources
${BASEDIR}/wireguide/packaging_scripts/version.sh
${BASEDIR}/wireguide/packaging_scripts/reprepro.sh
${BASEDIR}/wireguide/packaging_scripts/alien.sh

View file

@ -1,24 +0,0 @@
#!/usr/bin/env bash
BASEDIR=~/sources
version="${1}"
chlog_msg="${2}"
if [[ "x${version}" == "x" ]]; then
echo -n "Enter version (x.x.x): "
read version
fi
if [[ "x${chlog_msg}" == "x" ]]; then
echo -n "Enter changelog message: "
read chlog_msg
fi
# Code
echo sed -i -E 's/self\.version = "[0-9]+\.[0-9]+\.[0-9]+/self.version = "'${version}'/' ${BASEDIR}/wireguide/src/wireguide
# Changelog
echo 'wireguide ('${version}') unstable; urgency=low
* '${chlog_msg}'
-- Micke Nordin <hej@mic.ke> '$(LC_ALL=C date "+%a, %d %b %Y %T %z")'
'| wl-copy
vim ${BASEDIR}/wireguide/debian/changelog

2
requirements.txt Normal file
View file

@ -0,0 +1,2 @@
wxPython==4.0.7
PyGObject==3.38.0

View file

@ -1,3 +0,0 @@
%_gpg_name Mikael Nordin <hej@mic.ke>
%_gpg_path /home/micke/.gnupg
%__gpg /usr/bin/gpg

View file

@ -1,29 +0,0 @@
Buildroot: /home/micke/sources/wireguide-##VERSION##
Name: wireguide
Version: ##VERSION##
Release: 1
Requires: python3-wxpython4
Summary: WireGUIde is a graphical user interface for WireGuard
License: GPLv3+
Distribution: Fedora
%define _binary_filedigest_algorithm 2
%define _rpmdir ../
%define _rpmfilename %%{NAME}-%%{VERSION}.noarch.rpm
%define _unpackaged_files_terminate_build 0
%description
WireGUIde is a free and open source graphical user interface for WireGuard:
https://www.wireguard.com/. Using WireGUIde you will be able to easily manage
you Wireguard client connections on GNU/Linux without the need to use the
terminal. WireGUIde uses NetworkManager as a backend, so it is compatible with
connections set up with nmcli.
%files
"/usr/bin/wireguide"
"/usr/share/applications/wireguide.desktop"
%dir "/usr/share/doc/wireguide/"
"/usr/share/doc/wireguide/changelog.gz"
"/usr/share/doc/wireguide/copyright"
"/usr/share/icons/hicolor/256x256/ke.mic.wireguide.png"

24
setup.py Normal file
View file

@ -0,0 +1,24 @@
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name="wireguide",
version="0.0.1",
author="Mikael Nordin",
author_email="mik@elnord.in",
description="A WireGuard GUI for GNU/Linux",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/mickenordin/wireguide",
packages=setuptools.find_packages(),
scripts=["wireguide/wireguide"],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Environment :: X11 Applications",
"Operating System :: POSIX :: Linux",
],
python_requires='>=3.6',
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View file

@ -1,8 +0,0 @@
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=WireGUIde
Comment=WireGUIde is a graphical user interface for WireGuard
Exec=/usr/bin/wireguide
Icon=/usr/share/icons/hicolor/256x256/ke.mic.wireguide.png
Terminal=false

View file

@ -0,0 +1,44 @@
Metadata-Version: 2.1
Name: wireguide
Version: 0.0.1
Summary: A WireGuard GUI for GNU/Linux
Home-page: https://github.com/mickenordin/wireguide
Author: Mikael Nordin
Author-email: mik@elnord.in
License: UNKNOWN
Description: # WireGUIde
WireGUIde is a graphical user interface for WireGuard: https://www.wireguard.com/
It makes use of:
* libnm (https://developer.gnome.org/libnm/stable/usage.html)
* wxPython (https://wxpython.org/)
* GObject Introspection (https://gi.readthedocs.io/en/latest/)
For packaging a debian package you can use these dependencies:
* libnm0
* wxpython
* gir1.2-nm-1.0
Thanks to Jan Bodnar of zetcode.com for the valuable tutorial on wxPython dialogs:
* http://zetcode.com/wxpython/dialogs/
## Usage
```
sudo apt get install libnm0 wxpython gir1.2-nm-1.0
git clone https://github.com/mickenordin/wireguide.git
cd wireguide/
./wireguide
```
## Screenshots
![No config](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot0.png)
![Open dialog](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot1.png)
![Activate](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot2.png)
![Deactivate](https://raw.githubusercontent.com/mickenordin/wireguide/main/screenshots/scrot3.png)
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Environment :: X11 Applications
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.6
Description-Content-Type: text/markdown

View file

@ -0,0 +1,8 @@
README.md
setup.py
wireguide/__init__.py
wireguide/wireguide
wireguide.egg-info/PKG-INFO
wireguide.egg-info/SOURCES.txt
wireguide.egg-info/dependency_links.txt
wireguide.egg-info/top_level.txt

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@
wireguide

0
wireguide/__init__.py Normal file
View file

BIN
wireguide/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View file

@ -23,10 +23,8 @@ class WireFrame(wx.Frame): # pylint: disable=too-many-ancestors,too-many-instan
""" """
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
super().__init__(*args, **kw) super().__init__(*args, **kw)
icon = get_logo_path()
if icon: self.version = 0.1
self.SetIcon(wx.Icon(icon))
self.version = "0.2.1"
# Get active conns from NetworkManager # Get active conns from NetworkManager
self.client = NM.Client.new(None) self.client = NM.Client.new(None)
@ -73,26 +71,19 @@ class WireFrame(wx.Frame): # pylint: disable=too-many-ancestors,too-many-instan
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>."""
...
Wireguard ICON by CoreUI is licensed under CC0 1.0.
<https://creativecommons.org/publicdomain/zero/1.0/>
"""
#wx.MessageBox(about, "About WireGUIde" ,wx.OK | wx.ICON_INFORMATION) #wx.MessageBox(about, "About WireGUIde" ,wx.OK | wx.ICON_INFORMATION)
info = wx.adv.AboutDialogInfo() info = wx.adv.AboutDialogInfo()
logo = get_logo_path() info.SetIcon(wx.Icon('logo.png', wx.BITMAP_TYPE_PNG))
if logo:
info.SetIcon(wx.Icon(logo, wx.BITMAP_TYPE_PNG))
info.SetName('WireGUIde') info.SetName('WireGUIde')
info.SetVersion(self.version) info.SetVersion(str(self.version))
info.SetDescription(about) info.SetDescription(about)
info.SetCopyright('(C) 2020 Mikael Nordin') info.SetCopyright('(C) 2020 Mikael Nordin')
info.SetWebSite('https://github.com/mickenordin') info.SetWebSite('https://github.com/mickenordin')
info.SetLicence(lic_text) info.SetLicence(lic_text)
info.AddDeveloper('Mikael Nordin') info.AddDeveloper('Mikael Nordin')
info.AddDocWriter('Mikael Nordin') info.AddDocWriter('Mikael Nordin')
info.AddArtist('<a href="https://coreui.io/">CoreUI</a>') info.AddArtist('Mikael Nordin')
wx.adv.AboutBox(info) wx.adv.AboutBox(info)
@ -126,21 +117,9 @@ class WireFrame(wx.Frame): # pylint: disable=too-many-ancestors,too-many-instan
an object that can be user by NetworkManager an object that can be user by NetworkManager
""" """
filename = os.path.basename(pathname) filename = os.path.basename(pathname)
mfile = open(pathname)
numpeers = 0
wholefile = str()
for line in mfile:
if '[Peer]' in line:
newline = line.replace('[Peer]', '[Peer' + str(numpeers)+ ']')
numpeers += 1
wholefile += newline
else:
wholefile += line
try: try:
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read_string(wholefile) config.read(pathname)
iname = self.get_next_int_name() iname = self.get_next_int_name()
profile = NM.SimpleConnection.new() profile = NM.SimpleConnection.new()
s_con = NM.SettingConnection.new() s_con = NM.SettingConnection.new()
@ -153,13 +132,11 @@ class WireFrame(wx.Frame): # pylint: disable=too-many-ancestors,too-many-instan
s_wireguard = NM.SettingWireGuard.new() s_wireguard = NM.SettingWireGuard.new()
s_wireguard.set_property(NM.SETTING_WIREGUARD_PRIVATE_KEY, s_wireguard.set_property(NM.SETTING_WIREGUARD_PRIVATE_KEY,
config['Interface']['PrivateKey']) config['Interface']['PrivateKey'])
# peers s_peer = NM.WireGuardPeer.new()
for i in range(numpeers): s_peer.set_endpoint(config['Peer']['Endpoint'], False)
s_peer = NM.WireGuardPeer.new() s_peer.set_public_key(config['Peer']['PublicKey'], False)
s_peer.set_endpoint(config['Peer' + str(i)]['Endpoint'], False) s_peer.append_allowed_ip(config['Peer']['AllowedIPs'], False)
s_peer.set_public_key(config['Peer' + str(i)]['PublicKey'], False) s_wireguard.append_peer(s_peer)
s_peer.append_allowed_ip(config['Peer' + str(i)]['AllowedIPs'], False)
s_wireguard.append_peer(s_peer)
s_ip4 = NM.SettingIP4Config.new() s_ip4 = NM.SettingIP4Config.new()
s_ip4_address = NM.IPAddress(AF_INET, s_ip4_address = NM.IPAddress(AF_INET,
@ -229,7 +206,6 @@ class WireFrame(wx.Frame): # pylint: disable=too-many-ancestors,too-many-instan
with wx.FileDialog(self, with wx.FileDialog(self,
"Open WireGuard config file", "Open WireGuard config file",
wildcard="WireGuard files (*.conf)|*.conf", wildcard="WireGuard files (*.conf)|*.conf",
defaultDir="~/",
style=wx.FD_OPEN style=wx.FD_OPEN
| wx.FD_FILE_MUST_EXIST) as file_dialog: | wx.FD_FILE_MUST_EXIST) as file_dialog:
@ -407,13 +383,6 @@ def get_info_as_text(aconn):
return info return info
def get_logo_path():
"""
Try to find a logo
"""
return "/usr/share/icons/hicolor/256x256/ke.mic.wireguide.png"
if __name__ == '__main__': if __name__ == '__main__':
# When this module is run (not imported) then create the app, the # When this module is run (not imported) then create the app, the
# frame, show it, and start the event loop. # frame, show it, and start the event loop.