diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2020-02-20 22:08:40 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-03-09 22:32:36 +0100 |
commit | e8061df337d42b0e54f533b6f2a4e6bd8c313ca6 (patch) | |
tree | 65855ec6f5bc8b8ae401f7dc18a32932f18a35ef | |
parent | b4f4d37f121059c319dbdf186c79beb58e97e67a (diff) | |
download | network-manager-applet-bg/wireguard.tar.gz |
editor: add wireguard supportbg/wireguard
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | src/connection-editor/ce-page-wireguard.ui | 684 | ||||
-rw-r--r-- | src/connection-editor/ce.gresource.xml | 1 | ||||
-rw-r--r-- | src/connection-editor/connection-helpers.c | 2 | ||||
-rw-r--r-- | src/connection-editor/meson.build | 2 | ||||
-rw-r--r-- | src/connection-editor/nm-connection-editor.c | 4 | ||||
-rw-r--r-- | src/connection-editor/page-wireguard.c | 643 | ||||
-rw-r--r-- | src/connection-editor/page-wireguard.h | 48 |
8 files changed, 1387 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 495594e5..5576391e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -361,6 +361,8 @@ connection_editor_hc_real = \ src/connection-editor/page-vlan.c \ src/connection-editor/page-dcb.c \ src/connection-editor/page-dcb.h \ + src/connection-editor/page-wireguard.h \ + src/connection-editor/page-wireguard.c \ src/connection-editor/vpn-helpers.h \ src/connection-editor/vpn-helpers.c \ src/connection-editor/ip4-routes-dialog.h \ @@ -445,6 +447,7 @@ EXTRA_DIST += \ src/connection-editor/ce-page-vlan.ui \ src/connection-editor/ce-page-wifi-security.ui \ src/connection-editor/ce-page-wifi.ui \ + src/connection-editor/ce-page-wireguard.ui \ src/connection-editor/ce-ppp-auth-methods.ui \ src/connection-editor/gtk/menus.ui \ src/connection-editor/nm-connection-editor.ui \ diff --git a/src/connection-editor/ce-page-wireguard.ui b/src/connection-editor/ce-page-wireguard.ui new file mode 100644 index 00000000..6767d44d --- /dev/null +++ b/src/connection-editor/ce-page-wireguard.ui @@ -0,0 +1,684 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.22.1 --> +<interface domain="nm-applet"> + <requires lib="gtk+" version="3.10"/> + <object class="GtkAdjustment" id="adj_fwmark"> + <property name="upper">4294967295</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adj_listen_port"> + <property name="upper">65535</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adj_mtu"> + <property name="upper">65535</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkDialog" id="PeerDialog"> + <property name="width_request">400</property> + <property name="can_focus">False</property> + <property name="title" translatable="yes">Edit WireGuard peer</property> + <property name="type_hint">dialog</property> + <child> + <placeholder/> + </child> + <child internal-child="vbox"> + <object class="GtkBox"> + <property name="can_focus">False</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <property name="spacing">2</property> + <property name="baseline_position">top</property> + <child internal-child="action_area"> + <object class="GtkButtonBox"> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button_cancel"> + <property name="label" translatable="yes">_Cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button_apply"> + <property name="label" translatable="yes">_Apply</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box_info"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="baseline_position">top</property> + <child> + <object class="GtkInfoBar" id="info_bar"> + <property name="can_focus">False</property> + <property name="vexpand">True</property> + <property name="message_type">error</property> + <child internal-child="action_area"> + <object class="GtkButtonBox"> + <property name="can_focus">False</property> + <property name="spacing">6</property> + <property name="layout_style">end</property> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child internal-child="content_area"> + <object class="GtkBox"> + <property name="can_focus">False</property> + <property name="spacing">16</property> + <child> + <object class="GtkLabel" id="label_info"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="vexpand">True</property> + <property name="wrap">True</property> + <property name="track_visited_links">False</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkGrid" id="grid"> + <property name="name">grid</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_top">6</property> + <property name="row_spacing">6</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">_Public key</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_public_key</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">Allowed _IPs</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_allowed_ips</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">_Endpoint</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_endpoint</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">Pre_shared key</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_psk</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">Persistent _keepalive</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">spin_persistent_keepalive</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_public_key"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">A base64 public key calculated by 'wg pubkey' from a private key.</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_allowed_ips"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">Comma-separated list of IP (v4 or v6) addresses with CIDR masks from which incoming traffic for this peer is allowed and to which outgoing traffic for this peer is directed.</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_endpoint"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">An endpoint IP or hostname, followed by a colon, and then a port number.</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_psk"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">A base64 preshared key generated by 'wg genpsk'. Optional, and may be omitted. Adds an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography, for post-quantum resistance.</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkSpinButton" id="spin_persistent_keepalive"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">How often to send an authenticated empty packet to the peer for the purpose of keeping a stateful firewall or NAT mapping valid. This is optional and not recommended outside of specific setups.</property> + <property name="hexpand">True</property> + <property name="text" translatable="yes">0</property> + <property name="adjustment">adj_mtu</property> + <property name="climb_rate">1</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="label" translatable="yes">seconds</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="toggle_show_psk"> + <property name="label" translatable="yes">Sho_w preshared key</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-6">button_cancel</action-widget> + </action-widgets> + </object> + <object class="GtkBox" id="WireGuardPage"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">12</property> + <property name="margin_right">12</property> + <property name="margin_start">12</property> + <property name="margin_end">12</property> + <property name="margin_top">12</property> + <property name="margin_bottom">12</property> + <property name="hexpand">False</property> + <property name="orientation">vertical</property> + <property name="row_spacing">6</property> + <property name="column_spacing">6</property> + <property name="row_homogeneous">True</property> + <child> + <object class="GtkLabel" id="label_interface"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="hexpand">False</property> + <property name="label" translatable="yes">_Interface name</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_ifname</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_ifname"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">The name of the wireguard interface to create.</property> + <property name="hexpand">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_private_key"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="label" translatable="yes">Private _key</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry_private_key</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry_private_key"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">The 256 bit private key in base64 encoding</property> + <property name="hexpand">True</property> + <property name="input_purpose">password</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_listen_port"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="hexpand">False</property> + <property name="label" translatable="yes">_Listen port</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">spin_listen_port</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spin_listen_port"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">A port to listen on. If set to 'automatic', the port will be chosen randomly when the interface comes up.</property> + <property name="hexpand">True</property> + <property name="text" translatable="yes">0</property> + <property name="adjustment">adj_listen_port</property> + <property name="climb_rate">1</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_fwmark"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="hexpand">False</property> + <property name="label" translatable="yes">_Fwmark</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">spin_fwmark</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_mtu"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="hexpand">False</property> + <property name="label" translatable="yes">_MTU</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">spin_mtu</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label_peer_routes"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">end</property> + <property name="hexpand">False</property> + <property name="label" translatable="yes">Add peer _routes</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">toggle_peer_routes</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">6</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="toggle_peer_routes"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="tooltip_text" translatable="yes">Whether to automatically add routes for the AllowedIPs ranges of the peers</property> + <property name="use_underline">True</property> + <property name="use_stock">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">6</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">bytes</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spin_mtu"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="text" translatable="yes">0</property> + <property name="adjustment">adj_mtu</property> + <property name="climb_rate">1</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">5</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="spin_fwmark"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tooltip_text" translatable="yes">A 32-bit fwmark for outgoing packets. Leave it to 'off' to disable fwmark.</property> + <property name="text" translatable="yes">0</property> + <property name="adjustment">adj_fwmark</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">4</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="toggle_show_private_key"> + <property name="label" translatable="yes">_Show private key</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + <property name="width">2</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">4</property> + <property name="margin_right">4</property> + <property name="row_spacing">2</property> + <child> + <object class="GtkButtonBox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="orientation">vertical</property> + <property name="layout_style">start</property> + <child> + <object class="GtkButton" id="button_add"> + <property name="label" translatable="yes">_Add</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button_delete"> + <property name="label" translatable="yes">_Delete</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin_top">6</property> + <property name="margin_bottom">6</property> + <property name="label" translatable="yes"><b>_Peers</b></property> + <property name="use_markup">True</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">tree_peers</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hexpand">True</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="tree_peers"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="reorderable">True</property> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + </object> + </child> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> +</interface> diff --git a/src/connection-editor/ce.gresource.xml b/src/connection-editor/ce.gresource.xml index 75e89d31..b11dfb74 100644 --- a/src/connection-editor/ce.gresource.xml +++ b/src/connection-editor/ce.gresource.xml @@ -27,6 +27,7 @@ <file preprocess="xml-stripblanks">ce-page-vlan.ui</file> <file preprocess="xml-stripblanks">ce-page-wifi-security.ui</file> <file preprocess="xml-stripblanks">ce-page-wifi.ui</file> + <file preprocess="xml-stripblanks">ce-page-wireguard.ui</file> <file preprocess="xml-stripblanks">ce-ppp-auth-methods.ui</file> <file preprocess="xml-stripblanks">gtk/menus.ui</file> </gresource> diff --git a/src/connection-editor/connection-helpers.c b/src/connection-editor/connection-helpers.c index bb9dfb31..0d29f20a 100644 --- a/src/connection-editor/connection-helpers.c +++ b/src/connection-editor/connection-helpers.c @@ -23,6 +23,7 @@ #include "page-bridge.h" #include "page-vlan.h" #include "page-vpn.h" +#include "page-wireguard.h" #include "vpn-helpers.h" #include "nm-utils/nm-vpn-editor-plugin-call.h" @@ -106,6 +107,7 @@ get_connection_type_list (void) add_type_data_virtual (array, _("VLAN"), vlan_connection_new, NM_TYPE_SETTING_VLAN); add_type_data_virtual (array, _("IP tunnel"), ip_tunnel_connection_new, NM_TYPE_SETTING_IP_TUNNEL); add_type_data_virtual (array, _("MACsec"), macsec_connection_new, NM_TYPE_SETTING_MACSEC); + add_type_data_virtual (array, _("WireGuard"), wireguard_connection_new, NM_TYPE_SETTING_WIREGUARD); add_type_data_virtual (array, _("VPN"), vpn_connection_new, NM_TYPE_SETTING_VPN); diff --git a/src/connection-editor/meson.build b/src/connection-editor/meson.build index 9f354ce1..f36e0709 100644 --- a/src/connection-editor/meson.build +++ b/src/connection-editor/meson.build @@ -33,6 +33,7 @@ sources = files( 'page-vpn.c', 'page-wifi.c', 'page-wifi-security.c', + 'page-wireguard.c', 'ppp-auth-methods-dialog.c', 'vpn-helpers.c' ) @@ -62,6 +63,7 @@ resource_data = files( 'ce-page-vlan.ui', 'ce-page-wifi-security.ui', 'ce-page-wifi.ui', + 'ce-page-wireguard.ui', 'ce-ppp-auth-methods.ui', 'gtk/menus.ui', 'nm-connection-editor.ui', diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c index 4c49c770..3c30528b 100644 --- a/src/connection-editor/nm-connection-editor.c +++ b/src/connection-editor/nm-connection-editor.c @@ -48,6 +48,7 @@ #include "page-vlan.h" #include "page-dcb.h" #include "page-macsec.h" +#include "page-wireguard.h" #include "ce-polkit-button.h" #include "vpn-helpers.h" #include "eap-method.h" @@ -1037,6 +1038,9 @@ nm_connection_editor_set_connection (NMConnectionEditor *editor, goto out; if (!add_page (editor, ce_page_8021x_security_new, editor->connection, error)) goto out; + } else if (!strcmp (connection_type, NM_SETTING_WIREGUARD_SETTING_NAME)) { + if (!add_page (editor, ce_page_wireguard_new, editor->connection, error)) + goto out; } else { g_warning ("Unhandled setting type '%s'", connection_type); } diff --git a/src/connection-editor/page-wireguard.c b/src/connection-editor/page-wireguard.c new file mode 100644 index 00000000..745faa45 --- /dev/null +++ b/src/connection-editor/page-wireguard.c @@ -0,0 +1,643 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Copyright 2020 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include <string.h> + +#include "page-wireguard.h" +#include "nm-connection-editor.h" +#include "nma-ui-utils.h" + +G_DEFINE_TYPE (CEPageWireGuard, ce_page_wireguard, CE_TYPE_PAGE) + +#define CE_PAGE_WIREGUARD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_WIREGUARD, CEPageWireGuardPrivate)) + +typedef struct { + NMWireGuardPeer *peer; + GtkInfoBar *info_bar; + GtkLabel *label_info; + GtkButton *button_apply; + GtkBuilder *builder; + GtkEntry *entry_public_key; + GtkEntry *entry_allowed_ips; + GtkEntry *entry_endpoint; + GtkEntry *entry_psk; + GtkSpinButton *spin_persistent_keepalive; + GtkToggleButton *toggle_show_psk; +} PeerDialogData; + +typedef struct { + NMSettingWireGuard *setting; + + NMWireGuardPeer *dialog_peer; + int dialog_peer_index; + + GtkEntry *entry_ifname; + GtkEntry *entry_pk; + GtkSpinButton *spin_mtu; + GtkSpinButton *spin_fwmark; + GtkSpinButton *spin_listen_port; + GtkToggleButton *toggle_peer_routes; + GtkToggleButton *toggle_show_pk; + GtkButton *button_add; + GtkButton *button_delete; + + GtkTreeView *tree; + GtkTreeStore *store; +} CEPageWireGuardPrivate; + +enum { + COL_PUBLIC_KEY, + COL_ALLOWED_IPS, + N_COLUMNS, +}; + +static void +peer_dialog_data_destroy (PeerDialogData *data) +{ + g_object_unref (data->builder); + nm_wireguard_peer_unref (data->peer); + g_free (data); +} + +static char * +format_allowed_ips (NMWireGuardPeer *peer) +{ + guint i, len; + GString *string = NULL; + + len = nm_wireguard_peer_get_allowed_ips_len (peer); + for (i = 0; i < len; i++) { + if (!string) + string = g_string_new (""); + else + g_string_append_c (string, ','); + g_string_append (string, nm_wireguard_peer_get_allowed_ip (peer, i, NULL)); + } + + return string ? g_string_free (string, FALSE) : NULL; +} + +static void +peer_dialog_update_ui (GtkWidget *dialog) +{ + PeerDialogData *data; + gs_free char *allowed_ips = NULL; + + data = g_object_get_data (G_OBJECT (dialog), "data"); + g_return_if_fail (data && data->peer); + + allowed_ips = format_allowed_ips (data->peer); + + gtk_entry_set_text (data->entry_public_key, nm_wireguard_peer_get_public_key (data->peer) ?: ""); + gtk_entry_set_text (data->entry_allowed_ips, allowed_ips ?: ""); + gtk_entry_set_text (data->entry_endpoint, nm_wireguard_peer_get_endpoint (data->peer) ?: ""); + gtk_spin_button_set_value (data->spin_persistent_keepalive, nm_wireguard_peer_get_persistent_keepalive (data->peer)); + gtk_entry_set_text (data->entry_psk, nm_wireguard_peer_get_preshared_key (data->peer) ?: ""); + + nma_utils_update_password_storage (GTK_WIDGET (data->entry_psk), + nm_wireguard_peer_get_preshared_key_flags (data->peer), + NULL, + NULL); +} + +static void +peer_dialog_update_peer (GtkWidget *dialog) +{ + PeerDialogData *data; + const char *pk; + const char *allowed_ips; + const char *endpoint; + const char *psk; + char **strv; + guint i; + int keepalive; + NMSettingSecretFlags secret_flags; + + data = g_object_get_data (G_OBJECT (dialog), "data"); + g_return_if_fail (data && data->peer); + + pk = gtk_entry_get_text (data->entry_public_key); + nm_wireguard_peer_set_public_key (data->peer, pk && pk[0] ? pk : NULL, TRUE); + + nm_wireguard_peer_clear_allowed_ips (data->peer); + allowed_ips = gtk_entry_get_text (data->entry_allowed_ips); + strv = g_strsplit (allowed_ips, ",", -1); + for (i = 0; strv && strv[i]; i++) + nm_wireguard_peer_append_allowed_ip (data->peer, g_strstrip (strv[i]), TRUE); + g_strfreev (strv); + + endpoint = gtk_entry_get_text (data->entry_endpoint); + nm_wireguard_peer_set_endpoint (data->peer, endpoint && endpoint[0] ? endpoint : NULL, TRUE); + + keepalive = gtk_spin_button_get_value_as_int (data->spin_persistent_keepalive); + nm_wireguard_peer_set_persistent_keepalive (data->peer, keepalive); + + psk = gtk_entry_get_text (data->entry_psk); + nm_wireguard_peer_set_preshared_key (data->peer, psk && psk[0] ? psk : NULL, TRUE); + + secret_flags = nma_utils_menu_to_secret_flags ((GtkWidget *) data->entry_psk); + nm_wireguard_peer_set_preshared_key_flags (data->peer, secret_flags); +} + +static void +peer_dialog_apply_clicked (GtkWidget *dialog) +{ + PeerDialogData *data; + gs_free_error GError *error = NULL; + gs_free char *reason = NULL; + + data = g_object_get_data (G_OBJECT (dialog), "data"); + + if (!nm_wireguard_peer_is_valid (data->peer, TRUE, TRUE, &error)) { + reason = g_strdup_printf ("Error: %s", error->message); + gtk_label_set_text (data->label_info, reason); + gtk_widget_set_visible (GTK_WIDGET (data->info_bar), TRUE); + } else { + gtk_label_set_text (data->label_info, ""); + gtk_widget_set_visible (GTK_WIDGET (data->info_bar), FALSE); + gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY); + } +} + +static void +peer_dialog_show_psk (GtkDialog *dialog) +{ + PeerDialogData *data; + + data = g_object_get_data (G_OBJECT (dialog), "data"); + gtk_entry_set_visibility (data->entry_psk, + gtk_toggle_button_get_active (data->toggle_show_psk)); +} + +static GtkWidget * +peer_dialog_create (GtkWidget *toplevel, NMWireGuardPeer *peer) +{ + GtkWidget *dialog; + gs_free_error GError *error = NULL; + PeerDialogData *data; + GtkBuilder *builder; + + builder = gtk_builder_new (); + + if (!gtk_builder_add_from_resource (builder, + "/org/gnome/nm_connection_editor/ce-page-wireguard.ui", + &error)) { + g_warning ("Couldn't load builder resource: %s", error->message); + g_error_free (error); + return NULL; + } + + dialog = GTK_WIDGET (gtk_builder_get_object (builder, "PeerDialog")); + + data = g_new0 (PeerDialogData, 1); + data->peer = nm_wireguard_peer_ref (peer); + data->builder = builder; + data->button_apply = GTK_BUTTON (gtk_builder_get_object (builder, "button_apply")); + data->entry_public_key = GTK_ENTRY (gtk_builder_get_object (builder, "entry_public_key")); + data->entry_allowed_ips = GTK_ENTRY (gtk_builder_get_object (builder, "entry_allowed_ips")); + data->entry_endpoint = GTK_ENTRY (gtk_builder_get_object (builder, "entry_endpoint")); + data->entry_psk = GTK_ENTRY (gtk_builder_get_object (builder, "entry_psk")); + data->spin_persistent_keepalive = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "spin_persistent_keepalive")); + data->info_bar = GTK_INFO_BAR (gtk_builder_get_object (builder, "info_bar")); + data->label_info = GTK_LABEL (gtk_builder_get_object (builder, "label_info")); + data->toggle_show_psk = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "toggle_show_psk")); + + g_object_set_data_full (G_OBJECT (dialog), "data", + data, + (GDestroyNotify) peer_dialog_data_destroy); + + nma_utils_setup_password_storage ((GtkWidget *) data->entry_psk, 0, + NULL, NULL, TRUE, FALSE); + ce_spin_off_val (data->spin_persistent_keepalive, 0); + + gtk_entry_set_visibility (data->entry_psk, FALSE); + + peer_dialog_update_ui (dialog); + + g_signal_connect_swapped (data->button_apply, "clicked", G_CALLBACK (peer_dialog_apply_clicked), dialog); + g_signal_connect_swapped (data->entry_public_key, "changed", G_CALLBACK (peer_dialog_update_peer), dialog); + g_signal_connect_swapped (data->entry_allowed_ips, "changed", G_CALLBACK (peer_dialog_update_peer), dialog); + g_signal_connect_swapped (data->entry_endpoint, "changed", G_CALLBACK (peer_dialog_update_peer), dialog); + g_signal_connect_swapped (data->entry_psk, "changed", G_CALLBACK (peer_dialog_update_peer), dialog); + g_signal_connect_swapped (data->toggle_show_psk, "toggled", G_CALLBACK (peer_dialog_show_psk), dialog); + + gtk_label_set_text (data->label_info, ""); + gtk_widget_set_visible (GTK_WIDGET (data->info_bar), FALSE); + + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel)); + + return dialog; +} + +static void +wireguard_private_init (CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + GtkBuilder *builder; + GtkTreeViewColumn *column; + + builder = CE_PAGE (self)->builder; + + priv->entry_ifname = GTK_ENTRY (gtk_builder_get_object (builder, "entry_ifname")); + priv->entry_pk = GTK_ENTRY (gtk_builder_get_object (builder, "entry_private_key")); + priv->spin_mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "spin_mtu")); + priv->spin_fwmark = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "spin_fwmark")); + priv->spin_listen_port = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "spin_listen_port")); + priv->toggle_peer_routes = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "toggle_peer_routes")); + priv->toggle_show_pk = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "toggle_show_private_key")); + priv->tree = GTK_TREE_VIEW (gtk_builder_get_object (builder, "tree_peers")); + priv->button_add = GTK_BUTTON (gtk_builder_get_object (builder, "button_add")); + priv->button_delete = GTK_BUTTON (gtk_builder_get_object (builder, "button_delete")); + + gtk_entry_set_visibility (priv->entry_pk, FALSE); + + priv->store = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER); + column = gtk_tree_view_column_new_with_attributes (_("Public key"), + gtk_cell_renderer_text_new (), + "text", COL_PUBLIC_KEY, + NULL); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_append_column (priv->tree, column); + + column = gtk_tree_view_column_new_with_attributes (_("Allowed IPs"), + gtk_cell_renderer_text_new (), + "text", COL_ALLOWED_IPS, + NULL); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_append_column (priv->tree, column); + + gtk_tree_view_set_model (priv->tree, GTK_TREE_MODEL (priv->store)); +} + +static void +update_peers_table (CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + NMSettingWireGuard *setting = priv->setting; + guint i, num; + + gtk_tree_store_clear (priv->store); + + num = nm_setting_wireguard_get_peers_len (setting); + for (i = 0; i < num; i++) { + NMWireGuardPeer *peer; + GtkTreeIter iter; + gs_free char *ips = NULL; + + peer = nm_setting_wireguard_get_peer (setting, i); + ips = format_allowed_ips (peer); + gtk_tree_store_append (priv->store, &iter, NULL); + + gtk_tree_store_set (priv->store, &iter, + COL_PUBLIC_KEY, nm_wireguard_peer_get_public_key (peer), + COL_ALLOWED_IPS, ips, + -1); + } +} + +static int +get_selected_index (CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + GtkTreeSelection *selection; + GtkTreeModel *model; + GList *list; + int *indices; + int ret = -1; + + selection = gtk_tree_view_get_selection (priv->tree); + nm_assert (selection); + + list = gtk_tree_selection_get_selected_rows (selection, &model); + if (!list) + goto done; + + indices = gtk_tree_path_get_indices ((GtkTreePath *) list->data); + if (!indices) + goto done; + + ret = indices[0]; +done: + g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free); + return ret; +} + +static void +tree_selection_changed (CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + int index; + + index = get_selected_index (self); + gtk_widget_set_sensitive (GTK_WIDGET (priv->button_delete), index >= 0); +} + +static void +populate_ui (CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + NMSettingWireGuard *setting = priv->setting; + NMConnection *connection; + const char *str; + + connection = CE_PAGE (self)->connection; + str = nm_connection_get_interface_name (connection); + if (str) + gtk_entry_set_text (priv->entry_ifname, str); + + gtk_entry_set_text (priv->entry_pk, nm_setting_wireguard_get_private_key (setting) ?: ""); + nma_utils_setup_password_storage ((GtkWidget *) priv->entry_pk, 0, + (NMSetting *) priv->setting, + NM_SETTING_WIREGUARD_PRIVATE_KEY, + FALSE, FALSE); + + ce_spin_automatic_val (priv->spin_mtu, 0); + ce_spin_automatic_val (priv->spin_listen_port, 0); + ce_spin_off_val (priv->spin_fwmark, 0); + + gtk_spin_button_set_value (priv->spin_mtu, nm_setting_wireguard_get_mtu (setting)); + gtk_spin_button_set_value (priv->spin_fwmark, nm_setting_wireguard_get_fwmark (setting)); + gtk_spin_button_set_value (priv->spin_listen_port, nm_setting_wireguard_get_listen_port (setting)); + + gtk_toggle_button_set_active (priv->toggle_peer_routes, + nm_setting_wireguard_get_peer_routes (setting)); + + update_peers_table (self); + tree_selection_changed (self); +} + +static void +stuff_changed (GtkEditable *editable, gpointer user_data) +{ + ce_page_changed (CE_PAGE (user_data)); +} + +static void +peer_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data) +{ + CEPageWireGuard *self = CE_PAGE_WIREGUARD (user_data); + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + + if (response == GTK_RESPONSE_APPLY) { + peer_dialog_update_peer (dialog); + if (priv->dialog_peer_index >= 0) { + nm_setting_wireguard_set_peer (priv->setting, + priv->dialog_peer, + priv->dialog_peer_index); + } else { + nm_setting_wireguard_append_peer (priv->setting, + priv->dialog_peer); + } + update_peers_table (self); + } + + nm_wireguard_peer_unref (priv->dialog_peer); + priv->dialog_peer = NULL; + priv->dialog_peer_index = -1; + + gtk_widget_hide (dialog); + gtk_widget_destroy (dialog); +} + +static void +add_delete_clicked (GtkButton *button, CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + GtkWidget *dialog; + int index; + + g_return_if_fail (NM_IN_SET (button, priv->button_add, priv->button_delete)); + + if (button == priv->button_add) { + priv->dialog_peer = nm_wireguard_peer_new (); + priv->dialog_peer_index = -1; + dialog = peer_dialog_create (gtk_widget_get_toplevel (CE_PAGE (self)->page), + priv->dialog_peer); + if (!dialog) + return; + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (peer_dialog_response_cb), self); + gtk_widget_show (dialog); + } else { + index = get_selected_index (self); + if (index >= 0) { + nm_setting_wireguard_remove_peer (priv->setting, (guint) index); + update_peers_table (self); + } + } +} + +static void +row_activated (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + NMWireGuardPeer *peer; + GtkWidget *dialog; + int index; + + index = get_selected_index (self); + if (index < 0) + return; + + peer = nm_setting_wireguard_get_peer (priv->setting, index); + priv->dialog_peer = nm_wireguard_peer_new_clone (peer, TRUE); + priv->dialog_peer_index = index; + + dialog = peer_dialog_create (gtk_widget_get_toplevel (CE_PAGE (self)->page), + priv->dialog_peer); + if (!dialog) + return; + + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (peer_dialog_response_cb), self); + gtk_widget_show (dialog); +} + +static void +show_private_key (GtkToggleButton *button, gpointer user_data) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (user_data); + + gtk_entry_set_visibility (priv->entry_pk, gtk_toggle_button_get_active (button)); +} + +static void +finish_setup (CEPageWireGuard *self, gpointer user_data) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (priv->tree); + populate_ui (self); + + g_signal_connect (priv->entry_ifname, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->entry_pk, "changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->spin_mtu, "value-changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->spin_listen_port, "value-changed", G_CALLBACK (stuff_changed), self); + g_signal_connect (priv->button_add, "clicked", G_CALLBACK (add_delete_clicked), self); + g_signal_connect (priv->button_delete, "clicked", G_CALLBACK (add_delete_clicked), self); + g_signal_connect (priv->tree, "row-activated", G_CALLBACK (row_activated), self); + g_signal_connect (priv->toggle_show_pk, "toggled", G_CALLBACK (show_private_key), self); + + g_signal_connect_swapped (selection, "changed", G_CALLBACK (tree_selection_changed), self); +} + +CEPage * +ce_page_wireguard_new (NMConnectionEditor *editor, + NMConnection *connection, + GtkWindow *parent_window, + NMClient *client, + const char **out_secrets_setting_name, + GError **error) +{ + CEPageWireGuard *self; + CEPageWireGuardPrivate *priv; + + self = CE_PAGE_WIREGUARD (ce_page_new (CE_TYPE_PAGE_WIREGUARD, + editor, + connection, + parent_window, + client, + "/org/gnome/nm_connection_editor/ce-page-wireguard.ui", + "WireGuardPage", + _("WireGuard"))); + if (!self) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load WireGuard user interface.")); + return NULL; + } + + wireguard_private_init (self); + priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + + priv->setting = (NMSettingWireGuard *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIREGUARD); + if (!priv->setting) { + priv->setting = NM_SETTING_WIREGUARD (nm_setting_wireguard_new ()); + nm_connection_add_setting (connection, NM_SETTING (priv->setting)); + } + + g_signal_connect (self, CE_PAGE_INITIALIZED, G_CALLBACK (finish_setup), NULL); + + *out_secrets_setting_name = NM_SETTING_WIREGUARD_SETTING_NAME; + + return CE_PAGE (self); +} + +static void +ui_to_setting (CEPageWireGuard *self) +{ + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + NMSettingConnection *s_con; + guint32 mtu; + guint32 fwmark; + guint16 listen_port; + const char *private_key; + const char *ifname; + NMSettingSecretFlags secret_flags; + gboolean peer_routes; + + s_con = nm_connection_get_setting_connection (CE_PAGE (self)->connection); + g_return_if_fail (s_con != NULL); + + ifname = gtk_entry_get_text (priv->entry_ifname); + if (ifname && ifname[0] == '\0') + ifname = NULL; + g_object_set (s_con, + NM_SETTING_CONNECTION_INTERFACE_NAME, + ifname, + NULL); + + private_key = gtk_entry_get_text (priv->entry_pk); + if (private_key && private_key[0] == '\0') + private_key = NULL; + mtu = gtk_spin_button_get_value_as_int (priv->spin_mtu); + fwmark = gtk_spin_button_get_value_as_int (priv->spin_fwmark); + listen_port = gtk_spin_button_get_value_as_int (priv->spin_listen_port); + peer_routes = gtk_toggle_button_get_active (priv->toggle_peer_routes); + + g_object_set (priv->setting, + NM_SETTING_WIREGUARD_PRIVATE_KEY, private_key, + NM_SETTING_WIREGUARD_LISTEN_PORT, listen_port, + NM_SETTING_WIREGUARD_FWMARK, fwmark, + NM_SETTING_WIREGUARD_MTU, mtu, + NM_SETTING_WIREGUARD_PEER_ROUTES, peer_routes, + NULL); + + /* Save private key flags to the connection */ + secret_flags = nma_utils_menu_to_secret_flags ((GtkWidget *) priv->entry_pk); + nm_setting_set_secret_flags (NM_SETTING (priv->setting), + NM_SETTING_WIREGUARD_PRIVATE_KEY, + secret_flags, NULL); + + /* Update secret flags and popup when editing the connection */ + nma_utils_update_password_storage ((GtkWidget *) priv->entry_pk, + secret_flags, + NM_SETTING (priv->setting), + NM_SETTING_WIREGUARD_PRIVATE_KEY); +} + +static gboolean +ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error) +{ + CEPageWireGuard *self = CE_PAGE_WIREGUARD (page); + CEPageWireGuardPrivate *priv = CE_PAGE_WIREGUARD_GET_PRIVATE (self); + + ui_to_setting (self); + + return nm_setting_verify (NM_SETTING (priv->setting), connection, error) + && nm_setting_verify_secrets (NM_SETTING (priv->setting), connection, error); +} + +static void +ce_page_wireguard_init (CEPageWireGuard *self) +{ +} + +static void +ce_page_wireguard_class_init (CEPageWireGuardClass *wireguard_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (wireguard_class); + CEPageClass *parent_class = CE_PAGE_CLASS (wireguard_class); + + g_type_class_add_private (object_class, sizeof (CEPageWireGuardPrivate)); + + parent_class->ce_page_validate_v = ce_page_validate_v; +} + +void +wireguard_connection_new (FUNC_TAG_PAGE_NEW_CONNECTION_IMPL, + GtkWindow *parent, + const char *detail, + gpointer detail_data, + NMConnection *connection, + NMClient *client, + PageNewConnectionResultFunc result_func, + gpointer user_data) +{ + gs_unref_object NMConnection *connection_tmp = NULL; + NMSettingIPConfig *s_ip; + + connection = _ensure_connection_other (connection, &connection_tmp); + ce_page_complete_connection (connection, + _("WireGuard connection %d"), + NM_SETTING_WIREGUARD_SETTING_NAME, + FALSE, + client); + nm_connection_add_setting (connection, nm_setting_wireguard_new ()); + + s_ip = (NMSettingIPConfig *) nm_setting_ip4_config_new (); + g_object_set (s_ip, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL); + nm_connection_add_setting (connection, (NMSetting *) s_ip); + + s_ip = (NMSettingIPConfig *) nm_setting_ip6_config_new (); + g_object_set (s_ip, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, NULL); + nm_connection_add_setting (connection, (NMSetting *) s_ip); + + (*result_func) (FUNC_TAG_PAGE_NEW_CONNECTION_RESULT_CALL, connection, FALSE, NULL, user_data); +} diff --git a/src/connection-editor/page-wireguard.h b/src/connection-editor/page-wireguard.h new file mode 100644 index 00000000..d3e945e0 --- /dev/null +++ b/src/connection-editor/page-wireguard.h @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Copyright 2020 Red Hat, Inc. + */ + +#ifndef __PAGE_WIREGUARD_H__ +#define __PAGE_WIREGUARD_H__ + +#include <glib.h> +#include <glib-object.h> + +#include "ce-page.h" + +#define CE_TYPE_PAGE_WIREGUARD (ce_page_wireguard_get_type ()) +#define CE_PAGE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_WIREGUARD, CEPageWireGuard)) +#define CE_PAGE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_WIREGUARD, CEPageWireGuardClass)) +#define CE_IS_PAGE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_WIREGUARD)) +#define CE_IS_PAGE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_WIREGUARD)) +#define CE_PAGE_WIREGUARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_WIREGUARD, CEPageWireGuardClass)) + +typedef struct { + CEPage parent; +} CEPageWireGuard; + +typedef struct { + CEPageClass parent; +} CEPageWireGuardClass; + +GType ce_page_wireguard_get_type (void); + +CEPage *ce_page_wireguard_new (NMConnectionEditor *editor, + NMConnection *connection, + GtkWindow *parent, + NMClient *client, + const char **out_secrets_setting_name, + GError **error); + +void wireguard_connection_new (FUNC_TAG_PAGE_NEW_CONNECTION_IMPL, + GtkWindow *parent, + const char *detail, + gpointer detail_data, + NMConnection *connection, + NMClient *client, + PageNewConnectionResultFunc callback, + gpointer user_data); + +#endif /* __PAGE_WIREGUARD_H__ */ |