diff --git a/Makefile.am b/Makefile.am index e26801deeb..516e9acbf2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -847,6 +847,7 @@ libnm_lib_h_pub_real = \ libnm/nm-device-vxlan.h \ libnm/nm-device-wifi.h \ libnm/nm-device-wimax.h \ + libnm/nm-device-wireguard.h \ libnm/nm-device-wpan.h \ libnm/nm-device.h \ libnm/nm-dhcp-config.h \ @@ -905,6 +906,7 @@ libnm_lib_c_real = \ libnm/nm-device-vxlan.c \ libnm/nm-device-wifi.c \ libnm/nm-device-wimax.c \ + libnm/nm-device-wireguard.c \ libnm/nm-device-wpan.c \ libnm/nm-device.c \ libnm/nm-dhcp-config.c \ diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml index bdb3c2daec..cba1661045 100644 --- a/docs/libnm/libnm-docs.xml +++ b/docs/libnm/libnm-docs.xml @@ -265,6 +265,7 @@ print ("NetworkManager version " + client.get_version())]]> + diff --git a/libnm/NetworkManager.h b/libnm/NetworkManager.h index 9cecef3acb..070a02a9af 100644 --- a/libnm/NetworkManager.h +++ b/libnm/NetworkManager.h @@ -53,6 +53,7 @@ #include "nm-device-vxlan.h" #include "nm-device-wifi.h" #include "nm-device-wimax.h" +#include "nm-device-wireguard.h" #include "nm-device-wpan.h" #include "nm-device.h" #include "nm-dhcp-config.h" diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 23d551e69e..ef9701754a 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1386,6 +1386,10 @@ global: nm_connection_get_setting_sriov; nm_connection_get_setting_wpan; nm_device_6lowpan_get_type; + nm_device_wireguard_get_fwmark; + nm_device_wireguard_get_listen_port; + nm_device_wireguard_get_public_key; + nm_device_wireguard_get_type; nm_device_wpan_get_type; nm_setting_6lowpan_get_type; nm_setting_sriov_add_vf; diff --git a/libnm/meson.build b/libnm/meson.build index 27089004c7..62e3e9d755 100644 --- a/libnm/meson.build +++ b/libnm/meson.build @@ -57,6 +57,7 @@ libnm_headers = files( 'nm-device-vxlan.h', 'nm-device-wifi.h', 'nm-device-wimax.h', + 'nm-device-wireguard.h', 'nm-device-wpan.h', 'nm-dhcp-config.h', 'nm-ip-config.h', @@ -120,6 +121,7 @@ libnm_sources = files( 'nm-device-vxlan.c', 'nm-device-wifi.c', 'nm-device-wimax.c', + 'nm-device-wireguard.c', 'nm-device-wpan.c', 'nm-dhcp-config.c', 'nm-dhcp4-config.c', diff --git a/libnm/nm-client.c b/libnm/nm-client.c index cdf8bf13f9..96db30c756 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -75,6 +75,7 @@ #include "nm-device-vxlan.h" #include "nm-device-wifi.h" #include "nm-device-wimax.h" +#include "nm-device-wireguard.h" #include "nm-device-wpan.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" @@ -2575,6 +2576,8 @@ obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager type = NM_TYPE_DEVICE_WIFI; else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIMAX) == 0) type = NM_TYPE_DEVICE_WIMAX; + else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIREGUARD) == 0) + type = NM_TYPE_DEVICE_WIREGUARD; else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP4_CONFIG) == 0) type = NM_TYPE_DHCP4_CONFIG; else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP6_CONFIG) == 0) diff --git a/libnm/nm-device-wireguard.c b/libnm/nm-device-wireguard.c new file mode 100644 index 0000000000..aaad71a440 --- /dev/null +++ b/libnm/nm-device-wireguard.c @@ -0,0 +1,209 @@ +/* + * 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 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2018 Javier Arteaga + */ + +#include "nm-default.h" + +#include "nm-device-wireguard.h" +#include "nm-object-private.h" + +typedef struct { + GBytes *public_key; + guint listen_port; + guint fwmark; +} NMDeviceWireGuardPrivate; + +/** + * NMDeviceWireGuard: + */ +struct _NMDeviceWireGuard { + NMDevice parent; +}; + +struct _NMDeviceWireGuardClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE (NMDeviceWireGuard, nm_device_wireguard, NM_TYPE_DEVICE) + +#define NM_DEVICE_WIREGUARD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardPrivate)) + +NM_GOBJECT_PROPERTIES_DEFINE_BASE ( + PROP_PUBLIC_KEY, + PROP_LISTEN_PORT, + PROP_FWMARK, +); + +/** + * nm_device_wireguard_get_public_key: + * @device: a #NMDeviceWireGuard + * + * Gets the public key for this interface + * + * Returns: (transfer none): the #GBytes containing the 32-byte public key + * + * Since: 1.14 + **/ +GBytes * +nm_device_wireguard_get_public_key (NMDeviceWireGuard *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIREGUARD (device), NULL); + + return NM_DEVICE_WIREGUARD_GET_PRIVATE (device)->public_key; +} + +/** + * nm_device_wireguard_get_listen_port: + * @device: a #NMDeviceWireGuard + * + * Gets the local UDP port this interface listens on + * + * Returns: UDP listen port + * + * Since: 1.14 + **/ +guint16 +nm_device_wireguard_get_listen_port (NMDeviceWireGuard *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIREGUARD (device), 0); + + return NM_DEVICE_WIREGUARD_GET_PRIVATE (device)->listen_port; +} + +/** + * nm_device_wireguard_get_fwmark: + * @device: a #NMDeviceWireGuard + * + * Gets the fwmark (firewall mark) for this interface. + * It can be used to set routing policy for outgoing encrypted packets. + * See: ip-rule(8) + * + * Returns: 0 if fwmark not in use, 32-bit fwmark value otherwise + * + * Since: 1.14 + **/ +guint32 +nm_device_wireguard_get_fwmark (NMDeviceWireGuard *device) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIREGUARD (device), 0); + + return NM_DEVICE_WIREGUARD_GET_PRIVATE (device)->fwmark; +} + +/***********************************************************/ + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDeviceWireGuard *device = NM_DEVICE_WIREGUARD (object); + + switch (prop_id) { + case PROP_PUBLIC_KEY: + g_value_set_boxed (value, nm_device_wireguard_get_public_key (device)); + break; + case PROP_LISTEN_PORT: + g_value_set_uint (value, nm_device_wireguard_get_listen_port (device)); + break; + case PROP_FWMARK: + g_value_set_uint (value, nm_device_wireguard_get_fwmark (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_device_wireguard_init (NMDeviceWireGuard *device) +{ +} + +static void +init_dbus (NMObject *object) +{ + NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_DEVICE_WIREGUARD_PUBLIC_KEY, &priv->public_key }, + { NM_DEVICE_WIREGUARD_LISTEN_PORT, &priv->listen_port }, + { NM_DEVICE_WIREGUARD_FWMARK, &priv->fwmark }, + { NULL } + }; + + NM_OBJECT_CLASS (nm_device_wireguard_parent_class)->init_dbus (object); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_DEVICE_WIREGUARD, + property_info); +} + +static void +nm_device_wireguard_class_init (NMDeviceWireGuardClass *wireguard_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (wireguard_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wireguard_class); + + g_type_class_add_private (wireguard_class, sizeof (NMDeviceWireGuardPrivate)); + + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + /** + * NMDeviceWireGuard:public-key: + * + * 32-byte public key, derived from the current private key. + * + * Since: 1.14 + **/ + obj_properties[PROP_PUBLIC_KEY] = + g_param_spec_boxed (NM_DEVICE_WIREGUARD_PUBLIC_KEY, "", "", + G_TYPE_BYTES, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWireGuard:listen-port: + * + * Local UDP listen port. + * Set to 0 to allow a random port to be chosen (default). + * + * Since: 1.14 + **/ + obj_properties[PROP_LISTEN_PORT] = + g_param_spec_uint (NM_DEVICE_WIREGUARD_LISTEN_PORT, "", "", + 0, G_MAXUINT16, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceWireGuard:fwmark: + * + * Optional firewall mark - see ip-rule(8). + * Used when setting routing policy for outgoing encrypted packets. + * Set to 0 to disable the mark (default). + * + * Since: 1.14 + **/ + obj_properties[PROP_FWMARK] = + g_param_spec_uint (NM_DEVICE_WIREGUARD_FWMARK, "", "", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/libnm/nm-device-wireguard.h b/libnm/nm-device-wireguard.h new file mode 100644 index 0000000000..37e97a0aa2 --- /dev/null +++ b/libnm/nm-device-wireguard.h @@ -0,0 +1,56 @@ +/* + * 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 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2018 Javier Arteaga + */ + +#ifndef __NM_DEVICE_WIREGUARD_H__ +#define __NM_DEVICE_WIREGUARD_H__ + +#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION) +#error "Only can be included directly." +#endif + +#include "nm-device.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIREGUARD (nm_device_wireguard_get_type ()) +#define NM_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuard)) +#define NM_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) +#define NM_IS_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIREGUARD)) +#define NM_IS_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIREGUARD)) +#define NM_DEVICE_WIREGUARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) + +typedef struct _NMDeviceWireGuardClass NMDeviceWireGuardClass; + +#define NM_DEVICE_WIREGUARD_PUBLIC_KEY "public-key" +#define NM_DEVICE_WIREGUARD_LISTEN_PORT "listen-port" +#define NM_DEVICE_WIREGUARD_FWMARK "fwmark" + +NM_AVAILABLE_IN_1_14 +GType nm_device_wireguard_get_type (void); + +NM_AVAILABLE_IN_1_14 +GBytes* nm_device_wireguard_get_public_key (NMDeviceWireGuard *device); +NM_AVAILABLE_IN_1_14 +guint16 nm_device_wireguard_get_listen_port (NMDeviceWireGuard *device); +NM_AVAILABLE_IN_1_14 +guint32 nm_device_wireguard_get_fwmark (NMDeviceWireGuard *device); + +G_END_DECLS + +#endif /* __NM_DEVICE_WIREGUARD_H__ */ diff --git a/libnm/nm-types.h b/libnm/nm-types.h index d759b890ae..bb77e642df 100644 --- a/libnm/nm-types.h +++ b/libnm/nm-types.h @@ -55,6 +55,7 @@ typedef struct _NMDeviceVlan NMDeviceVlan; typedef struct _NMDeviceVxlan NMDeviceVxlan; typedef struct _NMDeviceWifi NMDeviceWifi; typedef struct _NMDeviceWimax NMDeviceWimax; +typedef struct _NMDeviceWireGuard NMDeviceWireGuard; typedef struct _NMDeviceWpan NMDeviceWpan; typedef struct _NMDhcpConfig NMDhcpConfig; typedef struct _NMIPConfig NMIPConfig;