Merge branch 'master' into master

pull/17/head
Max 2018-10-14 21:14:28 +02:00 committed by GitHub
commit 0c23f17362
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 27 deletions

View File

@ -26,7 +26,7 @@ Once the installation is completed, the Plugin can be used per NetworkManager (u
When a new WireGuard connection is created and configured via the NetworkManager GUI (can also be called via `nm-connection-editor`), it is the Connection Editor Plugin which is executed.
When the connection is activated, it is the service plugin that is being called.
A very basic testing suite is provided in the form of the Python script `examples/dbus/dbus.py`, which looks up the Plugin via name on D-BUS and sends it a Connect() instruction. More or less the same thing (and more) can however be achieved by just using NetworkManager after installing the package, so there should not be a need for this - except for the fact that the script is easily modifiable.
A very basic testing suite is provided in the form of the Python script `examples/dbus/dbus.py`, which looks up the Plugin via name on D-Bus and sends it a Connect() instruction. More or less the same thing (and more) can however be achieved by just using NetworkManager after installing the package, so there should not be a need for this - except for the fact that the script is easily modifiable.
### Viewing Logs
@ -41,18 +41,18 @@ The logs that are created by NetworkManager can be viewed with `journalctl -u Ne
Over the course of the project, I created some files that are not required for the project itself, but rather for its development.
Here is a brief overview over some of them:
* `includes2strings.py`: Searches the input for `-I` flags (useful for extracting the include dirs from a Makefile)
* `examples/dbus/dbus.py`: A small script that tests the availability of the Plugin and its responsiveness to D-BUS messages
* `examples/dbus/dbus.py`: A small script that tests the availability of the Plugin and its responsiveness to D-Bus messages
### Configuration
#### D-BUS Allowance
#### D-Bus Allowance
D-BUS does not allow just anybody to own any D-BUS service name they like. Thus, it may be necessary to tell D-BUS that it is not forbidden to use the name `org.freedesktop.NetworkManager.wireguard`.
D-Bus does not allow just anybody to own any D-Bus service name they like. Thus, it may be necessary to tell D-Bus that it is not forbidden to use the name `org.freedesktop.NetworkManager.wireguard`.
This can be achieved by placing an appropriate file (like `nm-wireguard-service.conf`) inside the directory `/etc/dbus-1/system.d` or similar.
The following is an example for the content of such a file:
~~~~
~~~~xml
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
@ -72,7 +72,7 @@ The following is an example for the content of such a file:
NetworkManager has to be told where the plugins live in order to be able to call them. This is done via `service.name` files, which usually reside in `/etc/NetworkManager/VPN` or `/usr/lib/NetworkManager/VPN` (e.g. `/usr/lib/NetworkManager/VPN/nm-wireguard-service.name`).
An example for the content of these files would be:
~~~~
~~~~ini
# This file is obsoleted by a file in /usr/local/lib/NetworkManager/VPN
[VPN Connection]
@ -98,10 +98,10 @@ supports-hints=false
### Service (the Plugin itself)
The service is responsible for setting up a VPN connection with the supplied parameters. For this, it has to implement a [D-BUS interface](https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html) and listen to incoming requests, which will be sent by NetworkManager in due time (i.e. when the user tells NM to set up the appropriate VPN connection).
The service is responsible for setting up a VPN connection with the supplied parameters. For this, it has to implement a [D-Bus interface](https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.VPN.Plugin.html) and listen to incoming requests, which will be sent by NetworkManager in due time (i.e. when the user tells NM to set up the appropriate VPN connection).
If the binary service is not running at the time when NM wants to set up the connection, it will try to start the binary ad hoc.
In principle, this piece of software can be written in any language, but in order to make the implementation sane, there should at least exist convenient D-BUS bindings for the language. Further, there are parts of the code already implemented in C, which might make it more convenient to just stick to that.
In principle, this piece of software can be written in any language, but in order to make the implementation sane, there should at least exist convenient D-Bus bindings for the language. Further, there are parts of the code already implemented in C, which might make it more convenient to just stick to that.
### Auth-Dialog
@ -157,7 +157,7 @@ Saved connections are stored in `/etc/NetworkManager/system-connections`, with o
This guarantees that nobody can have a look at the saved system-wide connections (and their stored secrets) that isn't supposed to.
An example of such a system-connection file would be (one can see that the user-input data is stored as key-value pairs with internally used keys in the vpn section):
~~~~
~~~~ini
[connection]
id=wiretest
uuid=8298d5ea-73d5-499b-9376-57409a7a2331

View File

@ -140,6 +140,11 @@ check_peer_public_key(const char *str){
static gboolean
check_interface_listen_port(const char *str)
{
// Listen port is not a required field according to man wg
if(is_empty(str)){
return TRUE;
}
if(!g_ascii_string_to_unsigned(str, 10, 0, 65535, NULL, NULL)){
return FALSE;
}

View File

@ -1064,13 +1064,6 @@ handle_line_error:
goto out_error;
}
if(!have_listen_port){
g_set_error_literal(error, NMV_EDITOR_PLUGIN_ERROR, NMV_EDITOR_PLUGIN_ERROR_FAILED,
"The file to import wasn't a valid Wireguard configuration (no local listen port)");
goto out_error;
}
if(!have_ip4_addr && !have_ip6_addr){
g_set_error_literal(error, NMV_EDITOR_PLUGIN_ERROR, NMV_EDITOR_PLUGIN_ERROR_FAILED,
"The file to import wasn't a valid Wireguard configuration (no local IPv4 or IPv6 addresses)");
@ -1154,6 +1147,7 @@ create_config_string (NMConnection *connection, GError **error)
const char *endpoint;
const char *psk;
const char *pka;
const char *dns;
char *value = NULL;
char **ip_list, **ip_iter;
GArray *ips;
@ -1180,6 +1174,7 @@ create_config_string (NMConnection *connection, GError **error)
endpoint = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_ENDPOINT));
psk = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_PRESHARED_KEY));
pka = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_PERSISTENT_KEEP_ALIVE));
dns = _arg_is_set(nm_setting_vpn_get_data_item(s_vpn, NM_WG_KEY_DNS));
if(!ip4 && !ip6){
g_set_error_literal(error,
@ -1189,14 +1184,6 @@ create_config_string (NMConnection *connection, GError **error)
return NULL;
}
if(!listen_port){
g_set_error_literal(error,
NMV_EDITOR_PLUGIN_ERROR,
NMV_EDITOR_PLUGIN_ERROR_FILE_NOT_VPN,
"Connection was incomplete (missing local listen port)");
return NULL;
}
if(!private_key){
g_set_error_literal(error,
NMV_EDITOR_PLUGIN_ERROR,
@ -1243,7 +1230,10 @@ create_config_string (NMConnection *connection, GError **error)
args_write_line(f, value);
g_free(value);
args_write_line(f, NMV_WG_TAG_LISTEN_PORT, "=", listen_port);
if(listen_port){
args_write_line(f, NMV_WG_TAG_LISTEN_PORT, "=", listen_port);
}
if(post_up){
args_write_line(f, NMV_WG_TAG_POST_UP, "=", post_up);
@ -1259,7 +1249,11 @@ create_config_string (NMConnection *connection, GError **error)
ip_list = g_strsplit_set (allowed_ips, " \t,", 0);
ips = g_array_new(TRUE, TRUE, sizeof(char *));
for (ip_iter = ip_list; ip_iter && *ip_iter; ip_iter++) {
g_array_append_val(ips, *ip_iter);
// Using the g_strsplit_set call above can create zero length array elements if
// there is multiple separators such as both a comma and a space so we need to
// ignore any 0 length strings
if (0 != strlen(*ip_iter))
g_array_append_val(ips, *ip_iter);
}
allowed_ips = concatenate_strings(ips, ", ");

View File

@ -94,6 +94,7 @@ typedef struct _Configs{
GVariant *config;
GVariant *ip4config;
GVariant *ip6config;
GVariant *dns_config;
} Configs;
typedef struct {
@ -346,13 +347,15 @@ set_config(NMVpnServicePlugin *plugin, NMConnection *connection)
{
NMSettingVpn *s_vpn = nm_connection_get_setting_vpn(connection);
GVariantBuilder builder, ip4builder, ip6builder;
GVariant *config, *ip4config, *ip6config;
GVariantBuilder dns_builder;
GVariant *config, *ip4config, *ip6config, *dns_config;
GVariant *val;
const char *setting;
const gchar *if_name;
guint64 subnet = 24;
gboolean has_ip4 = FALSE;
gboolean has_ip6 = FALSE;
gboolean has_dns = FALSE;
Configs *configs = malloc(sizeof(Configs));
memset(configs, 0, sizeof(Configs));
@ -361,6 +364,7 @@ set_config(NMVpnServicePlugin *plugin, NMConnection *connection)
g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init(&ip4builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init(&ip6builder, G_VARIANT_TYPE_VARDICT);
g_variant_builder_init(&dns_builder, G_VARIANT_TYPE_VARDICT);
// build the configs
setting = get_setting(s_vpn, NM_WG_KEY_ADDR_IP4);
@ -387,6 +391,9 @@ set_config(NMVpnServicePlugin *plugin, NMConnection *connection)
setting = get_setting(s_vpn, NM_WG_KEY_DNS);
if(setting){
// TODO
val = g_variant_new_string(setting);
g_variant_builder_add(&dns_builder, "{ss}", NMV_WG_TAG_DNS, val);
has_dns = TRUE;
}
setting = get_setting(s_vpn, NM_WG_KEY_ENDPOINT);
@ -447,10 +454,12 @@ set_config(NMVpnServicePlugin *plugin, NMConnection *connection)
config = g_variant_builder_end(&builder);
ip4config = g_variant_builder_end(&ip4builder);
ip6config = g_variant_builder_end(&ip6builder);
dns_config = g_variant_builder_end(&dns_builder);
// populate the configs struct and send the configuration asynchronously
configs->ip4config = (has_ip4) ? ip4config : NULL;
configs->ip6config = (has_ip6) ? ip6config : NULL;
configs->dns_config = (has_dns) ? dns_config : NULL;
configs->plugin = plugin;
configs->config = config;
g_timeout_add(0, send_config, configs);