diff -Nru unity-control-center-15.04.0+19.04.20190209/.bzr-builddeb/default.conf unity-control-center-15.04.0+19.04.20190209/.bzr-builddeb/default.conf --- unity-control-center-15.04.0+19.04.20190209/.bzr-builddeb/default.conf 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/.bzr-builddeb/default.conf 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,2 @@ +[BUILDDEB] +split = True diff -Nru unity-control-center-15.04.0+19.04.20190209/configure.ac unity-control-center-15.04.0+19.04.20190209/configure.ac --- unity-control-center-15.04.0+19.04.20190209/configure.ac 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/configure.ac 2019-05-01 13:21:41.000000000 +0000 @@ -113,7 +113,9 @@ CANBERRA_REQUIRED_VERSION=0.13 GDKPIXBUF_REQUIRED_VERSION=2.23.0 POLKIT_REQUIRED_VERSION=0.103 -NETWORK_MANAGER_REQUIRED_VERSION=0.8.992 +NETWORK_MANAGER_REQUIRED_VERSION=1.2.0 +NETWORK_MANAGER_APPLET_REQUIRED_VERSION=1.2.0 +MODEM_MANAGER_REQUIRED_VERSION=0.7 LIBNOTIFY_REQUIRED_VERSION=0.7.3 GNOME_DESKTOP_REQUIRED_VERSION=3.27.3 SCHEMAS_REQUIRED_VERSION=3.15.4 @@ -149,7 +151,8 @@ PKG_CHECK_MODULES(MEDIA_PANEL, $COMMON_MODULES) PKG_CHECK_MODULES(MOUSE_PANEL, $COMMON_MODULES xi >= 1.2 unity-settings-daemon x11) -PKG_CHECK_MODULES(NETWORK_PANEL, $COMMON_MODULES) +PKG_CHECK_MODULES(NETWORK_PANEL, $COMMON_MODULES gmodule-2.0 + polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION) PKG_CHECK_MODULES(POWER_PANEL, $COMMON_MODULES upower-glib >= 0.9.1 unity-settings-daemon) PKG_CHECK_MODULES(COLOR_PANEL, $COMMON_MODULES colord >= 0.1.8) @@ -182,14 +185,16 @@ GDESKTOP_PREFIX=`$PKG_CONFIG --variable prefix gsettings-desktop-schemas` AC_SUBST(GDESKTOP_PREFIX) -# Check for NetworkManager ~0.9 -PKG_CHECK_MODULES(NETWORK_MANAGER, NetworkManager >= $NETWORK_MANAGER_REQUIRED_VERSION - libnm-glib >= $NETWORK_MANAGER_REQUIRED_VERSION - libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION - libnm-gtk >= $NETWORK_MANAGER_REQUIRED_VERSION, +# Check for NetworkManager ~1.2 +PKG_CHECK_MODULES(NETWORK_MANAGER, + libnm >= $NETWORK_MANAGER_REQUIRED_VERSION + libnma >= $NETWORK_MANAGER_APPLET_REQUIRED_VERSION + mm-glib >= $MODEM_MANAGER_REQUIRED_VERSION, [have_networkmanager=yes], have_networkmanager=no) if test "x$have_networkmanager" = xno ; then - AC_MSG_WARN(*** Network panel will not be built (NetworkManager ~0.9 or newer not found) ***) + AC_MSG_WARN(*** Network panel will not be built (NetworkManager ~1.2 or newer not found) ***) +else + AC_DEFINE(BUILD_NETWORK, 1, [Define to 1 to build the Network panel]) fi AM_CONDITIONAL(BUILD_NETWORK, [test x$have_networkmanager = xyes]) @@ -516,6 +521,8 @@ panels/printers/Makefile panels/printers/unity-printers-panel.desktop.in panels/network/Makefile +panels/network/wireless-security/Makefile +panels/network/connection-editor/Makefile panels/network/unity-network-panel.desktop.in panels/universal-access/Makefile panels/universal-access/unity-universal-access-panel.desktop.in diff -Nru unity-control-center-15.04.0+19.04.20190209/debian/bzr-builder.manifest unity-control-center-15.04.0+19.04.20190209/debian/bzr-builder.manifest --- unity-control-center-15.04.0+19.04.20190209/debian/bzr-builder.manifest 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/debian/bzr-builder.manifest 2019-05-01 13:21:43.000000000 +0000 @@ -0,0 +1,2 @@ +# bzr-builder format 0.3 deb-version {debversion}+201905011321 +lp:~khurshid-alam/unity-control-center/libnm-port revid:khurshid.alam@linuxmail.org-20190501131651-az1gro4b39zom35v diff -Nru unity-control-center-15.04.0+19.04.20190209/debian/changelog unity-control-center-15.04.0+19.04.20190209/debian/changelog --- unity-control-center-15.04.0+19.04.20190209/debian/changelog 2019-05-01 13:25:15.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/debian/changelog 2019-05-01 13:21:43.000000000 +0000 @@ -1,3 +1,9 @@ +unity-control-center (15.04.0+19.04.20190209-0ubuntu3+201905011321~ubuntu19.04.1) disco; urgency=low + + * Auto build. + + -- Khurshid Alam Wed, 01 May 2019 13:21:43 +0000 + unity-control-center (15.04.0+19.04.20190209-0ubuntu3) disco; urgency=medium [ Khurshid Alam ] diff -Nru unity-control-center-15.04.0+19.04.20190209/debian/control unity-control-center-15.04.0+19.04.20190209/debian/control --- unity-control-center-15.04.0+19.04.20190209/debian/control 2019-05-01 13:25:15.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/debian/control 2019-05-01 13:21:41.000000000 +0000 @@ -35,9 +35,9 @@ libgtop2-dev, libibus-1.0-dev (>= 1.5.0), libkrb5-dev, - libnm-glib-dev (>= 0.9) [linux-any], - libnm-gtk-dev (>= 0.9) [linux-any], - libnm-util-dev (>= 0.9) [linux-any], + libnm-dev (>= 1.2.0) [linux-any], + libnma-dev (>= 1.2.0) [linux-any], + libmm-glib-dev [linux-any], libnotify-dev (>= 0.7.3), libpolkit-gobject-1-dev (>= 0.103), libpulse-dev (>= 1:2.0), diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.c unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.c 2019-05-01 13:21:41.000000000 +0000 @@ -2,6 +2,7 @@ * * Copyright (C) 2010-2012 Richard Hughes * Copyright (C) 2012 Thomas Bechtold + * Copyright (C) 2013 Aleksander Morgado * * 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 @@ -14,8 +15,7 @@ * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program; if not, see . * */ @@ -24,25 +24,24 @@ #include #include "cc-network-panel.h" +#include "cc-network-resources.h" -#include "nm-remote-settings.h" -#include "nm-client.h" -#include "nm-device.h" -#include "nm-device-modem.h" +#include #include "net-device.h" #include "net-device-mobile.h" #include "net-device-wifi.h" -#include "net-device-wired.h" +#include "net-device-ethernet.h" #include "net-object.h" #include "net-proxy.h" #include "net-vpn.h" -#include "rfkill-glib.h" - #include "panel-common.h" #include "network-dialogs.h" +#include "connection-editor/net-connection-editor.h" + +#include CC_PANEL_REGISTER (CcNetworkPanel, cc_network_panel) @@ -64,17 +63,13 @@ GtkBuilder *builder; GtkWidget *treeview; NMClient *client; - NMRemoteSettings *remote_settings; + MMManager *modem_manager; gboolean updating_device; - guint add_header_widgets_idle; - guint nm_warning_idle; - guint refresh_idle; /* Killswitch stuff */ + GDBusProxy *rfkill_proxy; GtkWidget *kill_switch_header; - CcRfkillGlib *rfkill; GtkSwitch *rfkill_switch; - GHashTable *killswitches; /* wireless dialog stuff */ CmdlineOperation arg_operation; @@ -85,8 +80,6 @@ enum { PANEL_DEVICES_COLUMN_ICON, - PANEL_DEVICES_COLUMN_TITLE, - PANEL_DEVICES_COLUMN_SORT, PANEL_DEVICES_COLUMN_OBJECT, PANEL_DEVICES_COLUMN_LAST }; @@ -96,7 +89,7 @@ PROP_ARGV }; -static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id); +static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out); static void handle_argv (CcNetworkPanel *panel); static void @@ -205,27 +198,13 @@ g_cancellable_cancel (priv->cancellable); g_clear_object (&priv->cancellable); + g_clear_object (&priv->rfkill_proxy); g_clear_object (&priv->builder); g_clear_object (&priv->client); - g_clear_object (&priv->remote_settings); + g_clear_object (&priv->modem_manager); g_clear_object (&priv->kill_switch_header); - g_clear_object (&priv->rfkill); - g_clear_pointer (&priv->killswitches, g_hash_table_destroy); priv->rfkill_switch = NULL; - if (priv->refresh_idle != 0) { - g_source_remove (priv->refresh_idle); - priv->refresh_idle = 0; - } - if (priv->nm_warning_idle != 0) { - g_source_remove (priv->nm_warning_idle); - priv->nm_warning_idle = 0; - } - if (priv->add_header_widgets_idle != 0) { - g_source_remove (priv->add_header_widgets_idle); - priv->add_header_widgets_idle = 0; - } - G_OBJECT_CLASS (cc_network_panel_parent_class)->dispose (object); } @@ -242,7 +221,132 @@ static const char * cc_network_panel_get_help_uri (CcPanel *panel) { - return "help:ubuntu-help/net"; + return "help:gnome-help/net"; +} + +static void +cc_network_panel_notify_enable_active_cb (GtkSwitch *sw, + GParamSpec *pspec, + CcNetworkPanel *panel) +{ + CcNetworkPanelPrivate *priv = panel->priv; + gboolean enable; + enable = gtk_switch_get_active (sw); + g_dbus_proxy_call (priv->rfkill_proxy, + "org.freedesktop.DBus.Properties.Set", + g_variant_new_parsed ("('org.gnome.SettingsDaemon.Rfkill'," + "'AirplaneMode', %v)", + g_variant_new_boolean (enable)), + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->cancellable, + NULL, NULL); +} + +static void +sync_airplane_mode_switch (CcNetworkPanel *panel) +{ + GVariant *result; + gboolean enabled, should_show; + gboolean hw_enabled; + + result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "HasAirplaneMode"); + enabled = g_variant_get_boolean (result); + + result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "ShouldShowAirplaneMode"); + should_show = g_variant_get_boolean (result); + + gtk_widget_set_visible (GTK_WIDGET (panel->priv->kill_switch_header), enabled && should_show); + if (!enabled || !should_show) + return; + + result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "AirplaneMode"); + enabled = g_variant_get_boolean (result); + + result = g_dbus_proxy_get_cached_property (panel->priv->rfkill_proxy, "HardwareAirplaneMode"); + hw_enabled = !!g_variant_get_boolean (result); + + enabled |= hw_enabled; + + if (enabled != gtk_switch_get_active (panel->priv->rfkill_switch)) { + g_signal_handlers_block_by_func (panel->priv->rfkill_switch, + cc_network_panel_notify_enable_active_cb, + panel); + gtk_switch_set_active (panel->priv->rfkill_switch, enabled); + g_signal_handlers_unblock_by_func (panel->priv->rfkill_switch, + cc_network_panel_notify_enable_active_cb, + panel); + } + + gtk_widget_set_sensitive (GTK_WIDGET (panel->priv->rfkill_switch), !hw_enabled); +} + +static void +on_property_change (GDBusProxy *proxy, + GVariant *changed_properties, + GVariant *invalidated_properties, + gpointer user_data) +{ + sync_airplane_mode_switch (CC_NETWORK_PANEL (user_data)); +} + +static void +got_rfkill_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data); + + panel->priv->rfkill_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + if (panel->priv->rfkill_proxy == NULL) { + g_printerr ("Error creating rfkill proxy: %s\n", error->message); + g_error_free (error); + return; + } + + g_signal_connect (panel->priv->rfkill_proxy, "g-properties-changed", + G_CALLBACK (on_property_change), panel); + sync_airplane_mode_switch (panel); +} + +static void +cc_network_panel_constructed (GObject *object) +{ + CcNetworkPanel *panel = CC_NETWORK_PANEL (object); + GtkWidget *box; + GtkWidget *label; + GtkWidget *widget; + + G_OBJECT_CLASS (cc_network_panel_parent_class)->constructed (object); + + /* add kill switch widgets */ + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + /* TRANSLATORS: this is to disable the radio hardware in the + * network panel */ + label = gtk_label_new_with_mnemonic (_("Air_plane Mode")); + gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); + gtk_widget_set_visible (label, TRUE); + widget = gtk_switch_new (); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 4); + gtk_widget_show_all (box); + panel->priv->rfkill_switch = GTK_SWITCH (widget); + cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (panel)), box); + panel->priv->kill_switch_header = g_object_ref (box); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + panel->priv->cancellable, + got_rfkill_proxy_cb, + panel); + + g_signal_connect (panel->priv->rfkill_switch, "notify::active", + G_CALLBACK (cc_network_panel_notify_enable_active_cb), + panel); } static void @@ -259,6 +363,7 @@ object_class->set_property = cc_network_panel_set_property; object_class->dispose = cc_network_panel_dispose; object_class->finalize = cc_network_panel_finalize; + object_class->constructed = cc_network_panel_constructed; g_object_class_override_property (object_class, PROP_ARGV, "argv"); } @@ -333,16 +438,140 @@ if (g_strcmp0 (net_object_get_id (object), net_object_get_id (object_tmp)) == 0) { g_object_unref (object_tmp); - if (!gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) - gtk_tree_model_get_iter_first (model, &iter); - gtk_tree_selection_select_iter (selection, &iter); - + if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) { + if (gtk_tree_model_get_iter_first (model, &iter)) + gtk_tree_selection_select_iter (selection, &iter); + } break; } g_object_unref (object_tmp); } while (gtk_tree_model_iter_next (model, &iter)); } +GPtrArray * +cc_network_panel_get_devices (CcNetworkPanel *panel) +{ + GPtrArray *devices; + GtkTreeModel *model; + GtkTreeIter iter; + NetObject *object; + + devices = g_ptr_array_new_with_free_func (g_object_unref); + + model = GTK_TREE_MODEL (gtk_builder_get_object (panel->priv->builder, + "liststore_devices")); + if (!gtk_tree_model_get_iter_first (model, &iter)) + return devices; + + do { + gtk_tree_model_get (model, &iter, + PANEL_DEVICES_COLUMN_OBJECT, &object, + -1); + if (NET_IS_DEVICE (object)) + g_ptr_array_add (devices, object); + else + g_object_unref (object); + } while (gtk_tree_model_iter_next (model, &iter)); + + return devices; +} + +static gint +panel_net_object_get_sort_category (NetObject *net_object) +{ + if (NET_IS_DEVICE (net_object)) { + return panel_device_get_sort_category (net_device_get_nm_device (NET_DEVICE (net_object))); + } else if (NET_IS_PROXY (net_object)) { + return 9; + } else if (NET_IS_VPN (net_object)) { + return 5; + } + + g_assert_not_reached (); +} + +static gint +panel_net_object_sort_func (GtkTreeModel *model, GtkTreeIter *a, + GtkTreeIter *b, void *data) +{ + g_autoptr(NetObject) obj_a = NULL; + g_autoptr(NetObject) obj_b = NULL; + gint cat_a, cat_b; + + gtk_tree_model_get (model, a, + PANEL_DEVICES_COLUMN_OBJECT, &obj_a, + -1); + gtk_tree_model_get (model, b, + PANEL_DEVICES_COLUMN_OBJECT, &obj_b, + -1); + + cat_a = panel_net_object_get_sort_category (obj_a); + cat_b = panel_net_object_get_sort_category (obj_b); + + if (cat_a != cat_b) + return cat_a - cat_b; + + return g_utf8_collate (net_object_get_title (obj_a), net_object_get_title (obj_b)); +} + +static void +panel_net_object_notify_title_cb (NetObject *net_object, GParamSpec *pspec, CcNetworkPanel *panel) +{ + GtkTreeIter iter; + GtkListStore *liststore; + + if (!find_in_model_by_id (panel, net_object_get_id (net_object), &iter)) + return; + + liststore = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, + "liststore_devices")); + + /* gtk_tree_model_row_changed would not cause the list store to resort. + * Instead set the object column to the current value. + * See https://bugzilla.gnome.org/show_bug.cgi?id=782737 */ + gtk_list_store_set (liststore, &iter, + PANEL_DEVICES_COLUMN_OBJECT, net_object, + -1); +} + +static void +panel_refresh_device_titles (CcNetworkPanel *panel) +{ + GPtrArray *ndarray, *nmdarray; + NetDevice **devices; + NMDevice **nm_devices, *nm_device; + gchar **titles; + gint i, num_devices; + + ndarray = cc_network_panel_get_devices (panel); + if (!ndarray->len) { + g_ptr_array_free (ndarray, TRUE); + return; + } + + nmdarray = g_ptr_array_new (); + for (i = 0; i < ndarray->len; i++) { + nm_device = net_device_get_nm_device (ndarray->pdata[i]); + if (nm_device) + g_ptr_array_add (nmdarray, nm_device); + else + g_ptr_array_remove_index (ndarray, i--); + } + + devices = (NetDevice **)ndarray->pdata; + nm_devices = (NMDevice **)nmdarray->pdata; + num_devices = ndarray->len; + + titles = nm_device_disambiguate_names (nm_devices, num_devices); + for (i = 0; i < num_devices; i++) { + net_object_set_title (NET_OBJECT (devices[i]), titles[i]); + g_free (titles[i]); + } + g_free (titles); + g_ptr_array_free (ndarray, TRUE); + g_ptr_array_free (nmdarray, TRUE); +} + static gboolean handle_argv_for_device (CcNetworkPanel *panel, NMDevice *device, @@ -350,6 +579,7 @@ { CcNetworkPanelPrivate *priv = panel->priv; NMDeviceType type; + GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); if (priv->arg_operation == OPERATION_NULL) return TRUE; @@ -363,21 +593,21 @@ select_tree_iter (panel, iter); if (priv->arg_operation == OPERATION_CREATE_WIFI) - cc_network_panel_create_wifi_network (panel, priv->client, priv->remote_settings); + cc_network_panel_create_wifi_network (toplevel, priv->client); else - cc_network_panel_connect_to_hidden_network (panel, priv->client, priv->remote_settings); + cc_network_panel_connect_to_hidden_network (toplevel, priv->client); reset_command_line_args (panel); /* done */ return TRUE; } else if (g_strcmp0 (nm_object_get_path (NM_OBJECT (device)), priv->arg_device) == 0) { if (priv->arg_operation == OPERATION_CONNECT_MOBILE) { - cc_network_panel_connect_to_3g_network (panel, priv->client, priv->remote_settings, device); + cc_network_panel_connect_to_3g_network (toplevel, priv->client, device); reset_command_line_args (panel); /* done */ select_tree_iter (panel, iter); return TRUE; } else if (priv->arg_operation == OPERATION_CONNECT_8021X) { - cc_network_panel_connect_to_8021x_network (panel, priv->client, priv->remote_settings, device, priv->arg_access_point); + cc_network_panel_connect_to_8021x_network (toplevel, priv->client, device, priv->arg_access_point); reset_command_line_args (panel); /* done */ select_tree_iter (panel, iter); return TRUE; @@ -392,6 +622,28 @@ return FALSE; } +static gboolean +handle_argv_for_connection (CcNetworkPanel *panel, + NMConnection *connection, + GtkTreeIter *iter) +{ + CcNetworkPanelPrivate *priv = panel->priv; + + if (priv->arg_operation == OPERATION_NULL) + return TRUE; + if (priv->arg_operation != OPERATION_SHOW_DEVICE) + return FALSE; + + if (g_strcmp0 (nm_connection_get_path (connection), priv->arg_device) == 0) { + reset_command_line_args (panel); + select_tree_iter (panel, iter); + return TRUE; + } + + return FALSE; +} + + static void handle_argv (CcNetworkPanel *panel) { @@ -408,15 +660,20 @@ while (ret) { GObject *object_tmp; NMDevice *device; + NMConnection *connection; gboolean done = FALSE; gtk_tree_model_get (model, &iter, PANEL_DEVICES_COLUMN_OBJECT, &object_tmp, -1); - if (g_object_class_find_property (G_OBJECT_GET_CLASS (object_tmp), "nm-device") != NULL) { + if (NET_IS_DEVICE (object_tmp)) { g_object_get (object_tmp, "nm-device", &device, NULL); done = handle_argv_for_device (panel, device, &iter); g_object_unref (device); + } else if (NET_IS_VPN (object_tmp)) { + g_object_get (object_tmp, "connection", &connection, NULL); + done = handle_argv_for_connection (panel, connection, &iter); + g_object_unref (connection); } g_object_unref (object_tmp); @@ -430,10 +687,31 @@ g_debug ("Could not handle argv operation, no matching device yet?"); } +static void +state_changed_cb (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + CcNetworkPanel *panel) +{ + GtkListStore *store; + GtkTreeIter iter; + + if (!find_in_model_by_id (panel, nm_device_get_udi (device), &iter)) { + return; + } + + store = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, + "liststore_devices")); + + gtk_list_store_set (store, &iter, + PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE), + -1); +} + static gboolean panel_add_device (CcNetworkPanel *panel, NMDevice *device) { - const gchar *title; GtkListStore *liststore_devices; GtkTreeIter iter; NMDeviceType type; @@ -442,20 +720,25 @@ GtkNotebook *notebook; GtkSizeGroup *size_group; GType device_g_type; + const char *udi; + + if (!nm_device_get_managed (device)) + goto out; /* do we have an existing object with this id? */ - if (find_in_model_by_id (panel, nm_device_get_udi (device)) != NULL) + udi = nm_device_get_udi (device); + if (find_in_model_by_id (panel, udi, NULL) != NULL) goto out; type = nm_device_get_device_type (device); g_debug ("device %s type %i path %s", - nm_device_get_udi (device), type, nm_object_get_path (NM_OBJECT (device))); + udi, type, nm_object_get_path (NM_OBJECT (device))); - /* map the NMDeviceType to the GType */ + /* map the NMDeviceType to the GType, or ignore */ switch (type) { case NM_DEVICE_TYPE_ETHERNET: - device_g_type = NET_TYPE_DEVICE_WIRED; + device_g_type = NET_TYPE_DEVICE_ETHERNET; break; case NM_DEVICE_TYPE_MODEM: device_g_type = NET_TYPE_DEVICE_MOBILE; @@ -463,23 +746,56 @@ case NM_DEVICE_TYPE_WIFI: device_g_type = NET_TYPE_DEVICE_WIFI; break; - default: + /* not going to set up a cluster in GNOME */ + case NM_DEVICE_TYPE_VETH: + /* enterprise features */ + case NM_DEVICE_TYPE_BOND: + case NM_DEVICE_TYPE_TEAM: + /* Don't need the libvirtd bridge */ + case NM_DEVICE_TYPE_BRIDGE: + /* Don't add VPN devices */ + case NM_DEVICE_TYPE_TUN: goto out; + default: + device_g_type = NET_TYPE_DEVICE_SIMPLE; + break; } /* create device */ - title = panel_device_to_localized_string (device); net_device = g_object_new (device_g_type, "panel", panel, "removable", FALSE, "cancellable", panel->priv->cancellable, "client", panel->priv->client, - "remote-settings", panel->priv->remote_settings, "nm-device", device, "id", nm_device_get_udi (device), - "title", title, NULL); + if (type == NM_DEVICE_TYPE_MODEM && + g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager1/Modem/")) { + GDBusObject *modem_object; + + if (priv->modem_manager == NULL) { + g_warning ("Cannot grab information for modem at %s: No ModemManager support", + nm_device_get_udi (device)); + goto out; + } + + modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (priv->modem_manager), + nm_device_get_udi (device)); + if (modem_object == NULL) { + g_warning ("Cannot grab information for modem at %s: Not found", + nm_device_get_udi (device)); + goto out; + } + + /* Set the modem object in the NetDeviceMobile */ + g_object_set (net_device, + "mm-object", modem_object, + NULL); + g_object_unref (modem_object); + } + /* add as a panel */ if (device_g_type != NET_TYPE_DEVICE) { notebook = GTK_NOTEBOOK (gtk_builder_get_object (panel->priv->builder, @@ -498,11 +814,15 @@ gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, - PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device), - PANEL_DEVICES_COLUMN_SORT, panel_device_to_sortable_string (device), - PANEL_DEVICES_COLUMN_TITLE, title, + PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE), PANEL_DEVICES_COLUMN_OBJECT, net_device, -1); + g_signal_connect (net_device, "notify::title", + G_CALLBACK (panel_net_object_notify_title_cb), panel); + + g_object_unref (net_device); + g_signal_connect (device, "state-changed", + G_CALLBACK (state_changed_cb), panel); out: return FALSE; @@ -539,6 +859,25 @@ } static void +get_object_title (GtkTreeViewColumn *column, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + NetObject *object; + + gtk_tree_model_get (model, iter, + PANEL_DEVICES_COLUMN_OBJECT, &object, + -1); + if (!object) + return; + + g_object_set (cell, "text", net_object_get_title (object), NULL); + g_object_unref (object); +} + +static void panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview) { CcNetworkPanelPrivate *priv = panel->priv; @@ -548,8 +887,13 @@ /* image */ renderer = gtk_cell_renderer_pixbuf_new (); - g_object_set (renderer, "stock-size", gtk_icon_size_from_name ("cc-sidebar-list"), NULL); - gtk_cell_renderer_set_padding (renderer, 4, 4); + g_object_set (renderer, + "width", 32, + "xalign", 1.0, + "stock-size", GTK_ICON_SIZE_MENU, + "follow-state", TRUE, + NULL); + gtk_cell_renderer_set_padding (renderer, 4, 10); column = gtk_tree_view_column_new_with_attributes ("icon", renderer, "icon-name", PANEL_DEVICES_COLUMN_ICON, @@ -562,14 +906,19 @@ "wrap-mode", PANGO_WRAP_WORD, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - column = gtk_tree_view_column_new_with_attributes ("title", renderer, - "markup", PANEL_DEVICES_COLUMN_TITLE, - NULL); - gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_SORT); + column = gtk_tree_view_column_new_with_attributes ("title", renderer, NULL); + gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column), + renderer, + get_object_title, + NULL, NULL); + gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_OBJECT); liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, "liststore_devices")); + gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (liststore_devices), + PANEL_DEVICES_COLUMN_OBJECT, + panel_net_object_sort_func, NULL, NULL); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore_devices), - PANEL_DEVICES_COLUMN_SORT, + PANEL_DEVICES_COLUMN_OBJECT, GTK_SORT_ASCENDING); gtk_tree_view_append_column (treeview, column); gtk_tree_view_column_set_expand (column, TRUE); @@ -616,6 +965,7 @@ } i++; } + g_object_unref (object); out: g_list_free (panels); } @@ -623,7 +973,6 @@ static void panel_add_proxy_device (CcNetworkPanel *panel) { - gchar *title; GtkListStore *liststore_devices; GtkTreeIter iter; NetProxy *proxy; @@ -643,36 +992,18 @@ /* add proxy to device list */ liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); - title = g_strdup_printf ("%s", _("Network proxy")); + net_object_set_title (NET_OBJECT (proxy), _("Network proxy")); gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, - PANEL_DEVICES_COLUMN_ICON, "preferences-system-network", - PANEL_DEVICES_COLUMN_TITLE, title, - PANEL_DEVICES_COLUMN_SORT, "9", + PANEL_DEVICES_COLUMN_ICON, "preferences-system-network-symbolic", PANEL_DEVICES_COLUMN_OBJECT, proxy, -1); - g_free (title); - g_object_unref (proxy); -} - -static void -cc_network_panel_notify_enable_active_cb (GtkSwitch *sw, - GParamSpec *pspec, - CcNetworkPanel *panel) -{ - gboolean enable; - struct rfkill_event event; - enable = gtk_switch_get_active (sw); - g_debug ("Setting killswitch to %d", enable); + /* NOTE: No connect to notify::title here as it is guaranteed to not + * be changed by anyone.*/ - memset (&event, 0, sizeof(event)); - event.op = RFKILL_OP_CHANGE_ALL; - event.type = RFKILL_TYPE_ALL; - event.soft = enable ? 1 : 0; - if (cc_rfkill_glib_send_event (panel->priv->rfkill, &event) < 0) - g_warning ("Setting the killswitch %s failed", enable ? "on" : "off"); + g_object_unref (proxy); } static void @@ -699,7 +1030,7 @@ for (j = 0; devices && j < devices->len; j++) g_debug (" %s", nm_device_get_udi (g_ptr_array_index (devices, j))); if (NM_IS_VPN_CONNECTION (connection)) - g_debug (" VPN base connection: %s", nm_active_connection_get_specific_object (connection)); + g_debug (" VPN base connection: %s", nm_active_connection_get_specific_object_path (connection)); if (g_object_get_data (G_OBJECT (connection), "has-state-changed-handler") == NULL) { g_signal_connect_object (connection, "notify::state", @@ -714,6 +1045,7 @@ { g_debug ("New device added"); panel_add_device (panel, device); + panel_refresh_device_titles (panel); } static void @@ -721,6 +1053,7 @@ { g_debug ("Device removed"); panel_remove_device (panel, device); + panel_refresh_device_titles (panel); } static void @@ -734,7 +1067,7 @@ CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data); /* clear all devices we added */ - if (!nm_client_get_manager_running (client)) { + if (!nm_client_get_nm_running (client)) { g_debug ("NM disappeared"); liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); @@ -759,12 +1092,14 @@ select_first_device (panel); } + panel_refresh_device_titles (panel); + g_debug ("Calling handle_argv() after cold-plugging devices"); handle_argv (panel); } static NetObject * -find_in_model_by_id (CcNetworkPanel *panel, const gchar *id) +find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out) { gboolean ret; NetObject *object_tmp; @@ -793,6 +1128,8 @@ } } while (object == NULL && gtk_tree_model_iter_next (model, &iter)); out: + if (iter_out) + *iter_out = iter; return object; } @@ -800,7 +1137,6 @@ panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection) { gchar *title; - gchar *title_markup; GtkListStore *liststore_devices; GtkTreeIter iter; NetVpn *net_vpn; @@ -810,10 +1146,10 @@ /* does already exist */ id = nm_connection_get_path (connection); - if (find_in_model_by_id (panel, id) != NULL) + if (find_in_model_by_id (panel, id, NULL) != NULL) return; - /* add as a virtual object */ + /* add as a VPN object */ net_vpn = g_object_new (NET_TYPE_VPN, "panel", panel, "removable", TRUE, @@ -836,19 +1172,19 @@ liststore_devices = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder, "liststore_devices")); title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (connection)); - title_markup = g_strdup (title); net_object_set_title (NET_OBJECT (net_vpn), title); gtk_list_store_append (liststore_devices, &iter); gtk_list_store_set (liststore_devices, &iter, - PANEL_DEVICES_COLUMN_ICON, "network-vpn", - PANEL_DEVICES_COLUMN_TITLE, title_markup, - PANEL_DEVICES_COLUMN_SORT, "5", + PANEL_DEVICES_COLUMN_ICON, "network-vpn-symbolic", PANEL_DEVICES_COLUMN_OBJECT, net_vpn, -1); + g_signal_connect (net_vpn, "notify::title", + G_CALLBACK (panel_net_object_notify_title_cb), panel); + g_free (title); - g_free (title_markup); + g_object_unref (net_vpn); } static void @@ -856,130 +1192,91 @@ NMConnection *connection) { NMSettingConnection *s_con; - const gchar *type; + const gchar *type, *iface; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); type = nm_setting_connection_get_connection_type (s_con); - if (g_strcmp0 (type, "vpn") != 0) + iface = nm_connection_get_interface_name (connection); + if (g_strcmp0 (type, "vpn") != 0 && iface == NULL) + return; + + /* Don't add the libvirtd bridge to the UI */ + if (g_strcmp0 (nm_setting_connection_get_interface_name (s_con), "virbr0") == 0) return; + g_debug ("add %s/%s remote connection: %s", type, g_type_name_from_instance ((GTypeInstance*)connection), nm_connection_get_path (connection)); - panel_add_vpn_device (panel, connection); + if (!iface) + panel_add_vpn_device (panel, connection); } static void -notify_new_connection_cb (NMRemoteSettings *settings, - NMRemoteConnection *connection, - CcNetworkPanel *panel) +notify_connection_added_cb (NMClient *client, + NMRemoteConnection *connection, + CcNetworkPanel *panel) { add_connection (panel, NM_CONNECTION (connection)); } static void -notify_connections_read_cb (NMRemoteSettings *settings, - CcNetworkPanel *panel) -{ - GSList *list, *iter; - NMConnection *connection; - - list = nm_remote_settings_list_connections (settings); - g_debug ("%p has %i remote connections", - panel, g_slist_length (list)); - for (iter = list; iter; iter = g_slist_next (iter)) { - connection = NM_CONNECTION (iter->data); - add_connection (panel, connection); - } -} - -static gboolean -display_version_warning_idle (CcNetworkPanel *panel) -{ - GtkWidget *dialog; - GtkWidget *image; - GtkWindow *window; - const char *message; - - /* TRANSLATORS: the user is running a NM that is not API compatible */ - message = _("The system network services are not compatible with this version."); - - window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))); - dialog = gtk_message_dialog_new (window, - GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "%s", - message); - image = gtk_image_new_from_icon_name ("computer-fail", GTK_ICON_SIZE_DIALOG); - gtk_widget_show (image); - gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; -} - -static gboolean panel_check_network_manager_version (CcNetworkPanel *panel) { + GtkWidget *box; + GtkWidget *label; + gchar *markup; const gchar *version; - guint minor = 0; - gboolean ret = TRUE; /* parse running version */ version = nm_client_get_version (panel->priv->client); if (version == NULL) { - ret = FALSE; + gtk_container_remove (GTK_CONTAINER (panel), gtk_bin_get_child (GTK_BIN (panel))); + + box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 20); + gtk_box_set_homogeneous (GTK_BOX (box), TRUE); + gtk_widget_set_vexpand (box, TRUE); + gtk_container_add (GTK_CONTAINER (panel), box); + + label = gtk_label_new (_("Oops, something has gone wrong. Please contact your software vendor.")); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_widget_set_valign (label, GTK_ALIGN_END); + gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); + + markup = g_strdup_printf ("%s", + _("NetworkManager needs to be running.")); + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), markup); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_widget_set_valign (label, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); - /* do modal dialog in idle so we don't block startup */ - panel->priv->nm_warning_idle = g_idle_add ((GSourceFunc)display_version_warning_idle, panel); + gtk_widget_show_all (box); + g_free (markup); + } else { + manager_running (panel->priv->client, NULL, panel); } +} - return ret; +static void +editor_done (NetConnectionEditor *editor, + gboolean success, + gpointer user_data) +{ + g_object_unref (editor); } static void add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel) { - GtkWidget *dialog; - gint response; + NetConnectionEditor *editor; + GtkWindow *toplevel; - dialog = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, - "connection_type_dialog")); - gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)))); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - - gtk_widget_hide (dialog); - - if (response == GTK_RESPONSE_OK) { - GtkComboBox *combo; - GtkTreeModel *model; - GtkTreeIter iter; - gchar *type; - gchar *cmdline; - GError *error; - - combo = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder, - "connection_type_combo")); - model = gtk_combo_box_get_model (combo); - gtk_combo_box_get_active_iter (combo, &iter); - type = NULL; - gtk_tree_model_get (model, &iter, 1, &type, -1); - - cmdline = g_strdup_printf ("nm-connection-editor --create --type %s", type); - g_debug ("Launching '%s'\n", cmdline); - - error = NULL; - if (!g_spawn_command_line_async (cmdline, &error)) { - g_warning ("Failed to launch nm-connection-editor: %s", error->message); - g_error_free (error); - } - g_free (cmdline); - g_free (type); - } + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))); + editor = net_connection_editor_new (toplevel, NULL, NULL, NULL, + panel->priv->client); + g_signal_connect (editor, "done", G_CALLBACK (editor_done), panel); + net_connection_editor_run (editor); } static void @@ -994,131 +1291,38 @@ /* delete the object */ net_object_delete (object); + g_object_unref (object); } static void on_toplevel_map (GtkWidget *widget, CcNetworkPanel *panel) { - gboolean ret; - /* is the user compiling against a new version, but not running * the daemon? */ - ret = panel_check_network_manager_version (panel); - if (ret) { - manager_running (panel->priv->client, NULL, panel); - } else { - /* just select the proxy settings */ - select_first_device (panel); - } -} - -static void -rfkill_changed (CcRfkillGlib *rfkill, - GList *events, - CcNetworkPanel *panel) -{ - gboolean enabled; - GList *l; - GHashTableIter iter; - gpointer key, value; - - enabled = TRUE; - - for (l = events; l != NULL; l = l->next) { - struct rfkill_event *event = l->data; - - if (event->op == RFKILL_OP_ADD) - g_hash_table_insert (panel->priv->killswitches, - GINT_TO_POINTER (event->idx), - GINT_TO_POINTER (event->soft || event->hard)); - else if (event->op == RFKILL_OP_CHANGE) - g_hash_table_insert (panel->priv->killswitches, - GINT_TO_POINTER (event->idx), - GINT_TO_POINTER (event->soft || event->hard)); - else if (event->op == RFKILL_OP_DEL) - g_hash_table_remove (panel->priv->killswitches, - GINT_TO_POINTER (event->idx)); - } - - g_hash_table_iter_init (&iter, panel->priv->killswitches); - while (g_hash_table_iter_next (&iter, &key, &value)) { - int idx, state; - - idx = GPOINTER_TO_INT (key); - state = GPOINTER_TO_INT (value); - g_debug ("Killswitch %d is %s", idx, state ? "enabled" : "disabled"); - - /* A single device that's enabled? airplane mode is off */ - if (state == FALSE) { - enabled = FALSE; - break; - } - } - - if (enabled != gtk_switch_get_active (panel->priv->rfkill_switch)) { - g_signal_handlers_block_by_func (panel->priv->rfkill_switch, - cc_network_panel_notify_enable_active_cb, - panel); - gtk_switch_set_active (panel->priv->rfkill_switch, enabled); - g_signal_handlers_unblock_by_func (panel->priv->rfkill_switch, - cc_network_panel_notify_enable_active_cb, - panel); - } -} - -static gboolean -network_add_shell_header_widgets_cb (gpointer user_data) -{ - CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data); - GtkWidget *box; - GtkWidget *label; - GtkWidget *widget; - - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); - /* TRANSLATORS: this is to disable the radio hardware in the - * network panel */ - label = gtk_label_new_with_mnemonic (_("Air_plane Mode")); - gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); - gtk_widget_set_visible (label, TRUE); - widget = gtk_switch_new (); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); - gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); - gtk_widget_show_all (box); - panel->priv->rfkill_switch = GTK_SWITCH (widget); - cc_shell_embed_widget_in_header (cc_panel_get_shell (CC_PANEL (panel)), box); - panel->priv->kill_switch_header = g_object_ref (box); - - panel->priv->killswitches = g_hash_table_new (g_direct_hash, g_direct_equal); - panel->priv->rfkill = cc_rfkill_glib_new (); - g_signal_connect (G_OBJECT (panel->priv->rfkill), "changed", - G_CALLBACK (rfkill_changed), panel); - if (cc_rfkill_glib_open (panel->priv->rfkill) < 0) - gtk_widget_hide (box); - - g_signal_connect (panel->priv->rfkill_switch, "notify::active", - G_CALLBACK (cc_network_panel_notify_enable_active_cb), - panel); - - return FALSE; + panel_check_network_manager_version (panel); } static void cc_network_panel_init (CcNetworkPanel *panel) { - DBusGConnection *bus = NULL; GError *error = NULL; GtkStyleContext *context; GtkTreeSelection *selection; GtkWidget *widget; GtkWidget *toplevel; + GDBusConnection *system_bus; + GtkCssProvider *provider; + const GPtrArray *connections; + guint i; panel->priv = NETWORK_PANEL_PRIVATE (panel); + g_resources_register (cc_network_get_resource ()); panel->priv->builder = gtk_builder_new (); - gtk_builder_add_from_file (panel->priv->builder, - GNOMECC_UI_DIR "/network.ui", - &error); + gtk_builder_add_from_resource (panel->priv->builder, + "/org/gnome/control-center/network/network.ui", + &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); @@ -1150,16 +1354,35 @@ panel_add_proxy_device (panel); /* use NetworkManager client */ - panel->priv->client = nm_client_new (); - g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_MANAGER_RUNNING, + panel->priv->client = nm_client_new (NULL, NULL); + g_signal_connect (panel->priv->client, "notify::nm-running" , G_CALLBACK (manager_running), panel); - g_signal_connect (panel->priv->client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS, + g_signal_connect (panel->priv->client, "notify::active-connections", G_CALLBACK (active_connections_changed), panel); g_signal_connect (panel->priv->client, "device-added", G_CALLBACK (device_added_cb), panel); g_signal_connect (panel->priv->client, "device-removed", G_CALLBACK (device_removed_cb), panel); + /* Setup ModemManager client */ + system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (system_bus == NULL) { + g_warning ("Error connecting to system D-Bus: %s", + error->message); + g_clear_error (&error); + } else { + panel->priv->modem_manager = mm_manager_new_sync (system_bus, + G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, + NULL, + &error); + if (panel->priv->modem_manager == NULL) { + g_warning ("Error connecting to ModemManager: %s", + error->message); + g_clear_error (&error); + } + g_object_unref (system_bus); + } + widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "add_toolbutton")); g_signal_connect (widget, "clicked", @@ -1172,17 +1395,8 @@ G_CALLBACK (remove_connection), panel); /* add remote settings such as VPN settings as virtual devices */ - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (bus == NULL) { - g_warning ("Error connecting to system D-Bus: %s", - error->message); - g_error_free (error); - } - panel->priv->remote_settings = nm_remote_settings_new (bus); - g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ, - G_CALLBACK (notify_connections_read_cb), panel); - g_signal_connect (panel->priv->remote_settings, NM_REMOTE_SETTINGS_NEW_CONNECTION, - G_CALLBACK (notify_new_connection_cb), panel); + g_signal_connect (panel->priv->client, NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK (notify_connection_added_cb), panel); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel)); g_signal_connect_after (toplevel, "map", G_CALLBACK (on_toplevel_map), panel); @@ -1194,10 +1408,22 @@ widget = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder, "vbox1")); - gtk_widget_reparent (widget, (GtkWidget *) panel); + gtk_container_add (GTK_CONTAINER (panel), widget); - /* add kill switch widgets when dialog activated */ - panel->priv->add_header_widgets_idle = g_idle_add (network_add_shell_header_widgets_cb, panel); + provider = gtk_css_provider_new (); + gtk_css_provider_load_from_data (provider, ".circular-button { border-radius: 20px; -gtk-outline-radius: 20px; }", -1, NULL); + gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), + GTK_STYLE_PROVIDER (provider), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + g_object_unref (provider); + + /* Cold-plug existing connections */ + connections = nm_client_get_connections (panel->priv->client); + for (i = 0; i < connections->len; i++) + add_connection (panel, connections->pdata[i]); + + g_debug ("Calling handle_argv() after cold-plugging connections"); + handle_argv (panel); } void diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.h unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.h 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/cc-network-panel.h 2019-05-01 13:21:41.000000000 +0000 @@ -65,7 +65,9 @@ GType cc_network_panel_get_type (void) G_GNUC_CONST; -void cc_network_panel_register (GIOModule *module); +void cc_network_panel_register (GIOModule *module); + +GPtrArray *cc_network_panel_get_devices (CcNetworkPanel *panel); G_END_DECLS diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/8021x-security-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/8021x-security-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/8021x-security-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/8021x-security-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,295 @@ + + + + + True + True + False + False + + + True + False + 50 + 50 + 12 + 12 + True + True + 10 + 6 + + + True + False + 1 + 802.1x _Security + True + 8021x_switch + + + 0 + 0 + 1 + 1 + + + + + True + True + start + True + + + 1 + 0 + 1 + 1 + + + + + True + False + vertical + + + + + + 0 + 1 + 2 + 1 + + + + + + + True + False + page 1 + + + False + + + + + True + False + 50 + 50 + 12 + 12 + 10 + 6 + + + True + True + + 35 + + + 1 + 0 + 1 + 1 + + + + + True + True + + + + 1 + 1 + 1 + 1 + + + + + True + True + + + + 1 + 2 + 1 + 1 + + + + + True + True + + + + 1 + 3 + 1 + 1 + + + + + True + True + + + + 1 + 4 + 1 + 1 + + + + + True + True + + + + 1 + 5 + 1 + 1 + + + + + True + True + + + + 1 + 6 + 1 + 1 + + + + + True + True + + + + 1 + 7 + 1 + 1 + + + + + True + True + + + + 1 + 8 + 1 + 1 + + + + + True + True + + + + 1 + 9 + 1 + 1 + + + + + True + False + Anony_mous identity + True + + + 0 + 0 + 1 + 1 + + + + + True + False + Inner _authentication + True + + + 0 + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + True + False + page 2 + + + 1 + False + + + + + + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,186 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2012 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include +#include + +#include + +#include "wireless-security.h" +#include "ce-page-ethernet.h" +#include "ce-page-8021x-security.h" + +G_DEFINE_TYPE (CEPage8021xSecurity, ce_page_8021x_security, CE_TYPE_PAGE) + +static void +enable_toggled (GObject *sw, GParamSpec *pspec, gpointer user_data) +{ + CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (user_data); + + gtk_widget_set_sensitive (page->security_widget, gtk_switch_get_active (page->enabled)); + ce_page_changed (CE_PAGE (page)); +} + +static void +stuff_changed (WirelessSecurity *sec, gpointer user_data) +{ + ce_page_changed (CE_PAGE (user_data)); +} + +static void +finish_setup (CEPage8021xSecurity *page, gpointer unused, GError *error, gpointer user_data) +{ + GtkWidget *parent; + GtkWidget *vbox; + GtkWidget *heading; + + if (error) + return; + + vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox")); + heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec")); + + page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + page->security = (WirelessSecurity *) ws_wpa_eap_new (CE_PAGE (page)->connection, TRUE, FALSE); + if (!page->security) { + g_warning ("Could not load 802.1x user interface."); + return; + } + + wireless_security_set_changed_notify (page->security, stuff_changed, page); + page->security_widget = wireless_security_get_widget (page->security); + parent = gtk_widget_get_parent (page->security_widget); + if (parent) + gtk_container_remove (GTK_CONTAINER (parent), page->security_widget); + + gtk_switch_set_active (page->enabled, page->initial_have_8021x); + g_signal_connect (page->enabled, "notify::active", G_CALLBACK (enable_toggled), page); + gtk_widget_set_sensitive (page->security_widget, page->initial_have_8021x); + + gtk_size_group_add_widget (page->group, heading); + wireless_security_add_to_size_group (page->security, page->group); + + gtk_container_add (GTK_CONTAINER (vbox), page->security_widget); + +} + +CEPage * +ce_page_8021x_security_new (NMConnection *connection, + NMClient *client) +{ + CEPage8021xSecurity *page; + + page = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY, + connection, + client, + "/org/gnome/control-center/network/8021x-security-page.ui", + _("Security"))); + + if (nm_connection_get_setting_802_1x (connection)) + page->initial_have_8021x = TRUE; + + page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "8021x_switch")); + + g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL); + + if (page->initial_have_8021x) + CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME; + + return CE_PAGE (page); +} + +static gboolean +validate (CEPage *cepage, NMConnection *connection, GError **error) +{ + CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (cepage); + gboolean valid = TRUE; + + if (gtk_switch_get_active (page->enabled)) { + NMConnection *tmp_connection; + NMSetting *s_8021x; + + /* FIXME: get failed property and error out of wireless security objects */ + valid = wireless_security_validate (page->security, error); + if (valid) { + NMSetting *s_con; + + /* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */ + tmp_connection = nm_simple_connection_new (); + nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ()); + + /* temp connection needs a 'connection' setting too, since most of + * the EAP methods need the UUID for CA cert ignore stuff. + */ + s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + nm_connection_add_setting (tmp_connection, nm_setting_duplicate (s_con)); + + ws_802_1x_fill_connection (page->security, "wpa_eap_auth_combo", tmp_connection); + + s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X); + nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x))); + + g_object_unref (tmp_connection); + } + } else { + nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X); + valid = TRUE; + } + + return valid; +} + +static void +ce_page_8021x_security_init (CEPage8021xSecurity *page) +{ +} + +static void +dispose (GObject *object) +{ + CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (object); + + if (page->security) { + wireless_security_unref (page->security); + page->security = NULL; + } + + g_clear_object (&page->group); + + G_OBJECT_CLASS (ce_page_8021x_security_parent_class)->dispose (object); +} + +static void +ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (security_class); + CEPageClass *parent_class = CE_PAGE_CLASS (security_class); + + /* virtual methods */ + object_class->dispose = dispose; + + parent_class->validate = validate; +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-8021x-security.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2012 Red Hat, Inc. + */ + +#ifndef __CE_PAGE_8021X_SECURITY_H +#define __CE_PAGE_8021X_SECURITY_H + +#include +#include "wireless-security.h" + +#include +#include + +#include "ce-page.h" + +#define CE_TYPE_PAGE_8021X_SECURITY (ce_page_8021x_security_get_type ()) +#define CE_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurity)) +#define CE_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass)) +#define CE_IS_PAGE_8021X_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CE_TYPE_PAGE_8021X_SECURITY)) +#define CE_IS_PAGE_8021X_SECURITY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CE_TYPE_PAGE_8021X_SECURITY)) +#define CE_PAGE_8021X_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityClass)) + +typedef struct CEPage8021xSecurity CEPage8021xSecurity; +typedef struct CEPage8021xSecurityClass CEPage8021xSecurityClass; + +struct CEPage8021xSecurity { + CEPage parent; + + GtkSwitch *enabled; + GtkWidget *security_widget; + WirelessSecurity *security; + GtkSizeGroup *group; + gboolean initial_have_8021x; +}; + +struct CEPage8021xSecurityClass { + CEPageClass parent; +}; + +GType ce_page_8021x_security_get_type (void); + +CEPage *ce_page_8021x_security_new (NMConnection *connection, + NMClient *client); + +#endif /* __CE_PAGE_8021X_SECURITY_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,541 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include + +#include +#include + +#include + +#include + +#include "ce-page.h" + + +G_DEFINE_ABSTRACT_TYPE (CEPage, ce_page, G_TYPE_OBJECT) + +enum { + PROP_0, + PROP_CONNECTION, + PROP_INITIALIZED, +}; + +enum { + CHANGED, + INITIALIZED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +gboolean +ce_page_validate (CEPage *page, NMConnection *connection, GError **error) +{ + g_return_val_if_fail (CE_IS_PAGE (page), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + + if (CE_PAGE_GET_CLASS (page)->validate) + return CE_PAGE_GET_CLASS (page)->validate (page, connection, error); + + return TRUE; +} + +static void +dispose (GObject *object) +{ + CEPage *self = CE_PAGE (object); + + g_clear_object (&self->page); + g_clear_object (&self->builder); + g_clear_object (&self->connection); + + G_OBJECT_CLASS (ce_page_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + CEPage *self = CE_PAGE (object); + + g_free (self->title); + if (self->cancellable) { + g_cancellable_cancel (self->cancellable); + g_object_unref (self->cancellable); + } + + G_OBJECT_CLASS (ce_page_parent_class)->finalize (object); +} + +GtkWidget * +ce_page_get_page (CEPage *self) +{ + g_return_val_if_fail (CE_IS_PAGE (self), NULL); + + return self->page; +} + +const char * +ce_page_get_title (CEPage *self) +{ + g_return_val_if_fail (CE_IS_PAGE (self), NULL); + + return self->title; +} + +gboolean +ce_page_get_initialized (CEPage *self) +{ + g_return_val_if_fail (CE_IS_PAGE (self), FALSE); + + return self->initialized; +} + +void +ce_page_changed (CEPage *self) +{ + g_return_if_fail (CE_IS_PAGE (self)); + + g_signal_emit (self, signals[CHANGED], 0); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + CEPage *self = CE_PAGE (object); + + switch (prop_id) { + case PROP_CONNECTION: + g_value_set_object (value, self->connection); + break; + case PROP_INITIALIZED: + g_value_set_boolean (value, self->initialized); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CEPage *self = CE_PAGE (object); + + switch (prop_id) { + case PROP_CONNECTION: + if (self->connection) + g_object_unref (self->connection); + self->connection = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ce_page_init (CEPage *self) +{ + self->builder = gtk_builder_new (); + self->cancellable = g_cancellable_new (); +} + +static void +ce_page_class_init (CEPageClass *page_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (page_class); + + /* virtual methods */ + object_class->dispose = dispose; + object_class->finalize = finalize; + object_class->get_property = get_property; + object_class->set_property = set_property; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_CONNECTION, + g_param_spec_object ("connection", + "Connection", + "Connection", + NM_TYPE_CONNECTION, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (object_class, PROP_INITIALIZED, + g_param_spec_boolean ("initialized", + "Initialized", + "Initialized", + FALSE, + G_PARAM_READABLE)); + + signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (CEPageClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[INITIALIZED] = + g_signal_new ("initialized", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (CEPageClass, initialized), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); +} + +CEPage * +ce_page_new (GType type, + NMConnection *connection, + NMClient *client, + const gchar *ui_resource, + const gchar *title) +{ + CEPage *page; + GError *error = NULL; + + page = CE_PAGE (g_object_new (type, + "connection", connection, + NULL)); + page->title = g_strdup (title); + page->client = client; + + if (ui_resource) { + if (!gtk_builder_add_from_resource (page->builder, ui_resource, &error)) { + g_warning ("Couldn't load builder file: %s", error->message); + g_error_free (error); + g_object_unref (page); + return NULL; + } + page->page = GTK_WIDGET (gtk_builder_get_object (page->builder, "page")); + if (!page->page) { + g_warning ("Couldn't load page widget from %s", ui_resource); + g_object_unref (page); + return NULL; + } + + g_object_ref_sink (page->page); + } + + return page; +} + +static void +emit_initialized (CEPage *page, + GError *error) +{ + page->initialized = TRUE; + g_signal_emit (page, signals[INITIALIZED], 0, error); + g_clear_error (&error); +} + +void +ce_page_complete_init (CEPage *page, + const gchar *setting_name, + GVariant *secrets, + GError *error) +{ + GError *update_error = NULL; + GVariant *setting_dict; + gboolean ignore_error = FALSE; + + g_return_if_fail (page != NULL); + g_return_if_fail (CE_IS_PAGE (page)); + + if (error) { + ignore_error = g_error_matches (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND) || + g_error_matches (error, NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NO_SECRETS); + } + + /* Ignore missing settings errors */ + if (error && !ignore_error) { + emit_initialized (page, error); + return; + } else if (!setting_name || !secrets || g_variant_n_children (secrets) == 0) { + /* Success, no secrets */ + emit_initialized (page, NULL); + return; + } + + g_assert (setting_name); + g_assert (secrets); + + setting_dict = g_variant_lookup_value (secrets, setting_name, NM_VARIANT_TYPE_SETTING); + if (!setting_dict) { + /* Success, no secrets */ + emit_initialized (page, NULL); + return; + } + g_variant_unref (setting_dict); + + /* Update the connection with the new secrets */ + if (nm_connection_update_secrets (page->connection, + setting_name, + secrets, + &update_error)) { + /* Success */ + emit_initialized (page, NULL); + return; + } + + g_warning ("Failed to update connection secrets due to an unknown error."); + emit_initialized (page, NULL); +} + +gchar ** +ce_page_get_mac_list (NMClient *client, + GType device_type, + const gchar *mac_property) +{ + const GPtrArray *devices; + GPtrArray *macs; + int i; + + macs = g_ptr_array_new (); + devices = nm_client_get_devices (client); + for (i = 0; devices && (i < devices->len); i++) { + NMDevice *dev = g_ptr_array_index (devices, i); + const char *iface; + char *mac, *item; + + if (!G_TYPE_CHECK_INSTANCE_TYPE (dev, device_type)) + continue; + + g_object_get (G_OBJECT (dev), mac_property, &mac, NULL); + iface = nm_device_get_iface (NM_DEVICE (dev)); + item = g_strdup_printf ("%s (%s)", mac, iface); + g_free (mac); + g_ptr_array_add (macs, item); + } + + g_ptr_array_add (macs, NULL); + return (char **)g_ptr_array_free (macs, FALSE); +} + +void +ce_page_setup_mac_combo (GtkComboBoxText *combo, + const gchar *current_mac, + gchar **mac_list) +{ + gchar **m, *active_mac = NULL; + gint current_mac_len; + GtkWidget *entry; + + if (current_mac) + current_mac_len = strlen (current_mac); + else + current_mac_len = -1; + + for (m= mac_list; m && *m; m++) { + gtk_combo_box_text_append_text (combo, *m); + if (current_mac && + g_ascii_strncasecmp (*m, current_mac, current_mac_len) == 0 + && ((*m)[current_mac_len] == '\0' || (*m)[current_mac_len] == ' ')) + active_mac = *m; + } + + if (current_mac) { + if (!active_mac) { + gtk_combo_box_text_prepend_text (combo, current_mac); + } + + entry = gtk_bin_get_child (GTK_BIN (combo)); + if (entry) + gtk_entry_set_text (GTK_ENTRY (entry), active_mac ? active_mac : current_mac); + } +} + +gchar * +ce_page_trim_address (const gchar *addr) +{ + char *space; + + if (!addr || *addr == '\0') + return NULL; + + space = strchr (addr, ' '); + if (space != NULL) + return g_strndup (addr, space - addr); + return g_strdup (addr); +} + +gboolean +ce_page_address_is_valid (const gchar *addr) +{ + guint8 invalid_addr[4][ETH_ALEN] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x44, 0x44, 0x44, 0x44, 0x44, 0x44}, + {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}, /* prism54 dummy MAC */ + }; + guint8 addr_bin[ETH_ALEN]; + char *trimmed_addr; + guint i; + + if (!addr || *addr == '\0') + return TRUE; + + trimmed_addr = ce_page_trim_address (addr); + + if (!nm_utils_hwaddr_valid (trimmed_addr, -1)) { + g_free (trimmed_addr); + return FALSE; + } + + if (!nm_utils_hwaddr_aton (trimmed_addr, addr_bin, ETH_ALEN)) { + g_free (trimmed_addr); + return FALSE; + } + + g_free (trimmed_addr); + + /* Check for multicast address */ + if ((((guint8 *) addr_bin)[0]) & 0x01) + return FALSE; + + for (i = 0; i < G_N_ELEMENTS (invalid_addr); i++) { + if (nm_utils_hwaddr_matches (addr_bin, ETH_ALEN, invalid_addr[i], ETH_ALEN)) + return FALSE; + } + + return TRUE; +} + +const gchar * +ce_page_get_security_setting (CEPage *page) +{ + return page->security_setting; +} + +gint +ce_get_property_default (NMSetting *setting, const gchar *property_name) +{ + GParamSpec *spec; + GValue value = { 0, }; + + spec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), property_name); + g_return_val_if_fail (spec != NULL, -1); + + g_value_init (&value, spec->value_type); + g_param_value_set_default (spec, &value); + + if (G_VALUE_HOLDS_CHAR (&value)) + return (int) g_value_get_schar (&value); + else if (G_VALUE_HOLDS_INT (&value)) + return g_value_get_int (&value); + else if (G_VALUE_HOLDS_INT64 (&value)) + return (int) g_value_get_int64 (&value); + else if (G_VALUE_HOLDS_LONG (&value)) + return (int) g_value_get_long (&value); + else if (G_VALUE_HOLDS_UINT (&value)) + return (int) g_value_get_uint (&value); + else if (G_VALUE_HOLDS_UINT64 (&value)) + return (int) g_value_get_uint64 (&value); + else if (G_VALUE_HOLDS_ULONG (&value)) + return (int) g_value_get_ulong (&value); + else if (G_VALUE_HOLDS_UCHAR (&value)) + return (int) g_value_get_uchar (&value); + g_return_val_if_fail (FALSE, 0); + return 0; +} + +gint +ce_spin_output_with_default (GtkSpinButton *spin, gpointer user_data) +{ + gint defvalue = GPOINTER_TO_INT (user_data); + gint val; + gchar *buf = NULL; + + val = gtk_spin_button_get_value_as_int (spin); + if (val == defvalue) + buf = g_strdup (_("automatic")); + else + buf = g_strdup_printf ("%d", val); + + if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin)))) + gtk_entry_set_text (GTK_ENTRY (spin), buf); + + g_free (buf); + return TRUE; +} + +gchar * +ce_page_get_next_available_name (const GPtrArray *connections, + NameFormat format, + const gchar *type_name) +{ + GSList *names = NULL, *l; + gchar *cname = NULL; + gint i = 0; + guint con_idx; + + for (con_idx = 0; con_idx < connections->len; con_idx++) { + NMConnection *connection = g_ptr_array_index (connections, con_idx); + const gchar *id; + + id = nm_connection_get_id (connection); + g_assert (id); + names = g_slist_append (names, (gpointer) id); + } + + /* Find the next available unique connection name */ + while (!cname && (i++ < 10000)) { + gchar *temp; + gboolean found = FALSE; + + switch (format) { + case NAME_FORMAT_TYPE: + temp = g_strdup_printf ("%s %d", type_name, i); + break; + case NAME_FORMAT_PROFILE: + temp = g_strdup_printf (_("Profile %d"), i); + break; + default: + g_assert_not_reached (); + } + + for (l = names; l; l = l->next) { + if (!strcmp (l->data, temp)) { + found = TRUE; + break; + } + } + if (!found) + cname = temp; + else + g_free (temp); + } + g_slist_free (names); + + return cname; +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,289 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "../panel-common.h" +#include "ce-page-details.h" + +G_DEFINE_TYPE (CEPageDetails, ce_page_details, CE_TYPE_PAGE) + +static void +forget_cb (GtkButton *button, CEPageDetails *page) +{ + net_connection_editor_forget (page->editor); +} + +static gchar * +get_ap_security_string (NMAccessPoint *ap) +{ + NM80211ApSecurityFlags wpa_flags, rsn_flags; + NM80211ApFlags flags; + GString *str; + + flags = nm_access_point_get_flags (ap); + wpa_flags = nm_access_point_get_wpa_flags (ap); + rsn_flags = nm_access_point_get_rsn_flags (ap); + + str = g_string_new (""); + if ((flags & NM_802_11_AP_FLAGS_PRIVACY) && + (wpa_flags == NM_802_11_AP_SEC_NONE) && + (rsn_flags == NM_802_11_AP_SEC_NONE)) { + /* TRANSLATORS: this WEP WiFi security */ + g_string_append_printf (str, "%s, ", _("WEP")); + } + if (wpa_flags != NM_802_11_AP_SEC_NONE) { + /* TRANSLATORS: this WPA WiFi security */ + g_string_append_printf (str, "%s, ", _("WPA")); + } + if (rsn_flags != NM_802_11_AP_SEC_NONE) { + /* TRANSLATORS: this WPA WiFi security */ + g_string_append_printf (str, "%s, ", _("WPA2")); + } + if ((wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) || + (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { + /* TRANSLATORS: this Enterprise WiFi security */ + g_string_append_printf (str, "%s, ", _("Enterprise")); + } + if (str->len > 0) + g_string_set_size (str, str->len - 2); + else { + g_string_append (str, C_("Wifi security", "None")); + } + return g_string_free (str, FALSE); +} + +static void +update_last_used (CEPageDetails *page, NMConnection *connection) +{ + gchar *last_used = NULL; + GDateTime *now = NULL; + GDateTime *then = NULL; + gint days; + GTimeSpan diff; + guint64 timestamp; + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + if (s_con == NULL) + goto out; + timestamp = nm_setting_connection_get_timestamp (s_con); + if (timestamp == 0) { + last_used = g_strdup (_("Never")); + goto out; + } + + /* calculate the amount of time that has elapsed */ + now = g_date_time_new_now_utc (); + then = g_date_time_new_from_unix_utc (timestamp); + + diff = g_date_time_difference (now, then); + days = diff / G_TIME_SPAN_DAY; + if (days == 0) + last_used = g_strdup (_("Today")); + else if (days == 1) + last_used = g_strdup (_("Yesterday")); + else + last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days); +out: + panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", last_used); + if (now != NULL) + g_date_time_unref (now); + if (then != NULL) + g_date_time_unref (then); + g_free (last_used); +} + +static void +all_user_changed (GtkToggleButton *b, CEPageDetails *page) +{ + gboolean all_users; + NMSettingConnection *sc; + + sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); + all_users = gtk_toggle_button_get_active (b); + + g_object_set (sc, "permissions", NULL, NULL); + if (!all_users) + nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL); +} + +static void +connect_details_page (CEPageDetails *page) +{ + NMSettingConnection *sc; + GtkWidget *widget; + guint speed; + guint strength; + NMDeviceState state; + NMAccessPoint *active_ap; + const gchar *str; + const gchar *type; + gboolean device_is_active; + + if (NM_IS_DEVICE_WIFI (page->device)) + active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (page->device)); + else + active_ap = NULL; + + state = page->device ? nm_device_get_state (page->device) : NM_DEVICE_STATE_DISCONNECTED; + + device_is_active = FALSE; + speed = 0; + if (active_ap && page->ap == active_ap && state != NM_DEVICE_STATE_UNAVAILABLE) { + device_is_active = TRUE; + if (NM_IS_DEVICE_WIFI (page->device)) + speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000; + } else if (page->device) { + NMActiveConnection *ac; + const gchar *p1, *p2; + + ac = nm_device_get_active_connection (page->device); + p1 = ac ? nm_active_connection_get_uuid (ac) : NULL; + p2 = nm_connection_get_uuid (CE_PAGE (page)->connection); + if (g_strcmp0 (p1, p2) == 0) { + device_is_active = TRUE; + if (NM_IS_DEVICE_WIFI (page->device)) + speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000; + else if (NM_IS_DEVICE_ETHERNET (page->device)) + speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (page->device)); + } + } + if (speed > 0) + str = g_strdup_printf (_("%d Mb/s"), speed); + else + str = NULL; + panel_set_device_widget_details (CE_PAGE (page)->builder, "speed", str); + g_clear_pointer (&str, g_free); + + if (NM_IS_DEVICE_WIFI (page->device)) + str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (page->device)); + else if (NM_IS_DEVICE_ETHERNET (page->device)) + str = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (page->device)); + + panel_set_device_widget_details (CE_PAGE (page)->builder, "mac", str); + + str = NULL; + if (device_is_active && active_ap) + str = get_ap_security_string (active_ap); + panel_set_device_widget_details (CE_PAGE (page)->builder, "security", str); + g_clear_pointer (&str, g_free); + + strength = 0; + if (page->ap != NULL) + strength = nm_access_point_get_strength (page->ap); + + if (strength <= 0) + str = NULL; + else if (strength < 20) + str = C_("Signal strength", "None"); + else if (strength < 40) + str = C_("Signal strength", "Weak"); + else if (strength < 50) + str = C_("Signal strength", "Ok"); + else if (strength < 80) + str = C_("Signal strength", "Good"); + else + str = C_("Signal strength", "Excellent"); + panel_set_device_widget_details (CE_PAGE (page)->builder, "strength", str); + + /* set IP entries */ + if (device_is_active) + panel_set_device_widgets (CE_PAGE (page)->builder, page->device); + else + panel_unset_device_widgets (CE_PAGE (page)->builder); + + if (!device_is_active && CE_PAGE (page)->connection) + update_last_used (page, CE_PAGE (page)->connection); + else + panel_set_device_widget_details (CE_PAGE (page)->builder, "last_used", NULL); + + /* Auto connect check */ + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, + "auto_connect_check")); + sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection); + g_object_bind_property (sc, "autoconnect", + widget, "active", + G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); + g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); + + /* All users check */ + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, + "all_user_check")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), + nm_setting_connection_get_num_permissions (sc) == 0); + g_signal_connect (widget, "toggled", + G_CALLBACK (all_user_changed), page); + g_signal_connect_swapped (widget, "toggled", G_CALLBACK (ce_page_changed), page); + + /* Forget button */ + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_forget")); + g_signal_connect (widget, "clicked", G_CALLBACK (forget_cb), page); + + type = nm_setting_connection_get_connection_type (sc); + if (g_str_equal (type, NM_SETTING_WIRELESS_SETTING_NAME)) + gtk_button_set_label (GTK_BUTTON (widget), _("Forget Connection")); + else if (g_str_equal (type, NM_SETTING_WIRED_SETTING_NAME)) + gtk_button_set_label (GTK_BUTTON (widget), _("Remove Connection Profile")); + else if (g_str_equal (type, NM_SETTING_VPN_SETTING_NAME)) + gtk_button_set_label (GTK_BUTTON (widget), _("Remove VPN")); + else + gtk_widget_hide (widget); +} + +static void +ce_page_details_init (CEPageDetails *page) +{ +} + +static void +ce_page_details_class_init (CEPageDetailsClass *class) +{ +} + +CEPage * +ce_page_details_new (NMConnection *connection, + NMClient *client, + NMDevice *device, + NMAccessPoint *ap, + NetConnectionEditor *editor) +{ + CEPageDetails *page; + + page = CE_PAGE_DETAILS (ce_page_new (CE_TYPE_PAGE_DETAILS, + connection, + client, + "/org/gnome/control-center/network/details-page.ui", + _("Details"))); + + page->editor = editor; + page->device = device; + page->ap = ap; + + connect_details_page (page); + + return CE_PAGE (page); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-details.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_DETAILS_H +#define __CE_PAGE_DETAILS_H + +#include + +#include +#include "net-connection-editor.h" +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_DETAILS (ce_page_details_get_type ()) +#define CE_PAGE_DETAILS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_DETAILS, CEPageDetails)) +#define CE_PAGE_DETAILS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass)) +#define CE_IS_PAGE_DETAILS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_DETAILS)) +#define CE_IS_PAGE_DETAILS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_DETAILS)) +#define CE_PAGE_DETAILS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_DETAILS, CEPageDetailsClass)) + +typedef struct _CEPageDetails CEPageDetails; +typedef struct _CEPageDetailsClass CEPageDetailsClass; + +struct _CEPageDetails +{ + CEPage parent; + + NMDevice *device; + NMAccessPoint *ap; + NetConnectionEditor *editor; +}; + +struct _CEPageDetailsClass +{ + CEPageClass parent_class; +}; + +GType ce_page_details_get_type (void); + +CEPage *ce_page_details_new (NMConnection *connection, + NMClient *client, + NMDevice *device, + NMAccessPoint *ap, + NetConnectionEditor *editor); + +G_END_DECLS + +#endif /* __CE_PAGE_DETAILS_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,187 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include + +#include + + +#include "ce-page-ethernet.h" +#include "ui-helpers.h" + +G_DEFINE_TYPE (CEPageEthernet, ce_page_ethernet, CE_TYPE_PAGE) + +static void +mtu_changed (GtkSpinButton *mtu, CEPageEthernet *page) +{ + if (gtk_spin_button_get_value_as_int (mtu) == 0) + gtk_widget_hide (page->mtu_label); + else + gtk_widget_show (page->mtu_label); +} + +static void +connect_ethernet_page (CEPageEthernet *page) +{ + NMSettingWired *setting = page->setting_wired; + int mtu_def; + char **mac_list; + const char *s_mac_str; + const gchar *name; + const gchar *cloned_mac; + + name = nm_setting_connection_get_id (page->setting_connection); + gtk_entry_set_text (page->name, name); + + /* Device MAC address */ + mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_ETHERNET, + NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS); + s_mac_str = nm_setting_wired_get_mac_address (setting); + ce_page_setup_mac_combo (page->device_mac, s_mac_str, mac_list); + g_strfreev (mac_list); + g_signal_connect_swapped (page->device_mac, "changed", G_CALLBACK (ce_page_changed), page); + + /* Cloned MAC address */ + cloned_mac = nm_setting_wired_get_cloned_mac_address (setting); + gtk_entry_set_text (GTK_ENTRY (page->cloned_mac), cloned_mac ? cloned_mac : ""); + g_signal_connect_swapped (page->cloned_mac, "changed", G_CALLBACK (ce_page_changed), page); + + /* MTU */ + mtu_def = ce_get_property_default (NM_SETTING (setting), NM_SETTING_WIRED_MTU); + g_signal_connect (page->mtu, "output", + G_CALLBACK (ce_spin_output_with_default), + GINT_TO_POINTER (mtu_def)); + gtk_spin_button_set_value (page->mtu, (gdouble) nm_setting_wired_get_mtu (setting)); + g_signal_connect (page->mtu, "value-changed", + G_CALLBACK (mtu_changed), page); + mtu_changed (page->mtu, page); + + g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (page->mtu, "value-changed", G_CALLBACK (ce_page_changed), page); +} + +static void +ui_to_setting (CEPageEthernet *page) +{ + gchar *device_mac = NULL; + gchar *cloned_mac; + const gchar *text; + GtkWidget *entry; + + entry = gtk_bin_get_child (GTK_BIN (page->device_mac)); + if (entry) { + text = gtk_entry_get_text (GTK_ENTRY (entry)); + device_mac = ce_page_trim_address (text); + } + text = gtk_entry_get_text (GTK_ENTRY (entry)); + cloned_mac = ce_page_trim_address (text); + + g_object_set (page->setting_wired, + NM_SETTING_WIRED_MAC_ADDRESS, device_mac, + NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac, + NM_SETTING_WIRED_MTU, (guint32) gtk_spin_button_get_value_as_int (page->mtu), + NULL); + + g_object_set (page->setting_connection, + NM_SETTING_CONNECTION_ID, gtk_entry_get_text (page->name), + NULL); + + g_free (cloned_mac); + g_free (device_mac); +} + +static gboolean +validate (CEPage *page, + NMConnection *connection, + GError **error) +{ + CEPageEthernet *self = CE_PAGE_ETHERNET (page); + GtkWidget *entry; + gboolean ret = TRUE; + + entry = gtk_bin_get_child (GTK_BIN (self->device_mac)); + if (entry) { + if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { + widget_set_error (entry); + ret = FALSE; + } else { + widget_unset_error (entry); + } + } + + if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (self->cloned_mac)))) { + widget_set_error (GTK_WIDGET (self->cloned_mac)); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (self->cloned_mac)); + } + + if (!ret) + return ret; + + ui_to_setting (self); + + return nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error) && + nm_setting_verify (NM_SETTING (self->setting_wired), NULL, error); +} + +static void +ce_page_ethernet_init (CEPageEthernet *page) +{ +} + +static void +ce_page_ethernet_class_init (CEPageEthernetClass *class) +{ + CEPageClass *page_class= CE_PAGE_CLASS (class); + + page_class->validate = validate; +} + +CEPage * +ce_page_ethernet_new (NMConnection *connection, + NMClient *client) +{ + CEPageEthernet *page; + + page = CE_PAGE_ETHERNET (ce_page_new (CE_TYPE_PAGE_ETHERNET, + connection, + client, + "/org/gnome/control-center/network/ethernet-page.ui", + _("Identity"))); + + page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name")); + page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")); + page->cloned_mac = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); + page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu")); + page->mtu_label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "label_mtu")); + + page->setting_connection = nm_connection_get_setting_connection (connection); + page->setting_wired = nm_connection_get_setting_wired (connection); + + connect_ethernet_page (page); + + return CE_PAGE (page); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ethernet.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 ethernet. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_ETHERNET_H +#define __CE_PAGE_ETHERNET_H + +#include + +#include + +#include +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_ETHERNET (ce_page_ethernet_get_type ()) +#define CE_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernet)) +#define CE_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass)) +#define CE_IS_PAGE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_ETHERNET)) +#define CE_IS_PAGE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_ETHERNET)) +#define CE_PAGE_ETHERNET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_ETHERNET, CEPageEthernetClass)) + +typedef struct _CEPageEthernet CEPageEthernet; +typedef struct _CEPageEthernetClass CEPageEthernetClass; + +struct _CEPageEthernet +{ + CEPage parent; + + NMSettingConnection *setting_connection; + NMSettingWired *setting_wired; + + GtkEntry *name; + GtkComboBoxText *device_mac; + GtkEntry *cloned_mac; + GtkSpinButton *mtu; + GtkWidget *mtu_label; +}; + +struct _CEPageEthernetClass +{ + CEPageClass parent_class; +}; + +GType ce_page_ethernet_get_type (void); + +CEPage *ce_page_ethernet_new (NMConnection *connection, + NMClient *client); + +G_END_DECLS + +#endif /* __CE_PAGE_ETHERNET_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,114 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_H +#define __CE_PAGE_H + +#include + +#include + +#include + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE (ce_page_get_type ()) +#define CE_PAGE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE, CEPage)) +#define CE_PAGE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE, CEPageClass)) +#define CE_IS_PAGE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE)) +#define CE_IS_PAGE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE)) +#define CE_PAGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE, CEPageClass)) + +typedef struct _CEPage CEPage; +typedef struct _CEPageClass CEPageClass; + +struct _CEPage +{ + GObject parent; + + gboolean initialized; + GtkBuilder *builder; + GtkWidget *page; + gchar *title; + const gchar *security_setting; + + NMConnection *connection; + NMClient *client; + GCancellable *cancellable; +}; + +struct _CEPageClass +{ + GObjectClass parent_class; + + gboolean (*validate) (CEPage *page, NMConnection *connection, GError **error); + void (*changed) (CEPage *page); + void (*initialized) (CEPage *page, GError *error); +}; + +GType ce_page_get_type (void); + +GtkWidget *ce_page_get_page (CEPage *page); +const gchar *ce_page_get_title (CEPage *page); +const gchar *ce_page_get_security_setting (CEPage *page); +gboolean ce_page_validate (CEPage *page, + NMConnection *connection, + GError **error); +gboolean ce_page_get_initialized (CEPage *page); +void ce_page_changed (CEPage *page); +CEPage *ce_page_new (GType type, + NMConnection *connection, + NMClient *client, + const gchar *ui_resource, + const gchar *title); +void ce_page_complete_init (CEPage *page, + const gchar *setting_name, + GVariant *variant, + GError *error); + +gchar **ce_page_get_mac_list (NMClient *client, + GType device_type, + const gchar *mac_property); +void ce_page_setup_mac_combo (GtkComboBoxText *combo, + const gchar *current_mac, + gchar **mac_list); +gint ce_get_property_default (NMSetting *setting, + const gchar *property_name); +gint ce_spin_output_with_default (GtkSpinButton *spin, + gpointer user_data); +gboolean ce_page_address_is_valid (const gchar *addr); +gchar *ce_page_trim_address (const gchar *addr); + +typedef enum { + NAME_FORMAT_TYPE, + NAME_FORMAT_PROFILE +} NameFormat; + +gchar * ce_page_get_next_available_name (const GPtrArray *connections, + NameFormat format, + const gchar *type_name); + + + +G_END_DECLS + +#endif /* __CE_PAGE_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,907 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "shell/list-box-helper.h" +#include "ce-page-ip4.h" +#include "ui-helpers.h" + +#define RADIO_IS_ACTIVE(x) (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(CE_PAGE (page)->builder, x)))) + +static void ensure_empty_address_row (CEPageIP4 *page); +static void ensure_empty_routes_row (CEPageIP4 *page); + +G_DEFINE_TYPE (CEPageIP4, ce_page_ip4, CE_TYPE_PAGE) + +enum { + METHOD_COL_NAME, + METHOD_COL_METHOD +}; + +enum { + IP4_METHOD_AUTO, + IP4_METHOD_MANUAL, + IP4_METHOD_LINK_LOCAL, + IP4_METHOD_SHARED, + IP4_METHOD_DISABLED +}; + +static void +method_changed (GtkToggleButton *radio, CEPageIP4 *page) +{ + gboolean addr_enabled; + gboolean dns_enabled; + gboolean routes_enabled; + GtkWidget *widget; + + if (RADIO_IS_ACTIVE ("radio_disabled")) { + addr_enabled = FALSE; + dns_enabled = FALSE; + routes_enabled = FALSE; + } else { + addr_enabled = RADIO_IS_ACTIVE ("radio_manual"); + dns_enabled = !RADIO_IS_ACTIVE ("radio_local"); + routes_enabled = !RADIO_IS_ACTIVE ("radio_local"); + } + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); + gtk_widget_set_visible (widget, addr_enabled); + gtk_widget_set_sensitive (page->dns_entry, dns_enabled); + gtk_widget_set_sensitive (page->routes_list, routes_enabled); + gtk_widget_set_sensitive (page->never_default, routes_enabled); + + ce_page_changed (CE_PAGE (page)); +} + +static void +switch_toggled (GObject *object, + GParamSpec *pspec, + CEPage *page) +{ + ce_page_changed (page); +} + +static void +update_row_sensitivity (CEPageIP4 *page, GtkWidget *list) +{ + GList *children, *l; + gint rows = 0, i = 0; + + children = gtk_container_get_children (GTK_CONTAINER (list)); + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkWidget *button; + + button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); + if (button != NULL) + rows++; + } + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkWidget *button; + + button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); + if (button != NULL) + gtk_widget_set_sensitive (button, rows > 1 && ++i < rows); + } + g_list_free (children); +} + +static void +update_row_gateway_sensitivity (CEPageIP4 *page) +{ + GList *children, *l; + gint rows = 0; + + children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkWidget *entry; + + entry = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway")); + + gtk_widget_set_sensitive (entry, (rows == 0)); + + rows++; + } + g_list_free (children); +} + +static void +remove_row (GtkButton *button, CEPageIP4 *page) +{ + GtkWidget *list; + GtkWidget *row; + GtkWidget *row_box; + + row_box = gtk_widget_get_parent (GTK_WIDGET (button)); + row = gtk_widget_get_parent (row_box); + list = gtk_widget_get_parent (row); + + gtk_container_remove (GTK_CONTAINER (list), row); + + ce_page_changed (CE_PAGE (page)); + + update_row_sensitivity (page, list); + if (list == page->address_list) + update_row_gateway_sensitivity (page); +} + +static gboolean +validate_row (GtkWidget *row) +{ + GtkWidget *box; + GList *children, *l; + gboolean valid; + + valid = FALSE; + box = gtk_bin_get_child (GTK_BIN (row)); + children = gtk_container_get_children (GTK_CONTAINER (box)); + + for (l = children; l != NULL; l = l->next) { + if (!GTK_IS_ENTRY (l->data)) + continue; + + valid = valid || gtk_entry_get_text_length (l->data) > 0; + } + + g_list_free (children); + + return valid; +} + +static gint +sort_first_last (gconstpointer a, gconstpointer b, gpointer data) +{ + gboolean afirst, bfirst, alast, blast; + + afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first")); + bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first")); + alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last")); + blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last")); + + if (afirst) + return -1; + if (bfirst) + return 1; + if (alast) + return 1; + if (blast) + return -1; + + return 0; +} + +static void +add_address_row (CEPageIP4 *page, + const gchar *address, + const gchar *network, + const gchar *gateway) +{ + GtkSizeGroup *group; + GtkWidget *row; + GtkWidget *row_box; + GtkWidget *widget; + GtkWidget *delete_button; + GtkWidget *image; + + row = gtk_list_box_row_new (); + + row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked"); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page); + g_object_set_data (G_OBJECT (row), "address", widget); + gtk_entry_set_text (GTK_ENTRY (widget), address); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page); + g_object_set_data (G_OBJECT (row), "network", widget); + gtk_entry_set_text (GTK_ENTRY (widget), network); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page); + g_object_set_data (G_OBJECT (row), "gateway", widget); + gtk_entry_set_text (GTK_ENTRY (widget), gateway ? gateway : ""); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + delete_button = gtk_button_new (); + gtk_widget_set_sensitive (delete_button, FALSE); + gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); + g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); + image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU); + atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Address")); + gtk_button_set_image (GTK_BUTTON (delete_button), image); + gtk_container_add (GTK_CONTAINER (row_box), delete_button); + g_object_set_data (G_OBJECT (row), "delete-button", delete_button); + + group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "address_sizegroup")); + gtk_size_group_add_widget (group, delete_button); + + gtk_container_add (GTK_CONTAINER (row), row_box); + gtk_widget_show_all (row); + gtk_container_add (GTK_CONTAINER (page->address_list), row); + + update_row_gateway_sensitivity (page); + update_row_sensitivity (page, page->address_list); +} + +static void +ensure_empty_address_row (CEPageIP4 *page) +{ + GList *children, *l; + + children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); + l = children; + + while (l && l->next) + l = l->next; + + /* Add the last, stub row if needed*/ + if (!l || validate_row (l->data)) + add_address_row (page, "", "", ""); + + g_list_free (children); +} + +static void +add_address_section (CEPageIP4 *page) +{ + GtkWidget *widget; + GtkWidget *list; + gint i; + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); + + page->address_list = list = gtk_list_box_new (); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); + gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); + gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); + gtk_container_add (GTK_CONTAINER (widget), list); + + for (i = 0; i < nm_setting_ip_config_get_num_addresses (page->setting); i++) { + NMIPAddress *addr; + struct in_addr tmp_addr; + gchar network[INET_ADDRSTRLEN + 1]; + + addr = nm_setting_ip_config_get_address (page->setting, i); + if (!addr) + continue; + + tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip_address_get_prefix (addr)); + (void) inet_ntop (AF_INET, &tmp_addr, &network[0], sizeof (network)); + + add_address_row (page, + nm_ip_address_get_address (addr), + network, + i == 0 ? nm_setting_ip_config_get_gateway (page->setting) : ""); + } + if (nm_setting_ip_config_get_num_addresses (page->setting) == 0) + ensure_empty_address_row (page); + + gtk_widget_show_all (widget); +} + +static void +add_dns_section (CEPageIP4 *page) +{ + GtkEntry *entry; + GString *string; + gint i; + + page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch")); + gtk_switch_set_active (page->auto_dns, !nm_setting_ip_config_get_ignore_auto_dns (page->setting)); + g_signal_connect (page->auto_dns, "notify::active", G_CALLBACK (switch_toggled), page); + + page->dns_entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_entry")); + entry = GTK_ENTRY (page->dns_entry); + string = g_string_new (""); + + for (i = 0; i < nm_setting_ip_config_get_num_dns (page->setting); i++) { + const char *address; + + address = nm_setting_ip_config_get_dns (page->setting, i); + + if (i > 0) + g_string_append (string, ", "); + + g_string_append (string, address); + } + + gtk_entry_set_text (entry, string->str); + + g_signal_connect_swapped (entry, "notify::text", G_CALLBACK (ce_page_changed), page); + + g_string_free (string, TRUE); +} + +static void +add_route_row (CEPageIP4 *page, + const gchar *address, + const gchar *netmask, + const gchar *gateway, + gint metric) +{ + GtkSizeGroup *group; + GtkWidget *row; + GtkWidget *row_box; + GtkWidget *widget; + GtkWidget *delete_button; + GtkWidget *image; + + row = gtk_list_box_row_new (); + + row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked"); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "address", widget); + gtk_entry_set_text (GTK_ENTRY (widget), address); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "netmask", widget); + gtk_entry_set_text (GTK_ENTRY (widget), netmask); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "gateway", widget); + gtk_entry_set_text (GTK_ENTRY (widget), gateway); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "metric", widget); + if (metric >= 0) { + gchar *s = g_strdup_printf ("%d", metric); + gtk_entry_set_text (GTK_ENTRY (widget), s); + g_free (s); + } + gtk_entry_set_width_chars (GTK_ENTRY (widget), 5); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_metric_sizegroup")); + gtk_size_group_add_widget (group, widget); + + delete_button = gtk_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); + g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); + image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU); + atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route")); + gtk_button_set_image (GTK_BUTTON (delete_button), image); + gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER); + gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER); + gtk_container_add (GTK_CONTAINER (row_box), delete_button); + g_object_set_data (G_OBJECT (row), "delete-button", delete_button); + + group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_sizegroup")); + gtk_size_group_add_widget (group, delete_button); + + gtk_container_add (GTK_CONTAINER (row), row_box); + gtk_widget_show_all (row); + gtk_container_add (GTK_CONTAINER (page->routes_list), row); + + update_row_sensitivity (page, page->routes_list); +} + +static void +ensure_empty_routes_row (CEPageIP4 *page) +{ + GList *children, *l; + + children = gtk_container_get_children (GTK_CONTAINER (page->routes_list)); + l = children; + + while (l && l->next) + l = l->next; + + /* Add the last, stub row if needed*/ + if (!l || validate_row (l->data)) + add_route_row (page, "", "", "", -1); + + g_list_free (children); +} + +static void +add_routes_section (CEPageIP4 *page) +{ + GtkWidget *widget; + GtkWidget *list; + gint i; + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section")); + + page->routes_list = list = gtk_list_box_new (); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); + gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); + gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); + gtk_container_add (GTK_CONTAINER (widget), list); + page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch")); + gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting)); + g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page); + + + for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) { + NMIPRoute *route; + struct in_addr tmp_addr; + gchar netmask[INET_ADDRSTRLEN + 1]; + + route = nm_setting_ip_config_get_route (page->setting, i); + if (!route) + continue; + + tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip_route_get_prefix (route)); + (void) inet_ntop (AF_INET, &tmp_addr, &netmask[0], sizeof (netmask)); + + add_route_row (page, + nm_ip_route_get_dest (route), + netmask, + nm_ip_route_get_next_hop (route), + nm_ip_route_get_metric (route)); + } + if (nm_setting_ip_config_get_num_routes (page->setting) == 0) + ensure_empty_routes_row (page); + + gtk_widget_show_all (widget); +} + +enum +{ + RADIO_AUTOMATIC, + RADIO_LOCAL, + RADIO_MANUAL, + RADIO_DISABLED, + N_RADIO +}; + +static void +connect_ip4_page (CEPageIP4 *page) +{ + GtkToggleButton *radios[N_RADIO]; + GtkWidget *content; + const gchar *str_method; + gboolean disabled; + guint method, i; + + add_address_section (page); + add_dns_section (page); + add_routes_section (page); + + page->disabled = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_disabled")); + + str_method = nm_setting_ip_config_get_method (page->setting); + disabled = g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0; + gtk_toggle_button_set_active (page->disabled, disabled); + g_signal_connect_swapped (page->disabled, "notify::active", G_CALLBACK (ce_page_changed), page); + content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content")); + g_object_bind_property (page->disabled, "active", + content, "sensitive", + G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); + + method = IP4_METHOD_AUTO; + if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) { + method = IP4_METHOD_LINK_LOCAL; + } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) { + method = IP4_METHOD_MANUAL; + } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { + method = IP4_METHOD_SHARED; + } else if (g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) { + method = IP4_METHOD_DISABLED; + } + + page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default), + nm_setting_ip_config_get_never_default (page->setting)); + g_signal_connect_swapped (page->never_default, "toggled", G_CALLBACK (ce_page_changed), page); + + /* Connect radio buttons */ + radios[RADIO_AUTOMATIC] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_automatic")); + radios[RADIO_LOCAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_local")); + radios[RADIO_MANUAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_manual")); + radios[RADIO_DISABLED] = page->disabled; + + for (i = RADIO_AUTOMATIC; i < RADIO_DISABLED; i++) + g_signal_connect (radios[i], "toggled", G_CALLBACK (method_changed), page); + + switch (method) { + case IP4_METHOD_AUTO: + gtk_toggle_button_set_active (radios[RADIO_AUTOMATIC], TRUE); + break; + case IP4_METHOD_LINK_LOCAL: + gtk_toggle_button_set_active (radios[RADIO_LOCAL], TRUE); + break; + case IP4_METHOD_MANUAL: + gtk_toggle_button_set_active (radios[RADIO_MANUAL], TRUE); + break; + case IP4_METHOD_DISABLED: + gtk_toggle_button_set_active (radios[RADIO_DISABLED], TRUE); + break; + default: + break; + } + + method_changed (NULL, page); +} + +static gboolean +parse_netmask (const char *str, guint32 *prefix) +{ + struct in_addr tmp_addr; + glong tmp_prefix; + + errno = 0; + + /* Is it a prefix? */ + if (!strchr (str, '.')) { + tmp_prefix = strtol (str, NULL, 10); + if (!errno && tmp_prefix >= 0 && tmp_prefix <= 32) { + *prefix = tmp_prefix; + return TRUE; + } + } + + /* Is it a netmask? */ + if (inet_pton (AF_INET, str, &tmp_addr) > 0) { + *prefix = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr); + return TRUE; + } + + return FALSE; +} + +static gboolean +ui_to_setting (CEPageIP4 *page) +{ + const gchar *method; + gboolean ignore_auto_dns; + gboolean ignore_auto_routes; + gboolean never_default; + GPtrArray *addresses = NULL; + GPtrArray *dns_servers = NULL; + GPtrArray *routes = NULL; + GStrv dns_addresses = NULL; + GList *children, *l; + gboolean ret = TRUE; + const char *default_gateway = NULL; + gchar *dns_text = NULL; + guint i; + + if (gtk_toggle_button_get_active (page->disabled)) { + method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + } else { + if (RADIO_IS_ACTIVE ("radio_automatic")) + method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; + else if (RADIO_IS_ACTIVE ("radio_local")) + method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL; + else if (RADIO_IS_ACTIVE ("radio_manual")) + method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + } + + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref); + if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); + else + children = NULL; + + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkEntry *entry; + GtkEntry *gateway_entry; + const gchar *text_address; + const gchar *text_netmask; + const gchar *text_gateway = ""; + NMIPAddress *addr; + guint32 prefix; + + entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); + if (!entry) + continue; + + text_address = gtk_entry_get_text (entry); + text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "network"))); + gateway_entry = g_object_get_data (G_OBJECT (row), "gateway"); + if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry))) + text_gateway = gtk_entry_get_text (gateway_entry); + + if (!*text_address && !*text_netmask && !*text_gateway) { + /* ignore empty rows */ + widget_unset_error (GTK_WIDGET (entry)); + widget_unset_error (g_object_get_data (G_OBJECT (row), "network")); + widget_unset_error (GTK_WIDGET (gateway_entry)); + continue; + } + + if (!nm_utils_ipaddr_valid (AF_INET, text_address)) { + widget_set_error (GTK_WIDGET (entry)); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (entry)); + } + + if (!parse_netmask (text_netmask, &prefix)) { + widget_set_error (g_object_get_data (G_OBJECT (row), "network")); + ret = FALSE; + } else { + widget_unset_error (g_object_get_data (G_OBJECT (row), "network")); + } + + if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry)) && + *text_gateway && + !nm_utils_ipaddr_valid (AF_INET, text_gateway)) { + widget_set_error (g_object_get_data (G_OBJECT (row), "gateway")); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (gateway_entry)); + if (gtk_widget_is_visible (GTK_WIDGET (gateway_entry)) && *text_gateway) { + g_assert (default_gateway == NULL); + default_gateway = text_gateway; + } + } + + if (!ret) + continue; + + addr = nm_ip_address_new (AF_INET, text_address, prefix, NULL); + if (addr) + g_ptr_array_add (addresses, addr); + + if (!l || !l->next) + ensure_empty_address_row (page); + } + g_list_free (children); + + if (addresses->len == 0) { + g_ptr_array_free (addresses, TRUE); + addresses = NULL; + } + + dns_servers = g_ptr_array_new_with_free_func (g_free); + dns_text = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (page->dns_entry)))); + if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) || + g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + dns_addresses = g_strsplit_set (dns_text, ", ", -1); + else + dns_addresses = NULL; + + for (i = 0; dns_addresses && dns_addresses[i]; i++) { + const gchar *text; + + text = dns_addresses[i]; + + if (!text || !*text) + continue; + + if (!nm_utils_ipaddr_valid (AF_INET, text)) { + g_ptr_array_remove_range (dns_servers, 0, dns_servers->len); + widget_set_error (page->dns_entry); + ret = FALSE; + break; + } else { + widget_unset_error (page->dns_entry); + g_ptr_array_add (dns_servers, g_strdup (text)); + } + } + g_clear_pointer (&dns_addresses, g_strfreev); + + if (dns_servers->len == 0) { + g_ptr_array_free (dns_servers, TRUE); + dns_servers = NULL; + } else { + g_ptr_array_add (dns_servers, NULL); + } + + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref); + if (g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) || + g_str_equal (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + children = gtk_container_get_children (GTK_CONTAINER (page->routes_list)); + else + children = NULL; + + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkEntry *entry; + const gchar *text_address; + const gchar *text_netmask; + const gchar *text_gateway; + const gchar *text_metric; + gint64 metric; + guint32 netmask; + NMIPRoute *route; + + entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); + if (!entry) + continue; + + text_address = gtk_entry_get_text (entry); + text_netmask = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "netmask"))); + text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway"))); + text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric"))); + + if (!*text_address && !*text_netmask && !*text_gateway && !*text_metric) { + /* ignore empty rows */ + continue; + } + + if (text_address && !nm_utils_ipaddr_valid (AF_INET, text_address)) { + widget_set_error (GTK_WIDGET (entry)); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (entry)); + } + + if (!parse_netmask (text_netmask, &netmask)) { + widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask"))); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "netmask"))); + } + + if (text_gateway && !nm_utils_ipaddr_valid (AF_INET, text_gateway)) { + widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway"))); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "gateway"))); + } + + metric = -1; + if (*text_metric) { + errno = 0; + metric = g_ascii_strtoull (text_metric, NULL, 10); + if (errno || metric < 0 || metric > G_MAXUINT32) { + widget_set_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric"))); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric"))); + } + } else { + widget_unset_error (GTK_WIDGET (g_object_get_data (G_OBJECT (row), "metric"))); + } + + if (!ret) + continue; + + route = nm_ip_route_new (AF_INET, text_address, netmask, text_gateway, metric, NULL); + if (route) + g_ptr_array_add (routes, route); + + if (!l || !l->next) + ensure_empty_routes_row (page); + } + g_list_free (children); + + if (routes->len == 0) { + g_ptr_array_free (routes, TRUE); + routes = NULL; + } + + if (!ret) + goto out; + + ignore_auto_dns = !gtk_switch_get_active (page->auto_dns); + ignore_auto_routes = !gtk_switch_get_active (page->auto_routes); + never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default)); + + g_object_set (page->setting, + NM_SETTING_IP_CONFIG_METHOD, method, + NM_SETTING_IP_CONFIG_ADDRESSES, addresses, + NM_SETTING_IP_CONFIG_GATEWAY, default_gateway, + NM_SETTING_IP_CONFIG_DNS, dns_servers ? dns_servers->pdata : NULL, + NM_SETTING_IP_CONFIG_ROUTES, routes, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, + NULL); + +out: + if (addresses) + g_ptr_array_free (addresses, TRUE); + + if (dns_servers) + g_ptr_array_free (dns_servers, TRUE); + + if (routes) + g_ptr_array_free (routes, TRUE); + + g_clear_pointer (&dns_text, g_free); + + return ret; +} + +static gboolean +validate (CEPage *page, + NMConnection *connection, + GError **error) +{ + if (!ui_to_setting (CE_PAGE_IP4 (page))) + return FALSE; + + return nm_setting_verify (NM_SETTING (CE_PAGE_IP4 (page)->setting), NULL, error); +} + +static void +ce_page_ip4_init (CEPageIP4 *page) +{ +} + +static void +ce_page_ip4_class_init (CEPageIP4Class *class) +{ + CEPageClass *page_class= CE_PAGE_CLASS (class); + + page_class->validate = validate; +} + +CEPage * +ce_page_ip4_new (NMConnection *connection, + NMClient *client) +{ + CEPageIP4 *page; + + page = CE_PAGE_IP4 (ce_page_new (CE_TYPE_PAGE_IP4, + connection, + client, + "/org/gnome/control-center/network/ip4-page.ui", + _("IPv4"))); + + page->setting = nm_connection_get_setting_ip4_config (connection); + if (!page->setting) { + page->setting = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); + nm_connection_add_setting (connection, NM_SETTING (page->setting)); + } + + connect_ip4_page (page); + + return CE_PAGE (page); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip4.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 ip4. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_IP4_H +#define __CE_PAGE_IP4_H + +#include + +#include +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_IP4 (ce_page_ip4_get_type ()) +#define CE_PAGE_IP4(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP4, CEPageIP4)) +#define CE_PAGE_IP4_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP4, CEPageIP4Class)) +#define CE_IS_PAGE_IP4(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP4)) +#define CE_IS_PAGE_IP4_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP4)) +#define CE_PAGE_IP4_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP4, CEPageIP4Class)) + +typedef struct _CEPageIP4 CEPageIP4; +typedef struct _CEPageIP4Class CEPageIP4Class; + +struct _CEPageIP4 +{ + CEPage parent; + + NMSettingIPConfig *setting; + + GtkToggleButton *disabled; + GtkWidget *address_list; + GtkSwitch *auto_dns; + GtkWidget *dns_entry; + GtkSwitch *auto_routes; + GtkWidget *routes_list; + GtkWidget *never_default; +}; + +struct _CEPageIP4Class +{ + CEPageClass parent_class; +}; + +GType ce_page_ip4_get_type (void); + +CEPage *ce_page_ip4_new (NMConnection *connection, + NMClient *client); + +G_END_DECLS + +#endif /* __CE_PAGE_IP4_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,838 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "shell/list-box-helper.h" +#include "ce-page-ip6.h" +#include "ui-helpers.h" + +#define RADIO_IS_ACTIVE(x) (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_builder_get_object(CE_PAGE (page)->builder, x)))) + +static void ensure_empty_address_row (CEPageIP6 *page); +static void ensure_empty_routes_row (CEPageIP6 *page); + +G_DEFINE_TYPE (CEPageIP6, ce_page_ip6, CE_TYPE_PAGE) + +enum { + METHOD_COL_NAME, + METHOD_COL_METHOD +}; + +enum { + IP6_METHOD_AUTO, + IP6_METHOD_DHCP, + IP6_METHOD_MANUAL, + IP6_METHOD_LINK_LOCAL, + IP6_METHOD_SHARED, + IP6_METHOD_IGNORE +}; + +static void +method_changed (GtkToggleButton *button, CEPageIP6 *page) +{ + gboolean addr_enabled; + gboolean dns_enabled; + gboolean routes_enabled; + GtkWidget *widget; + + if (RADIO_IS_ACTIVE ("radio_disabled")) { + addr_enabled = FALSE; + dns_enabled = FALSE; + routes_enabled = FALSE; + } else { + addr_enabled = RADIO_IS_ACTIVE ("radio_manual"); + dns_enabled = !RADIO_IS_ACTIVE ("radio_local"); + routes_enabled = !RADIO_IS_ACTIVE ("radio_local"); + } + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); + gtk_widget_set_visible (widget, addr_enabled); + gtk_widget_set_sensitive (page->dns_entry, dns_enabled); + gtk_widget_set_sensitive (page->routes_list, routes_enabled); + gtk_widget_set_sensitive (page->never_default, routes_enabled); + + ce_page_changed (CE_PAGE (page)); +} + +static void +switch_toggled (GObject *object, + GParamSpec *pspec, + CEPage *page) +{ + ce_page_changed (page); +} + +static void +update_row_sensitivity (CEPageIP6 *page, GtkWidget *list) +{ + GList *children, *l; + gint rows = 0, i = 0; + + children = gtk_container_get_children (GTK_CONTAINER (list)); + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkWidget *button; + + button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); + if (button != NULL) + rows++; + } + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkWidget *button; + + button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button")); + if (button != NULL) + gtk_widget_set_sensitive (button, rows > 1 && ++i < rows); + } + g_list_free (children); +} + +static void +remove_row (GtkButton *button, CEPageIP6 *page) +{ + GtkWidget *row; + GtkWidget *row_box; + GtkWidget *list; + + row_box = gtk_widget_get_parent (GTK_WIDGET (button)); + row = gtk_widget_get_parent (row_box); + list = gtk_widget_get_parent (row); + + gtk_container_remove (GTK_CONTAINER (list), row); + + ce_page_changed (CE_PAGE (page)); + + update_row_sensitivity (page, list); +} + +static gboolean +validate_row (GtkWidget *row) +{ + GtkWidget *box; + GList *children, *l; + gboolean valid; + + valid = FALSE; + box = gtk_bin_get_child (GTK_BIN (row)); + children = gtk_container_get_children (GTK_CONTAINER (box)); + + for (l = children; l != NULL; l = l->next) { + if (!GTK_IS_ENTRY (l->data)) + continue; + + valid = valid || gtk_entry_get_text_length (l->data) > 0; + } + + g_list_free (children); + + return valid; +} + +static gint +sort_first_last (gconstpointer a, gconstpointer b, gpointer data) +{ + gboolean afirst, bfirst, alast, blast; + + afirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "first")); + bfirst = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "first")); + alast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "last")); + blast = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "last")); + + if (afirst) + return -1; + if (bfirst) + return 1; + if (alast) + return 1; + if (blast) + return -1; + + return 0; +} + +static void +add_address_row (CEPageIP6 *page, + const gchar *address, + const gchar *network, + const gchar *gateway) +{ + GtkSizeGroup *group; + GtkWidget *row; + GtkWidget *row_box; + GtkWidget *widget; + GtkWidget *delete_button; + GtkWidget *image; + + row = gtk_list_box_row_new (); + + row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked"); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page); + g_object_set_data (G_OBJECT (row), "address", widget); + gtk_entry_set_text (GTK_ENTRY (widget), address); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page); + g_object_set_data (G_OBJECT (row), "prefix", widget); + gtk_entry_set_text (GTK_ENTRY (widget), network); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_address_row), page); + g_object_set_data (G_OBJECT (row), "gateway", widget); + gtk_entry_set_text (GTK_ENTRY (widget), gateway ? gateway : ""); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + delete_button = gtk_button_new (); + gtk_widget_set_sensitive (delete_button, FALSE); + gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); + g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); + image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU); + atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Address")); + gtk_button_set_image (GTK_BUTTON (delete_button), image); + gtk_container_add (GTK_CONTAINER (row_box), delete_button); + g_object_set_data (G_OBJECT (row), "delete-button", delete_button); + + group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "address_sizegroup")); + gtk_size_group_add_widget (group, delete_button); + + gtk_container_add (GTK_CONTAINER (row), row_box); + gtk_widget_show_all (row); + gtk_container_add (GTK_CONTAINER (page->address_list), row); + + update_row_sensitivity (page, page->address_list); +} + +static void +ensure_empty_address_row (CEPageIP6 *page) +{ + GList *children, *l; + + children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); + l = children; + + while (l && l->next) + l = l->next; + + /* Add the last, stub row if needed*/ + if (!l || validate_row (l->data)) + add_address_row (page, "", "", ""); + + g_list_free (children); +} + +static void +add_address_section (CEPageIP6 *page) +{ + GtkWidget *widget; + GtkWidget *list; + gint i; + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section")); + + page->address_list = list = gtk_list_box_new (); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); + gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); + gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); + gtk_container_add (GTK_CONTAINER (widget), list); + + for (i = 0; i < nm_setting_ip_config_get_num_addresses (page->setting); i++) { + NMIPAddress *addr; + char *netmask; + + addr = nm_setting_ip_config_get_address (page->setting, i); + netmask = g_strdup_printf ("%u", nm_ip_address_get_prefix (addr)); + add_address_row (page, nm_ip_address_get_address (addr), netmask, + i == 0 ? nm_setting_ip_config_get_gateway (page->setting) : NULL); + g_free (netmask); + } + if (nm_setting_ip_config_get_num_addresses (page->setting) == 0) + ensure_empty_address_row (page); + + gtk_widget_show_all (widget); +} + +static void +add_dns_section (CEPageIP6 *page) +{ + GtkEntry *entry; + GString *string; + gint i; + + page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch")); + gtk_switch_set_active (page->auto_dns, !nm_setting_ip_config_get_ignore_auto_dns (page->setting)); + g_signal_connect (page->auto_dns, "notify::active", G_CALLBACK (switch_toggled), page); + + page->dns_entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_entry")); + entry = GTK_ENTRY (page->dns_entry); + string = g_string_new (""); + + for (i = 0; i < nm_setting_ip_config_get_num_dns (page->setting); i++) { + const char *address; + + address = nm_setting_ip_config_get_dns (page->setting, i); + + if (i > 0) + g_string_append (string, ", "); + + g_string_append (string, address); + + } + + gtk_entry_set_text (entry, string->str); + + g_signal_connect_swapped (page->dns_entry, "notify::text", G_CALLBACK (ce_page_changed), page); + + g_string_free (string, TRUE); +} + +static void +add_route_row (CEPageIP6 *page, + const gchar *address, + const gchar *prefix, + const gchar *gateway, + const gchar *metric) +{ + GtkSizeGroup *group; + GtkWidget *row; + GtkWidget *row_box; + GtkWidget *widget; + GtkWidget *delete_button; + GtkWidget *image; + + row = gtk_list_box_row_new (); + + row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_style_context_add_class (gtk_widget_get_style_context (row_box), "linked"); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "address", widget); + gtk_entry_set_text (GTK_ENTRY (widget), address); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "prefix", widget); + gtk_entry_set_text (GTK_ENTRY (widget), prefix ? prefix : ""); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "gateway", widget); + gtk_entry_set_text (GTK_ENTRY (widget), gateway); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 16); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + widget = gtk_entry_new (); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + g_signal_connect_swapped (widget, "activate", G_CALLBACK (ensure_empty_routes_row), page); + g_object_set_data (G_OBJECT (row), "metric", widget); + gtk_entry_set_text (GTK_ENTRY (widget), metric ? metric : ""); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 5); + gtk_widget_set_hexpand (widget, TRUE); + gtk_container_add (GTK_CONTAINER (row_box), widget); + + group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_metric_sizegroup")); + gtk_size_group_add_widget (group, widget); + + delete_button = gtk_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (delete_button), "image-button"); + g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page); + image = gtk_image_new_from_icon_name ("edit-delete-symbolic", GTK_ICON_SIZE_MENU); + atk_object_set_name (gtk_widget_get_accessible (delete_button), _("Delete Route")); + gtk_button_set_image (GTK_BUTTON (delete_button), image); + gtk_widget_set_halign (delete_button, GTK_ALIGN_CENTER); + gtk_widget_set_valign (delete_button, GTK_ALIGN_CENTER); + gtk_container_add (GTK_CONTAINER (row_box), delete_button); + g_object_set_data (G_OBJECT (row), "delete-button", delete_button); + + group = GTK_SIZE_GROUP (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_sizegroup")); + gtk_size_group_add_widget (group, delete_button); + + gtk_container_add (GTK_CONTAINER (row), row_box); + gtk_widget_show_all (row); + gtk_container_add (GTK_CONTAINER (page->routes_list), row); + + update_row_sensitivity (page, page->routes_list); +} + +static void +ensure_empty_routes_row (CEPageIP6 *page) +{ + GList *children, *l; + + children = gtk_container_get_children (GTK_CONTAINER (page->routes_list)); + l = children; + + while (l && l->next) + l = l->next; + + /* Add the last, stub row if needed*/ + if (!l || validate_row (l->data)) + add_route_row (page, "", NULL, "", NULL); + + g_list_free (children); +} + +static void +add_empty_route_row (CEPageIP6 *page) +{ + add_route_row (page, "", NULL, "", NULL); +} + +static void +add_routes_section (CEPageIP6 *page) +{ + GtkWidget *widget; + GtkWidget *list; + gint i; + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section")); + + page->routes_list = list = gtk_list_box_new (); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); + gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); + gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)sort_first_last, NULL, NULL); + gtk_container_add (GTK_CONTAINER (widget), list); + page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch")); + gtk_switch_set_active (page->auto_routes, !nm_setting_ip_config_get_ignore_auto_routes (page->setting)); + g_signal_connect (page->auto_routes, "notify::active", G_CALLBACK (switch_toggled), page); + + for (i = 0; i < nm_setting_ip_config_get_num_routes (page->setting); i++) { + NMIPRoute *route; + char *prefix, *metric; + + route = nm_setting_ip_config_get_route (page->setting, i); + prefix = g_strdup_printf ("%u", nm_ip_route_get_prefix (route)); + metric = g_strdup_printf ("%u", (guint32) MIN (0, nm_ip_route_get_metric (route))); + add_route_row (page, nm_ip_route_get_dest (route), + prefix, + nm_ip_route_get_next_hop (route), + metric); + g_free (prefix); + g_free (metric); + } + if (nm_setting_ip_config_get_num_routes (page->setting) == 0) + add_empty_route_row (page); + + gtk_widget_show_all (widget); +} + +enum +{ + RADIO_AUTOMATIC, + RADIO_DHCP, + RADIO_LOCAL, + RADIO_MANUAL, + RADIO_DISABLED, + N_RADIO +}; + +static void +connect_ip6_page (CEPageIP6 *page) +{ + GtkToggleButton *radios[N_RADIO]; + GtkWidget *content; + const gchar *str_method; + gboolean disabled; + guint method, i; + + add_address_section (page); + add_dns_section (page); + add_routes_section (page); + + page->disabled = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_disabled")); + + str_method = nm_setting_ip_config_get_method (page->setting); + disabled = g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0; + gtk_toggle_button_set_active (page->disabled, disabled); + g_signal_connect_swapped (page->disabled, "notify::active", G_CALLBACK (ce_page_changed), page); + content = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "page_content")); + g_object_bind_property (page->disabled, "active", + content, "sensitive", + G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); + + method = IP6_METHOD_AUTO; + if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { + method = IP6_METHOD_DHCP; + } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) { + method = IP6_METHOD_LINK_LOCAL; + } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL) == 0) { + method = IP6_METHOD_MANUAL; + } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { + method = IP6_METHOD_SHARED; + } else if (g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0) { + method = IP6_METHOD_IGNORE; + } + + page->never_default = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "never_default_check")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (page->never_default), + nm_setting_ip_config_get_never_default (page->setting)); + g_signal_connect_swapped (page->never_default, "toggled", G_CALLBACK (ce_page_changed), page); + + + /* Connect radio buttons */ + radios[RADIO_AUTOMATIC] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_automatic")); + radios[RADIO_DHCP] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_dhcp")); + radios[RADIO_LOCAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_local")); + radios[RADIO_MANUAL] = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "radio_manual")); + radios[RADIO_DISABLED] = page->disabled; + + for (i = RADIO_AUTOMATIC; i < RADIO_DISABLED; i++) + g_signal_connect (radios[i], "toggled", G_CALLBACK (method_changed), page); + + switch (method) { + case IP6_METHOD_AUTO: + gtk_toggle_button_set_active (radios[RADIO_AUTOMATIC], TRUE); + break; + case IP6_METHOD_DHCP: + gtk_toggle_button_set_active (radios[RADIO_DHCP], TRUE); + break; + case IP6_METHOD_LINK_LOCAL: + gtk_toggle_button_set_active (radios[RADIO_LOCAL], TRUE); + break; + case IP6_METHOD_MANUAL: + gtk_toggle_button_set_active (radios[RADIO_MANUAL], TRUE); + break; + case IP6_METHOD_IGNORE: + gtk_toggle_button_set_active (radios[RADIO_DISABLED], TRUE); + break; + default: + break; + } + + method_changed (NULL, page); +} + +static gboolean +ui_to_setting (CEPageIP6 *page) +{ + const gchar *method; + gboolean ignore_auto_dns; + gboolean ignore_auto_routes; + gboolean never_default; + GList *children, *l; + gboolean ret = TRUE; + GStrv dns_addresses = NULL; + gchar *dns_text = NULL; + guint i; + + if (gtk_toggle_button_get_active (page->disabled)) { + method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + } else { + if (RADIO_IS_ACTIVE ("radio_manual")) { + method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + } else if (RADIO_IS_ACTIVE ("radio_local")) { + method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + } else if (RADIO_IS_ACTIVE ("radio_dhcp")) { + method = NM_SETTING_IP6_CONFIG_METHOD_DHCP; + } else if (RADIO_IS_ACTIVE ("radio_automatic")) { + method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; + } + } + + nm_setting_ip_config_clear_addresses (page->setting); + if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + children = gtk_container_get_children (GTK_CONTAINER (page->address_list)); + } else { + g_object_set (G_OBJECT (page->setting), + NM_SETTING_IP_CONFIG_GATEWAY, NULL, + NULL); + children = NULL; + } + + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkEntry *entry; + const gchar *text_address; + const gchar *text_prefix; + const gchar *text_gateway; + guint32 prefix; + gchar *end; + NMIPAddress *addr; + gboolean have_gateway = FALSE; + + entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); + if (!entry) + continue; + + text_address = gtk_entry_get_text (entry); + text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix"))); + text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway"))); + + if (!*text_address && !*text_prefix && !*text_gateway) { + /* ignore empty rows */ + widget_unset_error (GTK_WIDGET (entry)); + widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); + widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); + continue; + } + + if (!text_address || !nm_utils_ipaddr_valid (AF_INET6, text_address)) { + widget_set_error (GTK_WIDGET (entry)); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (entry)); + } + + prefix = strtoul (text_prefix, &end, 10); + if (!end || *end || prefix == 0 || prefix > 128) { + widget_set_error (g_object_get_data (G_OBJECT (row), "prefix")); + ret = FALSE; + } else { + widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); + } + + if (text_gateway && !nm_utils_ipaddr_valid (AF_INET6, text_gateway)) { + widget_set_error (g_object_get_data (G_OBJECT (row), "gateway")); + ret = FALSE; + } else { + widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); + have_gateway = TRUE; + } + + if (!ret) + continue; + + addr = nm_ip_address_new (AF_INET6, text_address, prefix, NULL); + if (have_gateway) + g_object_set (G_OBJECT (page->setting), + NM_SETTING_IP_CONFIG_GATEWAY, text_gateway, + NULL); + nm_setting_ip_config_add_address (page->setting, addr); + + if (!l || !l->next) + ensure_empty_address_row (page); + } + g_list_free (children); + + nm_setting_ip_config_clear_dns (page->setting); + dns_text = g_strstrip (g_strdup (gtk_entry_get_text (GTK_ENTRY (page->dns_entry)))); + + if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) || + g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) || + g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + dns_addresses = g_strsplit_set (dns_text, ", ", -1); + else + dns_addresses = NULL; + + for (i = 0; dns_addresses && dns_addresses[i]; i++) { + const gchar *text; + struct in6_addr tmp_addr; + + text = dns_addresses[i]; + + if (!text || !*text) + continue; + + if (inet_pton (AF_INET6, text, &tmp_addr) <= 0) { + g_clear_pointer (&dns_addresses, g_strfreev); + widget_set_error (page->dns_entry); + ret = FALSE; + break; + } else { + widget_unset_error (page->dns_entry); + nm_setting_ip_config_add_dns (page->setting, text); + } + } + + nm_setting_ip_config_clear_routes (page->setting); + if (g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) || + g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) || + g_str_equal (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + children = gtk_container_get_children (GTK_CONTAINER (page->routes_list)); + else + children = NULL; + + for (l = children; l; l = l->next) { + GtkWidget *row = l->data; + GtkEntry *entry; + const gchar *text_address; + const gchar *text_prefix; + const gchar *text_gateway; + const gchar *text_metric; + guint32 prefix, metric; + gchar *end; + NMIPRoute *route; + + entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address")); + if (!entry) + continue; + + text_address = gtk_entry_get_text (entry); + text_prefix = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "prefix"))); + text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway"))); + text_metric = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "metric"))); + + if (!*text_address && !*text_prefix && !*text_gateway && !*text_metric) { + /* ignore empty rows */ + widget_unset_error (GTK_WIDGET (entry)); + widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); + widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); + widget_unset_error (g_object_get_data (G_OBJECT (row), "metric")); + continue; + } + + if (!nm_utils_ipaddr_valid (AF_INET6, text_address)) { + widget_set_error (GTK_WIDGET (entry)); + ret = FALSE; + } else { + widget_unset_error (GTK_WIDGET (entry)); + } + + prefix = strtoul (text_prefix, &end, 10); + if (!end || *end || prefix == 0 || prefix > 128) { + widget_set_error (g_object_get_data (G_OBJECT (row), "prefix")); + ret = FALSE; + } else { + widget_unset_error (g_object_get_data (G_OBJECT (row), "prefix")); + } + + if (!nm_utils_ipaddr_valid (AF_INET6, text_gateway)) { + widget_set_error (g_object_get_data (G_OBJECT (row), "gateway")); + ret = FALSE; + } else { + widget_unset_error (g_object_get_data (G_OBJECT (row), "gateway")); + } + + metric = 0; + if (*text_metric) { + errno = 0; + metric = strtoul (text_metric, NULL, 10); + if (errno) { + widget_set_error (g_object_get_data (G_OBJECT (row), "metric")); + ret = FALSE; + } else { + widget_unset_error (g_object_get_data (G_OBJECT (row), "metric")); + } + } else { + widget_unset_error (g_object_get_data (G_OBJECT (row), "metric")); + } + + if (!ret) + continue; + + route = nm_ip_route_new (AF_INET6, text_address, prefix, text_gateway, metric, NULL); + nm_setting_ip_config_add_route (page->setting, route); + nm_ip_route_unref (route); + + if (!l || !l->next) + ensure_empty_routes_row (page); + } + g_list_free (children); + + if (!ret) + goto out; + + ignore_auto_dns = !gtk_switch_get_active (page->auto_dns); + ignore_auto_routes = !gtk_switch_get_active (page->auto_routes); + never_default = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (page->never_default)); + + g_object_set (page->setting, + NM_SETTING_IP_CONFIG_METHOD, method, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns, + NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes, + NM_SETTING_IP_CONFIG_NEVER_DEFAULT, never_default, + NULL); + +out: + g_clear_pointer (&dns_addresses, g_strfreev); + g_clear_pointer (&dns_text, g_free); + + return ret; +} + +static gboolean +validate (CEPage *page, + NMConnection *connection, + GError **error) +{ + if (!ui_to_setting (CE_PAGE_IP6 (page))) + return FALSE; + + return nm_setting_verify (NM_SETTING (CE_PAGE_IP6 (page)->setting), NULL, error); +} + +static void +ce_page_ip6_init (CEPageIP6 *page) +{ +} + +static void +ce_page_ip6_class_init (CEPageIP6Class *class) +{ + CEPageClass *page_class= CE_PAGE_CLASS (class); + + page_class->validate = validate; +} + +CEPage * +ce_page_ip6_new (NMConnection *connection, + NMClient *client) +{ + CEPageIP6 *page; + + page = CE_PAGE_IP6 (ce_page_new (CE_TYPE_PAGE_IP6, + connection, + client, + "/org/gnome/control-center/network/ip6-page.ui", + _("IPv6"))); + + page->setting = nm_connection_get_setting_ip6_config (connection); + if (!page->setting) { + page->setting = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); + nm_connection_add_setting (connection, NM_SETTING (page->setting)); + } + + connect_ip6_page (page); + + return CE_PAGE (page); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-ip6.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 ip6. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_IP6_H +#define __CE_PAGE_IP6_H + +#include + +#include +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_IP6 (ce_page_ip6_get_type ()) +#define CE_PAGE_IP6(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_IP6, CEPageIP6)) +#define CE_PAGE_IP6_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_IP6, CEPageIP6Class)) +#define CE_IS_PAGE_IP6(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_IP6)) +#define CE_IS_PAGE_IP6_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_IP6)) +#define CE_PAGE_IP6_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_IP6, CEPageIP6Class)) + +typedef struct _CEPageIP6 CEPageIP6; +typedef struct _CEPageIP6Class CEPageIP6Class; + +struct _CEPageIP6 +{ + CEPage parent; + + NMSettingIPConfig *setting; + + GtkToggleButton *disabled; + GtkWidget *address_list; + GtkSwitch *auto_dns; + GtkWidget *dns_entry; + GtkSwitch *auto_routes; + GtkWidget *routes_list; + GtkWidget *never_default; +}; + +struct _CEPageIP6Class +{ + CEPageClass parent_class; +}; + +GType ce_page_ip6_get_type (void); + +CEPage *ce_page_ip6_new (NMConnection *connection, + NMClient *client); + +G_END_DECLS + +#endif /* __CE_PAGE_IP6_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,467 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "wireless-security.h" +#include "ce-page-security.h" + +G_DEFINE_TYPE (CEPageSecurity, ce_page_security, CE_TYPE_PAGE) + +enum { + S_NAME_COLUMN, + S_SEC_COLUMN, + S_ADHOC_VALID_COLUMN +}; + +static gboolean +find_proto (NMSettingWirelessSecurity *sec, const char *item) +{ + guint32 i; + + for (i = 0; i < nm_setting_wireless_security_get_num_protos (sec); i++) { + if (!strcmp (item, nm_setting_wireless_security_get_proto (sec, i))) + return TRUE; + } + return FALSE; +} + +static NMUtilsSecurityType +get_default_type_for_security (NMSettingWirelessSecurity *sec) +{ + const char *key_mgmt, *auth_alg; + + g_return_val_if_fail (sec != NULL, NMU_SEC_NONE); + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (sec); + auth_alg = nm_setting_wireless_security_get_auth_alg (sec); + + /* No IEEE 802.1x */ + if (!strcmp (key_mgmt, "none")) + return NMU_SEC_STATIC_WEP; + + if (!strcmp (key_mgmt, "ieee8021x")) { + if (auth_alg && !strcmp (auth_alg, "leap")) + return NMU_SEC_LEAP; + return NMU_SEC_DYNAMIC_WEP; + } + + if ( !strcmp (key_mgmt, "wpa-none") + || !strcmp (key_mgmt, "wpa-psk")) { + if (find_proto (sec, "rsn")) + return NMU_SEC_WPA2_PSK; + else if (find_proto (sec, "wpa")) + return NMU_SEC_WPA_PSK; + else + return NMU_SEC_WPA_PSK; + } + + if (!strcmp (key_mgmt, "wpa-eap")) { + if (find_proto (sec, "rsn")) + return NMU_SEC_WPA2_ENTERPRISE; + else if (find_proto (sec, "wpa")) + return NMU_SEC_WPA_ENTERPRISE; + else + return NMU_SEC_WPA_ENTERPRISE; + } + + return NMU_SEC_INVALID; +} + +static WirelessSecurity * +security_combo_get_active (CEPageSecurity *page) +{ + GtkTreeIter iter; + GtkTreeModel *model; + WirelessSecurity *sec = NULL; + + model = gtk_combo_box_get_model (page->security_combo); + gtk_combo_box_get_active_iter (page->security_combo, &iter); + gtk_tree_model_get (model, &iter, S_SEC_COLUMN, &sec, -1); + + return sec; +} + +static void +wsec_size_group_clear (GtkSizeGroup *group) +{ + GSList *children; + GSList *iter; + + g_return_if_fail (group != NULL); + + children = gtk_size_group_get_widgets (group); + for (iter = children; iter; iter = g_slist_next (iter)) + gtk_size_group_remove_widget (group, GTK_WIDGET (iter->data)); +} + +static void +security_combo_changed (GtkComboBox *combo, + gpointer user_data) +{ + CEPageSecurity *page = CE_PAGE_SECURITY (user_data); + GtkWidget *vbox; + GList *l, *children; + WirelessSecurity *sec; + + wsec_size_group_clear (page->group); + + vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox")); + children = gtk_container_get_children (GTK_CONTAINER (vbox)); + for (l = children; l; l = l->next) { + gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (l->data)); + } + + sec = security_combo_get_active (page); + if (sec) { + GtkWidget *sec_widget; + GtkWidget *parent; + + sec_widget = wireless_security_get_widget (sec); + g_assert (sec_widget); + parent = gtk_widget_get_parent (sec_widget); + if (parent) + gtk_container_remove (GTK_CONTAINER (parent), sec_widget); + + gtk_size_group_add_widget (page->group, page->security_heading); + wireless_security_add_to_size_group (sec, page->group); + + gtk_container_add (GTK_CONTAINER (vbox), sec_widget); + wireless_security_unref (sec); + } + + ce_page_changed (CE_PAGE (page)); +} + +static void +stuff_changed_cb (WirelessSecurity *sec, gpointer user_data) +{ + ce_page_changed (CE_PAGE (user_data)); +} + +static void +add_security_item (CEPageSecurity *page, + WirelessSecurity *sec, + GtkListStore *model, + GtkTreeIter *iter, + const char *text, + gboolean adhoc_valid) +{ + wireless_security_set_changed_notify (sec, stuff_changed_cb, page); + gtk_list_store_append (model, iter); + gtk_list_store_set (model, iter, + S_NAME_COLUMN, text, + S_SEC_COLUMN, sec, + S_ADHOC_VALID_COLUMN, adhoc_valid, + -1); + wireless_security_unref (sec); +} + +static void +set_sensitive (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + gboolean *adhoc = data; + gboolean sensitive = TRUE, adhoc_valid = TRUE; + + gtk_tree_model_get (tree_model, iter, S_ADHOC_VALID_COLUMN, &adhoc_valid, -1); + if (*adhoc && !adhoc_valid) + sensitive = FALSE; + + g_object_set (cell, "sensitive", sensitive, NULL); +} + +static void +finish_setup (CEPageSecurity *page) +{ + NMConnection *connection = CE_PAGE (page)->connection; + NMSettingWireless *sw; + NMSettingWirelessSecurity *sws; + gboolean is_adhoc = FALSE; + GtkListStore *sec_model; + GtkTreeIter iter; + const gchar *mode; + guint32 dev_caps = 0; + NMUtilsSecurityType default_type = NMU_SEC_NONE; + int active = -1; + int item = 0; + GtkComboBox *combo; + GtkCellRenderer *renderer; + + sw = nm_connection_get_setting_wireless (connection); + g_assert (sw); + + page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + page->security_heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec")); + page->security_combo = combo = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_sec")); + + dev_caps = NM_WIFI_DEVICE_CAP_CIPHER_WEP40 + | NM_WIFI_DEVICE_CAP_CIPHER_WEP104 + | NM_WIFI_DEVICE_CAP_CIPHER_TKIP + | NM_WIFI_DEVICE_CAP_CIPHER_CCMP + | NM_WIFI_DEVICE_CAP_WPA + | NM_WIFI_DEVICE_CAP_RSN; + + mode = nm_setting_wireless_get_mode (sw); + if (mode && !strcmp (mode, "adhoc")) + is_adhoc = TRUE; + page->adhoc = is_adhoc; + + sws = nm_connection_get_setting_wireless_security (connection); + if (sws) + default_type = get_default_type_for_security (sws); + + sec_model = gtk_list_store_new (3, G_TYPE_STRING, WIRELESS_TYPE_SECURITY, G_TYPE_BOOLEAN); + + if (nm_utils_security_valid (NMU_SEC_NONE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { + gtk_list_store_insert_with_values (sec_model, &iter, -1, + S_NAME_COLUMN, C_("Wi-Fi/Ethernet security", "None"), + S_ADHOC_VALID_COLUMN, TRUE, + -1); + if (default_type == NMU_SEC_NONE) + active = item; + item++; + } + + if (nm_utils_security_valid (NMU_SEC_STATIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { + WirelessSecurityWEPKey *ws_wep; + NMWepKeyType wep_type = NM_WEP_KEY_TYPE_KEY; + + if (default_type == NMU_SEC_STATIC_WEP) { + sws = nm_connection_get_setting_wireless_security (connection); + if (sws) + wep_type = nm_setting_wireless_security_get_wep_key_type (sws); + if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN) + wep_type = NM_WEP_KEY_TYPE_KEY; + } + + ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_KEY, FALSE, FALSE); + if (ws_wep) { + add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model, + &iter, _("WEP 40/128-bit Key (Hex or ASCII)"), + TRUE); + if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_KEY)) + active = item; + item++; + } + + ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_PASSPHRASE, FALSE, FALSE); + if (ws_wep) { + add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model, + &iter, _("WEP 128-bit Passphrase"), TRUE); + if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE)) + active = item; + item++; + } + } + + if (nm_utils_security_valid (NMU_SEC_LEAP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { + WirelessSecurityLEAP *ws_leap; + + ws_leap = ws_leap_new (connection, FALSE); + if (ws_leap) { + add_security_item (page, WIRELESS_SECURITY (ws_leap), sec_model, + &iter, _("LEAP"), FALSE); + if ((active < 0) && (default_type == NMU_SEC_LEAP)) + active = item; + item++; + } + } + + if (nm_utils_security_valid (NMU_SEC_DYNAMIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { + WirelessSecurityDynamicWEP *ws_dynamic_wep; + + ws_dynamic_wep = ws_dynamic_wep_new (connection, TRUE, FALSE); + if (ws_dynamic_wep) { + add_security_item (page, WIRELESS_SECURITY (ws_dynamic_wep), sec_model, + &iter, _("Dynamic WEP (802.1x)"), FALSE); + if ((active < 0) && (default_type == NMU_SEC_DYNAMIC_WEP)) + active = item; + item++; + } + } + + if (nm_utils_security_valid (NMU_SEC_WPA_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0) || + nm_utils_security_valid (NMU_SEC_WPA2_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { + WirelessSecurityWPAPSK *ws_wpa_psk; + + ws_wpa_psk = ws_wpa_psk_new (connection, FALSE); + if (ws_wpa_psk) { + add_security_item (page, WIRELESS_SECURITY (ws_wpa_psk), sec_model, + &iter, _("WPA & WPA2 Personal"), FALSE); + if ((active < 0) && ((default_type == NMU_SEC_WPA_PSK) || (default_type == NMU_SEC_WPA2_PSK))) + active = item; + item++; + } + } + + if (nm_utils_security_valid (NMU_SEC_WPA_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0) || + nm_utils_security_valid (NMU_SEC_WPA2_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) { + WirelessSecurityWPAEAP *ws_wpa_eap; + + ws_wpa_eap = ws_wpa_eap_new (connection, TRUE, FALSE); + if (ws_wpa_eap) { + add_security_item (page, WIRELESS_SECURITY (ws_wpa_eap), sec_model, + &iter, _("WPA & WPA2 Enterprise"), FALSE); + if ((active < 0) && ((default_type == NMU_SEC_WPA_ENTERPRISE) || (default_type == NMU_SEC_WPA2_ENTERPRISE))) + active = item; + item++; + } + } + + gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sec_model)); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", S_NAME_COLUMN, NULL); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_sensitive, &page->adhoc, NULL); + + gtk_combo_box_set_active (combo, active < 0 ? 0 : (guint32) active); + g_object_unref (G_OBJECT (sec_model)); + + page->security_combo = combo; + + security_combo_changed (combo, page); + g_signal_connect (combo, "changed", + G_CALLBACK (security_combo_changed), page); +} + +static gboolean +validate (CEPage *page, + NMConnection *connection, + GError **error) +{ + NMSettingWireless *sw; + WirelessSecurity *sec; + gboolean valid = FALSE; + const char *mode; + + sw = nm_connection_get_setting_wireless (connection); + + mode = nm_setting_wireless_get_mode (sw); + if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) + CE_PAGE_SECURITY (page)->adhoc = TRUE; + else + CE_PAGE_SECURITY (page)->adhoc = FALSE; + + sec = security_combo_get_active (CE_PAGE_SECURITY (page)); + if (sec) { + GBytes *ssid = nm_setting_wireless_get_ssid (sw); + + if (ssid) { + /* FIXME: get failed property and error out of wifi security objects */ + valid = wireless_security_validate (sec, error); + if (valid) + wireless_security_fill_connection (sec, connection); + } else { + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING, "Missing SSID"); + valid = FALSE; + } + + if (CE_PAGE_SECURITY (page)->adhoc) { + if (!wireless_security_adhoc_compatible (sec)) { + if (valid) + g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, "Security not compatible with Ad-Hoc mode"); + valid = FALSE; + } + } + + wireless_security_unref (sec); + } else { + /* No security, unencrypted */ + nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X); + valid = TRUE; + } + + return valid; +} + +static void +ce_page_security_init (CEPageSecurity *page) +{ +} + +static void +dispose (GObject *object) +{ + CEPageSecurity *page = CE_PAGE_SECURITY (object); + + g_clear_object (&page->group); + + G_OBJECT_CLASS (ce_page_security_parent_class)->dispose (object); +} + +static void +ce_page_security_class_init (CEPageSecurityClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + CEPageClass *page_class = CE_PAGE_CLASS (class); + + object_class->dispose = dispose; + page_class->validate = validate; +} + +CEPage * +ce_page_security_new (NMConnection *connection, + NMClient *client) +{ + CEPageSecurity *page; + NMUtilsSecurityType default_type = NMU_SEC_NONE; + NMSettingWirelessSecurity *sws; + + page = CE_PAGE_SECURITY (ce_page_new (CE_TYPE_PAGE_SECURITY, + connection, + client, + "/org/gnome/control-center/network/security-page.ui", + _("Security"))); + + sws = nm_connection_get_setting_wireless_security (connection); + if (sws) + default_type = get_default_type_for_security (sws); + + if (default_type == NMU_SEC_STATIC_WEP || + default_type == NMU_SEC_LEAP || + default_type == NMU_SEC_WPA_PSK || + default_type == NMU_SEC_WPA2_PSK) { + CE_PAGE (page)->security_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; + } + + if (default_type == NMU_SEC_DYNAMIC_WEP || + default_type == NMU_SEC_WPA_ENTERPRISE || + default_type == NMU_SEC_WPA2_ENTERPRISE) { + CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME; + } + + g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL); + + return CE_PAGE (page); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-security.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 security. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_SECURITY_H +#define __CE_PAGE_SECURITY_H + +#include + +#include +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_SECURITY (ce_page_security_get_type ()) +#define CE_PAGE_SECURITY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_SECURITY, CEPageSecurity)) +#define CE_PAGE_SECURITY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_SECURITY, CEPageSecurityClass)) +#define CE_IS_PAGE_SECURITY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_SECURITY)) +#define CE_IS_PAGE_SECURITY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_SECURITY)) +#define CE_PAGE_SECURITY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_SECURITY, CEPageSecurityClass)) + +typedef struct _CEPageSecurity CEPageSecurity; +typedef struct _CEPageSecurityClass CEPageSecurityClass; + +struct _CEPageSecurity +{ + CEPage parent; + + GtkComboBox *security_combo; + GtkWidget *security_heading; + GtkSizeGroup *group; + gboolean adhoc; +}; + +struct _CEPageSecurityClass +{ + CEPageClass parent_class; +}; + +GType ce_page_security_get_type (void); + +CEPage *ce_page_security_new (NMConnection *connection, + NMClient *client); + +G_END_DECLS + +#endif /* __CE_PAGE_SECURITY_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,198 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2013 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "ce-page-vpn.h" +#include "vpn-helpers.h" + +G_DEFINE_TYPE (CEPageVpn, ce_page_vpn, CE_TYPE_PAGE) + +/* Hack to make the plugin-provided editor widget fit in better with + * the control center by changing + * + * Foo: [__________] + * Bar baz: [__________] + * + * to + * + * Foo [__________] + * Bar baz [__________] + */ +static void +vpn_gnome3ify_editor (GtkWidget *widget) +{ + if (GTK_IS_CONTAINER (widget)) { + GList *children, *iter; + + children = gtk_container_get_children (GTK_CONTAINER (widget)); + for (iter = children; iter; iter = iter->next) + vpn_gnome3ify_editor (iter->data); + g_list_free (children); + } else if (GTK_IS_LABEL (widget)) { + const char *text; + gfloat xalign; + char *newtext; + int len; + + xalign = gtk_label_get_xalign (GTK_LABEL (widget)); + if (xalign != 0.0) + return; + text = gtk_label_get_text (GTK_LABEL (widget)); + len = strlen (text); + if (len < 2 || text[len - 1] != ':') + return; + + newtext = g_strndup (text, len - 1); + gtk_label_set_text (GTK_LABEL (widget), newtext); + g_free (newtext); + gtk_label_set_xalign (GTK_LABEL (widget), 1.0); + } +} + +static void +load_vpn_plugin (CEPageVpn *page, NMConnection *connection) +{ + CEPage *parent = CE_PAGE (page); + GtkWidget *ui_widget, *failure; + + page->editor = nm_vpn_editor_plugin_get_editor (page->plugin, + connection, + NULL); + ui_widget = NULL; + if (page->editor) + ui_widget = GTK_WIDGET (nm_vpn_editor_get_widget (page->editor)); + + if (!ui_widget) { + g_clear_object (&page->editor); + page->plugin = NULL; + return; + } + vpn_gnome3ify_editor (ui_widget); + + failure = GTK_WIDGET (gtk_builder_get_object (parent->builder, "failure_label")); + gtk_widget_destroy (failure); + + gtk_box_pack_start (page->box, ui_widget, TRUE, TRUE, 0); + gtk_widget_show_all (ui_widget); + + g_signal_connect_swapped (page->editor, "changed", G_CALLBACK (ce_page_changed), page); +} + +static void +connect_vpn_page (CEPageVpn *page) +{ + const gchar *name; + + name = nm_setting_connection_get_id (page->setting_connection); + gtk_entry_set_text (page->name, name); + g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page); +} + +static gboolean +validate (CEPage *page, + NMConnection *connection, + GError **error) +{ + CEPageVpn *self = CE_PAGE_VPN (page); + + g_object_set (self->setting_connection, + NM_SETTING_CONNECTION_ID, gtk_entry_get_text (self->name), + NULL); + + if (!nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error)) + return FALSE; + + if (!self->editor) + return TRUE; + + return nm_vpn_editor_update_connection (self->editor, connection, error); +} + +static void +ce_page_vpn_init (CEPageVpn *page) +{ +} + +static void +dispose (GObject *object) +{ + CEPageVpn *page = CE_PAGE_VPN (object); + + g_clear_object (&page->editor); + + G_OBJECT_CLASS (ce_page_vpn_parent_class)->dispose (object); +} + +static void +ce_page_vpn_class_init (CEPageVpnClass *class) +{ + CEPageClass *page_class = CE_PAGE_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = dispose; + + page_class->validate = validate; +} + +static void +finish_setup (CEPageVpn *page, gpointer unused, GError *error, gpointer user_data) +{ + NMConnection *connection = CE_PAGE (page)->connection; + const char *vpn_type; + + page->setting_connection = nm_connection_get_setting_connection (connection); + page->setting_vpn = nm_connection_get_setting_vpn (connection); + vpn_type = nm_setting_vpn_get_service_type (page->setting_vpn); + + page->plugin = vpn_get_plugin_by_service (vpn_type); + if (page->plugin) + load_vpn_plugin (page, connection); + + connect_vpn_page (page); +} + +CEPage * +ce_page_vpn_new (NMConnection *connection, + NMClient *client) +{ + CEPageVpn *page; + + page = CE_PAGE_VPN (ce_page_new (CE_TYPE_PAGE_VPN, + connection, + client, + "/org/gnome/control-center/network/vpn-page.ui", + _("Identity"))); + + page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name")); + page->box = GTK_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "page")); + + g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL); + + CE_PAGE (page)->security_setting = NM_SETTING_VPN_SETTING_NAME; + + return CE_PAGE (page); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-vpn.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2013 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 vpn. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_VPN_H +#define __CE_PAGE_VPN_H + +#include + +#include + +#include +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_VPN (ce_page_vpn_get_type ()) +#define CE_PAGE_VPN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_VPN, CEPageVpn)) +#define CE_PAGE_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_VPN, CEPageVpnClass)) +#define CE_IS_PAGE_VPN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_VPN)) +#define CE_IS_PAGE_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_VPN)) +#define CE_PAGE_VPN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_VPN, CEPageVpnClass)) + +typedef struct _CEPageVpn CEPageVpn; +typedef struct _CEPageVpnClass CEPageVpnClass; + +struct _CEPageVpn +{ + CEPage parent; + + NMSettingConnection *setting_connection; + NMSettingVpn *setting_vpn; + + GtkEntry *name; + GtkBox *box; + + NMVpnEditorPlugin *plugin; + NMVpnEditor *editor; +}; + +struct _CEPageVpnClass +{ + CEPageClass parent_class; +}; + +GType ce_page_vpn_get_type (void); + +CEPage *ce_page_vpn_new (NMConnection *connection, + NMClient *client); + +G_END_DECLS + +#endif /* __CE_PAGE_VPN_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,201 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include + +#include "ce-page-wifi.h" +#include "ui-helpers.h" + +G_DEFINE_TYPE (CEPageWifi, ce_page_wifi, CE_TYPE_PAGE) + +static void +connect_wifi_page (CEPageWifi *page) +{ + GtkWidget *widget; + GBytes *ssid; + gchar *utf8_ssid; + GPtrArray *bssid_array; + gchar **bssid_list; + const char *s_bssid_str; + gchar **mac_list; + const gchar *s_mac_str; + const gchar *cloned_mac; + gint i; + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, + "entry_ssid")); + + ssid = nm_setting_wireless_get_ssid (page->setting); + if (ssid) + utf8_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); + else + utf8_ssid = g_strdup (""); + gtk_entry_set_text (GTK_ENTRY (widget), utf8_ssid); + g_free (utf8_ssid); + + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, + "combo_bssid")); + + bssid_array = g_ptr_array_new (); + for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (page->setting); i++) { + g_ptr_array_add (bssid_array, g_strdup (nm_setting_wireless_get_seen_bssid (page->setting, i))); + } + g_ptr_array_add (bssid_array, NULL); + bssid_list = (gchar **) g_ptr_array_free (bssid_array, FALSE); + s_bssid_str = nm_setting_wireless_get_bssid (page->setting); + ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_bssid_str, bssid_list); + g_strfreev (bssid_list); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, + "combo_mac")); + mac_list = ce_page_get_mac_list (CE_PAGE (page)->client, NM_TYPE_DEVICE_WIFI, + NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS); + s_mac_str = nm_setting_wireless_get_mac_address (page->setting); + ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_mac_str, mac_list); + g_strfreev (mac_list); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); + + + widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, + "entry_cloned_mac")); + cloned_mac = nm_setting_wireless_get_cloned_mac_address (page->setting); + gtk_entry_set_text (GTK_ENTRY (widget), cloned_mac ? cloned_mac : ""); + g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page); +} + +static void +ui_to_setting (CEPageWifi *page) +{ + GBytes *ssid; + const gchar *utf8_ssid, *bssid; + GtkWidget *entry; + char *device_mac, *cloned_mac; + + entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_ssid")); + utf8_ssid = gtk_entry_get_text (GTK_ENTRY (entry)); + if (!utf8_ssid || !*utf8_ssid) + ssid = NULL; + else { + ssid = g_bytes_new_static (utf8_ssid, strlen (utf8_ssid)); + } + entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_bssid"))); + bssid = gtk_entry_get_text (GTK_ENTRY (entry)); + if (*bssid == '\0') + bssid = NULL; + entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac"))); + device_mac = ce_page_trim_address (gtk_entry_get_text (GTK_ENTRY (entry))); + entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac")); + cloned_mac = ce_page_trim_address (gtk_entry_get_text (GTK_ENTRY (entry))); + + g_object_set (page->setting, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_BSSID, bssid, + NM_SETTING_WIRELESS_MAC_ADDRESS, device_mac, + NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, cloned_mac, + NULL); + + if (ssid) + g_bytes_unref (ssid); + g_free (cloned_mac); + g_free (device_mac); +} + +static gboolean +validate (CEPage *page, + NMConnection *connection, + GError **error) +{ + GtkWidget *entry; + gboolean ret = TRUE; + + entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_bssid"))); + if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { + widget_set_error (entry); + ret = FALSE; + } else { + widget_unset_error (entry); + } + + entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_mac"))); + if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { + widget_set_error (entry); + ret = FALSE; + } else { + widget_unset_error (entry); + } + + entry = GTK_WIDGET (gtk_builder_get_object (page->builder, "entry_cloned_mac")); + if (!ce_page_address_is_valid (gtk_entry_get_text (GTK_ENTRY (entry)))) { + widget_set_error (entry); + ret = FALSE; + } else { + widget_unset_error (entry); + } + + if (!ret) + return ret; + + ui_to_setting (CE_PAGE_WIFI (page)); + + return ret; +} + +static void +ce_page_wifi_init (CEPageWifi *page) +{ +} + +static void +ce_page_wifi_class_init (CEPageWifiClass *class) +{ + CEPageClass *page_class= CE_PAGE_CLASS (class); + + page_class->validate = validate; +} + +CEPage * +ce_page_wifi_new (NMConnection *connection, + NMClient *client) +{ + CEPageWifi *page; + + page = CE_PAGE_WIFI (ce_page_new (CE_TYPE_PAGE_WIFI, + connection, + client, + "/org/gnome/control-center/network/wifi-page.ui", + _("Identity"))); + + page->setting = nm_connection_get_setting_wireless (connection); + + connect_wifi_page (page); + + return CE_PAGE (page); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ce-page-wifi.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 wifi. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __CE_PAGE_WIFI_H +#define __CE_PAGE_WIFI_H + +#include + +#include +#include "ce-page.h" + +G_BEGIN_DECLS + +#define CE_TYPE_PAGE_WIFI (ce_page_wifi_get_type ()) +#define CE_PAGE_WIFI(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_WIFI, CEPageWifi)) +#define CE_PAGE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_WIFI, CEPageWifiClass)) +#define CE_IS_PAGE_WIFI(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_WIFI)) +#define CE_IS_PAGE_WIFI_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_WIFI)) +#define CE_PAGE_WIFI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_WIFI, CEPageWifiClass)) + +typedef struct _CEPageWifi CEPageWifi; +typedef struct _CEPageWifiClass CEPageWifiClass; + +struct _CEPageWifi +{ + CEPage parent; + + NMSettingWireless *setting; +}; + +struct _CEPageWifiClass +{ + CEPageClass parent_class; +}; + +GType ce_page_wifi_get_type (void); + +CEPage *ce_page_wifi_new (NMConnection *connection, + NMClient *client); + +G_END_DECLS + +#endif /* __CE_PAGE_WIFI_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.gresource.xml unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.gresource.xml --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.gresource.xml 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.gresource.xml 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,14 @@ + + + + 8021x-security-page.ui + connection-editor.ui + details-page.ui + ethernet-page.ui + ip4-page.ui + ip6-page.ui + security-page.ui + vpn-page.ui + wifi-page.ui + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/connection-editor.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,130 @@ + + + + + False + 0 + False + True + 500 + 300 + dialog + 1 + + + _Cancel + True + True + True + True + + + + + _Apply + True + True + True + True + True + + + + + False + vertical + 0 + 0 + + + True + True + False + False + + + True + False + + + True + True + False + + + + + + + True + False + page 1 + + + False + + + + + True + False + + + True + False + vertical + + + 300 + True + False + 0 + in + + + + + + False + True + 0 + + + + + True + False + 0 + + + + + 1 + + + + + True + False + page 2 + + + 1 + False + + + + + True + True + 1 + + + + + + details_cancel_button + details_apply_button + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/details-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/details-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/details-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/details-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,379 @@ + + + + + True + False + 24 + 24 + 24 + 24 + 12 + 12 + + + True + False + 1 + Signal Strength + label_strength + + + + 0 + 0 + 1 + 1 + + + + + True + True + True + 0 + Weak + True + + + 1 + 0 + 1 + 1 + + + + + True + False + 1 + Link speed + label_speed + + + + 0 + 1 + 1 + 1 + + + + + True + True + 0 + 1Mb/sec + True + True + + + 1 + 1 + 1 + 1 + + + + + True + False + 1 + Security + label_security + + + + 0 + 2 + 1 + 1 + + + + + True + False + 1 + IPv4 Address + label_ipv4 + + + + 0 + 3 + 1 + 1 + + + + + True + False + 1 + IPv6 Address + label_ipv6 + + + + 0 + 4 + 1 + 1 + + + + + True + False + 1 + Hardware Address + label_mac + + + + 0 + 5 + 1 + 1 + + + + + True + False + 1 + Default Route + label_route + + + + 0 + 6 + 1 + 1 + + + + + True + False + 1 + 0 + DNS + label_dns + + + + 0 + 7 + 1 + 1 + + + + + True + False + 1 + Last Used + label_last_used + + + + 0 + 8 + 1 + 1 + + + + + True + True + 0 + WPA + True + True + + + 1 + 2 + 1 + 1 + + + + + True + True + 0 + 127.0.0.1 + True + True + + + 1 + 3 + 1 + 1 + + + + + True + True + 0 + ::1 + True + True + + + 1 + 4 + 1 + 1 + + + + + True + True + 0 + AA:BB:CC:DD:55:66:77:88 + True + True + + + 1 + 5 + 1 + 1 + + + + + True + True + 0 + 127.0.0.1 + True + True + + + 1 + 6 + 1 + 1 + + + + + True + True + 0 + 0 + 127.0.0.1 + True + True + True + + + 1 + 7 + 1 + 1 + + + + + True + True + 0 + today + True + True + + + 1 + 8 + 1 + 1 + + + + + Connect _automatically + True + True + False + end + True + 0 + True + 12 + + + 0 + 9 + 2 + 1 + + + + + Make available to _other users + True + True + False + True + 0 + True + + + 0 + 10 + 2 + 1 + + + + + True + True + True + True + True + end + end + + + + 0 + 11 + 2 + 1 + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ethernet-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ethernet-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ethernet-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ethernet-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,236 @@ + + + + + 10000 + 1 + 10 + + + + + + + + + Automatic + + + Twisted Pair (TP) + + + Attachment Unit Interface (AUI) + + + BNC + + + Media Independent Interface (MII) + + + + + + + + + + + Automatic + + + 10 Mb/s + + + 100 Mb/s + + + 1 Gb/s + + + 10 Gb/s + + + + + True + False + 50 + 50 + 12 + 12 + True + True + 10 + 6 + + + True + False + 1 + _Name + True + entry_name + + + 0 + 0 + 1 + 1 + + + + + True + True + + + + 1 + 0 + 1 + 1 + + + + + True + False + 1 + _MAC Address + True + combo_mac + + + 0 + 1 + 1 + 1 + + + + + True + False + True + 0 + 1 + + + 1 + 1 + 1 + 1 + + + + + True + True + True + + True + + + 1 + 2 + 1 + 1 + + + + + True + False + 1 + M_TU + True + spin_mtu + + + 0 + 3 + 1 + 1 + + + + + True + False + center + 1 + _Cloned Address + True + entry_cloned_mac + + + 0 + 2 + 1 + 1 + + + + + True + False + bytes + + + 2 + 3 + 1 + 1 + + + + + True + True + + True + adjustment1 + + + 1 + 3 + 1 + 1 + + + + + True + False + + + 2 + 0 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip4-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip4-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip4-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip4-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,428 @@ + + + + + True + True + never + + + True + False + + + True + False + 24 + 24 + 24 + 24 + vertical + 6 + 6 + + + True + False + IPv_4 Method + True + radio_disabled + 0.0 + + + + + + 0 + 0 + + + + + Automatic (DHCP) + True + True + False + True + + + 0 + 1 + + + + + Link-Local Only + True + True + False + True + radio_automatic + + + 0 + 2 + + + + + Manual + True + True + False + True + radio_automatic + + + 1 + 1 + + + + + Disable + True + True + False + True + radio_automatic + + + 1 + 2 + + + + + True + False + vertical + 6 + + + True + False + vertical + + + True + False + 0 + Addresses + 24 + 8 + + + + + + + + True + False + horizontal + + + True + False + True + Address + + + + + + + + + True + False + True + Netmask + + + + + + + + + True + False + True + Gateway + + + + + + + + + + + True + False + + + + + + + False + True + 1 + + + + + True + False + 24 + 6 + + + True + False + True + 0 + DNS + + + + + + + + True + False + True + 1 + Automatic + + + + + True + True + end + center + + + Automatic DNS + + + + + + + 2 + + + + + True + True + + + 3 + + + + + True + False + 0 + Separate IP addresses with commas + + + + + + + + + True + False + 24 + 6 + + + True + False + 0 + True + Routes + + + + + + + + True + False + True + 1 + Automatic + + + + + True + True + end + center + + + Automatic Routes + + + + + + + 5 + + + + + True + False + vertical + + + True + False + horizontal + + + True + False + True + Address + + + + + + + + + True + False + True + Netmask + + + + + + + + + True + False + True + Gateway + + + + + + + + + True + False + Metric + + + + + + + + + + + True + False + + + + + + + False + True + 6 + + + + + Use this connection _only for resources on its network + True + True + False + True + 0 + True + + + False + True + 7 + + + + + 2 + 0 + 3 + + + + + + + + + horizontal + + + + + + horizontal + + + + + + horizontal + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip6-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip6-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip6-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ip6-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,442 @@ + + + + + True + True + never + + + True + False + + + True + False + 24 + 24 + 24 + 24 + vertical + 6 + 6 + + + True + False + IPv_6 Method + True + radio_disabled + 0.0 + + + + + + 0 + 0 + + + + + Automatic + True + True + False + True + + + 0 + 1 + + + + + Automatic, DHCP only + True + True + False + True + radio_automatic + + + 0 + 2 + + + + + Link-Local Only + True + True + False + True + radio_automatic + + + 1 + 1 + + + + + Manual + True + True + False + True + radio_automatic + + + 1 + 2 + + + + + Disable + True + True + False + True + radio_automatic + + + 2 + 1 + + + + + True + False + vertical + 6 + + + True + False + vertical + + + True + False + 0 + Addresses + 24 + 8 + + + + + + + + True + False + horizontal + + + True + False + True + Address + + + + + + + + + True + False + True + Prefix + + + + + + + + + True + False + True + Gateway + + + + + + + + + + + True + False + + + + + + + False + True + 1 + + + + + True + False + 24 + 6 + + + True + False + True + 0 + DNS + + + + + + + + True + False + True + 1 + Automatic + + + + + True + True + end + center + + + Automatic DNS + + + + + + + 2 + + + + + True + True + + + 3 + + + + + True + False + 0 + Separate IP addresses with commas + + + + + + + + + True + False + 24 + 6 + + + True + False + 0 + True + Routes + + + + + + + + True + False + True + 1 + Automatic + + + + + True + True + end + center + + + Automatic Routes + + + + + + + 5 + + + + + True + False + vertical + + + True + False + horizontal + + + True + False + True + Address + + + + + + + + + True + False + True + Prefix + + + + + + + + + True + False + True + Gateway + + + + + + + + + True + False + Metric + + + + + + + + + + + True + False + + + + + + + False + True + 6 + + + + + Use this connection _only for resources on its network + True + True + False + True + 0 + True + + + False + True + 7 + + + + + 3 + 0 + 3 + + + + + + + + + horizontal + + + + + + horizontal + + + + + + horizontal + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/Makefile.am unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/Makefile.am --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/Makefile.am 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,54 @@ +noinst_LTLIBRARIES = libconnection-editor.la + +BUILT_SOURCES = \ + net-connection-editor-resources.c \ + net-connection-editor-resources.h + +libconnection_editor_la_SOURCES = \ + $(BUILT_SOURCES) \ + net-connection-editor.h \ + net-connection-editor.c \ + ce-page.h \ + ce-page.c \ + ce-page-details.h \ + ce-page-details.c \ + ce-page-wifi.h \ + ce-page-wifi.c \ + ce-page-ip4.h \ + ce-page-ip4.c \ + ce-page-ip6.h \ + ce-page-ip6.c \ + ce-page-security.h \ + ce-page-security.c \ + ce-page-ethernet.h \ + ce-page-ethernet.c \ + ce-page-8021x-security.h \ + ce-page-8021x-security.c \ + ce-page-vpn.h \ + ce-page-vpn.c \ + vpn-helpers.h \ + vpn-helpers.c \ + ui-helpers.h \ + ui-helpers.c + +libconnection_editor_la_CPPFLAGS = \ + $(PANEL_CFLAGS) \ + -I$(srcdir)/../wireless-security \ + $(NETWORK_PANEL_CFLAGS) \ + $(NETWORK_MANAGER_CFLAGS) + +libconnection_editor_la_LIBADD = \ + $(builddir)/../wireless-security/libwireless-security.la \ + $(NETWORK_PANEL_LIBS) \ + $(NETWORK_MANAGER_LIBS) + +resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/connection-editor.gresource.xml) +net-connection-editor-resources.c: connection-editor.gresource.xml $(resource_files) + $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name net_connection_editor $< +net-connection-editor-resources.h: connection-editor.gresource.xml $(resource_files) + $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name net_connection_editor $< + +EXTRA_DIST = \ + $(resource_files) connection-editor.gresource.xml + +-include $(top_srcdir)/git.mk diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,893 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "shell/list-box-helper.h" +#include "net-connection-editor.h" +#include "net-connection-editor-resources.h" +#include "ce-page-details.h" +#include "ce-page-wifi.h" +#include "ce-page-ip4.h" +#include "ce-page-ip6.h" +#include "ce-page-security.h" +#include "ce-page-ethernet.h" +#include "ce-page-8021x-security.h" +#include "ce-page-vpn.h" +#include "vpn-helpers.h" +#include "eap-method.h" + +enum { + DONE, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (NetConnectionEditor, net_connection_editor, G_TYPE_OBJECT) + +static void page_changed (CEPage *page, gpointer user_data); + +static void +cancel_editing (NetConnectionEditor *editor) +{ + gtk_widget_hide (editor->window); + g_signal_emit (editor, signals[DONE], 0, FALSE); +} + +static void +update_connection (NetConnectionEditor *editor) +{ + GVariant *settings; + + settings = nm_connection_to_dbus (editor->connection, NM_CONNECTION_SERIALIZE_ALL); + nm_connection_replace_settings (editor->orig_connection, settings, NULL); + g_variant_unref (settings); +} + +static void +update_complete (NetConnectionEditor *editor, + gboolean success) +{ + gtk_widget_hide (editor->window); + g_signal_emit (editor, signals[DONE], 0, success); +} + +static void +updated_connection_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NetConnectionEditor *editor; + GError *error = NULL; + gboolean success = TRUE; + + if (!nm_remote_connection_commit_changes_finish (NM_REMOTE_CONNECTION (source_object), + res, &error)) { + g_warning ("Failed to commit changes: %s", error->message); + success = FALSE; + g_error_free (error); + //return; FIXME return if cancelled + } + + nm_connection_clear_secrets (NM_CONNECTION (source_object)); + + editor = user_data; + update_complete (editor, success); +} + +static void +added_connection_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NetConnectionEditor *editor; + GError *error = NULL; + gboolean success = TRUE; + + if (!nm_client_add_connection_finish (NM_CLIENT (source_object), res, &error)) { + g_warning ("Failed to add connection: %s", error->message); + success = FALSE; + g_error_free (error); + /* Leave the editor open */ + // return; FIXME return if cancelled + } + + editor = user_data; + update_complete (editor, success); +} + +static void +apply_edits (NetConnectionEditor *editor) +{ + update_connection (editor); + + eap_method_ca_cert_ignore_save (editor->connection); + + if (editor->is_new_connection) { + nm_client_add_connection_async (editor->client, + editor->orig_connection, + TRUE, + NULL, + added_connection_cb, + editor); + } else { + nm_remote_connection_commit_changes_async (NM_REMOTE_CONNECTION (editor->orig_connection), + TRUE, + NULL, + updated_connection_cb, editor); + } +} + +static void +net_connection_editor_init (NetConnectionEditor *editor) +{ + GError *error = NULL; + + editor->builder = gtk_builder_new (); + + gtk_builder_add_from_resource (editor->builder, + "/org/gnome/control-center/network/connection-editor.ui", + &error); + if (error != NULL) { + g_warning ("Could not load ui file: %s", error->message); + g_error_free (error); + return; + } + + editor->window = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_dialog")); +} + +void +net_connection_editor_run (NetConnectionEditor *editor) +{ + GtkWidget *button; + + button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_cancel_button")); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (cancel_editing), editor); + g_signal_connect_swapped (editor->window, "delete-event", + G_CALLBACK (cancel_editing), editor); + + button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (apply_edits), editor); + + net_connection_editor_present (editor); +} + +static void +net_connection_editor_finalize (GObject *object) +{ + NetConnectionEditor *editor = NET_CONNECTION_EDITOR (object); + GSList *l; + + for (l = editor->pages; l != NULL; l = l->next) + g_signal_handlers_disconnect_by_func (l->data, page_changed, editor); + + if (editor->permission_id > 0 && editor->client) + g_signal_handler_disconnect (editor->client, editor->permission_id); + g_clear_object (&editor->connection); + g_clear_object (&editor->orig_connection); + if (editor->window) { + gtk_widget_destroy (editor->window); + editor->window = NULL; + } + g_clear_object (&editor->parent_window); + g_clear_object (&editor->builder); + g_clear_object (&editor->device); + g_clear_object (&editor->client); + g_clear_object (&editor->ap); + + G_OBJECT_CLASS (net_connection_editor_parent_class)->finalize (object); +} + +static void +net_connection_editor_class_init (NetConnectionEditorClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + g_resources_register (net_connection_editor_get_resource ()); + + object_class->finalize = net_connection_editor_finalize; + + signals[DONE] = g_signal_new ("done", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NetConnectionEditorClass, done), + NULL, NULL, + NULL, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); +} + +static void +net_connection_editor_error_dialog (NetConnectionEditor *editor, + const char *primary_text, + const char *secondary_text) +{ + GtkWidget *dialog; + GtkWindow *parent; + + if (gtk_widget_is_visible (editor->window)) + parent = GTK_WINDOW (editor->window); + else + parent = GTK_WINDOW (editor->parent_window); + + dialog = gtk_message_dialog_new (parent, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "%s", primary_text); + + if (secondary_text) { + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", secondary_text); + } + + g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); + g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); + gtk_dialog_run (GTK_DIALOG (dialog)); +} + +static void +net_connection_editor_do_fallback (NetConnectionEditor *editor, const gchar *type) +{ + gchar *cmdline; + GError *error = NULL; + + if (editor->is_new_connection) { + cmdline = g_strdup_printf ("nm-connection-editor --type='%s' --create", type); + } else { + cmdline = g_strdup_printf ("nm-connection-editor --edit='%s'", + nm_connection_get_uuid (editor->connection)); + } + + g_spawn_command_line_async (cmdline, &error); + g_free (cmdline); + + if (error) { + net_connection_editor_error_dialog (editor, + _("Unable to open connection editor"), + error->message); + g_error_free (error); + } + + g_signal_emit (editor, signals[DONE], 0, FALSE); +} + +static void +net_connection_editor_update_title (NetConnectionEditor *editor) +{ + gchar *id; + + if (editor->title_set) + return; + + if (editor->is_new_connection) { + if (editor->device) { + id = g_strdup (_("New Profile")); + } else { + /* Leave it set to "Add New Connection" */ + return; + } + } else { + NMSettingWireless *sw; + sw = nm_connection_get_setting_wireless (editor->connection); + if (sw) { + GBytes *ssid; + ssid = nm_setting_wireless_get_ssid (sw); + id = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); + } else { + id = g_strdup (nm_connection_get_id (editor->connection)); + } + } + gtk_window_set_title (GTK_WINDOW (editor->window), id); + g_free (id); +} + +static gboolean +editor_is_initialized (NetConnectionEditor *editor) +{ + return editor->initializing_pages == NULL; +} + +static void +update_sensitivity (NetConnectionEditor *editor) +{ + NMSettingConnection *sc; + gboolean sensitive; + GtkWidget *widget; + GSList *l; + + if (!editor_is_initialized (editor)) + return; + + sc = nm_connection_get_setting_connection (editor->connection); + + if (nm_setting_connection_get_read_only (sc)) { + sensitive = FALSE; + } else { + sensitive = editor->can_modify; + } + + for (l = editor->pages; l; l = l->next) { + widget = ce_page_get_page (CE_PAGE (l->data)); + gtk_widget_set_sensitive (widget, sensitive); + } +} + +static void +validate (NetConnectionEditor *editor) +{ + gboolean valid = FALSE; + GSList *l; + + if (!editor_is_initialized (editor)) + goto done; + + valid = TRUE; + for (l = editor->pages; l; l = l->next) { + GError *error = NULL; + + if (!ce_page_validate (CE_PAGE (l->data), editor->connection, &error)) { + valid = FALSE; + if (error) { + g_debug ("Invalid setting %s: %s", ce_page_get_title (CE_PAGE (l->data)), error->message); + g_error_free (error); + } else { + g_debug ("Invalid setting %s", ce_page_get_title (CE_PAGE (l->data))); + } + } + } + + update_sensitivity (editor); +done: + gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")), valid && editor->is_changed); +} + +static void +page_changed (CEPage *page, gpointer user_data) +{ + NetConnectionEditor *editor= user_data; + + if (editor_is_initialized (editor)) + editor->is_changed = TRUE; + validate (editor); +} + +static gboolean +idle_validate (gpointer user_data) +{ + validate (NET_CONNECTION_EDITOR (user_data)); + + return G_SOURCE_REMOVE; +} + +static void +recheck_initialization (NetConnectionEditor *editor) +{ + GtkNotebook *notebook; + + if (!editor_is_initialized (editor)) + return; + + notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_notebook")); + gtk_notebook_set_current_page (notebook, 0); + + if (editor->show_when_initialized) + gtk_window_present (GTK_WINDOW (editor->window)); + + g_idle_add (idle_validate, editor); +} + +static void +page_initialized (CEPage *page, GError *error, NetConnectionEditor *editor) +{ + GtkNotebook *notebook; + GtkWidget *widget; + GtkWidget *label; + gint position; + GList *children, *l; + gint i; + + notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_notebook")); + widget = ce_page_get_page (page); + position = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (page), "position")); + g_object_set_data (G_OBJECT (widget), "position", GINT_TO_POINTER (position)); + children = gtk_container_get_children (GTK_CONTAINER (notebook)); + for (l = children, i = 0; l; l = l->next, i++) { + gint pos = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (l->data), "position")); + if (pos > position) + break; + } + g_list_free (children); + + label = gtk_label_new (ce_page_get_title (page)); + + gtk_notebook_insert_page (notebook, widget, label, i); + + editor->initializing_pages = g_slist_remove (editor->initializing_pages, page); + editor->pages = g_slist_append (editor->pages, page); + + recheck_initialization (editor); +} + +typedef struct { + NetConnectionEditor *editor; + CEPage *page; + const gchar *setting_name; +} GetSecretsInfo; + +static void +get_secrets_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NMRemoteConnection *connection; + GetSecretsInfo *info = user_data; + GError *error = NULL; + GVariant *variant; + + connection = NM_REMOTE_CONNECTION (source_object); + variant = nm_remote_connection_get_secrets_finish (connection, res, &error); + + if (!variant && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free (error); + g_free (info); + return; + } + + ce_page_complete_init (info->page, info->setting_name, variant, error); + g_variant_unref (variant); + g_free (info); +} + +static void +get_secrets_for_page (NetConnectionEditor *editor, + CEPage *page, + const gchar *setting_name) +{ + GetSecretsInfo *info; + + info = g_new0 (GetSecretsInfo, 1); + info->editor = editor; + info->page = page; + info->setting_name = setting_name; + + nm_remote_connection_get_secrets_async (NM_REMOTE_CONNECTION (editor->orig_connection), + setting_name, + NULL, //FIXME + get_secrets_cb, + info); +} + +static void +add_page (NetConnectionEditor *editor, CEPage *page) +{ + gint position; + + position = g_slist_length (editor->initializing_pages); + g_object_set_data (G_OBJECT (page), "position", GINT_TO_POINTER (position)); + + editor->initializing_pages = g_slist_append (editor->initializing_pages, page); + + g_signal_connect (page, "changed", G_CALLBACK (page_changed), editor); + g_signal_connect (page, "initialized", G_CALLBACK (page_initialized), editor); +} + +static void +net_connection_editor_set_connection (NetConnectionEditor *editor, + NMConnection *connection) +{ + GSList *pages, *l; + NMSettingConnection *sc; + const gchar *type; + gboolean is_wired; + gboolean is_wifi; + gboolean is_vpn; + + editor->is_new_connection = !nm_client_get_connection_by_uuid (editor->client, + nm_connection_get_uuid (connection)); + + if (editor->is_new_connection) { + GtkWidget *button; + + button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")); + gtk_button_set_label (GTK_BUTTON (button), _("_Add")); + editor->is_changed = TRUE; + } + + editor->connection = nm_simple_connection_new_clone (connection); + editor->orig_connection = g_object_ref (connection); + + net_connection_editor_update_title (editor); + + eap_method_ca_cert_ignore_load (editor->connection); + + sc = nm_connection_get_setting_connection (connection); + type = nm_setting_connection_get_connection_type (sc); + + is_wired = g_str_equal (type, NM_SETTING_WIRED_SETTING_NAME); + is_wifi = g_str_equal (type, NM_SETTING_WIRELESS_SETTING_NAME); + is_vpn = g_str_equal (type, NM_SETTING_VPN_SETTING_NAME); + + if (!editor->is_new_connection) + add_page (editor, ce_page_details_new (editor->connection, editor->client, editor->device, editor->ap, editor)); + + if (is_wifi) + add_page (editor, ce_page_wifi_new (editor->connection, editor->client)); + else if (is_wired) + add_page (editor, ce_page_ethernet_new (editor->connection, editor->client)); + else if (is_vpn) + add_page (editor, ce_page_vpn_new (editor->connection, editor->client)); + else { + /* Unsupported type */ + net_connection_editor_do_fallback (editor, type); + return; + } + + add_page (editor, ce_page_ip4_new (editor->connection, editor->client)); + add_page (editor, ce_page_ip6_new (editor->connection, editor->client)); + + if (is_wifi) + add_page (editor, ce_page_security_new (editor->connection, editor->client)); + else if (is_wired) + add_page (editor, ce_page_8021x_security_new (editor->connection, editor->client)); + + pages = g_slist_copy (editor->initializing_pages); + for (l = pages; l; l = l->next) { + CEPage *page = l->data; + const gchar *security_setting; + + security_setting = ce_page_get_security_setting (page); + if (!security_setting || editor->is_new_connection) { + ce_page_complete_init (page, NULL, NULL, NULL); + } else { + get_secrets_for_page (editor, page, security_setting); + } + } + g_slist_free (pages); +} + +static NMConnection * +complete_vpn_connection (NetConnectionEditor *editor, NMConnection *connection) +{ + NMSettingConnection *s_con; + NMSetting *s_type; + + if (!connection) + connection = nm_simple_connection_new (); + + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) { + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + } + + if (!nm_setting_connection_get_uuid (s_con)) { + gchar *uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_UUID, uuid, + NULL); + g_free (uuid); + } + + if (!nm_setting_connection_get_id (s_con)) { + const GPtrArray *connections; + gchar *id; + + connections = nm_client_get_connections (editor->client); + id = ce_page_get_next_available_name (connections, NAME_FORMAT_TYPE, _("VPN")); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, id, + NULL); + g_free (id); + } + + s_type = nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); + if (!s_type) { + s_type = g_object_new (NM_TYPE_SETTING_VPN, NULL); + nm_connection_add_setting (connection, s_type); + } + + if (!nm_setting_connection_get_connection_type (s_con)) { + g_object_set (s_con, + NM_SETTING_CONNECTION_TYPE, nm_setting_get_name (s_type), + NULL); + } + + return connection; +} + +static void +finish_add_connection (NetConnectionEditor *editor, NMConnection *connection) +{ + GtkNotebook *notebook; + GtkBin *frame; + + frame = GTK_BIN (gtk_builder_get_object (editor->builder, "details_add_connection_frame")); + gtk_widget_destroy (gtk_bin_get_child (frame)); + + notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_toplevel_notebook")); + gtk_notebook_set_current_page (notebook, 0); + gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button"))); + + if (connection) + net_connection_editor_set_connection (editor, connection); +} + +static void +vpn_import_complete (NMConnection *connection, gpointer user_data) +{ + NetConnectionEditor *editor = user_data; + + if (!connection) { + /* The import code shows its own error dialogs. */ + g_signal_emit (editor, signals[DONE], 0, FALSE); + return; + } + + complete_vpn_connection (editor, connection); + finish_add_connection (editor, connection); +} + +static void +vpn_type_activated (GtkListBox *list, GtkWidget *row, NetConnectionEditor *editor) +{ + const char *service_name = g_object_get_data (G_OBJECT (row), "service_name"); + NMConnection *connection; + NMSettingVpn *s_vpn; + NMSettingConnection *s_con; + + if (!strcmp (service_name, "import")) { + vpn_import (GTK_WINDOW (editor->window), vpn_import_complete, editor); + return; + } + + connection = complete_vpn_connection (editor, NULL); + s_vpn = nm_connection_get_setting_vpn (connection); + g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_name, NULL); + + /* Mark the connection as private to this user, and non-autoconnect */ + s_con = nm_connection_get_setting_connection (connection); + g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL); + nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL); + + finish_add_connection (editor, connection); +} + +static void +select_vpn_type (NetConnectionEditor *editor, GtkListBox *list) +{ + GSList *vpn_plugins, *iter; + GList *l; + GList *children; + GtkWidget *row, *row_box; + GtkWidget *name_label, *desc_label; + + /* Get the available VPN types */ + vpn_plugins = vpn_get_plugins (); + + /* Remove the previous menu contents */ + children = gtk_container_get_children (GTK_CONTAINER (list)); + for (l = children; l != NULL; l = l->next) + gtk_widget_destroy (l->data); + + /* Add the VPN types */ + for (iter = vpn_plugins; iter; iter = iter->next) { + NMVpnEditorPlugin *plugin = nm_vpn_plugin_info_get_editor_plugin (iter->data); + char *name, *desc, *desc_markup, *service_name; + GtkStyleContext *context; + + g_object_get (plugin, + NM_VPN_EDITOR_PLUGIN_NAME, &name, + NM_VPN_EDITOR_PLUGIN_DESCRIPTION, &desc, + NM_VPN_EDITOR_PLUGIN_SERVICE, &service_name, + NULL); + desc_markup = g_markup_printf_escaped ("%s", desc); + + row = gtk_list_box_row_new (); + + row_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_widget_set_margin_start (row_box, 12); + gtk_widget_set_margin_end (row_box, 12); + gtk_widget_set_margin_top (row_box, 12); + gtk_widget_set_margin_bottom (row_box, 12); + + name_label = gtk_label_new (name); + gtk_widget_set_halign (name_label, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (row_box), name_label, FALSE, TRUE, 0); + + desc_label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (desc_label), desc_markup); + gtk_label_set_line_wrap (GTK_LABEL (desc_label), TRUE); + gtk_widget_set_halign (desc_label, GTK_ALIGN_START); + context = gtk_widget_get_style_context (desc_label); + gtk_style_context_add_class (context, "dim-label"); + gtk_box_pack_start (GTK_BOX (row_box), desc_label, FALSE, TRUE, 0); + + g_free (name); + g_free (desc); + g_free (desc_markup); + + gtk_container_add (GTK_CONTAINER (row), row_box); + gtk_widget_show_all (row); + g_object_set_data_full (G_OBJECT (row), "service_name", service_name, g_free); + gtk_container_add (GTK_CONTAINER (list), row); + } + + /* Import */ + row = gtk_list_box_row_new (); + + row_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); + gtk_widget_set_margin_start (row_box, 12); + gtk_widget_set_margin_end (row_box, 12); + gtk_widget_set_margin_top (row_box, 12); + gtk_widget_set_margin_bottom (row_box, 12); + + name_label = gtk_label_new (_("Import from file…")); + gtk_widget_set_halign (name_label, GTK_ALIGN_START); + gtk_box_pack_start (GTK_BOX (row_box), name_label, FALSE, TRUE, 0); + + gtk_container_add (GTK_CONTAINER (row), row_box); + gtk_widget_show_all (row); + g_object_set_data (G_OBJECT (row), "service_name", "import"); + gtk_container_add (GTK_CONTAINER (list), row); + + g_signal_connect (list, "row-activated", + G_CALLBACK (vpn_type_activated), editor); +} + +static void +net_connection_editor_add_connection (NetConnectionEditor *editor) +{ + GtkNotebook *notebook; + GtkContainer *frame; + GtkListBox *list; + + notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_toplevel_notebook")); + frame = GTK_CONTAINER (gtk_builder_get_object (editor->builder, "details_add_connection_frame")); + + list = GTK_LIST_BOX (gtk_list_box_new ()); + gtk_list_box_set_selection_mode (list, GTK_SELECTION_NONE); + gtk_list_box_set_header_func (list, cc_list_box_update_header_func, NULL, NULL); + + select_vpn_type (editor, list); + + gtk_widget_show_all (GTK_WIDGET (list)); + gtk_container_add (frame, GTK_WIDGET (list)); + + gtk_notebook_set_current_page (notebook, 1); + gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button"))); + gtk_window_set_title (GTK_WINDOW (editor->window), _("Add VPN")); +} + +static void +permission_changed (NMClient *client, + NMClientPermission permission, + NMClientPermissionResult result, + NetConnectionEditor *editor) +{ + if (permission != NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM) + return; + + if (result == NM_CLIENT_PERMISSION_RESULT_YES || result == NM_CLIENT_PERMISSION_RESULT_AUTH) + editor->can_modify = TRUE; + else + editor->can_modify = FALSE; + + validate (editor); +} + +NetConnectionEditor * +net_connection_editor_new (GtkWindow *parent_window, + NMConnection *connection, + NMDevice *device, + NMAccessPoint *ap, + NMClient *client) +{ + NetConnectionEditor *editor; + + editor = g_object_new (NET_TYPE_CONNECTION_EDITOR, NULL); + + if (parent_window) { + editor->parent_window = g_object_ref (parent_window); + gtk_window_set_transient_for (GTK_WINDOW (editor->window), + parent_window); + } + if (ap) + editor->ap = g_object_ref (ap); + if (device) + editor->device = g_object_ref (device); + editor->client = g_object_ref (client); + + editor->can_modify = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM); + editor->permission_id = g_signal_connect (editor->client, "permission-changed", + G_CALLBACK (permission_changed), editor); + + if (connection) + net_connection_editor_set_connection (editor, connection); + else + net_connection_editor_add_connection (editor); + + return editor; +} + +void +net_connection_editor_present (NetConnectionEditor *editor) +{ + if (!editor_is_initialized (editor)) { + editor->show_when_initialized = TRUE; + return; + } + gtk_window_present (GTK_WINDOW (editor->window)); +} + +static void +forgotten_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NMRemoteConnection *connection = NM_REMOTE_CONNECTION (source_object); + NetConnectionEditor *editor = user_data; + GError *error = NULL; + + if (!nm_remote_connection_delete_finish (connection, res, &error)) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to delete connection %s: %s", + nm_connection_get_id (NM_CONNECTION (connection)), + error->message); + g_error_free (error); + return; + } + + cancel_editing (editor); +} + +void +net_connection_editor_forget (NetConnectionEditor *editor) +{ + nm_remote_connection_delete_async (NM_REMOTE_CONNECTION (editor->orig_connection), + NULL, forgotten_cb, editor); +} + +void +net_connection_editor_reset (NetConnectionEditor *editor) +{ + GVariant *settings; + + settings = nm_connection_to_dbus (editor->orig_connection, NM_CONNECTION_SERIALIZE_ALL); + nm_connection_replace_settings (editor->connection, settings, NULL); + g_variant_unref (settings); +} + +void +net_connection_editor_set_title (NetConnectionEditor *editor, + const gchar *title) +{ + gtk_window_set_title (GTK_WINDOW (editor->window), title); + editor->title_set = TRUE; +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/net-connection-editor.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,92 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __NET_CONNECTION_EDITOR_H +#define __NET_CONNECTION_EDITOR_H + +#include + +#include +#include + +G_BEGIN_DECLS + +#define NET_TYPE_CONNECTION_EDITOR (net_connection_editor_get_type ()) +#define NET_CONNECTION_EDITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditor)) +#define NET_CONNECTION_EDITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditorClass)) +#define NET_IS_CONNECTION_EDITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_CONNECTION_EDITOR)) +#define NET_IS_CONNECTION_EDITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_CONNECTION_EDITOR)) +#define NET_CONNECTION_EDITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_CONNECTION_EDITOR, NetConnectionEditorClass)) + +typedef struct _NetConnectionEditor NetConnectionEditor; +typedef struct _NetConnectionEditorClass NetConnectionEditorClass; + +struct _NetConnectionEditor +{ + GObject parent; + + GtkWidget *parent_window; + NMClient *client; + NMDevice *device; + + NMConnection *connection; + NMConnection *orig_connection; + gboolean is_new_connection; + gboolean is_changed; + NMAccessPoint *ap; + + GtkBuilder *builder; + GtkWidget *window; + + GSList *initializing_pages; + GSList *pages; + + guint permission_id; + NMClientPermissionResult can_modify; + + gboolean title_set; + gboolean show_when_initialized; +}; + +struct _NetConnectionEditorClass +{ + GObjectClass parent_class; + + void (*done) (NetConnectionEditor *details, gboolean success); +}; + +GType net_connection_editor_get_type (void); +NetConnectionEditor *net_connection_editor_new (GtkWindow *parent_window, + NMConnection *connection, + NMDevice *device, + NMAccessPoint *ap, + NMClient *client); +void net_connection_editor_set_title (NetConnectionEditor *editor, + const gchar *title); +void net_connection_editor_run (NetConnectionEditor *editor); +void net_connection_editor_present (NetConnectionEditor *editor); +void net_connection_editor_forget (NetConnectionEditor *editor); +void net_connection_editor_reset (NetConnectionEditor *editor); + +G_END_DECLS + +#endif /* __NET_CONNECTION_EDITOR_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/security-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/security-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/security-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/security-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,294 @@ + + + + + True + True + False + False + + + True + False + 50 + 50 + 12 + 12 + True + True + 10 + 6 + + + True + False + 1 + S_ecurity + True + combo_sec + + + 0 + 0 + 1 + 1 + + + + + True + False + True + + + 1 + 0 + 1 + 1 + + + + + True + False + vertical + + + + + + 0 + 1 + 2 + 1 + + + + + + + True + False + page 1 + + + False + + + + + True + False + 50 + 50 + 12 + 12 + 10 + 6 + + + True + True + + 35 + + + 1 + 0 + 1 + 1 + + + + + True + True + + + + 1 + 1 + 1 + 1 + + + + + True + True + + + + 1 + 2 + 1 + 1 + + + + + True + True + + + + 1 + 3 + 1 + 1 + + + + + True + True + + + + 1 + 4 + 1 + 1 + + + + + True + True + + + + 1 + 5 + 1 + 1 + + + + + True + True + + + + 1 + 6 + 1 + 1 + + + + + True + True + + + + 1 + 7 + 1 + 1 + + + + + True + True + + + + 1 + 8 + 1 + 1 + + + + + True + True + + + + 1 + 9 + 1 + 1 + + + + + True + False + Anony_mous identity + True + + + 0 + 0 + 1 + 1 + + + + + True + False + Inner _authentication + True + + + 0 + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + True + False + page 2 + + + 1 + False + + + + + + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2014 Red Hat, Inc. + */ + +#include "config.h" + +#include "ui-helpers.h" + +void +widget_set_error (GtkWidget *widget) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + gtk_style_context_add_class (gtk_widget_get_style_context (widget), "error"); +} + +void +widget_unset_error (GtkWidget *widget) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + gtk_style_context_remove_class (gtk_widget_get_style_context (widget), "error"); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/ui-helpers.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,27 @@ +/* + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2014 Red Hat, Inc. + */ + +#ifndef _UI_HELPERS_H_ +#define _UI_HELPERS_H_ + +#include + +void widget_set_error (GtkWidget *widget); +void widget_unset_error (GtkWidget *widget); + +#endif /* _UI_HELPERS_H_ */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.c unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,352 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include + +#include "vpn-helpers.h" + +NMVpnEditorPlugin * +vpn_get_plugin_by_service (const char *service) +{ + NMVpnPluginInfo *plugin_info; + + g_return_val_if_fail (service != NULL, NULL); + + plugin_info = nm_vpn_plugin_info_list_find_by_service (vpn_get_plugins (), service); + if (plugin_info) + return nm_vpn_plugin_info_get_editor_plugin (plugin_info); + return NULL; +} + +static gint +_sort_vpn_plugins (NMVpnPluginInfo *aa, NMVpnPluginInfo *bb) +{ + return strcmp (nm_vpn_plugin_info_get_name (aa), nm_vpn_plugin_info_get_name (bb)); +} + +GSList * +vpn_get_plugins (void) +{ + static gboolean plugins_loaded = FALSE; + static GSList *plugins = NULL; + GSList *p; + + if (G_LIKELY (plugins_loaded)) + return plugins; + plugins_loaded = TRUE; + + p = nm_vpn_plugin_info_list_load (); + plugins = NULL; + while (p) { + NMVpnPluginInfo *plugin_info = NM_VPN_PLUGIN_INFO (p->data); + GError *error = NULL; + + /* load the editor plugin, and preserve only those NMVpnPluginInfo that can + * successfully load the plugin. */ + if (nm_vpn_plugin_info_load_editor_plugin (plugin_info, &error)) + plugins = g_slist_prepend (plugins, plugin_info); + else { + if ( !nm_vpn_plugin_info_get_plugin (plugin_info) + && nm_vpn_plugin_info_lookup_property (plugin_info, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "properties")) { + g_message ("vpn: (%s,%s) cannot load legacy-only plugin", + nm_vpn_plugin_info_get_name (plugin_info), + nm_vpn_plugin_info_get_filename (plugin_info)); + } else if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { + g_message ("vpn: (%s,%s) file \"%s\" not found. Did you install the client package?", + nm_vpn_plugin_info_get_name (plugin_info), + nm_vpn_plugin_info_get_filename (plugin_info), + nm_vpn_plugin_info_get_plugin (plugin_info)); + } else { + g_warning ("vpn: (%s,%s) could not load plugin: %s", + nm_vpn_plugin_info_get_name (plugin_info), + nm_vpn_plugin_info_get_filename (plugin_info), + error->message); + } + g_clear_error (&error); + g_object_unref (plugin_info); + } + p = g_slist_delete_link (p, p); + } + + /* sort the list of plugins alphabetically. */ + plugins = g_slist_sort (plugins, (GCompareFunc) _sort_vpn_plugins); + return plugins; +} + +typedef struct { + VpnImportCallback callback; + gpointer user_data; +} ActionInfo; + +static void +import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data) +{ + char *filename = NULL; + ActionInfo *info = (ActionInfo *) user_data; + NMConnection *connection = NULL; + GError *error = NULL; + GSList *iter; + + if (response != GTK_RESPONSE_ACCEPT) + goto out; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (!filename) { + g_warning ("%s: didn't get a filename back from the chooser!", __func__); + goto out; + } + + for (iter = vpn_get_plugins (); !connection && iter; iter = iter->next) { + NMVpnEditorPlugin *plugin; + + plugin = nm_vpn_plugin_info_get_editor_plugin (iter->data); + g_clear_error (&error); + connection = nm_vpn_editor_plugin_import (plugin, filename, &error); + } + + if (!connection) { + GtkWidget *err_dialog; + char *bname = g_path_get_basename (filename); + + err_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Cannot import VPN connection")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog), + _("The file “%s” could not be read or does not contain recognized VPN connection information\n\nError: %s."), + bname, error ? error->message : "unknown error"); + g_free (bname); + g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); + g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); + gtk_dialog_run (GTK_DIALOG (err_dialog)); + } + g_clear_error (&error); + g_free (filename); + +out: + gtk_widget_hide (dialog); + gtk_widget_destroy (dialog); + + info->callback (connection, info->user_data); + g_free (info); +} + +static void +destroy_import_chooser (GtkWidget *dialog, gpointer user_data) +{ + ActionInfo *info = (ActionInfo *) user_data; + + gtk_widget_destroy (dialog); + info->callback (NULL, info->user_data); + g_free (info); +} + +void +vpn_import (GtkWindow *parent, VpnImportCallback callback, gpointer user_data) +{ + GtkWidget *dialog; + ActionInfo *info; + const char *home_folder; + + dialog = gtk_file_chooser_dialog_new (_("Select file to import"), + parent, + GTK_FILE_CHOOSER_ACTION_OPEN, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Open"), GTK_RESPONSE_ACCEPT, + NULL); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + home_folder = g_get_home_dir (); + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder); + + info = g_malloc0 (sizeof (ActionInfo)); + info->callback = callback; + info->user_data = user_data; + + g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (destroy_import_chooser), info); + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (import_vpn_from_file_cb), info); + gtk_widget_show_all (dialog); + gtk_window_present (GTK_WINDOW (dialog)); +} + +static void +export_vpn_to_file_cb (GtkWidget *dialog, gint response, gpointer user_data) +{ + NMConnection *connection = NM_CONNECTION (user_data); + char *filename = NULL; + GError *error = NULL; + NMVpnEditorPlugin *plugin; + NMSettingConnection *s_con = NULL; + NMSettingVpn *s_vpn = NULL; + const char *service_type; + const char *id = NULL; + gboolean success = FALSE; + + if (response != GTK_RESPONSE_ACCEPT) + goto out; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + if (!filename) { + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "no filename"); + goto done; + } + + if (g_file_test (filename, G_FILE_TEST_EXISTS)) { + int replace_response; + GtkWidget *replace_dialog; + char *bname; + + bname = g_path_get_basename (filename); + replace_dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_CANCEL, + _("A file named “%s” already exists."), + bname); + gtk_dialog_add_buttons (GTK_DIALOG (replace_dialog), _("_Replace"), GTK_RESPONSE_OK, NULL); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (replace_dialog), + _("Do you want to replace %s with the VPN connection you are saving?"), bname); + g_free (bname); + replace_response = gtk_dialog_run (GTK_DIALOG (replace_dialog)); + gtk_widget_destroy (replace_dialog); + if (replace_response != GTK_RESPONSE_OK) + goto out; + } + + s_con = nm_connection_get_setting_connection (connection); + id = s_con ? nm_setting_connection_get_id (s_con) : NULL; + if (!id) { + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "connection setting invalid"); + goto done; + } + + s_vpn = nm_connection_get_setting_vpn (connection); + service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL; + + if (!service_type) { + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "VPN setting invalid"); + goto done; + } + + plugin = vpn_get_plugin_by_service (service_type); + if (plugin) + success = nm_vpn_editor_plugin_export (plugin, filename, connection, &error); + +done: + if (!success) { + GtkWidget *err_dialog; + char *bname = filename ? g_path_get_basename (filename) : g_strdup ("(none)"); + + err_dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Cannot export VPN connection")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog), + _("The VPN connection “%s” could not be exported to %s.\n\nError: %s."), + id ? id : "(unknown)", bname, error ? error->message : "unknown error"); + g_free (bname); + g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL); + g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); + gtk_widget_show_all (err_dialog); + gtk_window_present (GTK_WINDOW (err_dialog)); + } + +out: + if (error) + g_error_free (error); + g_object_unref (connection); + + gtk_widget_hide (dialog); + gtk_widget_destroy (dialog); +} + +void +vpn_export (NMConnection *connection) +{ + GtkWidget *dialog; + NMVpnEditorPlugin *plugin; + NMSettingVpn *s_vpn = NULL; + const char *service_type; + const char *home_folder; + + s_vpn = nm_connection_get_setting_vpn (connection); + service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL; + + if (!service_type) { + g_warning ("%s: invalid VPN connection!", __func__); + return; + } + + dialog = gtk_file_chooser_dialog_new (_("Export VPN connection"), + NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Save"), GTK_RESPONSE_ACCEPT, + NULL); + home_folder = g_get_home_dir (); + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder); + + plugin = vpn_get_plugin_by_service (service_type); + if (plugin) { + char *suggested = NULL; + + suggested = nm_vpn_editor_plugin_get_suggested_filename (plugin, connection); + if (suggested) { + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), suggested); + g_free (suggested); + } + } + + g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (gtk_widget_destroy), NULL); + g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (export_vpn_to_file_cb), g_object_ref (connection)); + gtk_widget_show_all (dialog); + gtk_window_present (GTK_WINDOW (dialog)); +} + +gboolean +vpn_supports_ipv6 (NMConnection *connection) +{ + NMSettingVpn *s_vpn; + const char *service_type; + NMVpnEditorPlugin *plugin; + guint32 capabilities; + + s_vpn = nm_connection_get_setting_vpn (connection); + g_return_val_if_fail (s_vpn != NULL, FALSE); + + service_type = nm_setting_vpn_get_service_type (s_vpn); + g_return_val_if_fail (service_type != NULL, FALSE); + + plugin = vpn_get_plugin_by_service (service_type); + g_return_val_if_fail (plugin != NULL, FALSE); + + capabilities = nm_vpn_editor_plugin_get_capabilities (plugin); + return (capabilities & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6) != 0; +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.h unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-helpers.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,41 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Connection editor -- Connection editor for NetworkManager + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#ifndef _VPN_HELPERS_H_ +#define _VPN_HELPERS_H_ + +#include +#include +#include + +GSList *vpn_get_plugins (void); + +NMVpnEditorPlugin *vpn_get_plugin_by_service (const char *service); + +typedef void (*VpnImportCallback) (NMConnection *connection, gpointer user_data); +void vpn_import (GtkWindow *parent, VpnImportCallback callback, gpointer user_data); + +void vpn_export (NMConnection *connection); + +gboolean vpn_supports_ipv6 (NMConnection *connection); + +#endif /* _VPN_HELPERS_H_ */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/vpn-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,75 @@ + + + + + True + False + 50 + 50 + 12 + 12 + vertical + 10 + + + True + False + 6 + + + True + False + 1 + _Name + True + entry_name + + + False + True + 0 + + + + + True + True + + True + + + True + True + 1 + + + + + False + True + 0 + + + + + True + False + 0 + (Error: unable to load VPN connection editor) + + + + + + False + True + 3 + + + + + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/wifi-page.ui unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/wifi-page.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/wifi-page.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/connection-editor/wifi-page.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,140 @@ + + + + + True + False + 50 + 50 + 12 + 12 + True + True + 10 + 6 + + + True + False + 1 + _SSID + True + entry_ssid + + + 0 + 0 + 1 + 1 + + + + + True + False + 1 + _BSSID + True + combo_bssid + + + 0 + 1 + 1 + 1 + + + + + True + True + True + + My Home Network + True + + + 1 + 0 + 1 + 1 + + + + + True + False + 1 + _MAC Address + True + combo_mac + + + 0 + 2 + 1 + 1 + + + + + True + True + True + + True + + + 1 + 3 + 1 + 1 + + + + + True + False + _Cloned Address + True + entry_cloned_mac + + + 0 + 3 + 1 + 1 + + + + + True + False + True + 0 + 1 + + + 1 + 1 + 1 + 1 + + + + + True + False + True + 0 + 1 + + + 1 + 2 + 1 + 1 + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/Makefile.am unity-control-center-15.04.0+19.04.20190209/panels/network/Makefile.am --- unity-control-center-15.04.0+19.04.20190209/panels/network/Makefile.am 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/Makefile.am 2019-05-01 13:21:41.000000000 +0000 @@ -1,19 +1,26 @@ cappletname = network -INCLUDES = \ +SUBDIRS = wireless-security connection-editor + +AM_CPPFLAGS = \ $(PANEL_CFLAGS) \ $(NETWORK_PANEL_CFLAGS) \ $(NETWORK_MANAGER_CFLAGS) \ -DGNOMECC_UI_DIR="\"$(uidir)\"" \ -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \ -DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \ + -I$(srcdir)/wireless-security \ $(NULL) ccpanelsdir = $(PANELS_DIR) ccpanels_LTLIBRARIES = libnetwork.la +BUILT_SOURCES = \ + cc-network-resources.c \ + cc-network-resources.h + libnetwork_la_SOURCES = \ - network-module.c \ + $(BUILT_SOURCES) \ panel-common.c \ panel-common.h \ net-object.c \ @@ -22,45 +29,31 @@ net-device.h \ net-device-wifi.c \ net-device-wifi.h \ - net-device-wired.c \ - net-device-wired.h \ + net-device-simple.c \ + net-device-simple.h \ + net-device-ethernet.c \ + net-device-ethernet.h \ net-device-mobile.c \ net-device-mobile.h \ net-vpn.c \ net-vpn.h \ net-proxy.c \ net-proxy.h \ - panel-cell-renderer-mode.c \ - panel-cell-renderer-mode.h \ - panel-cell-renderer-security.c \ - panel-cell-renderer-security.h \ - panel-cell-renderer-signal.c \ - panel-cell-renderer-signal.h \ - panel-cell-renderer-separator.c \ - panel-cell-renderer-separator.h \ - panel-cell-renderer-text.c \ - panel-cell-renderer-text.h \ - panel-cell-renderer-pixbuf.c \ - panel-cell-renderer-pixbuf.h \ network-dialogs.c \ network-dialogs.h \ + network-module.c \ cc-network-panel.c \ - cc-network-panel.h \ - rfkill-glib.c \ - rfkill-glib.h \ - rfkill.h + cc-network-panel.h + +libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS) $(builddir)/connection-editor/libconnection-editor.la -libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS) libnetwork_la_LDFLAGS = $(PANEL_LDFLAGS) -uidir = $(pkgdatadir)/ui -dist_ui_DATA = \ - network-proxy.ui \ - network-vpn.ui \ - network-wifi.ui \ - network-wired.ui \ - network-mobile.ui \ - network.ui +resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/network.gresource.xml) +cc-network-resources.c: network.gresource.xml $(resource_files) + $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name cc_network $< +cc-network-resources.h: network.gresource.xml $(resource_files) + $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name cc_network $< @INTLTOOL_DESKTOP_RULE@ @@ -68,6 +61,7 @@ desktop_in_files = unity-network-panel.desktop.in desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) -CLEANFILES = $(desktop_in_files) $(desktop_DATA) +CLEANFILES = $(desktop_in_files) $(desktop_DATA) $(BUILT_SOURCES) +EXTRA_DIST = $(resource_files) network.gresource.xml -include $(top_srcdir)/git.mk diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.c 2019-05-01 13:21:41.000000000 +0000 @@ -26,12 +26,7 @@ #include #include -#include -#include -#include -#include -#include -#include +#include #include "net-device.h" @@ -58,8 +53,6 @@ if (!connection) return NULL; - const GByteArray *mac = NULL; - /* check the connection type */ if (nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) { @@ -67,38 +60,14 @@ NMSettingWireless *s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) return NULL; - mac = nm_setting_wireless_get_mac_address (s_wireless); - if (mac) - return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER); + return g_strdup (nm_setting_wireless_get_mac_address (s_wireless)); } else if (nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { /* check wired settings */ NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) return NULL; - mac = nm_setting_wired_get_mac_address (s_wired); - if (mac) - return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER); - } else if (nm_connection_is_type (connection, - NM_SETTING_WIMAX_SETTING_NAME)) { - /* check wimax settings */ - NMSettingWimax *s_wimax = nm_connection_get_setting_wimax (connection); - if (!s_wimax) - return NULL; - mac = nm_setting_wimax_get_mac_address (s_wimax); - if (mac) - return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER); - } else if (nm_connection_is_type (connection, - NM_SETTING_INFINIBAND_SETTING_NAME)) { - /* check infiniband settings */ - NMSettingInfiniband *s_infiniband = \ - nm_connection_get_setting_infiniband (connection); - if (!s_infiniband) - return NULL; - mac = nm_setting_infiniband_get_mac_address (s_infiniband); - if (mac) - return nm_utils_hwaddr_ntoa (mac->data, - ARPHRD_INFINIBAND); + return g_strdup (nm_setting_wired_get_mac_address (s_wired)); } /* no MAC address found */ return NULL; @@ -122,19 +91,6 @@ mac = nm_device_ethernet_get_hw_address (device_ethernet); break; } - case NM_DEVICE_TYPE_WIMAX: - { - NMDeviceWimax *device_wimax = NM_DEVICE_WIMAX (device); - mac = nm_device_wimax_get_hw_address (device_wimax); - break; - } - case NM_DEVICE_TYPE_INFINIBAND: - { - NMDeviceInfiniband *device_infiniband = \ - NM_DEVICE_INFINIBAND (device); - mac = nm_device_infiniband_get_hw_address (device_infiniband); - break; - } default: break; } @@ -165,53 +121,20 @@ return FALSE; } -static GSList * -valid_connections_for_device (NMRemoteSettings *remote_settings, - NetDevice *device) -{ - GSList *all, *filtered, *iterator, *valid; - NMConnection *connection; - NMSettingConnection *s_con; - - all = nm_remote_settings_list_connections (remote_settings); - filtered = nm_device_filter_connections (device->priv->nm_device, all); - g_slist_free (all); - - valid = NULL; - for (iterator = filtered; iterator; iterator = iterator->next) { - connection = iterator->data; - s_con = nm_connection_get_setting_connection (connection); - if (!s_con) - continue; - - if (nm_setting_connection_get_master (s_con)) - continue; - - valid = g_slist_prepend (valid, connection); - } - g_slist_free (filtered); - - return g_slist_reverse (valid); -} - -NMConnection * -net_device_get_find_connection (NetDevice *device) +static NMConnection * +net_device_real_get_find_connection (NetDevice *device) { GSList *list, *iterator; NMConnection *connection = NULL; NMActiveConnection *ac; - NMRemoteSettings *remote_settings; /* is the device available in a active connection? */ - remote_settings = net_object_get_remote_settings (NET_OBJECT (device)); ac = nm_device_get_active_connection (device->priv->nm_device); - if (ac) { - return (NMConnection*)nm_remote_settings_get_connection_by_path (remote_settings, - nm_active_connection_get_connection (ac)); - } + if (ac) + return (NMConnection*) nm_active_connection_get_connection (ac); /* not found in active connections - check all available connections */ - list = valid_connections_for_device (remote_settings, device); + list = net_device_get_valid_connections (device); if (list != NULL) { /* if list has only one connection, use this connection */ if (g_slist_length (list) == 1) { @@ -236,6 +159,12 @@ return connection; } +NMConnection * +net_device_get_find_connection (NetDevice *device) +{ + return NET_DEVICE_GET_CLASS (device)->get_find_connection (device); +} + static void state_changed_cb (NMDevice *device, NMDeviceState new_state, @@ -250,6 +179,7 @@ NMDevice * net_device_get_nm_device (NetDevice *device) { + g_return_val_if_fail (NET_IS_DEVICE (device), NULL); return device->priv->nm_device; } @@ -314,10 +244,13 @@ priv->changed_id); } priv->nm_device = g_value_dup_object (value); - priv->changed_id = g_signal_connect (priv->nm_device, - "state-changed", - G_CALLBACK (state_changed_cb), - net_device); + if (priv->nm_device) { + priv->changed_id = g_signal_connect (priv->nm_device, + "state-changed", + G_CALLBACK (state_changed_cb), + net_device); + } else + priv->changed_id = 0; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (net_device, prop_id, pspec); @@ -352,6 +285,7 @@ object_class->get_property = net_device_get_property; object_class->set_property = net_device_set_property; parent_class->edit = net_device_edit; + klass->get_find_connection = net_device_real_get_find_connection; pspec = g_param_spec_object ("nm-device", NULL, NULL, NM_TYPE_DEVICE, @@ -377,3 +311,38 @@ return NET_DEVICE (device); } +GSList * +net_device_get_valid_connections (NetDevice *device) +{ + GSList *valid; + NMConnection *connection; + NMSettingConnection *s_con; + NMActiveConnection *active_connection; + const char *active_uuid; + const GPtrArray *all; + GPtrArray *filtered; + guint i; + + all = nm_client_get_connections (net_object_get_client (NET_OBJECT (device))); + filtered = nm_device_filter_connections (net_device_get_nm_device (device), all); + + active_connection = nm_device_get_active_connection (net_device_get_nm_device (device)); + active_uuid = active_connection ? nm_active_connection_get_uuid (active_connection) : NULL; + + valid = NULL; + for (i = 0; i < filtered->len; i++) { + connection = g_ptr_array_index (filtered, i); + s_con = nm_connection_get_setting_connection (connection); + if (!s_con) + continue; + + if (nm_setting_connection_get_master (s_con) && + g_strcmp0 (nm_setting_connection_get_uuid (s_con), active_uuid) != 0) + continue; + + valid = g_slist_prepend (valid, connection); + } + g_ptr_array_free (filtered, FALSE); + + return g_slist_reverse (valid); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,638 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2011-2012 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "panel-common.h" + +#include "shell/list-box-helper.h" +#include "connection-editor/net-connection-editor.h" +#include "connection-editor/ce-page.h" + +#include "net-device-ethernet.h" + +G_DEFINE_TYPE (NetDeviceEthernet, net_device_ethernet, NET_TYPE_DEVICE_SIMPLE) + +static char * +device_ethernet_get_speed (NetDeviceSimple *device_simple) +{ + NMDevice *nm_device; + guint speed; + + nm_device = net_device_get_nm_device (NET_DEVICE (device_simple)); + + speed = nm_device_ethernet_get_speed (NM_DEVICE_ETHERNET (nm_device)); + if (speed > 0) { + /* Translators: network device speed */ + return g_strdup_printf (_("%d Mb/s"), speed); + } else + return NULL; +} + +static GtkWidget * +device_ethernet_add_to_notebook (NetObject *object, + GtkNotebook *notebook, + GtkSizeGroup *heading_size_group) +{ + NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); + GtkWidget *vbox; + + vbox = GTK_WIDGET (gtk_builder_get_object (device->builder, "vbox6")); + gtk_notebook_append_page (notebook, vbox, NULL); + return vbox; +} + +static void +add_details_row (GtkWidget *details, gint top, const gchar *heading, const gchar *value) +{ + GtkWidget *heading_label; + GtkWidget *value_label; + + heading_label = gtk_label_new (heading); + gtk_style_context_add_class (gtk_widget_get_style_context (heading_label), "dim-label"); + gtk_widget_set_halign (heading_label, GTK_ALIGN_END); + gtk_widget_set_hexpand (heading_label, TRUE); + + gtk_grid_attach (GTK_GRID (details), heading_label, 0, top, 1, 1); + + value_label = gtk_label_new (value); + gtk_widget_set_halign (value_label, GTK_ALIGN_START); + gtk_widget_set_hexpand (value_label, TRUE); + + gtk_label_set_mnemonic_widget (GTK_LABEL (heading_label), value_label); + + gtk_grid_attach (GTK_GRID (details), value_label, 1, top, 1, 1); +} + +static gchar * +get_last_used_string (NMConnection *connection) +{ + gchar *last_used = NULL; + GDateTime *now = NULL; + GDateTime *then = NULL; + gint days; + GTimeSpan diff; + guint64 timestamp; + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + if (s_con == NULL) + goto out; + timestamp = nm_setting_connection_get_timestamp (s_con); + if (timestamp == 0) { + last_used = g_strdup (_("never")); + goto out; + } + + /* calculate the amount of time that has elapsed */ + now = g_date_time_new_now_utc (); + then = g_date_time_new_from_unix_utc (timestamp); + diff = g_date_time_difference (now, then); + days = diff / G_TIME_SPAN_DAY; + if (days == 0) + last_used = g_strdup (_("today")); + else if (days == 1) + last_used = g_strdup (_("yesterday")); + else + last_used = g_strdup_printf (ngettext ("%i day ago", "%i days ago", days), days); +out: + if (now != NULL) + g_date_time_unref (now); + if (then != NULL) + g_date_time_unref (then); + + return last_used; +} + +static void +add_details (GtkWidget *details, NMDevice *device, NMConnection *connection) +{ + NMIPConfig *ip4_config = NULL; + NMIPConfig *ip6_config = NULL; + gchar *ip4_address = NULL; + gchar *ip4_route = NULL; + gchar *ip4_dns = NULL; + gchar *ip6_address = NULL; + gint i = 0; + + ip4_config = nm_device_get_ip4_config (device); + if (ip4_config) { + ip4_address = panel_get_ip4_address_as_string (ip4_config, "address"); + ip4_route = panel_get_ip4_address_as_string (ip4_config, "gateway"); + ip4_dns = panel_get_ip4_dns_as_string (ip4_config); + } + ip6_config = nm_device_get_ip6_config (device); + if (ip6_config) { + ip6_address = panel_get_ip6_address_as_string (ip6_config); + } + + if (ip4_address && ip6_address) { + add_details_row (details, i++, _("IPv4 Address"), ip4_address); + add_details_row (details, i++, _("IPv6 Address"), ip6_address); + } else if (ip4_address) { + add_details_row (details, i++, _("IP Address"), ip4_address); + } else if (ip6_address) { + add_details_row (details, i++, _("IPv6 Address"), ip6_address); + } + + add_details_row (details, i++, _("Hardware Address"), + nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device))); + + if (ip4_route) + add_details_row (details, i++, _("Default Route"), ip4_route); + if (ip4_dns) + add_details_row (details, i++, _("DNS"), ip4_dns); + + if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) { + gchar *last_used; + last_used = get_last_used_string (connection); + add_details_row (details, i++, _("Last used"), last_used); + g_free (last_used); + } + + g_free (ip4_address); + g_free (ip4_route); + g_free (ip4_dns); + g_free (ip6_address); +} + +static void populate_ui (NetDeviceEthernet *device); + +static gboolean +device_state_to_off_switch (NMDeviceState state) +{ + switch (state) { + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_DEACTIVATING: + case NM_DEVICE_STATE_FAILED: + return FALSE; + default: + return TRUE; + } +} + +static void +device_ethernet_refresh_ui (NetDeviceEthernet *device) +{ + NMDevice *nm_device; + NMDeviceState state; + GtkWidget *widget; + gchar *speed = NULL; + + nm_device = net_device_get_nm_device (NET_DEVICE (device)); + + widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "label_device")); + gtk_label_set_label (GTK_LABEL (widget), net_object_get_title (NET_OBJECT (device))); + + widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "image_device")); + gtk_image_set_from_icon_name (GTK_IMAGE (widget), + panel_device_to_icon_name (nm_device, FALSE), + GTK_ICON_SIZE_DIALOG); + + widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "device_off_switch")); + state = nm_device_get_state (nm_device); + gtk_widget_set_visible (widget, + state != NM_DEVICE_STATE_UNAVAILABLE + && state != NM_DEVICE_STATE_UNMANAGED); + device->updating_device = TRUE; + gtk_switch_set_active (GTK_SWITCH (widget), device_state_to_off_switch (state)); + device->updating_device = FALSE; + + if (state != NM_DEVICE_STATE_UNAVAILABLE) + speed = net_device_simple_get_speed (NET_DEVICE_SIMPLE (device)); + panel_set_device_status (device->builder, "label_status", nm_device, speed); + + populate_ui (device); +} + +static void +editor_done (NetConnectionEditor *editor, + gboolean success, + NetDeviceEthernet *device) +{ + g_object_unref (editor); + device_ethernet_refresh_ui (device); +} + +static void +show_details (GtkButton *button, NetDeviceEthernet *device, const gchar *title) +{ + GtkWidget *row; + NMConnection *connection; + GtkWidget *window; + NetConnectionEditor *editor; + NMClient *client; + NMDevice *nmdev; + + window = gtk_widget_get_toplevel (GTK_WIDGET (button)); + + row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row")); + connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection")); + + nmdev = net_device_get_nm_device (NET_DEVICE (device)); + client = net_object_get_client (NET_OBJECT (device)); + editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client); + if (title) + net_connection_editor_set_title (editor, title); + g_signal_connect (editor, "done", G_CALLBACK (editor_done), device); + net_connection_editor_run (editor); +} + +static void +show_details_for_row (GtkButton *button, NetDeviceEthernet *device) +{ + show_details (button, device, NULL); +} + +static void +show_details_for_wired (GtkButton *button, NetDeviceEthernet *device) +{ + /* Translators: This is used as the title of the connection + * details window for ethernet, if there is only a single + * profile. It is also used to display ethernet in the + * device list. + */ + show_details (button, device, _("Wired")); +} + +static void +add_row (NetDeviceEthernet *device, NMConnection *connection) +{ + GtkWidget *row; + GtkWidget *widget; + GtkWidget *box; + GtkWidget *details; + NMDevice *nmdev; + NMActiveConnection *aconn; + gboolean active; + GtkWidget *image; + + active = FALSE; + + nmdev = net_device_get_nm_device (NET_DEVICE (device)); + aconn = nm_device_get_active_connection (nmdev); + if (aconn) { + const gchar *uuid1, *uuid2; + uuid1 = nm_active_connection_get_uuid (aconn); + uuid2 = nm_connection_get_uuid (connection); + active = g_strcmp0 (uuid1, uuid2) == 0; + } + + row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (row), box, FALSE, TRUE, 0); + widget = gtk_label_new (nm_connection_get_id (connection)); + gtk_widget_set_margin_start (widget, 12); + gtk_widget_set_margin_end (widget, 12); + gtk_widget_set_margin_top (widget, 12); + gtk_widget_set_margin_bottom (widget, 12); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); + + if (active) { + widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); + + details = gtk_grid_new (); + gtk_grid_set_row_spacing (GTK_GRID (details), 10); + gtk_grid_set_column_spacing (GTK_GRID (details), 10); + + gtk_box_pack_start (GTK_BOX (row), details, FALSE, TRUE, 0); + + add_details (details, nmdev, connection); + } + + /* filler */ + widget = gtk_label_new (""); + gtk_widget_set_hexpand (widget, TRUE); + gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0); + + image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + widget = gtk_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (widget), "image-button"); + gtk_widget_set_margin_start (widget, 12); + gtk_widget_set_margin_end (widget, 12); + gtk_widget_set_margin_top (widget, 12); + gtk_widget_set_margin_bottom (widget, 12); + gtk_widget_show (widget); + gtk_container_add (GTK_CONTAINER (widget), image); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + atk_object_set_name (gtk_widget_get_accessible (widget), _("Options…")); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, TRUE, 0); + g_object_set_data (G_OBJECT (row), "edit", widget); + g_object_set_data (G_OBJECT (widget), "row", row); + g_signal_connect (widget, "clicked", + G_CALLBACK (show_details_for_row), device); + + gtk_widget_show_all (row); + + g_object_set_data (G_OBJECT (row), "connection", connection); + + gtk_container_add (GTK_CONTAINER (device->list), row); +} + +static void +connection_removed (NMClient *client, + NMRemoteConnection *connection, + NetDeviceEthernet *device) +{ + if (g_hash_table_remove (device->connections, connection)) + device_ethernet_refresh_ui (device); +} + +static void +populate_ui (NetDeviceEthernet *device) +{ + GList *children, *c; + GSList *connections, *l; + NMConnection *connection; + gint n_connections; + + children = gtk_container_get_children (GTK_CONTAINER (device->list)); + for (c = children; c; c = c->next) { + gtk_container_remove (GTK_CONTAINER (device->list), c->data); + } + g_list_free (children); + + children = gtk_container_get_children (GTK_CONTAINER (device->details)); + for (c = children; c; c = c->next) { + gtk_container_remove (GTK_CONTAINER (device->details), c->data); + } + g_list_free (children); + + connections = net_device_get_valid_connections (NET_DEVICE (device)); + for (l = connections; l; l = l->next) { + NMConnection *connection = l->data; + if (!g_hash_table_contains (device->connections, connection)) { + g_hash_table_add (device->connections, connection); + } + } + n_connections = g_slist_length (connections); + + if (n_connections > 4) { + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + gtk_widget_set_vexpand (device->scrolled_window, TRUE); + } else { + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window), + GTK_POLICY_NEVER, + GTK_POLICY_NEVER); + gtk_widget_set_vexpand (device->scrolled_window, FALSE); + } + + if (n_connections > 1) { + gtk_widget_hide (device->details); + gtk_widget_hide (device->details_button); + for (l = connections; l; l = l->next) { + NMConnection *connection = l->data; + add_row (device, connection); + } + gtk_widget_show (device->scrolled_window); + } else if (n_connections == 1) { + connection = connections->data; + gtk_widget_hide (device->scrolled_window); + add_details (device->details, net_device_get_nm_device (NET_DEVICE (device)), connection); + gtk_widget_show_all (device->details); + gtk_widget_show (device->details_button); + g_object_set_data (G_OBJECT (device->details_button), "row", device->details_button); + g_object_set_data (G_OBJECT (device->details_button), "connection", connection); + + } else { + gtk_widget_hide (device->scrolled_window); + gtk_widget_hide (device->details); + gtk_widget_hide (device->details_button); + } + + g_slist_free (connections); +} + +static void +client_connection_added_cb (NMClient *client, + NMRemoteConnection *connection, + NetDeviceEthernet *device) +{ + device_ethernet_refresh_ui (device); +} + +static void +add_profile (GtkButton *button, NetDeviceEthernet *device) +{ + NMConnection *connection; + NMSettingConnection *sc; + gchar *uuid, *id; + NetConnectionEditor *editor; + GtkWidget *window; + NMClient *client; + NMDevice *nmdev; + const GPtrArray *connections; + + connection = nm_simple_connection_new (); + sc = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + nm_connection_add_setting (connection, NM_SETTING (sc)); + + uuid = nm_utils_uuid_generate (); + + client = net_object_get_client (NET_OBJECT (device)); + connections = nm_client_get_connections (client); + id = ce_page_get_next_available_name (connections, NAME_FORMAT_PROFILE, NULL); + + g_object_set (sc, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_ID, id, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NULL); + + nm_connection_add_setting (connection, nm_setting_wired_new ()); + + g_free (uuid); + g_free (id); + + window = gtk_widget_get_toplevel (GTK_WIDGET (button)); + + nmdev = net_device_get_nm_device (NET_DEVICE (device)); + editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client); + g_signal_connect (editor, "done", G_CALLBACK (editor_done), device); + net_connection_editor_run (editor); +} + +static void +device_off_toggled (GtkSwitch *sw, + GParamSpec *pspec, + NetDeviceEthernet *device) +{ + NMClient *client; + NMDevice *nm_device; + NMConnection *connection; + + if (device->updating_device) + return; + + client = net_object_get_client (NET_OBJECT (device)); + nm_device = net_device_get_nm_device (NET_DEVICE (device)); + + if (gtk_switch_get_active (sw)) { + connection = net_device_get_find_connection (NET_DEVICE (device)); + if (connection != NULL) { + nm_client_activate_connection_async (client, + connection, + nm_device, + NULL, NULL, NULL, NULL); + } + } else { + nm_device_disconnect (nm_device, NULL, NULL); + } +} + +static void +device_title_changed (NetDeviceEthernet *device, + GParamSpec *pspec, + gpointer user_data) +{ + device_ethernet_refresh_ui (device); +} + +static void +connection_activated (GtkListBox *list, GtkListBoxRow *row, NetDeviceEthernet *device) +{ + NMClient *client; + NMDevice *nm_device; + NMConnection *connection; + + client = net_object_get_client (NET_OBJECT (device)); + nm_device = net_device_get_nm_device (NET_DEVICE (device)); + + if (!NM_IS_DEVICE_ETHERNET (nm_device) || + !nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (nm_device))) + return; + + connection = NM_CONNECTION (g_object_get_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (row))), "connection")); + + nm_client_activate_connection_async (client, + connection, + nm_device, + NULL, NULL, NULL, NULL); +} + +static void +device_ethernet_constructed (GObject *object) +{ + NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); + NMClient *client; + GtkWidget *list; + GtkWidget *swin; + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (device->builder, + "device_off_switch")); + g_signal_connect (widget, "notify::active", + G_CALLBACK (device_off_toggled), device); + + device->scrolled_window = swin = GTK_WIDGET (gtk_builder_get_object (device->builder, "list")); + device->list = list = GTK_WIDGET (gtk_list_box_new ()); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); + gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); + gtk_container_add (GTK_CONTAINER (swin), list); + g_signal_connect (list, "row-activated", + G_CALLBACK (connection_activated), device); + gtk_widget_show (list); + + device->details = GTK_WIDGET (gtk_builder_get_object (device->builder, "details")); + + device->details_button = GTK_WIDGET (gtk_builder_get_object (device->builder, "details_button")); + g_signal_connect (device->details_button, "clicked", + G_CALLBACK (show_details_for_wired), device); + + device->add_profile_button = GTK_WIDGET (gtk_builder_get_object (device->builder, "add_profile_button")); + g_signal_connect (device->add_profile_button, "clicked", + G_CALLBACK (add_profile), device); + + client = net_object_get_client (NET_OBJECT (object)); + g_signal_connect (client, NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK (client_connection_added_cb), object); + g_signal_connect_object (client, NM_CLIENT_CONNECTION_REMOVED, + G_CALLBACK (connection_removed), device, 0); + + device_ethernet_refresh_ui (device); +} + +static void +device_ethernet_finalize (GObject *object) +{ + NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); + + g_object_unref (device->builder); + g_hash_table_destroy (device->connections); + + G_OBJECT_CLASS (net_device_ethernet_parent_class)->finalize (object); +} + +static void +device_ethernet_refresh (NetObject *object) +{ + NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object); + device_ethernet_refresh_ui (device); +} + +static void +net_device_ethernet_class_init (NetDeviceEthernetClass *klass) +{ + NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass); + NetObjectClass *obj_class = NET_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + simple_class->get_speed = device_ethernet_get_speed; + obj_class->refresh = device_ethernet_refresh; + obj_class->add_to_notebook = device_ethernet_add_to_notebook; + object_class->constructed = device_ethernet_constructed; + object_class->finalize = device_ethernet_finalize; +} + +static void +net_device_ethernet_init (NetDeviceEthernet *device) +{ + GError *error = NULL; + + device->builder = gtk_builder_new (); + gtk_builder_add_from_resource (device->builder, + "/org/gnome/control-center/network/network-ethernet.ui", + &error); + if (error != NULL) { + g_warning ("Could not load interface file: %s", error->message); + g_error_free (error); + return; + } + + device->connections = g_hash_table_new (NULL, NULL); + + g_signal_connect (device, "notify::title", G_CALLBACK (device_title_changed), NULL); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.h unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-ethernet.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __NET_DEVICE_ETHERNET_H +#define __NET_DEVICE_ETHERNET_H + +#include + +#include "net-device-simple.h" + +G_BEGIN_DECLS + +#define NET_TYPE_DEVICE_ETHERNET (net_device_ethernet_get_type ()) +#define NET_DEVICE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE_ETHERNET, NetDeviceEthernet)) +#define NET_DEVICE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE_ETHERNET, NetDeviceEthernetClass)) +#define NET_IS_DEVICE_ETHERNET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE_ETHERNET)) +#define NET_IS_DEVICE_ETHERNET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE_ETHERNET)) +#define NET_DEVICE_ETHERNET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE_ETHERNET, NetDeviceEthernetClass)) + +typedef struct _NetDeviceEthernetPrivate NetDeviceEthernetPrivate; +typedef struct _NetDeviceEthernet NetDeviceEthernet; +typedef struct _NetDeviceEthernetClass NetDeviceEthernetClass; + +struct _NetDeviceEthernet +{ + NetDeviceSimple parent; + + GtkBuilder *builder; + + GtkWidget *list; + GtkWidget *scrolled_window; + GtkWidget *details; + GtkWidget *details_button; + GtkWidget *add_profile_button; + gboolean updating_device; + + GHashTable *connections; +}; + +struct _NetDeviceEthernetClass +{ + NetDeviceSimpleClass parent_class; +}; + +GType net_device_ethernet_get_type (void); + +G_END_DECLS + +#endif /* __NET_DEVICE_ETHERNET_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.h unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.h 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device.h 2019-05-01 13:21:41.000000000 +0000 @@ -24,8 +24,8 @@ #include +#include #include "net-object.h" -#include "nm-device.h" G_BEGIN_DECLS @@ -49,6 +49,8 @@ struct _NetDeviceClass { NetObjectClass parent_class; + + NMConnection * (*get_find_connection) (NetDevice *device); }; GType net_device_get_type (void); @@ -56,6 +58,8 @@ NMDevice *net_device_get_nm_device (NetDevice *device); NMConnection *net_device_get_find_connection (NetDevice *device); +GSList *net_device_get_valid_connections (NetDevice *device); + G_END_DECLS #endif /* __NET_DEVICE_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.c 2019-05-01 13:21:41.000000000 +0000 @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * * Copyright (C) 2011-2012 Richard Hughes + * Copyright (C) 2013 Aleksander Morgado * * Licensed under the GNU General Public License Version 2 * @@ -24,14 +25,12 @@ #include #include -#include -#include -#include -#include +#include +#include +#include #include "panel-common.h" #include "network-dialogs.h" - #include "net-device-mobile.h" #define NET_DEVICE_MOBILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_MOBILE, NetDeviceMobilePrivate)) @@ -40,8 +39,18 @@ struct _NetDeviceMobilePrivate { - GtkBuilder *builder; - gboolean updating_device; + GtkBuilder *builder; + gboolean updating_device; + + /* Old MM < 0.7 support */ + GDBusProxy *gsm_proxy; + GDBusProxy *cdma_proxy; + + /* New MM >= 0.7 support */ + MMObject *mm_object; + guint operator_name_updated; + + NMAMobileProvidersDatabase *mpd; }; enum { @@ -50,6 +59,12 @@ COLUMN_LAST }; +enum { + PROP_0, + PROP_MODEM_OBJECT, + PROP_LAST +}; + G_DEFINE_TYPE (NetDeviceMobile, net_device_mobile, NET_TYPE_DEVICE) static GtkWidget * @@ -58,7 +73,6 @@ GtkSizeGroup *heading_size_group) { GtkWidget *widget; - GtkWindow *window; NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object); /* add widgets to size group */ @@ -69,29 +83,23 @@ "heading_network")); gtk_size_group_add_widget (heading_size_group, widget); - /* reparent */ - window = GTK_WINDOW (gtk_builder_get_object (device_mobile->priv->builder, - "window_tmp")); widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "vbox7")); - g_object_ref (widget); - gtk_container_remove (GTK_CONTAINER (window), widget); gtk_notebook_append_page (notebook, widget, NULL); - g_object_unref (widget); return widget; } static void -connection_activate_cb (NMClient *client, - NMActiveConnection *connection, - GError *error, +connection_activate_cb (GObject *source_object, + GAsyncResult *res, gpointer user_data) { - NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (user_data); + GError *error = NULL; - if (connection == NULL) { + if (!nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { /* failed to activate */ - nm_device_mobile_refresh_ui (device_mobile); + nm_device_mobile_refresh_ui (user_data); + g_error_free (error); } } @@ -105,8 +113,8 @@ NMConnection *connection; NMDevice *device; NMClient *client; - NMRemoteSettings *remote_settings; CcNetworkPanel *panel; + GtkWidget *toplevel; if (device_mobile->priv->updating_device) goto out; @@ -119,7 +127,6 @@ if (device == NULL) goto out; client = net_object_get_client (NET_OBJECT (device_mobile)); - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_mobile)); /* get entry */ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); @@ -128,24 +135,23 @@ -1); if (g_strcmp0 (object_path, NULL) == 0) { panel = net_object_get_panel (NET_OBJECT (device_mobile)); - cc_network_panel_connect_to_3g_network (panel, + toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); + cc_network_panel_connect_to_3g_network (toplevel, client, - remote_settings, device); goto out; } /* activate the connection */ g_debug ("try to switch to connection %s", object_path); - connection = (NMConnection*) nm_remote_settings_get_connection_by_path (remote_settings, - object_path); + connection = (NMConnection*) nm_client_get_connection_by_path (client, object_path); if (connection != NULL) { nm_device_disconnect (device, NULL, NULL); - nm_client_activate_connection (client, - connection, - device, NULL, - connection_activate_cb, - device_mobile); + nm_client_activate_connection_async (client, + connection, + device, NULL, NULL, + connection_activate_cb, + device_mobile); goto out; } out: @@ -165,7 +171,22 @@ if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_MODEM) return; - enabled = nm_client_wwan_get_enabled (client); + if (nm_client_wwan_get_enabled (client)) { + NMDeviceState state; + + state = nm_device_get_state (device); + if (state == NM_DEVICE_STATE_UNKNOWN || + state == NM_DEVICE_STATE_UNMANAGED || + state == NM_DEVICE_STATE_UNAVAILABLE || + state == NM_DEVICE_STATE_DISCONNECTED || + state == NM_DEVICE_STATE_DEACTIVATING || + state == NM_DEVICE_STATE_FAILED) { + enabled = FALSE; + } else { + enabled = TRUE; + } + } + sw = GTK_SWITCH (gtk_builder_get_object (device_mobile->priv->builder, "device_off_switch")); @@ -181,21 +202,16 @@ GtkComboBox *combobox) { NetDeviceMobilePrivate *priv = device_mobile->priv; - GSList *filtered; GSList *list, *l; GtkTreeIter treeiter; NMActiveConnection *active_connection; NMConnection *connection; - NMRemoteSettings *remote_settings; /* get the list of available connections for this device */ - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_mobile)); - g_assert (remote_settings != NULL); - list = nm_remote_settings_list_connections (remote_settings); - filtered = nm_device_filter_connections (nm_device, list); + list = net_device_get_valid_connections (NET_DEVICE (device_mobile)); gtk_list_store_clear (liststore); active_connection = nm_device_get_active_connection (nm_device); - for (l = filtered; l; l = g_slist_next (l)) { + for (l = list; l; l = g_slist_next (l)) { connection = NM_CONNECTION (l->data); gtk_list_store_append (liststore, &treeiter); gtk_list_store_set (liststore, @@ -206,8 +222,8 @@ /* is this already activated? */ if (active_connection != NULL && - g_strcmp0 (nm_connection_get_path (connection), - nm_active_connection_get_connection (active_connection)) == 0) { + g_strcmp0 (nm_connection_get_uuid (connection), + nm_active_connection_get_uuid (active_connection)) == 0) { priv->updating_device = TRUE; gtk_combo_box_set_active_iter (combobox, &treeiter); priv->updating_device = FALSE; @@ -223,28 +239,158 @@ -1); g_slist_free (list); - g_slist_free (filtered); +} + +static void +device_mobile_refresh_equipment_id (NetDeviceMobile *device_mobile) +{ + const gchar *equipment_id = NULL; + + if (device_mobile->priv->mm_object != NULL) { + MMModem *modem; + + /* Modem interface should always be present */ + modem = mm_object_peek_modem (device_mobile->priv->mm_object); + equipment_id = mm_modem_get_equipment_identifier (modem); + + /* Set equipment ID */ + if (equipment_id != NULL) { + g_debug ("[%s] Equipment ID set to '%s'", + mm_object_get_path (device_mobile->priv->mm_object), + equipment_id); + } + } else { + /* Assume old MM handling */ + equipment_id = g_object_get_data (G_OBJECT (device_mobile), + "ControlCenter::EquipmentIdentifier"); + } + + panel_set_device_widget_details (device_mobile->priv->builder, "imei", equipment_id); +} + +static gchar * +device_mobile_find_provider (NetDeviceMobile *device_mobile, + const gchar *mccmnc, + guint32 sid) +{ + NMAMobileProvider *provider; + GString *name = NULL; + + if (device_mobile->priv->mpd == NULL) { + GError *error = NULL; + + /* Use defaults */ + device_mobile->priv->mpd = nma_mobile_providers_database_new_sync (NULL, NULL, NULL, &error); + if (device_mobile->priv->mpd == NULL) { + g_debug ("Couldn't load mobile providers database: %s", + error ? error->message : ""); + g_clear_error (&error); + return NULL; + } + } + + if (mccmnc != NULL) { + provider = nma_mobile_providers_database_lookup_3gpp_mcc_mnc (device_mobile->priv->mpd, mccmnc); + if (provider != NULL) + name = g_string_new (nma_mobile_provider_get_name (provider)); + } + + if (sid != 0) { + provider = nma_mobile_providers_database_lookup_cdma_sid (device_mobile->priv->mpd, sid); + if (provider != NULL) { + if (name == NULL) + name = g_string_new (nma_mobile_provider_get_name (provider)); + else + g_string_append_printf (name, ", %s", nma_mobile_provider_get_name (provider)); + } + } + + return (name != NULL ? g_string_free (name, FALSE) : NULL); +} + +static void +device_mobile_refresh_operator_name (NetDeviceMobile *device_mobile) +{ + if (device_mobile->priv->mm_object != NULL) { + gchar *operator_name = NULL; + MMModem3gpp *modem_3gpp; + MMModemCdma *modem_cdma; + + modem_3gpp = mm_object_peek_modem_3gpp (device_mobile->priv->mm_object); + modem_cdma = mm_object_peek_modem_cdma (device_mobile->priv->mm_object); + + if (modem_3gpp != NULL) { + const gchar *operator_name_unsafe; + + operator_name_unsafe = mm_modem_3gpp_get_operator_name (modem_3gpp); + if (operator_name_unsafe != NULL && operator_name_unsafe[0] != '\0') + operator_name = g_strescape (operator_name_unsafe, NULL); + } + + /* If not directly given in the 3GPP interface, try to guess from + * MCCMNC/SID */ + if (operator_name == NULL) { + const gchar *mccmnc = NULL; + guint32 sid = 0; + + if (modem_3gpp != NULL) + mccmnc = mm_modem_3gpp_get_operator_code (modem_3gpp); + if (modem_cdma != NULL) + sid = mm_modem_cdma_get_sid (modem_cdma); + operator_name = device_mobile_find_provider (device_mobile, mccmnc, sid); + } + + /* Set operator name */ + if (operator_name != NULL) { + g_debug ("[%s] Operator name set to '%s'", + mm_object_get_path (device_mobile->priv->mm_object), + operator_name); + } + + panel_set_device_widget_details (device_mobile->priv->builder, "provider", operator_name); + g_free (operator_name); + } else { + const gchar *gsm; + const gchar *cdma; + + /* Assume old MM handling */ + gsm = g_object_get_data (G_OBJECT (device_mobile), + "ControlCenter::OperatorNameGsm"); + cdma = g_object_get_data (G_OBJECT (device_mobile), + "ControlCenter::OperatorNameCdma"); + + if (gsm != NULL && cdma != NULL) { + gchar *both; + + both = g_strdup_printf ("%s, %s", gsm, cdma); + panel_set_device_widget_details (device_mobile->priv->builder, "provider", both); + g_free (both); + } else if (gsm != NULL) { + panel_set_device_widget_details (device_mobile->priv->builder, "provider", gsm); + } else if (cdma != NULL) { + panel_set_device_widget_details (device_mobile->priv->builder, "provider", cdma); + } else { + panel_set_device_widget_details (device_mobile->priv->builder, "provider", NULL); + } + } } static void nm_device_mobile_refresh_ui (NetDeviceMobile *device_mobile) { - const char *str; gboolean is_connected; - GString *status; GtkListStore *liststore; GtkWidget *widget; - guint speed = 0; NetDeviceMobilePrivate *priv = device_mobile->priv; NMClient *client; NMDeviceModemCapabilities caps; NMDevice *nm_device; - /* set device kind */ nm_device = net_device_get_nm_device (NET_DEVICE (device_mobile)); + + /* set device kind */ widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "label_device")); - gtk_label_set_label (GTK_LABEL (widget), - panel_device_to_localized_string (nm_device)); + g_object_bind_property (device_mobile, "title", widget, "label", 0); /* set up the device on/off switch */ widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "device_off_switch")); @@ -252,17 +398,8 @@ client = net_object_get_client (NET_OBJECT (device_mobile)); mobilebb_enabled_toggled (client, NULL, device_mobile); - /* set device state, with status and optionally speed */ - widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, "label_status")); - status = g_string_new (panel_device_state_to_localized_string (nm_device)); - if (speed > 0) { - g_string_append (status, " - "); - /* Translators: network device speed */ - g_string_append_printf (status, _("%d Mb/s"), speed); - } - gtk_label_set_label (GTK_LABEL (widget), status->str); - g_string_free (status, TRUE); - gtk_widget_set_tooltip_text (widget, panel_device_state_reason_to_localized_string (nm_device)); + /* set device state, with status */ + panel_set_device_status (device_mobile->priv->builder, "label_status", nm_device, NULL); /* sensitive for other connection types if the device is currently connected */ widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, @@ -272,20 +409,10 @@ caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (nm_device)); if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || - (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) { - /* IMEI */ - str = g_object_get_data (G_OBJECT (nm_device), - "ControlCenter::EquipmentIdentifier"); - panel_set_device_widget_details (device_mobile->priv->builder, - "imei", - str); - - /* operator name */ - str = g_object_get_data (G_OBJECT (nm_device), - "ControlCenter::OperatorName"); - panel_set_device_widget_details (device_mobile->priv->builder, - "provider", - str); + (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) || + (caps & NM_DEVICE_MODEM_CAPABILITY_LTE)) { + device_mobile_refresh_operator_name (device_mobile); + device_mobile_refresh_equipment_id (device_mobile); } /* add possible connections to device */ @@ -313,7 +440,6 @@ GParamSpec *pspec, NetDeviceMobile *device_mobile) { - const gchar *path; const GPtrArray *acs; gboolean active; gint i; @@ -330,21 +456,23 @@ connection = net_device_get_find_connection (NET_DEVICE (device_mobile)); if (connection == NULL) return; - nm_client_activate_connection (client, - connection, - net_device_get_nm_device (NET_DEVICE (device_mobile)), - NULL, NULL, NULL); + nm_client_activate_connection_async (client, + connection, + net_device_get_nm_device (NET_DEVICE (device_mobile)), + NULL, NULL, NULL, NULL); } else { + const gchar *uuid; + connection = net_device_get_find_connection (NET_DEVICE (device_mobile)); if (connection == NULL) return; - path = nm_connection_get_path (connection); + uuid = nm_connection_get_uuid (connection); client = net_object_get_client (NET_OBJECT (device_mobile)); acs = nm_client_get_active_connections (client); - for (i = 0; i < acs->len; i++) { + for (i = 0; acs && i < acs->len; i++) { a = (NMActiveConnection*)acs->pdata[i]; - if (strcmp (nm_active_connection_get_connection (a), path) == 0) { - nm_client_deactivate_connection (client, a); + if (strcmp (nm_active_connection_get_uuid (a), uuid) == 0) { + nm_client_deactivate_connection (client, a, NULL, NULL); break; } } @@ -359,20 +487,20 @@ static void device_mobile_device_got_modem_manager_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) + GAsyncResult *res, + gpointer user_data) { GError *error = NULL; GVariant *result = NULL; GDBusProxy *proxy; - NMDevice *device = (NMDevice *) user_data; + NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; proxy = g_dbus_proxy_new_for_bus_finish (res, &error); - if (proxy == NULL) { + if (!proxy) { g_warning ("Error creating ModemManager proxy: %s", error->message); g_error_free (error); - goto out; + return; } /* get the IMEI */ @@ -380,27 +508,48 @@ "EquipmentIdentifier"); /* save */ - g_object_set_data_full (G_OBJECT (device), - "ControlCenter::EquipmentIdentifier", - g_variant_dup_string (result, NULL), - g_free); -out: - if (result != NULL) + if (result) { + g_object_set_data_full (G_OBJECT (device_mobile), + "ControlCenter::EquipmentIdentifier", + g_variant_dup_string (result, NULL), + g_free); g_variant_unref (result); - if (proxy != NULL) - g_object_unref (proxy); + } + + device_mobile_refresh_equipment_id (device_mobile); + g_object_unref (proxy); } static void -device_mobile_get_registration_info_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +device_mobile_save_operator_name (NetDeviceMobile *device_mobile, + const gchar *field, + const gchar *operator_name) +{ + gchar *operator_name_safe = NULL; + + if (operator_name != NULL && operator_name[0] != '\0') + operator_name_safe = g_strescape (operator_name, NULL); + + /* save */ + g_object_set_data_full (G_OBJECT (device_mobile), + field, + operator_name_safe, + g_free); + /* refresh */ + device_mobile_refresh_operator_name (device_mobile); +} + +static void +device_mobile_get_registration_info_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { gchar *operator_code = NULL; GError *error = NULL; guint registration_status; GVariant *result = NULL; gchar *operator_name = NULL; - gchar *operator_name_safe = NULL; - NMDevice *device = (NMDevice *) user_data; + NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); if (result == NULL) { @@ -415,14 +564,17 @@ ®istration_status, &operator_code, &operator_name); - if (operator_name != NULL && operator_name[0] != '\0') - operator_name_safe = g_strescape (operator_name, NULL); - /* save */ - g_object_set_data_full (G_OBJECT (device), - "ControlCenter::OperatorName", - operator_name_safe, - g_free); + /* If none give, try to guess it */ + if (operator_name == NULL || operator_name[0] == '\0') { + g_free (operator_name); + operator_name = device_mobile_find_provider (device_mobile, operator_code, 0); + } + + /* save and refresh */ + device_mobile_save_operator_name (device_mobile, + "ControlCenter::OperatorNameGsm", + operator_name); g_free (operator_name); g_free (operator_code); @@ -430,33 +582,138 @@ } static void -device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +device_mobile_gsm_signal_cb (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + guint registration_status = 0; + gchar *operator_code = NULL; + gchar *operator_name = NULL; + NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; + + if (!g_str_equal (signal_name, "RegistrationInfo")) + return; + + g_variant_get (parameters, + "(uss)", + ®istration_status, + &operator_code, + &operator_name); + + /* If none given, try to guess it */ + if (operator_name == NULL || operator_name[0] == '\0') { + g_free (operator_name); + operator_name = device_mobile_find_provider (device_mobile, operator_code, 0); + } + + /* save and refresh */ + device_mobile_save_operator_name (device_mobile, + "ControlCenter::OperatorNameGsm", + operator_name); + + g_free (operator_code); + g_free (operator_name); +} + +static void +device_mobile_device_got_modem_manager_gsm_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { GError *error = NULL; - GDBusProxy *proxy; - NMDevice *device = (NMDevice *) user_data; + NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); - if (proxy == NULL) { + device_mobile->priv->gsm_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + if (device_mobile->priv->gsm_proxy == NULL) { g_warning ("Error creating ModemManager GSM proxy: %s\n", error->message); g_error_free (error); - goto out; + return; } - g_dbus_proxy_call (proxy, + /* Setup value updates */ + g_signal_connect (device_mobile->priv->gsm_proxy, + "g-signal", + G_CALLBACK (device_mobile_gsm_signal_cb), + device_mobile); + + /* Load initial value */ + g_dbus_proxy_call (device_mobile->priv->gsm_proxy, "GetRegistrationInfo", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, device_mobile_get_registration_info_cb, - device); -out: - if (proxy != NULL) - g_object_unref (proxy); + device_mobile); +} + +static void +device_mobile_get_serving_system_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; + GVariant *result = NULL; + GError *error = NULL; + + guint32 band_class; + gchar *band; + guint32 sid; + gchar *operator_name; + + result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error); + if (result == NULL) { + g_warning ("Error getting serving system: %s\n", + error->message); + g_error_free (error); + return; + } + + /* get values */ + g_variant_get (result, "((usu))", + &band_class, + &band, + &sid); + + operator_name = device_mobile_find_provider (device_mobile, NULL, sid); + + /* save and refresh */ + device_mobile_save_operator_name (device_mobile, + "ControlCenter::OperatorNameCdma", + operator_name); + + g_free (band); + g_variant_unref (result); +} + +static void +device_mobile_device_got_modem_manager_cdma_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + NetDeviceMobile *device_mobile = (NetDeviceMobile *)user_data; + + device_mobile->priv->cdma_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + if (device_mobile->priv->cdma_proxy == NULL) { + g_warning ("Error creating ModemManager CDMA proxy: %s\n", + error->message); + g_error_free (error); + return; + } + + /* Load initial value */ + g_dbus_proxy_call (device_mobile->priv->cdma_proxy, + "GetServingSystem", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + device_mobile_get_serving_system_cb, + device_mobile); } static void @@ -466,46 +723,151 @@ NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object); NMClient *client; NMDevice *device; + NMDeviceModemCapabilities caps; G_OBJECT_CLASS (net_device_mobile_parent_class)->constructed (object); device = net_device_get_nm_device (NET_DEVICE (device_mobile)); cancellable = net_object_get_cancellable (NET_OBJECT (device_mobile)); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.ModemManager", - nm_device_get_udi (device), - "org.freedesktop.ModemManager.Modem", - cancellable, - device_mobile_device_got_modem_manager_cb, - device); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.ModemManager", - nm_device_get_udi (device), - "org.freedesktop.ModemManager.Modem.Gsm.Network", - cancellable, - device_mobile_device_got_modem_manager_gsm_cb, - device); + + caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); + + /* Only load proxies if we have broadband modems of the OLD ModemManager interface */ + if (g_str_has_prefix (nm_device_get_udi (device), "/org/freedesktop/ModemManager/") && + ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || + (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) || + (caps & NM_DEVICE_MODEM_CAPABILITY_LTE))) { + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.ModemManager", + nm_device_get_udi (device), + "org.freedesktop.ModemManager.Modem", + cancellable, + device_mobile_device_got_modem_manager_cb, + device_mobile); + + if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || + (caps & NM_DEVICE_MODEM_CAPABILITY_LTE)) { + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.ModemManager", + nm_device_get_udi (device), + "org.freedesktop.ModemManager.Modem.Gsm.Network", + cancellable, + device_mobile_device_got_modem_manager_gsm_cb, + device_mobile); + } + + if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) { + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.ModemManager", + nm_device_get_udi (device), + "org.freedesktop.ModemManager.Modem.Cdma", + cancellable, + device_mobile_device_got_modem_manager_cdma_cb, + device_mobile); + } + } client = net_object_get_client (NET_OBJECT (device_mobile)); - g_signal_connect (client, "notify::wwan-enabled", - G_CALLBACK (mobilebb_enabled_toggled), - device_mobile); + g_signal_connect_object (client, "notify::wwan-enabled", + G_CALLBACK (mobilebb_enabled_toggled), + device_mobile, 0); nm_device_mobile_refresh_ui (device_mobile); } static void -net_device_mobile_finalize (GObject *object) +operator_name_updated (MMModem3gpp *modem_3gpp_iface, + GParamSpec *pspec, + NetDeviceMobile *self) +{ + device_mobile_refresh_operator_name (self); +} + +static void +net_device_mobile_setup_modem_object (NetDeviceMobile *self) +{ + MMModem3gpp *modem_3gpp; + + if (self->priv->mm_object == NULL) + return; + + /* Load equipment ID initially */ + device_mobile_refresh_equipment_id (self); + + /* Follow changes in operator name and load initial values */ + modem_3gpp = mm_object_peek_modem_3gpp (self->priv->mm_object); + if (modem_3gpp != NULL) { + g_assert (self->priv->operator_name_updated == 0); + self->priv->operator_name_updated = g_signal_connect (modem_3gpp, + "notify::operator-name", + G_CALLBACK (operator_name_updated), + self); + device_mobile_refresh_operator_name (self); + } +} + + +static void +net_device_mobile_get_property (GObject *device_, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NetDeviceMobile *self = NET_DEVICE_MOBILE (device_); + + switch (prop_id) { + case PROP_MODEM_OBJECT: + g_value_set_object (value, self->priv->mm_object); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + break; + } +} + +static void +net_device_mobile_set_property (GObject *device_, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + NetDeviceMobile *self = NET_DEVICE_MOBILE (device_); + + switch (prop_id) { + case PROP_MODEM_OBJECT: + self->priv->mm_object = g_value_dup_object (value); + net_device_mobile_setup_modem_object (self); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec); + break; + } +} + +static void +net_device_mobile_dispose (GObject *object) { NetDeviceMobile *device_mobile = NET_DEVICE_MOBILE (object); NetDeviceMobilePrivate *priv = device_mobile->priv; - g_object_unref (priv->builder); + g_clear_object (&priv->builder); + g_clear_object (&priv->gsm_proxy); + g_clear_object (&priv->cdma_proxy); + + if (priv->operator_name_updated) { + g_assert (priv->mm_object != NULL); + g_signal_handler_disconnect (mm_object_peek_modem_3gpp (priv->mm_object), priv->operator_name_updated); + priv->operator_name_updated = 0; + } + g_clear_object (&priv->mm_object); + g_clear_object (&priv->mpd); - G_OBJECT_CLASS (net_device_mobile_parent_class)->finalize (object); + G_OBJECT_CLASS (net_device_mobile_parent_class)->dispose (object); } static void @@ -514,11 +876,22 @@ GObjectClass *object_class = G_OBJECT_CLASS (klass); NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); - object_class->finalize = net_device_mobile_finalize; + object_class->dispose = net_device_mobile_dispose; object_class->constructed = net_device_mobile_constructed; + object_class->get_property = net_device_mobile_get_property; + object_class->set_property = net_device_mobile_set_property; parent_class->add_to_notebook = device_mobile_proxy_add_to_notebook; parent_class->refresh = device_mobile_refresh; + g_type_class_add_private (klass, sizeof (NetDeviceMobilePrivate)); + + g_object_class_install_property (object_class, + PROP_MODEM_OBJECT, + g_param_spec_object ("mm-object", + NULL, + NULL, + MM_TYPE_OBJECT, + G_PARAM_READWRITE)); } static void @@ -532,9 +905,9 @@ device_mobile->priv = NET_DEVICE_MOBILE_GET_PRIVATE (device_mobile); device_mobile->priv->builder = gtk_builder_new (); - gtk_builder_add_from_file (device_mobile->priv->builder, - GNOMECC_UI_DIR "/network-mobile.ui", - &error); + gtk_builder_add_from_resource (device_mobile->priv->builder, + "/org/gnome/control-center/network/network-mobile.ui", + &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); @@ -564,9 +937,4 @@ "button_options")); g_signal_connect (widget, "clicked", G_CALLBACK (edit_connection), device_mobile); - - widget = GTK_WIDGET (gtk_builder_get_object (device_mobile->priv->builder, - "device_off_switch")); - g_signal_connect (widget, "notify::active", - G_CALLBACK (device_off_toggled), device_mobile); } diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.h unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.h 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-mobile.h 2019-05-01 13:21:41.000000000 +0000 @@ -23,9 +23,9 @@ #define __NET_DEVICE_MOBILE_H #include +#include #include "net-device.h" -#include "nm-connection.h" G_BEGIN_DECLS diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,299 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2011-2012 Richard Hughes + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include +#include + +#include + +#include "panel-common.h" + +#include "net-device-simple.h" + +#define NET_DEVICE_SIMPLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimplePrivate)) + +struct _NetDeviceSimplePrivate +{ + GtkBuilder *builder; + gboolean updating_device; +}; + +G_DEFINE_TYPE (NetDeviceSimple, net_device_simple, NET_TYPE_DEVICE) + +static GtkWidget * +device_simple_proxy_add_to_notebook (NetObject *object, + GtkNotebook *notebook, + GtkSizeGroup *heading_size_group) +{ + GtkWidget *widget; + NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); + + /* add widgets to size group */ + widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, + "heading_ipv4")); + gtk_size_group_add_widget (heading_size_group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, + "vbox6")); + gtk_notebook_append_page (notebook, widget, NULL); + return widget; +} + +static void +update_off_switch_from_device_state (GtkSwitch *sw, + NMDeviceState state, + NetDeviceSimple *device_simple) +{ + device_simple->priv->updating_device = TRUE; + switch (state) { + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_DEACTIVATING: + case NM_DEVICE_STATE_FAILED: + gtk_switch_set_active (sw, FALSE); + break; + default: + gtk_switch_set_active (sw, TRUE); + break; + } + device_simple->priv->updating_device = FALSE; +} + +static void +nm_device_simple_refresh_ui (NetDeviceSimple *device_simple) +{ + NetDeviceSimplePrivate *priv = device_simple->priv; + const char *hwaddr; + GtkWidget *widget; + char *speed = NULL; + NMDevice *nm_device; + NMDeviceState state; + + nm_device = net_device_get_nm_device (NET_DEVICE (device_simple)); + + /* set device kind */ + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_device")); + g_object_bind_property (device_simple, "title", widget, "label", 0); + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "image_device")); + gtk_image_set_from_icon_name (GTK_IMAGE (widget), + panel_device_to_icon_name (nm_device, FALSE), + GTK_ICON_SIZE_DIALOG); + + /* set up the device on/off switch */ + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "device_off_switch")); + state = nm_device_get_state (nm_device); + gtk_widget_set_visible (widget, + state != NM_DEVICE_STATE_UNAVAILABLE + && state != NM_DEVICE_STATE_UNMANAGED); + update_off_switch_from_device_state (GTK_SWITCH (widget), state, device_simple); + + /* set up the Options button */ + widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "button_options")); + gtk_widget_set_visible (widget, state != NM_DEVICE_STATE_UNMANAGED); + + /* set device state, with status and optionally speed */ + if (state != NM_DEVICE_STATE_UNAVAILABLE) + speed = net_device_simple_get_speed (device_simple); + panel_set_device_status (priv->builder, "label_status", nm_device, speed); + + /* device MAC */ + hwaddr = nm_device_get_hw_address (nm_device); + panel_set_device_widget_details (priv->builder, "mac", hwaddr); + + /* set IP entries */ + panel_set_device_widgets (priv->builder, nm_device); +} + +static void +device_simple_refresh (NetObject *object) +{ + NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); + nm_device_simple_refresh_ui (device_simple); +} + +static void +device_off_toggled (GtkSwitch *sw, + GParamSpec *pspec, + NetDeviceSimple *device_simple) +{ + const GPtrArray *acs; + gboolean active; + gint i; + NMActiveConnection *a; + NMConnection *connection; + NMClient *client; + + if (device_simple->priv->updating_device) + return; + + active = gtk_switch_get_active (sw); + if (active) { + client = net_object_get_client (NET_OBJECT (device_simple)); + connection = net_device_get_find_connection (NET_DEVICE (device_simple)); + if (connection == NULL) + return; + nm_client_activate_connection_async (client, + connection, + net_device_get_nm_device (NET_DEVICE (device_simple)), + NULL, NULL, NULL, NULL); + } else { + const gchar *uuid; + + connection = net_device_get_find_connection (NET_DEVICE (device_simple)); + if (connection == NULL) + return; + uuid = nm_connection_get_uuid (connection); + client = net_object_get_client (NET_OBJECT (device_simple)); + acs = nm_client_get_active_connections (client); + for (i = 0; acs && i < acs->len; i++) { + a = (NMActiveConnection*)acs->pdata[i]; + if (strcmp (nm_active_connection_get_uuid (a), uuid) == 0) { + nm_client_deactivate_connection (client, a, NULL, NULL); + break; + } + } + } +} + +static void +edit_connection (GtkButton *button, NetDeviceSimple *device_simple) +{ + net_object_edit (NET_OBJECT (device_simple)); +} + +static void +net_device_simple_constructed (GObject *object) +{ + NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); + + G_OBJECT_CLASS (net_device_simple_parent_class)->constructed (object); + + net_object_refresh (NET_OBJECT (device_simple)); +} + +static void +net_device_simple_finalize (GObject *object) +{ + NetDeviceSimple *device_simple = NET_DEVICE_SIMPLE (object); + NetDeviceSimplePrivate *priv = device_simple->priv; + + g_object_unref (priv->builder); + + G_OBJECT_CLASS (net_device_simple_parent_class)->finalize (object); +} + +static char * +device_simple_get_speed (NetDeviceSimple *simple) +{ + return NULL; +} + +static void +net_device_simple_class_init (NetDeviceSimpleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NetObjectClass *parent_class = NET_OBJECT_CLASS (klass); + NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass); + + object_class->finalize = net_device_simple_finalize; + object_class->constructed = net_device_simple_constructed; + parent_class->add_to_notebook = device_simple_proxy_add_to_notebook; + parent_class->refresh = device_simple_refresh; + simple_class->get_speed = device_simple_get_speed; + + g_type_class_add_private (klass, sizeof (NetDeviceSimplePrivate)); +} + +static void +net_device_simple_init (NetDeviceSimple *device_simple) +{ + GError *error = NULL; + GtkWidget *widget; + + device_simple->priv = NET_DEVICE_SIMPLE_GET_PRIVATE (device_simple); + + device_simple->priv->builder = gtk_builder_new (); + gtk_builder_add_from_resource (device_simple->priv->builder, + "/org/gnome/control-center/network/network-simple.ui", + &error); + if (error != NULL) { + g_warning ("Could not load interface file: %s", error->message); + g_error_free (error); + return; + } + + /* setup simple combobox model */ + widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, + "device_off_switch")); + g_signal_connect (widget, "notify::active", + G_CALLBACK (device_off_toggled), device_simple); + + widget = GTK_WIDGET (gtk_builder_get_object (device_simple->priv->builder, + "button_options")); + g_signal_connect (widget, "clicked", + G_CALLBACK (edit_connection), device_simple); +} + +char * +net_device_simple_get_speed (NetDeviceSimple *device_simple) +{ + NetDeviceSimpleClass *klass = NET_DEVICE_SIMPLE_GET_CLASS (device_simple); + + return klass->get_speed (device_simple); +} + +void +net_device_simple_add_row (NetDeviceSimple *device_simple, + const char *label_string, + const char *property_name) +{ + NetDeviceSimplePrivate *priv = device_simple->priv; + GtkGrid *grid; + GtkWidget *label, *value; + GtkStyleContext *context; + gint top_attach; + + grid = GTK_GRID (gtk_builder_get_object (priv->builder, "grid")); + + label = gtk_label_new (label_string); + gtk_widget_set_halign (label, GTK_ALIGN_END); + gtk_container_add (GTK_CONTAINER (grid), label); + + context = gtk_widget_get_style_context (label); + gtk_style_context_add_class (context, "dim-label"); + gtk_widget_show (label); + + gtk_container_child_get (GTK_CONTAINER (grid), label, + "top-attach", &top_attach, + NULL); + + value = gtk_label_new (NULL); + gtk_widget_set_halign (value, GTK_ALIGN_START); + g_object_bind_property (device_simple, property_name, value, "label", 0); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), value); + gtk_grid_attach (grid, value, 1, top_attach, 1, 1); + gtk_widget_show (value); +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.h unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-simple.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,67 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2011-2012 Richard Hughes + * Copyright (C) 2012 Red Hat, Inc. + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __NET_DEVICE_SIMPLE_H +#define __NET_DEVICE_SIMPLE_H + +#include + +#include "net-device.h" + +G_BEGIN_DECLS + +#define NET_TYPE_DEVICE_SIMPLE (net_device_simple_get_type ()) +#define NET_DEVICE_SIMPLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimple)) +#define NET_DEVICE_SIMPLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimpleClass)) +#define NET_IS_DEVICE_SIMPLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NET_TYPE_DEVICE_SIMPLE)) +#define NET_IS_DEVICE_SIMPLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NET_TYPE_DEVICE_SIMPLE)) +#define NET_DEVICE_SIMPLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NET_TYPE_DEVICE_SIMPLE, NetDeviceSimpleClass)) + +typedef struct _NetDeviceSimplePrivate NetDeviceSimplePrivate; +typedef struct _NetDeviceSimple NetDeviceSimple; +typedef struct _NetDeviceSimpleClass NetDeviceSimpleClass; + +struct _NetDeviceSimple +{ + NetDevice parent; + NetDeviceSimplePrivate *priv; +}; + +struct _NetDeviceSimpleClass +{ + NetDeviceClass parent_class; + + char *(*get_speed) (NetDeviceSimple *device_simple); +}; + +GType net_device_simple_get_type (void); + +char *net_device_simple_get_speed (NetDeviceSimple *device_simple); + +void net_device_simple_add_row (NetDeviceSimple *device_simple, + const char *label, + const char *property_name); + +G_END_DECLS + +#endif /* __NET_DEVICE_SIMPLE_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-wifi.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-wifi.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-wifi.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-device-wifi.c 2019-05-01 13:21:41.000000000 +0000 @@ -24,37 +24,40 @@ #include #include -//#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include "shell/list-box-helper.h" +#include "shell/hostname-helper.h" #include "network-dialogs.h" #include "panel-common.h" -#include "panel-cell-renderer-mode.h" -#include "panel-cell-renderer-signal.h" -#include "panel-cell-renderer-security.h" -#include "panel-cell-renderer-separator.h" -#include "panel-cell-renderer-text.h" -#include "panel-cell-renderer-pixbuf.h" +#include "connection-editor/net-connection-editor.h" #include "net-device-wifi.h" #define NET_DEVICE_WIFI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE_WIFI, NetDeviceWifiPrivate)) +typedef enum { + NM_AP_SEC_UNKNOWN, + NM_AP_SEC_NONE, + NM_AP_SEC_WEP, + NM_AP_SEC_WPA, + NM_AP_SEC_WPA2 +} NMAccessPointSecurity; + static void nm_device_wifi_refresh_ui (NetDeviceWifi *device_wifi); static void show_wifi_list (NetDeviceWifi *device_wifi); +static void populate_ap_list (NetDeviceWifi *device_wifi); +static void show_hotspot_ui (NetDeviceWifi *device_wifi); struct _NetDeviceWifiPrivate { GtkBuilder *builder; + GtkWidget *details_dialog; + GtkWidget *hotspot_dialog; + GtkSwitch *hotspot_switch; gboolean updating_device; gchar *selected_ssid_title; gchar *selected_connection_id; @@ -84,7 +87,6 @@ GtkSizeGroup *heading_size_group) { GtkWidget *widget; - GtkWindow *window; NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); /* add widgets to size group */ @@ -92,15 +94,9 @@ "heading_ipv4")); gtk_size_group_add_widget (heading_size_group, widget); - /* reparent */ - window = GTK_WINDOW (gtk_builder_get_object (device_wifi->priv->builder, - "window_tmp")); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); - g_object_ref (widget); - gtk_container_remove (GTK_CONTAINER (window), widget); gtk_notebook_append_page (notebook, widget, NULL); - g_object_unref (widget); return widget; } @@ -135,52 +131,10 @@ return type; } -static void -add_access_point (NetDeviceWifi *device_wifi, NMAccessPoint *ap, NMAccessPoint *active, NMDevice *device) -{ - const GByteArray *ssid; - const gchar *object_path; - gchar *ssid_text; - gboolean is_active_ap; - gchar *title; - GtkListStore *liststore_network; - GtkTreeIter treeiter; - NetDeviceWifiPrivate *priv = device_wifi->priv; - - ssid = nm_access_point_get_ssid (ap); - if (ssid == NULL) - return; - ssid_text = nm_utils_ssid_to_utf8 (ssid); - title = g_markup_escape_text (ssid_text, -1); - - is_active_ap = active && nm_utils_same_ssid (ssid, nm_access_point_get_ssid (active), TRUE); - liststore_network = GTK_LIST_STORE (gtk_builder_get_object (priv->builder, - "liststore_network")); - - object_path = nm_object_get_path (NM_OBJECT (ap)); - gtk_list_store_insert_with_values (liststore_network, - &treeiter, - -1, - COLUMN_ACCESS_POINT_ID, object_path, - COLUMN_TITLE, title, - COLUMN_SORT, ssid_text, - COLUMN_STRENGTH, nm_access_point_get_strength (ap), - COLUMN_MODE, nm_access_point_get_mode (ap), - COLUMN_SECURITY, get_access_point_security (ap), - COLUMN_ACTIVE, is_active_ap, - COLUMN_AP_IN_RANGE, TRUE, - COLUMN_AP_OUT_OF_RANGE, FALSE, - COLUMN_AP_IS_SAVED, FALSE, - -1); - g_free (ssid_text); - g_free (title); -} - static GPtrArray * panel_get_strongest_unique_aps (const GPtrArray *aps) { - const GByteArray *ssid; - const GByteArray *ssid_tmp; + GBytes *ssid, *ssid_tmp; GPtrArray *aps_unique = NULL; gboolean add_ap; guint i; @@ -209,18 +163,20 @@ g_assert (ssid_tmp); /* is this the same type and data? */ - if (nm_utils_same_ssid (ssid, ssid_tmp, TRUE)) { + if (nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), + g_bytes_get_data (ssid_tmp, NULL), g_bytes_get_size (ssid_tmp), + TRUE)) { g_debug ("found duplicate: %s", - nm_utils_escape_ssid (ssid_tmp->data, - ssid_tmp->len)); + nm_utils_escape_ssid (g_bytes_get_data (ssid_tmp, NULL), + g_bytes_get_size (ssid_tmp))); /* the new access point is stronger */ if (nm_access_point_get_strength (ap) > nm_access_point_get_strength (ap_tmp)) { g_debug ("removing %s", - nm_utils_escape_ssid (ssid_tmp->data, - ssid_tmp->len)); + nm_utils_escape_ssid (g_bytes_get_data (ssid_tmp, NULL), + g_bytes_get_size (ssid_tmp))); g_ptr_array_remove (aps_unique, ap_tmp); add_ap = TRUE; } else { @@ -232,8 +188,8 @@ } if (add_ap) { g_debug ("adding %s", - nm_utils_escape_ssid (ssid->data, - ssid->len)); + nm_utils_escape_ssid (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid))); g_ptr_array_add (aps_unique, g_object_ref (ap)); } } @@ -280,6 +236,18 @@ } static void +net_device_wifi_access_point_changed (NMDeviceWifi *nm_device_wifi, + NMAccessPoint *ap, + gpointer user_data) +{ + NetDeviceWifi *device_wifi; + + device_wifi = NET_DEVICE_WIFI (user_data); + + populate_ap_list (device_wifi); +} + +static void wireless_enabled_toggled (NMClient *client, GParamSpec *pspec, NetDeviceWifi *device_wifi) @@ -301,43 +269,17 @@ device_wifi->priv->updating_device = FALSE; } -#if 0 -static void -update_off_switch_from_device_state (GtkSwitch *sw, - NMDeviceState state, - NetDeviceWifi *device_wifi) -{ - device_wifi->priv->updating_device = TRUE; - switch (state) { - case NM_DEVICE_STATE_UNMANAGED: - case NM_DEVICE_STATE_UNAVAILABLE: - case NM_DEVICE_STATE_DISCONNECTED: - case NM_DEVICE_STATE_DEACTIVATING: - case NM_DEVICE_STATE_FAILED: - gtk_switch_set_active (sw, FALSE); - break; - default: - gtk_switch_set_active (sw, TRUE); - break; - } - device_wifi->priv->updating_device = FALSE; -} -#endif - static NMConnection * find_connection_for_device (NetDeviceWifi *device_wifi, NMDevice *device) { NetDevice *tmp; NMConnection *connection; - NMRemoteSettings *remote_settings; NMClient *client; client = net_object_get_client (NET_OBJECT (device_wifi)); - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); tmp = g_object_new (NET_TYPE_DEVICE, "client", client, - "remote-settings", remote_settings, "nm-device", device, NULL); connection = net_device_get_find_connection (tmp); @@ -348,10 +290,10 @@ static gboolean connection_is_shared (NMConnection *c) { - NMSettingIP4Config *s_ip4; + NMSettingIPConfig *s_ip4; s_ip4 = nm_connection_get_setting_ip4_config (c); - if (g_strcmp0 (nm_setting_ip4_config_get_method (s_ip4), + if (g_strcmp0 (nm_setting_ip_config_get_method (s_ip4), NM_SETTING_IP4_CONFIG_METHOD_SHARED) != 0) { return FALSE; } @@ -366,6 +308,9 @@ NMDevice *device; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + if (nm_device_get_active_connection (device) == NULL) + return FALSE; + c = find_connection_for_device (device_wifi, device); if (c == NULL) return FALSE; @@ -373,7 +318,7 @@ return connection_is_shared (c); } -static const GByteArray * +static GBytes * device_get_hotspot_ssid (NetDeviceWifi *device_wifi, NMDevice *device) { @@ -390,18 +335,23 @@ } static void -get_secrets_cb (NMRemoteConnection *c, - GHashTable *secrets, - GError *error, +get_secrets_cb (GObject *source_object, + GAsyncResult *res, gpointer data) { NetDeviceWifi *device_wifi = data; - NMSettingWireless *sw; + GVariant *secrets; + GError *error = NULL; - sw = nm_connection_get_setting_wireless (NM_CONNECTION (c)); + secrets = nm_remote_connection_get_secrets_finish (NM_REMOTE_CONNECTION (source_object), res, &error); + if (!secrets) { + g_error_free (error); + //FIXME ignore cancelled + return; + } - nm_connection_update_secrets (NM_CONNECTION (c), - nm_setting_wireless_get_security (sw), + nm_connection_update_secrets (NM_CONNECTION (source_object), + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, secrets, NULL); nm_device_wifi_refresh_ui (device_wifi); @@ -414,7 +364,6 @@ gchar **security) { NMConnection *c; - NMSettingWireless *sw; NMSettingWirelessSecurity *sws; const gchar *key_mgmt; const gchar *tmp_secret; @@ -424,20 +373,25 @@ if (c == NULL) return; - sw = nm_connection_get_setting_wireless (c); sws = nm_connection_get_setting_wireless_security (c); - if (sw == NULL || sws == NULL) + if (sws == NULL) return; tmp_secret = NULL; tmp_security = C_("Wifi security", "None"); + /* Key management values: + * "none" = WEP + * "wpa-none" = WPAv1 Ad-Hoc mode (not supported in NM >= 0.9.4) + * "wpa-psk" = WPAv2 Ad-Hoc mode (eg IBSS RSN) and AP-mode WPA v1 and v2 + */ key_mgmt = nm_setting_wireless_security_get_key_mgmt (sws); if (strcmp (key_mgmt, "none") == 0) { tmp_secret = nm_setting_wireless_security_get_wep_key (sws, 0); tmp_security = _("WEP"); } - else if (strcmp (key_mgmt, "wpa-none") == 0) { + else if (strcmp (key_mgmt, "wpa-none") == 0 || + strcmp (key_mgmt, "wpa-psk") == 0) { tmp_secret = nm_setting_wireless_security_get_psk (sws); tmp_security = _("WPA"); } else { @@ -448,10 +402,11 @@ * We'll refresh the UI when secrets arrive. */ if (tmp_secret == NULL) { - nm_remote_connection_get_secrets ((NMRemoteConnection*)c, - nm_setting_wireless_get_security (sw), - get_secrets_cb, - device_wifi); + nm_remote_connection_get_secrets_async ((NMRemoteConnection*)c, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL, + get_secrets_cb, + device_wifi); return; } @@ -462,137 +417,9 @@ } static void -device_wifi_refresh_aps (NetDeviceWifi *device_wifi) -{ - const GPtrArray *aps; - GPtrArray *aps_unique = NULL; - GtkListStore *liststore_network; - guint i; - NMAccessPoint *active_ap; - NMAccessPoint *ap; - NMDevice *nm_device; - - /* populate access points */ - liststore_network = GTK_LIST_STORE (gtk_builder_get_object (device_wifi->priv->builder, - "liststore_network")); - device_wifi->priv->updating_device = TRUE; - gtk_list_store_clear (liststore_network); - nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); - aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device)); - aps_unique = panel_get_strongest_unique_aps (aps); - active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); - - for (i = 0; i < aps_unique->len; i++) { - ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i)); - add_access_point (device_wifi, ap, active_ap, nm_device); - } - - device_wifi->priv->updating_device = FALSE; - g_ptr_array_unref (aps_unique); -} - -static gboolean -find_ssid_in_store (GtkTreeModel *model, GtkTreeIter *iter, const gchar *ssid) -{ - gboolean found; - gchar *sort; - - found = gtk_tree_model_get_iter_first (model, iter); - - while (found) { - gtk_tree_model_get (model, iter, - COLUMN_SORT, &sort, - -1); - if (g_strcmp0 (ssid, sort) == 0) { - g_free (sort); - return TRUE; - } - g_free (sort); - found = gtk_tree_model_iter_next (model, iter); - } - - return FALSE; - -} - -static void -add_saved_connection (NetDeviceWifi *device_wifi, NMConnection *connection, NMDevice *nm_device) -{ - const GByteArray *ssid; - const gchar *id; - gchar *ssid_text; - gchar *title; - GtkListStore *store; - GtkTreeIter iter; - NMSetting *setting; - - setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME); - - if (setting == NULL) - return; - - ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting)); - ssid_text = nm_utils_ssid_to_utf8 (ssid); - title = g_markup_escape_text (ssid_text, -1); - g_debug ("got saved %s", title); - - id = nm_connection_get_path (connection); - - store = GTK_LIST_STORE (gtk_builder_get_object (device_wifi->priv->builder, - "liststore_network")); - if (find_ssid_in_store (GTK_TREE_MODEL (store), &iter, ssid_text)) - gtk_list_store_set (store, &iter, - COLUMN_CONNECTION_ID, id, - COLUMN_AP_IS_SAVED, TRUE, - -1); - else - gtk_list_store_insert_with_values (store, &iter, - -1, - COLUMN_CONNECTION_ID, id, - COLUMN_TITLE, title, - COLUMN_SORT, ssid_text, - COLUMN_STRENGTH, 0, - COLUMN_MODE, 0, - COLUMN_SECURITY, 0, - COLUMN_ACTIVE, FALSE, - COLUMN_AP_IN_RANGE, FALSE, - COLUMN_AP_OUT_OF_RANGE, TRUE, - COLUMN_AP_IS_SAVED, TRUE, - -1); - g_free (title); - g_free (ssid_text); -} - -static void -device_wifi_refresh_saved_connections (NetDeviceWifi *device_wifi) -{ - GSList *connections; - GSList *filtered; - GSList *l; - NMDevice *nm_device; - NMRemoteSettings *remote_settings; - - /* add stored connections */ - device_wifi->priv->updating_device = TRUE; - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); - connections = nm_remote_settings_list_connections (remote_settings); - nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); - filtered = nm_device_filter_connections (nm_device, connections); - for (l = filtered; l; l = l->next) { - NMConnection *connection = l->data; - if (!connection_is_shared (connection)) - add_saved_connection (device_wifi, connection, nm_device); - } - device_wifi->priv->updating_device = FALSE; - - g_slist_free (connections); - g_slist_free (filtered); -} - -static void nm_device_wifi_refresh_hotspot (NetDeviceWifi *device_wifi) { - const GByteArray *ssid; + GBytes *ssid; gchar *hotspot_secret = NULL; gchar *hotspot_security = NULL; gchar *hotspot_ssid = NULL; @@ -602,7 +429,7 @@ nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); ssid = device_get_hotspot_ssid (device_wifi, nm_device); if (ssid) - hotspot_ssid = nm_utils_ssid_to_utf8 (ssid); + hotspot_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); device_get_hotspot_security_details (device_wifi, nm_device, &hotspot_secret, @@ -627,26 +454,17 @@ } static void -update_last_used (NetDeviceWifi *device_wifi) +update_last_used (NetDeviceWifi *device_wifi, NMConnection *connection) { - NetDeviceWifiPrivate *priv = device_wifi->priv; gchar *last_used = NULL; GDateTime *now = NULL; GDateTime *then = NULL; gint days; GTimeSpan diff; guint64 timestamp; - NMRemoteConnection *connection; - NMRemoteSettings *settings; NMSettingConnection *s_con; - if (priv->selected_connection_id == NULL) - goto out; - - settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); - connection = nm_remote_settings_get_connection_by_path (settings, - priv->selected_connection_id); - s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); + s_con = nm_connection_get_setting_connection (connection); if (s_con == NULL) goto out; timestamp = nm_setting_connection_get_timestamp (s_con); @@ -683,7 +501,6 @@ const gchar *str; gboolean is_hotspot; gchar *str_tmp = NULL; - GtkWidget *widget; gint strength = 0; guint speed = 0; NMAccessPoint *active_ap; @@ -691,23 +508,23 @@ NMDeviceState state; NMClient *client; NMAccessPoint *ap; + NMConnection *connection; NetDeviceWifiPrivate *priv = device_wifi->priv; + GtkWidget *dialog; is_hotspot = device_is_hotspot (device_wifi); if (is_hotspot) { nm_device_wifi_refresh_hotspot (device_wifi); + show_hotspot_ui (device_wifi); return; } nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); - if (priv->selected_ap_id) { - ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (nm_device), - priv->selected_ap_id); - } - else { - ap = NULL; - } + dialog = device_wifi->priv->details_dialog; + + ap = g_object_get_data (G_OBJECT (dialog), "ap"); + connection = g_object_get_data (G_OBJECT (dialog), "connection"); active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); @@ -730,20 +547,6 @@ "speed", str_tmp); - /* set device state, with status and optionally speed */ - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "label_status")); - if (ap != active_ap) { - if (ap) - gtk_label_set_label (GTK_LABEL (widget), _("Not connected")); - else - gtk_label_set_label (GTK_LABEL (widget), _("Out of range")); - gtk_widget_set_tooltip_text (widget, ""); - } else { - gtk_label_set_label (GTK_LABEL (widget), - panel_device_state_to_localized_string (nm_device)); - gtk_widget_set_tooltip_text (widget, panel_device_state_reason_to_localized_string (nm_device)); - } - /* device MAC */ str = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (nm_device)); panel_set_device_widget_details (device_wifi->priv->builder, @@ -780,29 +583,6 @@ "strength", str); - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "label_device")); - gtk_label_set_label (GTK_LABEL (widget), - priv->selected_ssid_title ? priv->selected_ssid_title : panel_device_to_localized_string (nm_device)); - - /* only disconnect when connection active */ - if (ap == active_ap) { - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_disconnect1")); - gtk_widget_set_sensitive (widget, state == NM_DEVICE_STATE_ACTIVATED); - gtk_widget_show (widget); - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_connect1")); - gtk_widget_hide (widget); - } else { - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_disconnect1")); - gtk_widget_hide (widget); - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_connect1")); - gtk_widget_show (widget); - gtk_widget_set_sensitive (widget, ap != NULL); - } - /* device MAC */ if (ap != active_ap) str = NULL; @@ -816,14 +596,16 @@ else panel_set_device_widgets (priv->builder, nm_device); - if (ap != active_ap) - update_last_used (device_wifi); + if (ap != active_ap && connection) + update_last_used (device_wifi, connection); else panel_set_device_widget_details (priv->builder, "last_used", NULL); + panel_set_device_status (priv->builder, "heading_status", nm_device, NULL); + /* update list of APs */ - device_wifi_refresh_aps (device_wifi); - device_wifi_refresh_saved_connections (device_wifi); + show_wifi_list (device_wifi); + populate_ap_list (device_wifi); } static void @@ -849,205 +631,59 @@ nm_client_wireless_set_enabled (client, active); } - -static gboolean -find_connection_id_in_store (GtkTreeModel *model, - GtkTreeIter *iter, - const gchar *connection_id) -{ - gboolean found; - gchar *id; - - found = gtk_tree_model_get_iter_first (model, iter); - while (found) { - gtk_tree_model_get (model, iter, - COLUMN_CONNECTION_ID, &id, - -1); - if (g_strcmp0 (connection_id, id) == 0) { - g_free (id); - return TRUE; - } - g_free (id); - found = gtk_tree_model_iter_next (model, iter); - } - return FALSE; -} - -static void -forget_network_connection_delete_cb (NMRemoteConnection *connection, - GError *error, - gpointer user_data) -{ - gboolean ret; - GtkTreeIter iter; - GtkTreeModel *model; - GtkTreeView *treeview; - - NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (user_data); - - if (error != NULL) { - g_warning ("failed to delete connection %s: %s", - nm_object_get_path (NM_OBJECT (connection)), - error->message); - return; - } - - /* remove the entry from the list */ - treeview = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder, - "treeview_list")); - model = gtk_tree_view_get_model (treeview); - ret = find_connection_id_in_store (model, &iter, - device_wifi->priv->selected_connection_id); - if (ret) - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - show_wifi_list (device_wifi); -} - -static void -forget_network_response_cb (GtkWidget *dialog, - gint response, - NetDeviceWifi *device_wifi) -{ - NMRemoteConnection *connection; - NMRemoteSettings *remote_settings; - - if (response != GTK_RESPONSE_OK) - goto out; - - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); - connection = nm_remote_settings_get_connection_by_path (remote_settings, device_wifi->priv->selected_connection_id); - if (connection == NULL) { - g_warning ("failed to get remote connection"); - goto out; - } - - /* delete the connection */ - g_debug ("deleting %s", device_wifi->priv->selected_connection_id); - nm_remote_connection_delete (connection, - forget_network_connection_delete_cb, - device_wifi); -out: - gtk_widget_destroy (dialog); -} - -static void -disconnect_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi) -{ - NMDevice *device; - device = net_device_get_nm_device (NET_DEVICE (device_wifi)); - if (device == NULL) - return; - nm_device_disconnect (device, NULL, NULL); -} - -static void activate_connection (NetDeviceWifi *device, const gchar *id); - -static void -connect_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi) -{ - if (device_wifi->priv->selected_connection_id) - activate_connection (device_wifi, device_wifi->priv->selected_connection_id); -} - -static void -forget_button_clicked_cb (GtkButton *button, NetDeviceWifi *device_wifi) -{ - gchar *ssid_pretty = NULL; - gchar *warning = NULL; - GtkWidget *dialog; - GtkWidget *window; - CcNetworkPanel *panel; - - ssid_pretty = g_strdup_printf ("%s", device_wifi->priv->selected_ssid_title); - warning = g_strdup_printf (_("Network details for %s including password and any custom configuration will be lost."), ssid_pretty); - panel = net_object_get_panel (NET_OBJECT (device_wifi)); - window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); - dialog = gtk_message_dialog_new (GTK_WINDOW (window), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_OTHER, - GTK_BUTTONS_NONE, - NULL); - gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), warning); - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - _("_Cancel"), GTK_RESPONSE_CANCEL, - _("Forget"), GTK_RESPONSE_OK, - NULL); - g_signal_connect (dialog, "response", - G_CALLBACK (forget_network_response_cb), device_wifi); - gtk_window_present (GTK_WINDOW (dialog)); - - g_free (ssid_pretty); - g_free (warning); -} - - static void connect_to_hidden_network (NetDeviceWifi *device_wifi) { - NMRemoteSettings *remote_settings; NMClient *client; CcNetworkPanel *panel; + GtkWidget *toplevel; - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); client = net_object_get_client (NET_OBJECT (device_wifi)); panel = net_object_get_panel (NET_OBJECT (device_wifi)); - cc_network_panel_connect_to_hidden_network (panel, client, remote_settings); + toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); + cc_network_panel_connect_to_hidden_network (toplevel, client); } static void -connection_add_activate_cb (NMClient *client, - NMActiveConnection *connection, - const char *path, - GError *error, +connection_add_activate_cb (GObject *source_object, + GAsyncResult *res, gpointer user_data) { - NetDeviceWifi *device_wifi = user_data; + NMActiveConnection *conn; + GError *error = NULL; - if (connection == NULL) { + conn = nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object), res, &error); + if (!conn) { + //FIXME cancelled + nm_device_wifi_refresh_ui (user_data); /* failed to activate */ g_debug ("Failed to add and activate connection '%d': %s", error->code, error->message); - nm_device_wifi_refresh_ui (device_wifi); + g_error_free (error); + return; } } static void -connection_activate_cb (NMClient *client, - NMActiveConnection *connection, - GError *error, +connection_activate_cb (GObject *source_object, + GAsyncResult *res, gpointer user_data) { - NetDeviceWifi *device_wifi = user_data; + GError *error = NULL; - if (connection == NULL) { + if (!nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { + //FIXME cancelled + nm_device_wifi_refresh_ui (user_data); /* failed to activate */ - g_debug ("Failed to activate connection '%d': %s", + g_debug ("Failed to add and activate connection '%d': %s", error->code, error->message); - nm_device_wifi_refresh_ui (device_wifi); + g_error_free (error); + return; } } -static void -activate_connection (NetDeviceWifi *device_wifi, - const gchar *connection_id) -{ - NMDevice *device; - NMClient *client; - NMRemoteSettings *settings; - NMRemoteConnection *connection; - - device = net_device_get_nm_device (NET_DEVICE (device_wifi)); - client = net_object_get_client (NET_OBJECT (device_wifi)); - settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); - connection = nm_remote_settings_get_connection_by_path (settings, connection_id); - nm_client_activate_connection (client, - NM_CONNECTION (connection), - device, NULL, - connection_activate_cb, device_wifi); -} - static gboolean is_8021x (NMDevice *device, const char *ap_object_path) @@ -1072,17 +708,15 @@ static void wireless_try_to_connect (NetDeviceWifi *device_wifi, - const gchar *ssid_target, + GBytes *ssid, const gchar *ap_object_path) { - const GByteArray *ssid; - gchar *ssid_tmp = NULL; + GBytes *match_ssid; + const gchar *ssid_target; GSList *list, *l; - GSList *filtered; NMConnection *connection_activate = NULL; NMDevice *device; NMSettingWireless *setting_wireless; - NMRemoteSettings *remote_settings; NMClient *client; if (device_wifi->priv->updating_device) @@ -1095,47 +729,43 @@ if (device == NULL) goto out; + ssid_target = nm_utils_escape_ssid ((gpointer) g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); g_debug ("try to connect to WIFI network %s [%s]", ssid_target, ap_object_path); /* look for an existing connection we can use */ - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); - list = nm_remote_settings_list_connections (remote_settings); - g_debug ("%i existing remote connections available", g_slist_length (list)); - filtered = nm_device_filter_connections (device, list); - g_debug ("%i suitable remote connections to check", g_slist_length (filtered)); - for (l = filtered; l; l = g_slist_next (l)) { + list = net_device_get_valid_connections (NET_DEVICE (device_wifi)); + g_debug ("%i suitable remote connections to check", g_slist_length (list)); + for (l = list; l; l = g_slist_next (l)) { NMConnection *connection; connection = NM_CONNECTION (l->data); setting_wireless = nm_connection_get_setting_wireless (connection); if (!NM_IS_SETTING_WIRELESS (setting_wireless)) continue; - ssid = nm_setting_wireless_get_ssid (setting_wireless); - if (ssid == NULL) + match_ssid = nm_setting_wireless_get_ssid (setting_wireless); + if (match_ssid == NULL) continue; - ssid_tmp = nm_utils_ssid_to_utf8 (ssid); - if (g_strcmp0 (ssid_target, ssid_tmp) == 0) { + if (g_bytes_equal (ssid, match_ssid)) { g_debug ("we found an existing connection %s to activate!", nm_connection_get_id (connection)); connection_activate = connection; break; } - g_free (ssid_tmp); - ssid_tmp = NULL; } - g_free (ssid_tmp); g_slist_free (list); - g_slist_free (filtered); /* activate the connection */ client = net_object_get_client (NET_OBJECT (device_wifi)); if (connection_activate != NULL) { - nm_client_activate_connection (client, - connection_activate, - device, NULL, - connection_activate_cb, device_wifi); + nm_client_activate_connection_async (client, + connection_activate, + device, + NULL, + NULL, + connection_activate_cb, + device_wifi); goto out; } @@ -1143,103 +773,57 @@ g_debug ("no existing connection found for %s, creating", ssid_target); if (!is_8021x (device, ap_object_path)) { + GPermission *permission; + gboolean allowed_to_share = FALSE; + NMConnection *partial = NULL; + + permission = polkit_permission_new_sync ("org.freedesktop.NetworkManager.settings.modify.system", + NULL, NULL, NULL); + if (permission) { + allowed_to_share = g_permission_get_allowed (permission); + g_object_unref (permission); + } + + if (!allowed_to_share) { + NMSettingConnection *s_con; + + s_con = (NMSettingConnection *)nm_setting_connection_new (); + nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL); + partial = nm_simple_connection_new (); + nm_connection_add_setting (partial, NM_SETTING (s_con)); + } + g_debug ("no existing connection found for %s, creating and activating one", ssid_target); - nm_client_add_and_activate_connection (client, - NULL, - device, ap_object_path, - connection_add_activate_cb, device_wifi); + nm_client_add_and_activate_connection_async (client, + partial, + device, + ap_object_path, + NULL, + connection_add_activate_cb, + device_wifi); + if (!allowed_to_share) + g_object_unref (partial); } else { CcNetworkPanel *panel; - GPtrArray *array; + GVariantBuilder *builder; + GVariant *parameters; g_debug ("no existing connection found for %s, creating", ssid_target); - array = g_ptr_array_new (); - g_ptr_array_add (array, "connect-8021x-wifi"); - g_ptr_array_add (array, (gpointer) nm_object_get_path (NM_OBJECT (device))); - g_ptr_array_add (array, (gpointer) ap_object_path); - g_ptr_array_add (array, NULL); + builder = g_variant_builder_new (G_VARIANT_TYPE ("av")); + g_variant_builder_add (builder, "v", g_variant_new_string ("connect-8021x-wifi")); + g_variant_builder_add (builder, "v", g_variant_new_string (nm_object_get_path (NM_OBJECT (device)))); + g_variant_builder_add (builder, "v", g_variant_new_string (ap_object_path)); + parameters = g_variant_new ("av", builder); panel = net_object_get_panel (NET_OBJECT (device_wifi)); - g_object_set (G_OBJECT (panel), "argv", array->pdata, NULL); + g_object_set (G_OBJECT (panel), "parameters", parameters, NULL); - g_ptr_array_free (array, FALSE); + g_variant_builder_unref (builder); } out: return; } -static gint -wireless_ap_model_sort_cb (GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) -{ - gboolean active_a; - gboolean active_b; - gboolean ap_a; - gboolean ap_b; - gchar *str_a; - gchar *str_b; - gint retval; - gint strength_a; - gint strength_b; - - gtk_tree_model_get (model, a, - COLUMN_SORT, &str_a, - COLUMN_STRENGTH, &strength_a, - COLUMN_ACTIVE, &active_a, - COLUMN_AP_IN_RANGE, &ap_a, - -1); - gtk_tree_model_get (model, b, - COLUMN_SORT, &str_b, - COLUMN_STRENGTH, &strength_b, - COLUMN_ACTIVE, &active_b, - COLUMN_AP_IN_RANGE, &ap_b, - -1); - - /* active entry first */ - if (active_a) { - retval = -1; - goto out; - } - - if (active_b) { - retval = 1; - goto out; - } - - /* aps before connections */ - if (ap_a && !ap_b) { - retval = -1; - goto out; - } - if (!ap_a && ap_b) { - retval = 1; - goto out; - } - - /* case sensitive search like before */ - retval = strength_b - strength_a; -out: - g_free (str_a); - g_free (str_b); - - return retval; -} - -static GByteArray * -ssid_to_byte_array (const gchar *ssid) -{ - guint32 len; - GByteArray *ba; - - len = strlen (ssid); - ba = g_byte_array_sized_new (len); - g_byte_array_append (ba, (guchar *)ssid, len); - - return ba; -} - static gchar * get_hostname (void) { @@ -1251,7 +835,7 @@ error = NULL; bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (error != NULL) { + if (bus == NULL) { g_warning ("Failed to get system bus connection: %s", error->message); g_error_free (error); @@ -1272,7 +856,7 @@ &error); g_object_unref (bus); - if (error != NULL) { + if (res == NULL) { g_warning ("Getting pretty hostname failed: %s", error->message); g_error_free (error); } @@ -1285,32 +869,54 @@ g_variant_unref (res); } - if (str == NULL || *str == '\0') { - str = g_strdup (g_get_host_name ()); - } - - if (str == NULL || *str == '\0') { - str = g_strdup ("GNOME"); - } - return str; } -static GByteArray * +static GBytes * generate_ssid_for_hotspot (NetDeviceWifi *device_wifi) { - GByteArray *ssid_array; - gchar *ssid; + GBytes *ssid_bytes; + gchar *hostname, *ssid; - ssid = get_hostname (); - ssid_array = ssid_to_byte_array (ssid); - g_free (ssid); + hostname = get_hostname (); + ssid = pretty_hostname_to_ssid (hostname); + g_free (hostname); - return ssid_array; + ssid_bytes = g_bytes_new_with_free_func (ssid, + strlen (ssid), + g_free, + NULL); + + return ssid_bytes; } -static gchar * -generate_wep_key (NetDeviceWifi *device_wifi) +#define WPA_PASSKEY_SIZE 8 +static void +set_wpa_key (NMSettingWirelessSecurity *sws) +{ + /* generate a 8-chars ASCII WPA key */ + char key[WPA_PASSKEY_SIZE + 1]; + guint i; + + for (i = 0; i < WPA_PASSKEY_SIZE; i++) { + gint c; + c = g_random_int_range (33, 126); + /* too many non alphanumeric characters are hard to remember for humans */ + while (!g_ascii_isalnum (c)) + c = g_random_int_range (33, 126); + + key[i] = (gchar) c; + } + key[WPA_PASSKEY_SIZE] = '\0'; + + g_object_set (sws, + "key-mgmt", "wpa-psk", + "psk", key, + NULL); +} + +static void +set_wep_key (NMSettingWirelessSecurity *sws) { gchar key[11]; gint i; @@ -1324,7 +930,11 @@ } key[10] = 0; - return g_strdup (key); + g_object_set (sws, + "key-mgmt", "none", + "wep-key0", key, + "wep-key-type", NM_WEP_KEY_TYPE_KEY, + NULL); } static gboolean @@ -1332,21 +942,24 @@ { NMSettingConnection *sc; NMSettingWireless *sw; - NMSettingIP4Config *sip; + NMSettingIPConfig *sip; + NMSetting *setting; sc = nm_connection_get_setting_connection (connection); if (g_strcmp0 (nm_setting_connection_get_connection_type (sc), "802-11-wireless") != 0) { return FALSE; } sw = nm_connection_get_setting_wireless (connection); - if (g_strcmp0 (nm_setting_wireless_get_mode (sw), "adhoc") != 0) { + if (g_strcmp0 (nm_setting_wireless_get_mode (sw), "adhoc") != 0 && + g_strcmp0 (nm_setting_wireless_get_mode (sw), "ap") != 0) { return FALSE; } - if (g_strcmp0 (nm_setting_wireless_get_security (sw), "802-11-wireless-security") != 0) { + setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME); + if (!setting) return FALSE; - } + sip = nm_connection_get_setting_ip4_config (connection); - if (g_strcmp0 (nm_setting_ip4_config_get_method (sip), "shared") != 0) { + if (g_strcmp0 (nm_setting_ip_config_get_method (sip), "shared") != 0) { return FALSE; } @@ -1357,99 +970,162 @@ show_hotspot_ui (NetDeviceWifi *device_wifi) { GtkWidget *widget; - GtkSwitch *sw; /* show hotspot tab */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); - gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 3); + gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1); /* force switch to on as this succeeded */ - sw = GTK_SWITCH (gtk_builder_get_object (device_wifi->priv->builder, - "switch_hotspot_off")); device_wifi->priv->updating_device = TRUE; - gtk_switch_set_active (sw, TRUE); + gtk_switch_set_active (device_wifi->priv->hotspot_switch, TRUE); device_wifi->priv->updating_device = FALSE; } static void -activate_cb (NMClient *client, - NMActiveConnection *connection, - GError *error, - NetDeviceWifi *device_wifi) +activate_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - if (error != NULL) { + GError *error = NULL; + + if (nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error) == NULL) { g_warning ("Failed to add new connection: (%d) %s", error->code, error->message); + g_error_free (error); return; } /* show hotspot tab */ - nm_device_wifi_refresh_ui (device_wifi); - show_hotspot_ui (device_wifi); + nm_device_wifi_refresh_ui (user_data); } static void -activate_new_cb (NMClient *client, - NMActiveConnection *connection, - const gchar *path, - GError *error, - NetDeviceWifi *device_wifi) +activate_new_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - activate_cb (client, connection, error, device_wifi); + NMActiveConnection *conn; + GError *error = NULL; + + conn = nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object), + res, &error); + if (!conn) { + g_warning ("Failed to add new connection: (%d) %s", + error->code, + error->message); + g_error_free (error); + return; + } + + /* show hotspot tab */ + nm_device_wifi_refresh_ui (user_data); +} + +static NMConnection * +net_device_wifi_get_hotspot_connection (NetDeviceWifi *device_wifi) +{ + GSList *connections, *l; + NMConnection *c = NULL; + + connections = net_device_get_valid_connections (NET_DEVICE (device_wifi)); + for (l = connections; l; l = l->next) { + NMConnection *tmp = l->data; + if (is_hotspot_connection (tmp)) { + c = tmp; + break; + } + } + g_slist_free (connections); + + return c; +} + +static void +overwrite_ssid_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + GError *error = NULL; + NMClient *client; + NMRemoteConnection *connection; + NMDevice *device; + NMConnection *c; + NetDeviceWifi *device_wifi; + + connection = NM_REMOTE_CONNECTION (source_object); + + if (!nm_remote_connection_commit_changes_finish (connection, res, &error)) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to save hotspot's settings to disk: %s", + error->message); + g_error_free (error); + return; + } + + device_wifi = user_data; + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + client = net_object_get_client (NET_OBJECT (device_wifi)); + c = net_device_wifi_get_hotspot_connection (device_wifi); + + g_debug ("activate existing hotspot connection\n"); + nm_client_activate_connection_async (client, + c, + device, + NULL, + NULL, + activate_cb, + device_wifi); } static void start_shared_connection (NetDeviceWifi *device_wifi) { NMConnection *c; - NMConnection *tmp; NMSettingConnection *sc; NMSettingWireless *sw; NMSettingIP4Config *sip; NMSettingWirelessSecurity *sws; NMDevice *device; - GByteArray *ssid_array; - gchar *wep_key; + GBytes *ssid; const gchar *str_mac; struct ether_addr *bin_mac; - GSList *connections; - GSList *filtered; - GSList *l; NMClient *client; - NMRemoteSettings *remote_settings; + const char *mode; + NMDeviceWifiCapabilities caps; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); g_assert (nm_device_get_device_type (device) == NM_DEVICE_TYPE_WIFI); - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); - connections = nm_remote_settings_list_connections (remote_settings); - filtered = nm_device_filter_connections (device, connections); - g_slist_free (connections); - c = NULL; - for (l = filtered; l; l = l->next) { - tmp = l->data; - if (is_hotspot_connection (tmp)) { - c = tmp; - break; - } - } - g_slist_free (filtered); + c = net_device_wifi_get_hotspot_connection (device_wifi); + + ssid = generate_ssid_for_hotspot (device_wifi); client = net_object_get_client (NET_OBJECT (device_wifi)); if (c != NULL) { - g_debug ("activate existing hotspot connection\n"); - nm_client_activate_connection (client, - c, - device, - NULL, - (NMClientActivateFn)activate_cb, - device_wifi); + NMSettingWireless *sw; + const char *c_path; + NMRemoteConnection *connection; + + sw = nm_connection_get_setting_wireless (c); + g_object_set (sw, "ssid", ssid, NULL); + g_bytes_unref (ssid); + + c_path = nm_connection_get_path (c); + connection = nm_client_get_connection_by_path (client, c_path); + + g_debug ("overwriting ssid to %s", (char *) g_bytes_get_data (ssid, NULL)); + + nm_remote_connection_commit_changes_async (connection, + TRUE, + NULL, + overwrite_ssid_cb, + device_wifi); return; } g_debug ("create new hotspot connection\n"); - c = nm_connection_new (); + c = nm_simple_connection_new (); sc = (NMSettingConnection *)nm_setting_connection_new (); g_object_set (sc, @@ -1460,9 +1136,16 @@ nm_connection_add_setting (c, (NMSetting *)sc); sw = (NMSettingWireless *)nm_setting_wireless_new (); + + /* Use real AP mode if the device supports it */ + caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device)); + if (caps & NM_WIFI_DEVICE_CAP_AP) + mode = NM_SETTING_WIRELESS_MODE_AP; + else + mode = NM_SETTING_WIRELESS_MODE_ADHOC; + g_object_set (sw, - "mode", "adhoc", - "security", "802-11-wireless-security", + "mode", mode, NULL); str_mac = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device)); @@ -1483,28 +1166,38 @@ g_object_set (sip, "method", "shared", NULL); nm_connection_add_setting (c, (NMSetting *)sip); - ssid_array = generate_ssid_for_hotspot (device_wifi); - g_object_set (sw, - "ssid", ssid_array, - NULL); - g_byte_array_unref (ssid_array); + g_object_set (sw, "ssid", ssid, NULL); + g_bytes_unref (ssid); sws = (NMSettingWirelessSecurity*) nm_setting_wireless_security_new (); - wep_key = generate_wep_key (device_wifi); - g_object_set (sws, - "key-mgmt", "none", - "wep-key0", wep_key, - "wep-key-type", NM_WEP_KEY_TYPE_KEY, - NULL); - g_free (wep_key); + + if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { + if (caps & NM_WIFI_DEVICE_CAP_RSN) { + set_wpa_key (sws); + nm_setting_wireless_security_add_proto (sws, "rsn"); + nm_setting_wireless_security_add_pairwise (sws, "ccmp"); + nm_setting_wireless_security_add_group (sws, "ccmp"); + } else if (caps & NM_WIFI_DEVICE_CAP_WPA) { + set_wpa_key (sws); + nm_setting_wireless_security_add_proto (sws, "wpa"); + nm_setting_wireless_security_add_pairwise (sws, "tkip"); + nm_setting_wireless_security_add_group (sws, "tkip"); + } else { + set_wep_key (sws); + } + } else { + set_wep_key (sws); + } + nm_connection_add_setting (c, (NMSetting *)sws); - nm_client_add_and_activate_connection (client, - c, - device, - NULL, - (NMClientAddActivateFn)activate_new_cb, - device_wifi); + nm_client_add_and_activate_connection_async (client, + c, + device, + NULL, + NULL, + activate_new_cb, + device_wifi); g_object_unref (c); } @@ -1544,8 +1237,10 @@ devices = nm_active_connection_get_devices (c); if (devices && devices->pdata[0] == device) { NMAccessPoint *ap; + GBytes *ssid; ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device)); - active_ssid = nm_utils_ssid_to_utf8 (nm_access_point_get_ssid (ap)); + ssid = nm_access_point_get_ssid (ap); + active_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); break; } } @@ -1553,10 +1248,10 @@ window = gtk_widget_get_toplevel (GTK_WIDGET (button)); - dialog = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "hotspot-dialog")); + dialog = device_wifi->priv->hotspot_dialog; gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window)); - str = g_string_new (_("If you have a connection to the Internet other than wireless, you can use it to share your internet connection with others.")); + str = g_string_new (_("If you have a connection to the Internet other than wireless, you can set up a wireless hotspot to share the connection with others.")); g_string_append (str, "\n\n"); if (active_ssid) { @@ -1564,7 +1259,7 @@ g_string_append (str, " "); } - g_string_append (str, _("It is not possible to access the internet through your wireless while the hotspot is active.")); + g_string_append (str, _("It is not possible to access the Internet through your wireless while the hotspot is active.")); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "hotspot-dialog-content")); gtk_label_set_markup (GTK_LABEL (widget), str->str); @@ -1572,6 +1267,9 @@ g_signal_connect (dialog, "response", G_CALLBACK (start_hotspot_response_cb), device_wifi); + g_signal_connect (dialog, "delete-event", + G_CALLBACK (gtk_widget_hide_on_delete), NULL); + gtk_window_present (GTK_WINDOW (dialog)); g_free (active_ssid); } @@ -1585,22 +1283,31 @@ gint i; NMActiveConnection *c; NMClient *client; + gboolean found = FALSE; device = net_device_get_nm_device (NET_DEVICE (device_wifi)); client = net_object_get_client (NET_OBJECT (device_wifi)); connections = nm_client_get_active_connections (client); - for (i = 0; i < connections->len; i++) { + for (i = 0; connections && i < connections->len; i++) { c = (NMActiveConnection *)connections->pdata[i]; devices = nm_active_connection_get_devices (c); if (devices && devices->pdata[0] == device) { - nm_client_deactivate_connection (client, c); + nm_client_deactivate_connection (client, c, NULL, NULL); + found = TRUE; break; } } + if (!found) { + g_warning ("Could not stop hotspot connection as no connection attached to the device could be found."); + device_wifi->priv->updating_device = TRUE; + gtk_switch_set_active (device_wifi->priv->hotspot_switch, TRUE); + device_wifi->priv->updating_device = FALSE; + return; + } + nm_device_wifi_refresh_ui (device_wifi); - show_wifi_list (device_wifi); } static void @@ -1608,6 +1315,10 @@ { if (response == GTK_RESPONSE_OK) { stop_shared_connection (device_wifi); + } else { + device_wifi->priv->updating_device = TRUE; + gtk_switch_set_active (device_wifi->priv->hotspot_switch, TRUE); + device_wifi->priv->updating_device = FALSE; } gtk_widget_destroy (dialog); } @@ -1641,82 +1352,6 @@ } static void -connect_wifi_network (NetDeviceWifi *device_wifi, - GtkTreeView *tv, - GtkTreePath *path) -{ - gboolean ap_in_range; - gchar *ap_object_path; - gchar *ssid; - gchar *connection_id; - GtkTreeIter iter; - GtkTreeModel *model; - NM80211Mode mode; - - model = gtk_tree_view_get_model (tv); - gtk_tree_model_get_iter (model, &iter, path); - - gtk_tree_model_get (model, &iter, - COLUMN_ACCESS_POINT_ID, &ap_object_path, - COLUMN_CONNECTION_ID, &connection_id, - COLUMN_TITLE, &ssid, - COLUMN_AP_IN_RANGE, &ap_in_range, - COLUMN_MODE, &mode, - -1); - if (ap_in_range) { - if (connection_id) - activate_connection (device_wifi, connection_id); - else - wireless_try_to_connect (device_wifi, ssid, ap_object_path); - } else { - g_warning ("can't connect"); - } - - g_free (ap_object_path); - g_free (connection_id); - g_free (ssid); -} - -static void -show_wifi_details (NetDeviceWifi *device_wifi, - GtkTreeView *tv, - GtkTreePath *path) -{ - GtkWidget *widget; - gboolean ret; - gboolean in_range; - GtkTreeModel *model; - GtkTreeIter iter; - gchar *path_str; - - model = gtk_tree_view_get_model (tv); - path_str = gtk_tree_path_to_string (path); - ret = gtk_tree_model_get_iter_from_string (model, &iter, path_str); - if (!ret) - goto out; - - /* get parameters about the selected connection */ - g_free (device_wifi->priv->selected_connection_id); - g_free (device_wifi->priv->selected_ssid_title); - gtk_tree_model_get (model, &iter, - COLUMN_ACCESS_POINT_ID, &device_wifi->priv->selected_ap_id, - COLUMN_CONNECTION_ID, &device_wifi->priv->selected_connection_id, - COLUMN_TITLE, &device_wifi->priv->selected_ssid_title, - COLUMN_AP_IN_RANGE, &in_range, - -1); - g_debug ("ssid = %s, in-range = %i", - device_wifi->priv->selected_ssid_title, in_range); - - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); - - nm_device_wifi_refresh_ui (device_wifi); - gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1); - -out: - g_free (path_str); -} - -static void show_wifi_list (NetDeviceWifi *device_wifi) { GtkWidget *widget; @@ -1724,136 +1359,57 @@ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0); } -static gboolean -arrow_visible (GtkTreeModel *model, - GtkTreeIter *iter) -{ - gboolean active; - gboolean ap_is_saved; - gboolean ret; - gchar *sort; - - gtk_tree_model_get (model, iter, - COLUMN_ACTIVE, &active, - COLUMN_AP_IS_SAVED, &ap_is_saved, - COLUMN_SORT, &sort, - -1); - - if (active || ap_is_saved) - ret = TRUE; - else - ret = FALSE; - - g_free (sort); - - return ret; -} - static void -set_arrow_image (GtkCellLayout *layout, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - NetDeviceWifi *device = user_data; - const gchar *icon; - - if (arrow_visible (model, iter)) { - GtkWidget *widget; - - widget = GTK_WIDGET (gtk_builder_get_object (device->priv->builder, - "treeview_list")); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - icon = "go-previous"; - else - icon = "go-next"; - } - else { - icon = ""; - } - - g_object_set (cell, "icon-name", icon, NULL); -} - -static void -edit_connection (GtkButton *button, NetDeviceWifi *device_wifi) -{ - net_object_edit (NET_OBJECT (device_wifi)); -} - -static void -remote_settings_read_cb (NMRemoteSettings *remote_settings, - NetDeviceWifi *device_wifi) +client_connection_added_cb (NMClient *client, + NMRemoteConnection *connection, + NetDeviceWifi *device_wifi) { gboolean is_hotspot; - device_wifi_refresh_saved_connections (device_wifi); - /* go straight to the hotspot UI */ is_hotspot = device_is_hotspot (device_wifi); if (is_hotspot) { nm_device_wifi_refresh_hotspot (device_wifi); show_hotspot_ui (device_wifi); + return; } -} - -static gboolean -separator_visible (GtkTreeModel *model, - GtkTreeIter *iter) -{ - gboolean active; - gboolean ap_is_saved; - gboolean ap_in_range; - gchar *sort; - gboolean ret; - - gtk_tree_model_get (model, iter, - COLUMN_ACTIVE, &active, - COLUMN_AP_IS_SAVED, &ap_is_saved, - COLUMN_AP_IN_RANGE, &ap_in_range, - COLUMN_SORT, &sort, - -1); - - if (!active && ap_is_saved && ap_in_range) - ret = TRUE; - else - ret = FALSE; - - g_free (sort); - - return ret; + populate_ap_list (device_wifi); + show_wifi_list (device_wifi); } static void -set_draw_separator (GtkCellLayout *layout, - GtkCellRenderer *cell, - GtkTreeModel *model, - GtkTreeIter *iter, - gpointer user_data) -{ - gboolean draw; +client_connection_removed_cb (NMClient *client, + NMRemoteConnection *connection, + NetDeviceWifi *device_wifi) +{ + GtkWidget *swin; + GtkWidget *list; + GList *rows, *l; + const char *uuid; - draw = separator_visible (model, iter); + uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); - g_object_set (cell, "draw", draw, NULL); -} + swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "scrolledwindow_list")); + list = gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (swin)))); + rows = gtk_container_get_children (GTK_CONTAINER (list)); + for (l = rows; l != NULL; l = l->next) { + GtkWidget *row = l->data; + NMConnection *connection; + const char *uuid_r; -static void -switch_page_cb (GtkNotebook *notebook, - GtkWidget *page, - guint page_num, - NetDeviceWifi *device_wifi) -{ - GtkWidget *widget; + connection = g_object_get_data (G_OBJECT (row), "connection"); + if (!connection) + continue; - if (page_num == 1) { - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_back1")); - gtk_widget_grab_focus (widget); + uuid_r = nm_connection_get_uuid (connection); + if (g_strcmp0 (uuid_r, uuid) == 0) { + gtk_widget_destroy (row); + break; + } } + g_list_free (rows); } static void @@ -1861,26 +1417,48 @@ { NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); NMClient *client; - NMRemoteSettings *remote_settings; NMClientPermissionResult perm; + NMDevice *nm_device; + NMDeviceWifiCapabilities caps; GtkWidget *widget; G_OBJECT_CLASS (net_device_wifi_parent_class)->constructed (object); client = net_object_get_client (NET_OBJECT (device_wifi)); - g_signal_connect (client, "notify::wireless-enabled", - G_CALLBACK (wireless_enabled_toggled), device_wifi); + g_signal_connect_object (client, "notify::wireless-enabled", + G_CALLBACK (wireless_enabled_toggled), device_wifi, 0); - /* only show the button if the user can create a hotspot */ - perm = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN); + nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + + g_signal_connect_object (nm_device, "access-point-added", + G_CALLBACK (net_device_wifi_access_point_changed), + device_wifi, 0); + g_signal_connect_object (nm_device, "access-point-removed", + G_CALLBACK (net_device_wifi_access_point_changed), + device_wifi, 0); + + /* only enable the button if the user can create a hotspot */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "start_hotspot_button")); - gtk_widget_set_sensitive (widget, perm == NM_CLIENT_PERMISSION_RESULT_YES || - perm == NM_CLIENT_PERMISSION_RESULT_AUTH); + perm = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN); + caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (nm_device)); + if (perm != NM_CLIENT_PERMISSION_RESULT_YES && + perm != NM_CLIENT_PERMISSION_RESULT_AUTH) { + gtk_widget_set_tooltip_text (widget, _("System policy prohibits use as a Hotspot")); + gtk_widget_set_sensitive (widget, FALSE); + } else if (!(caps & (NM_WIFI_DEVICE_CAP_AP | NM_WIFI_DEVICE_CAP_ADHOC))) { + gtk_widget_set_tooltip_text (widget, _("Wireless device does not support Hotspot mode")); + gtk_widget_set_sensitive (widget, FALSE); + } else + gtk_widget_set_sensitive (widget, TRUE); + + g_signal_connect (client, NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK (client_connection_added_cb), device_wifi); + g_signal_connect (client, NM_CLIENT_CONNECTION_REMOVED, + G_CALLBACK (client_connection_removed_cb), device_wifi); - remote_settings = net_object_get_remote_settings (NET_OBJECT (device_wifi)); - g_signal_connect (remote_settings, "connections-read", - G_CALLBACK (remote_settings_read_cb), device_wifi); + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "heading_list")); + g_object_bind_property (device_wifi, "title", widget, "label", 0); nm_device_wifi_refresh_ui (device_wifi); } @@ -1891,6 +1469,8 @@ NetDeviceWifi *device_wifi = NET_DEVICE_WIFI (object); NetDeviceWifiPrivate *priv = device_wifi->priv; + g_clear_pointer (&priv->details_dialog, gtk_widget_destroy); + g_clear_pointer (&priv->hotspot_dialog, gtk_widget_destroy); g_object_unref (priv->builder); g_free (priv->selected_ssid_title); g_free (priv->selected_connection_id); @@ -1906,11 +1486,11 @@ gchar *cmdline; GError *error = NULL; NetDeviceWifi *device = NET_DEVICE_WIFI (object); - NMRemoteSettings *settings; + NMClient *client; NMRemoteConnection *connection; - settings = net_object_get_remote_settings (object); - connection = nm_remote_settings_get_connection_by_path (settings, device->priv->selected_connection_id); + client = net_object_get_client (object); + connection = nm_client_get_connection_by_path (client, device->priv->selected_connection_id); if (connection == NULL) { g_warning ("failed to get remote connection"); return; @@ -1941,45 +1521,573 @@ } static void -activate_ssid_cb (PanelCellRendererText *cell, - const gchar *path, - NetDeviceWifi *device_wifi) +really_forgotten (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - GtkTreeView *tv; - GtkTreePath *tpath; + GError *error = NULL; + + if (!nm_remote_connection_delete_finish (NM_REMOTE_CONNECTION (source_object), res, &error)) { + g_warning ("failed to delete connection %s: %s", + nm_object_get_path (NM_OBJECT (source_object)), + error->message); + g_error_free (error); + return; + } + + /* remove the entry from the list */ + populate_ap_list (user_data); +} - g_debug ("activate ssid!\n"); +static void +really_forget (GtkDialog *dialog, gint response, gpointer data) +{ + GtkWidget *forget = data; + GtkWidget *row; + GList *rows; + GList *r; + NMRemoteConnection *connection; + NetDeviceWifi *device_wifi; - tv = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder, - "treeview_list")); - tpath = gtk_tree_path_new_from_string (path); + gtk_widget_destroy (GTK_WIDGET (dialog)); - connect_wifi_network (device_wifi, tv, tpath); + if (response != GTK_RESPONSE_OK) + return; - gtk_tree_path_free (tpath); + device_wifi = NET_DEVICE_WIFI (g_object_get_data (G_OBJECT (forget), "net")); + rows = g_object_steal_data (G_OBJECT (forget), "rows"); + for (r = rows; r; r = r->next) { + row = r->data; + connection = g_object_get_data (G_OBJECT (row), "connection"); + //FIXME cancellable + nm_remote_connection_delete_async (connection, NULL, really_forgotten, device_wifi); + gtk_widget_destroy (row); + } + g_list_free (rows); } static void -activate_arrow_cb (PanelCellRendererText *cell, - const gchar *path, - NetDeviceWifi *device_wifi) +forget_selected (GtkButton *forget, NetDeviceWifi *device_wifi) { - GtkTreeView *tv; - GtkTreeModel *model; - GtkTreePath *tpath; - GtkTreeIter iter; + GtkWidget *window; + GtkWidget *dialog; - g_debug ("activate arrow!\n"); + window = gtk_widget_get_toplevel (GTK_WIDGET (forget)); + dialog = gtk_message_dialog_new (GTK_WINDOW (window), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_OTHER, + GTK_BUTTONS_NONE, + NULL); + gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), + _("Network details for the selected networks, including passwords and any custom configuration will be lost.")); - tv = GTK_TREE_VIEW (gtk_builder_get_object (device_wifi->priv->builder, - "treeview_list")); - model = gtk_tree_view_get_model (tv); - tpath = gtk_tree_path_new_from_string (path); - gtk_tree_model_get_iter (model, &iter, tpath); + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Forget"), GTK_RESPONSE_OK, + NULL); + g_signal_connect (dialog, "response", + G_CALLBACK (really_forget), forget); + gtk_window_present (GTK_WINDOW (dialog)); +} - if (arrow_visible (model, &iter)) - show_wifi_details (device_wifi, tv, tpath); - gtk_tree_path_free (tpath); +static void +check_toggled (GtkToggleButton *check, GtkWidget *forget) +{ + gboolean active; + GtkWidget *row; + GList *rows; + + row = gtk_widget_get_ancestor (GTK_WIDGET (check), GTK_TYPE_LIST_BOX_ROW); + active = gtk_toggle_button_get_active (check); + rows = g_object_steal_data (G_OBJECT (forget), "rows"); + + if (active) { + rows = g_list_prepend (rows, row); + } else { + rows = g_list_remove (rows, row); + } + + g_object_set_data_full (G_OBJECT (forget), "rows", rows, (GDestroyNotify)g_list_free); + gtk_widget_set_sensitive (forget, rows != NULL); +} + +static void +update_forget (GtkWidget *forget, + gpointer row) +{ + GList *rows; + + rows = g_object_steal_data (G_OBJECT (forget), "rows"); + rows = g_list_remove (rows, row); + g_object_set_data_full (G_OBJECT (forget), "rows", rows, (GDestroyNotify)g_list_free); + gtk_widget_set_sensitive (forget, rows != NULL); +} + +static void +make_row (GtkSizeGroup *rows, + GtkSizeGroup *icons, + GtkWidget *forget, + NMDevice *device, + NMConnection *connection, + NMAccessPoint *ap, + NMAccessPoint *active_ap, + GtkWidget **row_out, + GtkWidget **check_out, + GtkWidget **edit_out) +{ + GtkWidget *row, *row_box; + GtkWidget *widget; + GtkWidget *box; + GtkWidget *button_stack; + GtkWidget *image; + gchar *title; + gboolean active; + gboolean in_range; + gboolean connecting; + guint security; + guint strength; + GBytes *ssid; + const gchar *icon_name; + guint64 timestamp; + NMDeviceState state; + + g_assert (connection || ap); + + state = nm_device_get_state (device); + + if (connection != NULL) { + NMSettingWireless *sw; + NMSettingConnection *sc; + sw = nm_connection_get_setting_wireless (connection); + ssid = nm_setting_wireless_get_ssid (sw); + sc = nm_connection_get_setting_connection (connection); + timestamp = nm_setting_connection_get_timestamp (sc); + } else { + ssid = nm_access_point_get_ssid (ap); + timestamp = 0; + } + + if (ap != NULL) { + in_range = TRUE; + active = (ap == active_ap) && (state == NM_DEVICE_STATE_ACTIVATED); + connecting = (ap == active_ap) && + (state == NM_DEVICE_STATE_PREPARE || + state == NM_DEVICE_STATE_CONFIG || + state == NM_DEVICE_STATE_IP_CONFIG || + state == NM_DEVICE_STATE_IP_CHECK || + state == NM_DEVICE_STATE_NEED_AUTH); + security = get_access_point_security (ap); + strength = nm_access_point_get_strength (ap); + } else { + in_range = FALSE; + active = FALSE; + connecting = FALSE; + security = 0; + strength = 0; + } + + row = gtk_list_box_row_new (); + gtk_size_group_add_widget (rows, row); + + row_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_widget_set_margin_start (row_box, 12); + gtk_widget_set_margin_end (row_box, 12); + gtk_container_add (GTK_CONTAINER (row), row_box); + + button_stack = gtk_stack_new (); + gtk_widget_show (button_stack); + + widget = gtk_label_new (""); + gtk_widget_show (widget); + gtk_container_add (GTK_CONTAINER (button_stack), widget); + + widget = NULL; + if (forget) { + widget = gtk_check_button_new (); + g_signal_connect (widget, "toggled", + G_CALLBACK (check_toggled), forget); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + gtk_box_pack_start (GTK_BOX (row_box), widget, FALSE, FALSE, 0); + g_signal_connect_object (row, "destroy", + G_CALLBACK (update_forget), forget, G_CONNECT_SWAPPED); + } + if (check_out) + *check_out = widget; + + title = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); + widget = gtk_label_new (title); + g_free (title); + gtk_widget_set_margin_top (widget, 12); + gtk_widget_set_margin_bottom (widget, 12); + gtk_box_pack_start (GTK_BOX (row_box), widget, FALSE, FALSE, 0); + + if (active) { + widget = gtk_image_new_from_icon_name ("object-select-symbolic", GTK_ICON_SIZE_MENU); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + gtk_box_pack_start (GTK_BOX (row_box), widget, FALSE, FALSE, 0); + } + + gtk_box_pack_start (GTK_BOX (row_box), gtk_label_new (""), TRUE, FALSE, 0); + + widget = NULL; + image = gtk_image_new_from_icon_name ("emblem-system-symbolic", GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + widget = gtk_button_new (); + gtk_style_context_add_class (gtk_widget_get_style_context (widget), "image-button"); + gtk_style_context_add_class (gtk_widget_get_style_context (widget), "circular-button"); + gtk_widget_show (widget); + gtk_container_add (GTK_CONTAINER (widget), image); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + atk_object_set_name (gtk_widget_get_accessible (widget), _("Options…")); + gtk_stack_add_named (GTK_STACK (button_stack), widget, "button"); + g_object_set_data (G_OBJECT (row), "edit", widget); + + if (connection) + gtk_stack_set_visible_child_name (GTK_STACK (button_stack), "button"); + + gtk_box_pack_start (GTK_BOX (row_box), button_stack, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (row), "button_stack", button_stack); + + + if (edit_out) + *edit_out = widget; + + widget = gtk_spinner_new (); + gtk_spinner_start (GTK_SPINNER (widget)); + gtk_widget_show (widget); + + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_valign (widget, GTK_ALIGN_CENTER); + gtk_stack_add_named (GTK_STACK (button_stack), widget, "spinner"); + if (connecting) + gtk_stack_set_visible_child_name (GTK_STACK (button_stack), "spinner"); + + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_set_homogeneous (GTK_BOX (box), TRUE); + gtk_size_group_add_widget (icons, box); + gtk_box_pack_start (GTK_BOX (row_box), box, FALSE, FALSE, 0); + + if (in_range) { + if (security != NM_AP_SEC_UNKNOWN && + security != NM_AP_SEC_NONE) { + widget = gtk_image_new_from_icon_name ("network-wireless-encrypted-symbolic", GTK_ICON_SIZE_MENU); + } else { + widget = gtk_label_new (""); + } + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); + + if (strength < 20) + icon_name = "network-wireless-signal-none-symbolic"; + else if (strength < 40) + icon_name = "network-wireless-signal-weak-symbolic"; + else if (strength < 50) + icon_name = "network-wireless-signal-ok-symbolic"; + else if (strength < 80) + icon_name = "network-wireless-signal-good-symbolic"; + else + icon_name = "network-wireless-signal-excellent-symbolic"; + widget = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU); + gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0); + } + + gtk_widget_show_all (row); + + g_object_set_data (G_OBJECT (row), "ap", ap); + if (connection) + g_object_set_data (G_OBJECT (row), "connection", connection); + g_object_set_data (G_OBJECT (row), "timestamp", GUINT_TO_POINTER (timestamp)); + g_object_set_data (G_OBJECT (row), "active", GUINT_TO_POINTER (active)); + g_object_set_data (G_OBJECT (row), "strength", GUINT_TO_POINTER (strength)); + + *row_out = row; +} + +static gint +history_sort (gconstpointer a, gconstpointer b, gpointer data) +{ + guint64 ta, tb; + + ta = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "timestamp")); + tb = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (b), "timestamp")); + + if (ta > tb) return -1; + if (tb > ta) return 1; + + return 0; +} + +static gint +ap_sort (gconstpointer a, gconstpointer b, gpointer data) +{ + guint sa, sb; + + sa = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (a), "strength")); + sb = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (b), "strength")); + if (sa > sb) return -1; + if (sb > sa) return 1; + + return 0; +} + +static void +editor_done (NetConnectionEditor *editor, + gboolean success, + NetDeviceWifi *device_wifi) +{ + g_object_unref (editor); +} + +static void +show_details_for_row (GtkButton *button, NetDeviceWifi *device_wifi) +{ + GtkWidget *row; + NMConnection *connection; + NMAccessPoint *ap; + GtkWidget *window; + NetConnectionEditor *editor; + NMClient *client; + NMDevice *device; + + window = gtk_widget_get_toplevel (GTK_WIDGET (button)); + + row = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "row")); + connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection")); + ap = NM_ACCESS_POINT (g_object_get_data (G_OBJECT (row), "ap")); + + device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + client = net_object_get_client (NET_OBJECT (device_wifi)); + editor = net_connection_editor_new (GTK_WINDOW (window), connection, device, ap, client); + g_signal_connect (editor, "done", G_CALLBACK (editor_done), device_wifi); + net_connection_editor_run (editor); +} + +static void +open_history (NetDeviceWifi *device_wifi) +{ + GtkWidget *dialog; + GtkWidget *window; + CcNetworkPanel *panel; + GtkWidget *button; + GtkWidget *forget; + GtkWidget *swin; + GSList *connections; + GSList *l; + const GPtrArray *aps; + GPtrArray *aps_unique = NULL; + NMAccessPoint *active_ap; + guint i; + NMDevice *nm_device; + GtkWidget *list; + GtkWidget *row; + GtkSizeGroup *rows; + GtkSizeGroup *icons; + + dialog = gtk_dialog_new (); + panel = net_object_get_panel (NET_OBJECT (device_wifi)); + window = gtk_widget_get_toplevel (GTK_WIDGET (panel)); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window)); + gtk_window_set_title (GTK_WINDOW (dialog), _("History")); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400); + + button = gtk_button_new_with_mnemonic (_("_Close")); + gtk_widget_set_can_default (button, TRUE); + gtk_widget_show (button); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, 0); + g_signal_connect_swapped (button, "clicked", + G_CALLBACK (gtk_widget_destroy), dialog); + + /* translators: This is the label for the "Forget wireless network" functionality */ + forget = gtk_button_new_with_mnemonic (C_("Wi-Fi Network", "_Forget")); + gtk_widget_show (forget); + gtk_widget_set_sensitive (forget, FALSE); + gtk_dialog_add_action_widget (GTK_DIALOG (dialog), forget, 0); + g_signal_connect (forget, "clicked", + G_CALLBACK (forget_selected), device_wifi); + gtk_container_child_set (GTK_CONTAINER (gtk_widget_get_parent (forget)), forget, "secondary", TRUE, NULL); + g_object_set_data (G_OBJECT (forget), "net", device_wifi); + + swin = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (swin); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_IN); + gtk_widget_set_margin_start (swin, 50); + gtk_widget_set_margin_end (swin, 50); + gtk_widget_set_margin_top (swin, 12); + gtk_widget_set_margin_bottom (swin, 12); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), swin, TRUE, TRUE, 0); + + list = GTK_WIDGET (gtk_list_box_new ()); + gtk_widget_show (list); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); + gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); + gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)history_sort, NULL, NULL); + gtk_container_add (GTK_CONTAINER (swin), list); + + rows = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); + icons = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + g_object_set_data_full (G_OBJECT (list), "rows", rows, g_object_unref); + g_object_set_data_full (G_OBJECT (list), "icons", icons, g_object_unref); + + nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + + connections = net_device_get_valid_connections (NET_DEVICE (device_wifi)); + + aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device)); + aps_unique = panel_get_strongest_unique_aps (aps); + active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); + + for (l = connections; l; l = l->next) { + NMConnection *connection = l->data; + NMAccessPoint *ap = NULL; + NMSetting *setting; + GBytes *ssid; + if (connection_is_shared (connection)) + continue; + + setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME); + ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting)); + for (i = 0; i < aps_unique->len; i++) { + GBytes *ssid_ap; + ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i)); + ssid_ap = nm_access_point_get_ssid (ap); + if (nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), + g_bytes_get_data (ssid_ap, NULL), g_bytes_get_size (ssid_ap), + TRUE)) + break; + ap = NULL; + } + + make_row (rows, icons, forget, nm_device, connection, ap, active_ap, &row, NULL, &button); + gtk_container_add (GTK_CONTAINER (list), row); + if (button) { + g_signal_connect (button, "clicked", + G_CALLBACK (show_details_for_row), device_wifi); + g_object_set_data (G_OBJECT (button), "row", row); + } + } + g_slist_free (connections); + g_ptr_array_free (aps_unique, TRUE); + + gtk_window_present (GTK_WINDOW (dialog)); +} + +static void +populate_ap_list (NetDeviceWifi *device_wifi) +{ + GtkWidget *swin; + GtkWidget *list; + GtkSizeGroup *rows; + GtkSizeGroup *icons; + NMDevice *nm_device; + GSList *connections; + GSList *l; + const GPtrArray *aps; + GPtrArray *aps_unique = NULL; + NMAccessPoint *active_ap; + guint i; + GtkWidget *row; + GtkWidget *button; + GList *children, *child; + + swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "scrolledwindow_list")); + list = gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (swin)))); + + children = gtk_container_get_children (GTK_CONTAINER (list)); + for (child = children; child; child = child->next) { + gtk_container_remove (GTK_CONTAINER (list), GTK_WIDGET (child->data)); + } + g_list_free (children); + + rows = GTK_SIZE_GROUP (g_object_get_data (G_OBJECT (list), "rows")); + icons = GTK_SIZE_GROUP (g_object_get_data (G_OBJECT (list), "icons")); + + nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + + connections = net_device_get_valid_connections (NET_DEVICE (device_wifi)); + + aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (nm_device)); + aps_unique = panel_get_strongest_unique_aps (aps); + active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (nm_device)); + + for (i = 0; i < aps_unique->len; i++) { + GBytes *ssid_ap; + NMAccessPoint *ap; + NMConnection *connection = NULL; + ap = NM_ACCESS_POINT (g_ptr_array_index (aps_unique, i)); + ssid_ap = nm_access_point_get_ssid (ap); + for (l = connections; l; l = l->next) { + connection = l->data; + NMSetting *setting; + GBytes *ssid; + + if (connection_is_shared (connection)) { + connection = NULL; + continue; + } + + setting = nm_connection_get_setting_by_name (connection, NM_SETTING_WIRELESS_SETTING_NAME); + ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (setting)); + if (nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), + g_bytes_get_data (ssid_ap, NULL), g_bytes_get_size (ssid_ap), + TRUE)) + break; + connection = NULL; + } + + make_row (rows, icons, NULL, nm_device, connection, ap, active_ap, &row, NULL, &button); + gtk_container_add (GTK_CONTAINER (list), row); + if (button) { + g_signal_connect (button, "clicked", + G_CALLBACK (show_details_for_row), device_wifi); + g_object_set_data (G_OBJECT (button), "row", row); + } + } + + g_slist_free (connections); + g_ptr_array_free (aps_unique, TRUE); +} + +static void +ap_activated (GtkListBox *list, GtkListBoxRow *row, NetDeviceWifi *device_wifi) +{ + NMConnection *connection; + NMAccessPoint *ap; + NMClient *client; + NMDevice *nm_device; + GtkWidget *edit; + GtkWidget *stack; + + connection = NM_CONNECTION (g_object_get_data (G_OBJECT (row), "connection")); + ap = NM_ACCESS_POINT (g_object_get_data (G_OBJECT (row), "ap")); + edit = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "edit")); + stack = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "button_stack")); + + + if (ap != NULL) { + if (connection != NULL) { + gtk_widget_hide (edit); + client = net_object_get_client (NET_OBJECT (device_wifi)); + nm_device = net_device_get_nm_device (NET_DEVICE (device_wifi)); + nm_client_activate_connection_async (client, + connection, + nm_device, NULL, NULL, + connection_activate_cb, device_wifi); + } else { + GBytes *ssid; + const gchar *object_path; + + gtk_stack_set_visible_child_name (GTK_STACK (stack), "spinner"); + + ssid = nm_access_point_get_ssid (ap); + object_path = nm_object_get_path (NM_OBJECT (ap)); + wireless_try_to_connect (device_wifi, ssid, object_path); + } + } } static void @@ -1987,192 +2095,58 @@ { GError *error = NULL; GtkWidget *widget; - GtkCellRenderer *renderer1; - GtkCellRenderer *renderer2; - GtkCellRenderer *renderer3; - GtkCellRenderer *renderer4; - GtkCellRenderer *renderer5; - GtkCellRenderer *renderer6; - GtkCellRenderer *renderer7; - GtkCellRenderer *renderer8; - GtkTreeSortable *sortable; - GtkTreeViewColumn *column; - GtkCellArea *area; + GtkWidget *swin; + GtkWidget *list; + GtkSizeGroup *rows; + GtkSizeGroup *icons; device_wifi->priv = NET_DEVICE_WIFI_GET_PRIVATE (device_wifi); device_wifi->priv->builder = gtk_builder_new (); - gtk_builder_add_from_file (device_wifi->priv->builder, - GNOMECC_UI_DIR "/network-wifi.ui", - &error); + gtk_builder_add_from_resource (device_wifi->priv->builder, + "/org/gnome/control-center/network/network-wifi.ui", + &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); return; } - /* setup wifi views */ - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "device_off_switch")); - g_signal_connect (widget, "notify::active", - G_CALLBACK (device_off_toggled), device_wifi); - - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_options1")); - g_signal_connect (widget, "clicked", - G_CALLBACK (edit_connection), device_wifi); - - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_forget1")); - g_signal_connect (widget, "clicked", - G_CALLBACK (forget_button_clicked_cb), device_wifi); - - widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_disconnect1")); - g_signal_connect (widget, "clicked", - G_CALLBACK (disconnect_button_clicked_cb), device_wifi); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_connect1")); - g_signal_connect (widget, "clicked", - G_CALLBACK (connect_button_clicked_cb), device_wifi); + "details_dialog")); + device_wifi->priv->details_dialog = widget; widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "treeview_list")); - - /* sort networks in drop down */ - sortable = GTK_TREE_SORTABLE (gtk_builder_get_object (device_wifi->priv->builder, - "liststore_network")); - gtk_tree_sortable_set_sort_column_id (sortable, - COLUMN_SORT, - GTK_SORT_ASCENDING); - gtk_tree_sortable_set_sort_func (sortable, - COLUMN_SORT, - wireless_ap_model_sort_cb, - device_wifi, - NULL); - - - column = GTK_TREE_VIEW_COLUMN (gtk_builder_get_object (device_wifi->priv->builder, - "treeview_list_column")); - area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column)); - - renderer1 = gtk_cell_renderer_pixbuf_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer1, FALSE); - g_object_set (renderer1, - "follow-state", TRUE, - "icon-name", "object-select-symbolic", - "xpad", 6, - "ypad", 6, - NULL); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer1, - "visible", COLUMN_ACTIVE, - NULL); - gtk_cell_area_cell_set (area, renderer1, "align", TRUE, NULL); - - renderer2 = panel_cell_renderer_text_new (); - g_object_set (renderer2, - "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, - "ellipsize", PANGO_ELLIPSIZE_END, - NULL); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer2, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer2, - "markup", COLUMN_TITLE, - NULL); - gtk_cell_area_cell_set (area, renderer2, - "align", TRUE, - "expand", TRUE, - NULL); - g_signal_connect (renderer2, "activate", - G_CALLBACK (activate_ssid_cb), device_wifi); - - renderer3 = panel_cell_renderer_mode_new (); - gtk_cell_renderer_set_padding (renderer3, 4, 0); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), - renderer3, - FALSE); - g_object_set (renderer3, "follow-state", TRUE, NULL); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer3, - "ap-mode", COLUMN_MODE, - NULL); - - renderer4 = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer4, FALSE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer4, - "visible", COLUMN_AP_OUT_OF_RANGE, - NULL); - g_object_set (renderer4, - "text", _("Out of range"), - "mode", GTK_CELL_RENDERER_MODE_INERT, - "xalign", 1.0, - NULL); - - renderer5 = panel_cell_renderer_signal_new (); - gtk_cell_renderer_set_padding (renderer5, 4, 0); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), - renderer5, - FALSE); - g_object_set (renderer5, "follow-state", TRUE, NULL); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer5, - "signal", COLUMN_STRENGTH, - "visible", COLUMN_AP_IN_RANGE, - NULL); - - renderer6 = panel_cell_renderer_security_new (); - gtk_cell_renderer_set_padding (renderer6, 4, 0); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), - renderer6, - FALSE); - g_object_set (renderer6, "follow-state", TRUE, NULL); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (column), renderer6, - "security", COLUMN_SECURITY, - "visible", COLUMN_AP_IN_RANGE, - NULL); - - renderer7 = panel_cell_renderer_separator_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer7, FALSE); - g_object_set (renderer7, - "visible", TRUE, - "sensitive", FALSE, - "draw", TRUE, - NULL); - gtk_cell_renderer_set_fixed_size (renderer7, 1, -1); - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer7, - set_draw_separator, device_wifi, NULL); - - renderer8 = panel_cell_renderer_pixbuf_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), renderer8, FALSE); - g_object_set (renderer8, - "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, - "follow-state", TRUE, - "visible", TRUE, - "xpad", 6, - "ypad", 6, - NULL); - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (column), renderer8, - set_arrow_image, device_wifi, NULL); - g_signal_connect (renderer8, "activate", - G_CALLBACK (activate_arrow_cb), device_wifi); + "hotspot-dialog")); + device_wifi->priv->hotspot_dialog = widget; + /* setup wifi views */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, - "button_back1")); - g_signal_connect_swapped (widget, "clicked", - G_CALLBACK (show_wifi_list), device_wifi); + "device_off_switch")); + g_signal_connect (widget, "notify::active", + G_CALLBACK (device_off_toggled), device_wifi); - /* draw focus around everything but the arrow */ - gtk_cell_area_add_focus_sibling (area, renderer2, renderer1); - gtk_cell_area_add_focus_sibling (area, renderer2, renderer3); - gtk_cell_area_add_focus_sibling (area, renderer2, renderer4); - gtk_cell_area_add_focus_sibling (area, renderer2, renderer5); - gtk_cell_area_add_focus_sibling (area, renderer2, renderer6); - gtk_cell_area_add_focus_sibling (area, renderer2, renderer7); + swin = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "scrolledwindow_list")); + list = GTK_WIDGET (gtk_list_box_new ()); + gtk_widget_show (list); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (list), GTK_SELECTION_NONE); + gtk_list_box_set_header_func (GTK_LIST_BOX (list), cc_list_box_update_header_func, NULL, NULL); + gtk_list_box_set_sort_func (GTK_LIST_BOX (list), (GtkListBoxSortFunc)ap_sort, NULL, NULL); + gtk_container_add (GTK_CONTAINER (swin), list); + g_signal_connect (list, "row-activated", + G_CALLBACK (ap_activated), device_wifi); + + rows = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); + icons = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + g_object_set_data_full (G_OBJECT (list), "rows", rows, g_object_unref); + g_object_set_data_full (G_OBJECT (list), "icons", icons, g_object_unref); /* setup view */ widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "notebook_view")); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0); - g_signal_connect_after (widget, "switch-page", - G_CALLBACK (switch_page_cb), device_wifi); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "start_hotspot_button")); @@ -2185,7 +2159,13 @@ G_CALLBACK (connect_to_hidden_network), device_wifi); widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, + "history_button")); + g_signal_connect_swapped (widget, "clicked", + G_CALLBACK (open_history), device_wifi); + + widget = GTK_WIDGET (gtk_builder_get_object (device_wifi->priv->builder, "switch_hotspot_off")); + device_wifi->priv->hotspot_switch = GTK_SWITCH (widget); g_signal_connect (widget, "notify::active", G_CALLBACK (switch_hotspot_changed_cb), device_wifi); } diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.c 2019-05-01 13:21:41.000000000 +0000 @@ -35,7 +35,6 @@ gboolean removable; GCancellable *cancellable; NMClient *client; - NMRemoteSettings *remote_settings; CcNetworkPanel *panel; }; @@ -45,7 +44,6 @@ PROP_TITLE, PROP_REMOVABLE, PROP_CLIENT, - PROP_REMOTE_SETTINGS, PROP_CANCELLABLE, PROP_PANEL, PROP_LAST @@ -87,7 +85,9 @@ net_object_set_id (NetObject *object, const gchar *id) { g_return_if_fail (NET_IS_OBJECT (object)); + g_clear_pointer (&object->priv->id, g_free); object->priv->id = g_strdup (id); + g_object_notify (G_OBJECT (object), "id"); } gboolean @@ -108,7 +108,9 @@ net_object_set_title (NetObject *object, const gchar *title) { g_return_if_fail (NET_IS_OBJECT (object)); + g_clear_pointer (&object->priv->title, g_free); object->priv->title = g_strdup (title); + g_object_notify (G_OBJECT (object), "title"); } NMClient * @@ -118,13 +120,6 @@ return object->priv->client; } -NMRemoteSettings * -net_object_get_remote_settings (NetObject *object) -{ - g_return_val_if_fail (NET_IS_OBJECT (object), NULL); - return object->priv->remote_settings; -} - GCancellable * net_object_get_cancellable (NetObject *object) { @@ -207,16 +202,13 @@ g_value_set_boolean (value, priv->removable); break; case PROP_CLIENT: - g_value_set_object (value, priv->client); - break; - case PROP_REMOTE_SETTINGS: - g_value_set_object (value, priv->remote_settings); + g_value_set_pointer (value, priv->client); break; case PROP_CANCELLABLE: g_value_set_object (value, priv->cancellable); break; case PROP_PANEL: - g_value_set_object (value, priv->panel); + g_value_set_pointer (value, priv->panel); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -249,16 +241,19 @@ priv->removable = g_value_get_boolean (value); break; case PROP_CLIENT: - priv->client = g_value_dup_object (value); - break; - case PROP_REMOTE_SETTINGS: - priv->remote_settings = g_value_dup_object (value); + priv->client = g_value_get_pointer (value); + if (priv->client) + g_object_add_weak_pointer (G_OBJECT (priv->client), (gpointer *) (&priv->client)); break; case PROP_CANCELLABLE: + g_assert (!priv->cancellable); priv->cancellable = g_value_dup_object (value); break; case PROP_PANEL: - priv->panel = g_value_dup_object (value); + g_assert (!priv->panel); + priv->panel = g_value_get_pointer (value); + if (priv->panel) + g_object_add_weak_pointer (G_OBJECT (priv->panel), (gpointer *) (&priv->panel)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -274,14 +269,14 @@ g_free (priv->id); g_free (priv->title); - if (priv->client != NULL) - g_object_unref (priv->client); - if (priv->remote_settings != NULL) - g_object_unref (priv->remote_settings); if (priv->cancellable != NULL) g_object_unref (priv->cancellable); - if (priv->panel != NULL) - g_object_unref (priv->panel); + + if (priv->client) + g_object_remove_weak_pointer (G_OBJECT (priv->client), (gpointer *) (&priv->client)); + if (priv->panel) + g_object_remove_weak_pointer (G_OBJECT (priv->panel), (gpointer *) (&priv->panel)); + G_OBJECT_CLASS (net_object_parent_class)->finalize (object); } @@ -301,7 +296,7 @@ pspec = g_param_spec_string ("title", NULL, NULL, NULL, - G_PARAM_READWRITE); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_TITLE, pspec); pspec = g_param_spec_boolean ("removable", NULL, NULL, @@ -309,24 +304,17 @@ G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_REMOVABLE, pspec); - pspec = g_param_spec_object ("client", NULL, NULL, - NM_TYPE_CLIENT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + pspec = g_param_spec_pointer ("client", NULL, NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_CLIENT, pspec); - pspec = g_param_spec_object ("remote-settings", NULL, NULL, - NM_TYPE_REMOTE_SETTINGS, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); - g_object_class_install_property (object_class, PROP_REMOTE_SETTINGS, pspec); - pspec = g_param_spec_object ("cancellable", NULL, NULL, G_TYPE_CANCELLABLE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_CANCELLABLE, pspec); - pspec = g_param_spec_object ("panel", NULL, NULL, - CC_TYPE_NETWORK_PANEL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + pspec = g_param_spec_pointer ("panel", NULL, NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); g_object_class_install_property (object_class, PROP_PANEL, pspec); signals[SIGNAL_CHANGED] = diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.h unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.h 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-object.h 2019-05-01 13:21:41.000000000 +0000 @@ -24,8 +24,7 @@ #include #include -#include -#include +#include #include "cc-network-panel.h" @@ -42,6 +41,8 @@ typedef struct _NetObject NetObject; typedef struct _NetObjectClass NetObjectClass; +G_DEFINE_AUTOPTR_CLEANUP_FUNC (NetObject, g_object_unref) + struct _NetObject { GObject parent; @@ -73,7 +74,6 @@ void net_object_set_title (NetObject *object, const gchar *title); NMClient *net_object_get_client (NetObject *object); -NMRemoteSettings *net_object_get_remote_settings (NetObject *object); GCancellable *net_object_get_cancellable (NetObject *object); CcNetworkPanel *net_object_get_panel (NetObject *object); void net_object_emit_changed (NetObject *object); diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-proxy.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-proxy.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-proxy.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-proxy.c 2019-05-01 13:21:41.000000000 +0000 @@ -25,14 +25,8 @@ #include #include -#include -#include -#include - #include "net-proxy.h" - - #define NET_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_PROXY, NetProxyPrivate)) struct _NetProxyPrivate @@ -84,6 +78,8 @@ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "label_proxy_warning")); gtk_label_set_markup (GTK_LABEL (widget), string->str); + gtk_widget_set_visible (widget, (string->len > 0)); + g_free (autoconfig_url); g_string_free (string, TRUE); } @@ -147,6 +143,12 @@ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "spinbutton_proxy_socks")); gtk_widget_set_visible (widget, value == 1); + widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, + "heading_proxy_ignore")); + gtk_widget_set_visible (widget, value == 1); + widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, + "entry_proxy_ignore")); + gtk_widget_set_visible (widget, value == 1); /* perhaps show the wpad warning */ check_wpad_warning (proxy); @@ -213,7 +215,6 @@ GtkSizeGroup *heading_size_group) { GtkWidget *widget; - GtkWindow *window; NetProxy *proxy = NET_PROXY (object); /* add widgets to size group */ @@ -221,15 +222,9 @@ "heading_proxy_method")); gtk_size_group_add_widget (heading_size_group, widget); - /* reparent */ - window = GTK_WINDOW (gtk_builder_get_object (proxy->priv->builder, - "window_tmp")); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "grid5")); - g_object_ref (widget); - gtk_container_remove (GTK_CONTAINER (window), widget); gtk_notebook_append_page (notebook, widget, NULL); - g_object_unref (widget); return widget; } @@ -256,146 +251,52 @@ g_type_class_add_private (klass, sizeof (NetProxyPrivate)); } - -static gboolean -ubuntu_is_in_admin_group (int id_group) -{ - gid_t groups [1024]; - int i, ngroups; - - ngroups = getgroups (1024, groups); - if (ngroups < 0) { - perror ("getgroups"); - return FALSE; - } - - for (i = 0; i < ngroups; ++i) { - if (groups[i] == id_group) - return TRUE; - } - - return FALSE; -} - static gboolean -ubuntu_is_admin () -{ - struct group *admin_group; - - admin_group = getgrnam ("admin"); - if (admin_group != NULL && ubuntu_is_in_admin_group (admin_group->gr_gid)) - return TRUE; - - admin_group = getgrnam ("sudo"); - if (admin_group != NULL && ubuntu_is_in_admin_group (admin_group->gr_gid)) - return TRUE; - - return FALSE; -} - -static void -ubuntu_reset_system_proxy (GDBusProxy *proxy, const gchar *protocol) -{ - GVariant *result; - GError *error = NULL; - - result = g_dbus_proxy_call_sync (proxy, "set_proxy", - g_variant_new ("(ss)", protocol, ""), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); - if (result) - g_variant_unref (result); - else { - g_warning ("Error while calling set_proxy for %s protocol: %s", protocol, error->message); - g_error_free (error); - } -} - -static void -ubuntu_set_proxy_for_protocol (GDBusProxy *proxy, const gchar *protocol, GSettings *settings) -{ - GVariant *result; - gchar *proxy_str, *host; - GError *error = NULL; - gint port; - - host = g_settings_get_string (settings, "host"); - port = g_settings_get_int (settings, "port"); - - if (host && *host == '\0') { - ubuntu_reset_system_proxy (proxy, protocol); - } else { - proxy_str = g_strdup_printf ("%s://%s:%i/", protocol, host, port); - - result = g_dbus_proxy_call_sync (proxy, "set_proxy", - g_variant_new ("(ss)", protocol, proxy_str), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); - if (result) - g_variant_unref (result); - else { - g_warning ("Error while calling set_proxy for %s protocol: %s", protocol, error->message); - g_error_free (error); +get_ignore_hosts (GValue *value, + GVariant *variant, + gpointer user_data) +{ + GVariantIter iter; + const gchar *s; + gchar **av, **p; + gsize n; + + n = g_variant_iter_init (&iter, variant); + p = av = g_new0 (gchar *, n + 1); + + while (g_variant_iter_next (&iter, "&s", &s)) + if (s[0] != '\0') { + *p = (gchar *) s; + ++p; } - g_free (proxy_str); - } - /* Free memory */ - g_free (host); - g_object_unref (settings); + g_value_take_string (value, g_strjoinv (", ", av)); + g_free (av); + + return TRUE; } -static void -ubuntu_on_proxy_apply_system_settings (GtkButton *button, gpointer user_data) +static GVariant * +set_ignore_hosts (const GValue *value, + const GVariantType *expected_type, + gpointer user_data) { - GDBusConnection *bus; - GDBusProxy *dbus_proxy; - GError *error; - GDesktopProxyMode proxy_mode; - NetProxy *proxy = NET_PROXY (user_data); - - error = NULL; - bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (!bus) { - g_warning ("Could not retrieve system bus: %s", error->message); - g_error_free (error); - - return; - } + GVariantBuilder builder; + const gchar *sv; + gchar **av, **p; - dbus_proxy = g_dbus_proxy_new_sync (bus, 0, NULL, - "com.ubuntu.SystemService", - "/", - "com.ubuntu.SystemService", - NULL, - &error); - if (!dbus_proxy) { - g_warning ("Could not retrieve bus object: %s", error->message); - g_error_free (error); + sv = g_value_get_string (value); + av = g_strsplit_set (sv, ", ", 0); - return; + g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); + for (p = av; *p; ++p) { + if (*p[0] != '\0') + g_variant_builder_add (&builder, "s", *p); } - /* Retrieve the current settings */ - proxy_mode = g_settings_get_enum (proxy->priv->settings, "mode"); - switch (proxy_mode) { - case G_DESKTOP_PROXY_MODE_AUTO: - case G_DESKTOP_PROXY_MODE_NONE: - ubuntu_reset_system_proxy (dbus_proxy, "http"); - ubuntu_reset_system_proxy (dbus_proxy, "https"); - ubuntu_reset_system_proxy (dbus_proxy, "ftp"); - ubuntu_reset_system_proxy (dbus_proxy, "socks"); - break; - case G_DESKTOP_PROXY_MODE_MANUAL: - ubuntu_set_proxy_for_protocol (dbus_proxy, "http", g_settings_get_child (proxy->priv->settings, "http")); - ubuntu_set_proxy_for_protocol (dbus_proxy, "https", g_settings_get_child (proxy->priv->settings, "https")); - ubuntu_set_proxy_for_protocol (dbus_proxy, "ftp", g_settings_get_child (proxy->priv->settings, "ftp")); - ubuntu_set_proxy_for_protocol (dbus_proxy, "socks", g_settings_get_child (proxy->priv->settings, "socks")); - break; - } + g_strfreev (av); - /* Free memory */ - g_object_unref (dbus_proxy); + return g_variant_builder_end (&builder); } static void @@ -410,9 +311,9 @@ proxy->priv = NET_PROXY_GET_PRIVATE (proxy); proxy->priv->builder = gtk_builder_new (); - gtk_builder_add_from_file (proxy->priv->builder, - GNOMECC_UI_DIR "/network-proxy.ui", - &error); + gtk_builder_add_from_resource (proxy->priv->builder, + "/org/gnome/control-center/network/network-proxy.ui", + &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); @@ -425,12 +326,6 @@ G_CALLBACK (settings_changed_cb), proxy); - /* explicitly set this to false as the panel has no way of - * linking the http and https proxies them together */ - g_settings_set_boolean (proxy->priv->settings, - "use-same-proxy", - FALSE); - /* actions */ value = g_settings_get_enum (proxy->priv->settings, "mode"); widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, @@ -517,12 +412,13 @@ "label_proxy_status")); gtk_label_set_label (GTK_LABEL (widget), ""); - /* Ubuntu button for system proxy settings */ - if (ubuntu_is_admin ()) { - g_signal_connect (G_OBJECT (gtk_builder_get_object (proxy->priv->builder, "system_proxy_button")), "clicked", - G_CALLBACK (ubuntu_on_proxy_apply_system_settings), proxy); - } else - gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, "system_proxy_button"))); + /* bind the proxy ignore hosts */ + widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, + "entry_proxy_ignore")); + g_settings_bind_with_mapping (proxy->priv->settings, "ignore-hosts", + widget, "text", + G_SETTINGS_BIND_DEFAULT, get_ignore_hosts, set_ignore_hosts, + NULL, NULL); /* hide the switch until we get some more detail in the mockup */ widget = GTK_WIDGET (gtk_builder_get_object (proxy->priv->builder, diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.c unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.c 2019-05-01 13:21:41.000000000 +0000 @@ -23,13 +23,13 @@ #include #include +#include #include "panel-common.h" #include "net-vpn.h" -#include "nm-client.h" -#include "nm-remote-connection.h" -#include "nm-setting-vpn.h" + +#include "connection-editor/net-connection-editor.h" #define NET_VPN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_VPN, NetVpnPrivate)) @@ -37,6 +37,7 @@ { GtkBuilder *builder; NMConnection *connection; + NMActiveConnection *active_connection; gchar *service_type; gboolean valid; gboolean updating_device; @@ -51,9 +52,9 @@ G_DEFINE_TYPE (NetVpn, net_vpn, NET_TYPE_OBJECT) static void -connection_vpn_state_changed_cb (NMVPNConnection *connection, - NMVPNConnectionState state, - NMVPNConnectionStateReason reason, +connection_vpn_state_changed_cb (NMVpnConnection *connection, + NMVpnConnectionState state, + NMVpnConnectionStateReason reason, NetVpn *vpn) { net_object_emit_changed (NET_OBJECT (vpn)); @@ -67,10 +68,14 @@ } static void -connection_removed_cb (NMConnection *connection, - NetVpn *vpn) +connection_removed_cb (NMClient *client, + NMConnection *connection, + NetVpn *vpn) { - net_object_emit_removed (NET_OBJECT (vpn)); + NetVpnPrivate *priv = vpn->priv; + + if (priv->connection == connection) + net_object_emit_removed (NET_OBJECT (vpn)); } static char * @@ -88,6 +93,8 @@ net_vpn_set_connection (NetVpn *vpn, NMConnection *connection) { NetVpnPrivate *priv = vpn->priv; + NMClient *client; + /* * vpnc config exmaple: * key=IKE DH Group, value=dh2 @@ -99,14 +106,17 @@ * key=Xauth username, value=rhughes */ priv->connection = g_object_ref (connection); - g_signal_connect (priv->connection, - NM_REMOTE_CONNECTION_REMOVED, + + client = net_object_get_client (NET_OBJECT (vpn)); + g_signal_connect (client, + NM_CLIENT_CONNECTION_REMOVED, G_CALLBACK (connection_removed_cb), vpn); - g_signal_connect (priv->connection, - NM_REMOTE_CONNECTION_UPDATED, + g_signal_connect (connection, + NM_CONNECTION_CHANGED, G_CALLBACK (connection_changed_cb), vpn); + if (NM_IS_VPN_CONNECTION (priv->connection)) { g_signal_connect (priv->connection, NM_VPN_CONNECTION_VPN_STATE, @@ -117,7 +127,7 @@ priv->service_type = net_vpn_connection_to_type (priv->connection); } -static NMVPNConnectionState +static NMVpnConnectionState net_vpn_get_state (NetVpn *vpn) { NetVpnPrivate *priv = vpn->priv; @@ -222,8 +232,8 @@ vpn_proxy_delete (NetObject *object) { NetVpn *vpn = NET_VPN (object); - nm_remote_connection_delete (NM_REMOTE_CONNECTION (vpn->priv->connection), - NULL, vpn); + nm_remote_connection_delete_async (NM_REMOTE_CONNECTION (vpn->priv->connection), + NULL, NULL, vpn); } static GtkWidget * @@ -232,7 +242,6 @@ GtkSizeGroup *heading_size_group) { GtkWidget *widget; - GtkWindow *window; NetVpn *vpn = NET_VPN (object); /* add widgets to size group */ @@ -240,15 +249,9 @@ "heading_group_password")); gtk_size_group_add_widget (heading_size_group, widget); - /* reparent */ - window = GTK_WINDOW (gtk_builder_get_object (vpn->priv->builder, - "window_tmp")); widget = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder, "vbox9")); - g_object_ref (widget); - gtk_container_remove (GTK_CONTAINER (window), widget); gtk_notebook_append_page (notebook, widget, NULL); - g_object_unref (widget); return widget; } @@ -262,9 +265,7 @@ const GPtrArray *acs; NMActiveConnection *a; gint i; - const gchar *path; - const gchar *apath; - NMVPNConnectionState state; + NMVpnConnectionState state; gchar *title; NMClient *client; @@ -275,22 +276,42 @@ /* update title */ widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "label_device")); + /* Translators: this is the title of the connection details + * window for vpn connections, it is also used to display + * vpn connections in the device list. + */ title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (vpn->priv->connection)); net_object_set_title (NET_OBJECT (vpn), title); gtk_label_set_label (GTK_LABEL (widget), title); g_free (title); + if (priv->active_connection) { + g_signal_handlers_disconnect_by_func (vpn->priv->active_connection, + nm_device_refresh_vpn_ui, + vpn); + g_clear_object (&priv->active_connection); + } + + /* use status */ state = net_vpn_get_state (vpn); client = net_object_get_client (NET_OBJECT (vpn)); acs = nm_client_get_active_connections (client); if (acs != NULL) { - path = nm_connection_get_path (vpn->priv->connection); + const gchar *uuid; + + uuid = nm_connection_get_uuid (vpn->priv->connection); for (i = 0; i < acs->len; i++) { + const gchar *auuid; + a = (NMActiveConnection*)acs->pdata[i]; - apath = nm_active_connection_get_connection (a); - if (NM_IS_VPN_CONNECTION (a) && strcmp (apath, path) == 0) { + auuid = nm_active_connection_get_uuid (a); + if (NM_IS_VPN_CONNECTION (a) && strcmp (auuid, uuid) == 0) { + priv->active_connection = g_object_ref (a); + g_signal_connect_swapped (a, "notify::vpn-state", + G_CALLBACK (nm_device_refresh_vpn_ui), + vpn); state = nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (a)); break; } @@ -334,6 +355,12 @@ } static void +nm_active_connections_changed (NetVpn *vpn) +{ + nm_device_refresh_vpn_ui (vpn); +} + +static void vpn_proxy_refresh (NetObject *object) { NetVpn *vpn = NET_VPN (object); @@ -345,7 +372,6 @@ GParamSpec *pspec, NetVpn *vpn) { - const gchar *path; const GPtrArray *acs; gboolean active; gint i; @@ -358,17 +384,19 @@ active = gtk_switch_get_active (sw); if (active) { client = net_object_get_client (NET_OBJECT (vpn)); - nm_client_activate_connection (client, - vpn->priv->connection, NULL, NULL, - NULL, NULL); + nm_client_activate_connection_async (client, + vpn->priv->connection, NULL, NULL, + NULL, NULL, NULL); } else { - path = nm_connection_get_path (vpn->priv->connection); + const gchar *uuid; + + uuid = nm_connection_get_uuid (vpn->priv->connection); client = net_object_get_client (NET_OBJECT (vpn)); acs = nm_client_get_active_connections (client); - for (i = 0; i < acs->len; i++) { + for (i = 0; acs && i < acs->len; i++) { a = (NMActiveConnection*)acs->pdata[i]; - if (strcmp (nm_active_connection_get_connection (a), path) == 0) { - nm_client_deactivate_connection (client, a); + if (strcmp (nm_active_connection_get_uuid (a), uuid) == 0) { + nm_client_deactivate_connection (client, a, NULL, NULL); break; } } @@ -382,21 +410,39 @@ } static void +editor_done (NetConnectionEditor *editor, + gboolean success, + NetVpn *vpn) +{ + g_object_unref (editor); + net_object_refresh (NET_OBJECT (vpn)); + g_object_unref (vpn); +} + +static void vpn_proxy_edit (NetObject *object) { - const gchar *uuid; - gchar *cmdline; - GError *error = NULL; NetVpn *vpn = NET_VPN (object); + GtkWidget *button, *window; + NetConnectionEditor *editor; + NMClient *client; + gchar *title; - uuid = nm_connection_get_uuid (vpn->priv->connection); - cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid); - g_debug ("Launching '%s'\n", cmdline); - if (!g_spawn_command_line_async (cmdline, &error)) { - g_warning ("Failed to launch nm-connection-editor: %s", error->message); - g_error_free (error); - } - g_free (cmdline); + button = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder, + "button_options")); + window = gtk_widget_get_toplevel (button); + + client = net_object_get_client (object); + + editor = net_connection_editor_new (GTK_WINDOW (window), + vpn->priv->connection, + NULL, NULL, client); + title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (vpn->priv->connection)); + net_connection_editor_set_title (editor, title); + g_free (title); + + g_signal_connect (editor, "done", G_CALLBACK (editor_done), g_object_ref (vpn)); + net_connection_editor_run (editor); } /** @@ -446,10 +492,17 @@ net_vpn_constructed (GObject *object) { NetVpn *vpn = NET_VPN (object); + NMClient *client = net_object_get_client (NET_OBJECT (object)); G_OBJECT_CLASS (net_vpn_parent_class)->constructed (object); nm_device_refresh_vpn_ui (vpn); + + g_signal_connect_swapped (client, + "notify::active-connections", + G_CALLBACK (nm_active_connections_changed), + vpn); + } static void @@ -457,10 +510,35 @@ { NetVpn *vpn = NET_VPN (object); NetVpnPrivate *priv = vpn->priv; + NMClient *client = net_object_get_client (NET_OBJECT (object)); + if (client) { + g_signal_handlers_disconnect_by_func (client, + nm_active_connections_changed, + vpn); + } + + if (priv->active_connection) { + g_signal_handlers_disconnect_by_func (priv->active_connection, + nm_device_refresh_vpn_ui, + vpn); + g_object_unref (priv->active_connection); + } + + g_signal_handlers_disconnect_by_func (priv->connection, + connection_vpn_state_changed_cb, + vpn); + g_signal_handlers_disconnect_by_func (priv->connection, + connection_removed_cb, + vpn); + g_signal_handlers_disconnect_by_func (priv->connection, + connection_changed_cb, + vpn); g_object_unref (priv->connection); g_free (priv->service_type); + g_clear_object (&priv->builder); + G_OBJECT_CLASS (net_vpn_parent_class)->finalize (object); } @@ -497,9 +575,9 @@ vpn->priv = NET_VPN_GET_PRIVATE (vpn); vpn->priv->builder = gtk_builder_new (); - gtk_builder_add_from_file (vpn->priv->builder, - GNOMECC_UI_DIR "/network-vpn.ui", - &error); + gtk_builder_add_from_resource (vpn->priv->builder, + "/org/gnome/control-center/network/network-vpn.ui", + &error); if (error != NULL) { g_warning ("Could not load interface file: %s", error->message); g_error_free (error); diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.h unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.h 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/net-vpn.h 2019-05-01 13:21:41.000000000 +0000 @@ -23,11 +23,9 @@ #define __NET_VPN_H #include +#include -#include "NetworkManagerVPN.h" #include "net-object.h" -#include "nm-connection.h" -#include "nm-vpn-connection.h" G_BEGIN_DECLS diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.c unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.c 2019-05-01 13:21:41.000000000 +0000 @@ -20,27 +20,18 @@ * Copyright 2008 - 2011 Red Hat, Inc. */ -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include "network-dialogs.h" -#include "nm-wifi-dialog.h" -#include "nm-mobile-wizard.h" typedef struct { NMClient *client; - NMRemoteSettings *settings; } WirelessDialogClosure; typedef struct { NMClient *client; - NMRemoteSettings *settings; NMDevice *device; } MobileDialogClosure; @@ -50,7 +41,6 @@ { WirelessDialogClosure *closure = data; g_object_unref (closure->client); - g_object_unref (closure->settings); g_slice_free (WirelessDialogClosure, data); } @@ -60,7 +50,6 @@ { MobileDialogClosure *closure = data; g_object_unref (closure->client); - g_object_unref (closure->settings); g_object_unref (closure->device); g_slice_free (MobileDialogClosure, data); @@ -83,36 +72,28 @@ } static void -activate_existing_cb (NMClient *client, - NMActiveConnection *active, - GError *error, +activate_existing_cb (GObject *source_object, + GAsyncResult *res, gpointer user_data) { - if (error) + GError *error = NULL; + + if (!nm_client_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { g_warning ("Failed to activate connection: (%d) %s", error->code, error->message); + g_error_free (error); + } } static void -activate_new_cb (NMClient *client, - NMActiveConnection *active, - const char *connection_path, - GError *error, +activate_new_cb (GObject *source_object, + GAsyncResult *res, gpointer user_data) { - if (error) - g_warning ("Failed to add new connection: (%d) %s", error->code, error->message); -} - -static void -nag_dialog_response_cb (GtkDialog *nag_dialog, - gint response, - gpointer user_data) -{ - NMAWifiDialog *wireless_dialog = NMA_WIFI_DIALOG (user_data); + GError *error = NULL; - if (response == GTK_RESPONSE_NO) { /* user opted not to correct the warning */ - nma_wifi_dialog_set_nag_ignored (wireless_dialog, TRUE); - gtk_dialog_response (GTK_DIALOG (wireless_dialog), GTK_RESPONSE_OK); + if (!nm_client_add_and_activate_connection_finish (NM_CLIENT (source_object), res, &error)) { + g_warning ("Failed to add new connection: (%d) %s", error->code, error->message); + g_error_free (error); } } @@ -126,27 +107,12 @@ NMConnection *connection, *fuzzy_match = NULL; NMDevice *device; NMAccessPoint *ap; - GSList *all, *iter; + const GPtrArray *all; + guint i; if (response != GTK_RESPONSE_OK) goto done; - if (!nma_wifi_dialog_get_nag_ignored (dialog)) { - GtkWidget *nag_dialog; - - /* Nag the user about certificates or whatever. Only destroy the dialog - * if no nagging was done. - */ - nag_dialog = nma_wifi_dialog_nag_user (dialog); - if (nag_dialog) { - gtk_window_set_transient_for (GTK_WINDOW (nag_dialog), GTK_WINDOW (dialog)); - g_signal_connect (nag_dialog, "response", - G_CALLBACK (nag_dialog_response_cb), - dialog); - return; - } - } - /* nma_wifi_dialog_get_connection() returns a connection with the * refcount incremented, so the caller must remember to unref it. */ @@ -155,24 +121,24 @@ g_assert (device); /* Find a similar connection and use that instead */ - all = nm_remote_settings_list_connections (closure->settings); - for (iter = all; iter; iter = g_slist_next (iter)) { + all = nm_client_get_connections (closure->client); + for (i = 0; i < all->len; i++) { if (nm_connection_compare (connection, - NM_CONNECTION (iter->data), + NM_CONNECTION (g_ptr_array_index (all, i)), (NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) { - fuzzy_match = NM_CONNECTION (iter->data); + fuzzy_match = NM_CONNECTION (g_ptr_array_index (all, i)); break; } } - g_slist_free (all); if (fuzzy_match) { - nm_client_activate_connection (closure->client, - fuzzy_match, - device, - ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL, - activate_existing_cb, - NULL); + nm_client_activate_connection_async (closure->client, + fuzzy_match, + device, + ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL, + NULL, + activate_existing_cb, + NULL); } else { NMSetting *s_con; NMSettingWireless *s_wifi; @@ -193,12 +159,13 @@ g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL); } - nm_client_add_and_activate_connection (closure->client, - connection, - device, - ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL, - activate_new_cb, - NULL); + nm_client_add_and_activate_connection_async (closure->client, + connection, + device, + ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL, + NULL, + activate_new_cb, + NULL); } /* Balance nma_wifi_dialog_get_connection() */ @@ -210,12 +177,10 @@ } static void -show_wireless_dialog (CcNetworkPanel *panel, +show_wireless_dialog (GtkWidget *toplevel, NMClient *client, - NMRemoteSettings *settings, GtkWidget *dialog) { - GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); WirelessDialogClosure *closure; g_debug ("About to parent and show a network dialog"); @@ -228,7 +193,6 @@ closure = g_slice_new (WirelessDialogClosure); closure->client = g_object_ref (client); - closure->settings = g_object_ref (settings); g_signal_connect_data (dialog, "response", G_CALLBACK (wireless_dialog_response_cb), closure, wireless_dialog_closure_closure_notify, 0); @@ -239,30 +203,27 @@ } void -cc_network_panel_create_wifi_network (CcNetworkPanel *panel, - NMClient *client, - NMRemoteSettings *settings) +cc_network_panel_create_wifi_network (GtkWidget *toplevel, + NMClient *client) { if (wifi_can_create_wifi_network (client)) { - show_wireless_dialog (panel, client, settings, - nma_wifi_dialog_new_for_create (client, settings)); + show_wireless_dialog (toplevel, client, + nma_wifi_dialog_new_for_create (client)); } } void -cc_network_panel_connect_to_hidden_network (CcNetworkPanel *panel, - NMClient *client, - NMRemoteSettings *settings) +cc_network_panel_connect_to_hidden_network (GtkWidget *toplevel, + NMClient *client) { g_debug ("connect to hidden wifi"); - show_wireless_dialog (panel, client, settings, - nma_wifi_dialog_new_for_other (client, settings)); + show_wireless_dialog (toplevel, client, + nma_wifi_dialog_new_for_hidden (client)); } void -cc_network_panel_connect_to_8021x_network (CcNetworkPanel *panel, +cc_network_panel_connect_to_8021x_network (GtkWidget *toplevel, NMClient *client, - NMRemoteSettings *settings, NMDevice *device, const gchar *arg_access_point) { @@ -295,7 +256,7 @@ return; } - connection = nm_connection_new (); + connection = nm_simple_connection_new (); /* Need a UUID for the "always ask" stuff in the Dialog of Doom */ s_con = (NMSettingConnection *) nm_setting_connection_new (); @@ -308,7 +269,6 @@ nm_connection_add_setting (connection, NM_SETTING (s_wifi)); g_object_set (s_wifi, NM_SETTING_WIRELESS_SSID, nm_access_point_get_ssid (ap), - NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL); s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); @@ -320,8 +280,8 @@ g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL); nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - dialog = nma_wifi_dialog_new (client, settings, connection, device, ap, FALSE); - show_wireless_dialog (panel, client, settings, dialog); + dialog = nma_wifi_dialog_new (client, connection, device, ap, FALSE); + show_wireless_dialog (toplevel, client, dialog); } static void @@ -337,12 +297,13 @@ /* Ask NM to add the new connection and activate it; NM will fill in the * missing details based on the specific object and the device. */ - nm_client_add_and_activate_connection (closure->client, - connection, - closure->device, - "/", - activate_new_cb, - NULL); + nm_client_add_and_activate_connection_async (closure->client, + connection, + closure->device, + "/", + NULL, + activate_new_cb, + NULL); } mobile_dialog_closure_free (closure); @@ -366,7 +327,7 @@ goto done; } - connection = nm_connection_new (); + connection = nm_simple_connection_new (); setting = nm_setting_cdma_new (); g_object_set (setting, @@ -428,7 +389,7 @@ goto done; } - connection = nm_connection_new (); + connection = nm_simple_connection_new (); setting = nm_setting_gsm_new (); g_object_set (setting, @@ -493,12 +454,10 @@ } void -cc_network_panel_connect_to_3g_network (CcNetworkPanel *panel, +cc_network_panel_connect_to_3g_network (GtkWidget *toplevel, NMClient *client, - NMRemoteSettings *settings, NMDevice *device) { - GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); MobileDialogClosure *closure; NMAMobileWizard *wizard; NMDeviceModemCapabilities caps; @@ -513,7 +472,6 @@ closure = g_slice_new (MobileDialogClosure); closure->client = g_object_ref (client); - closure->settings = g_object_ref (settings); closure->device = g_object_ref (device); caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.h unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.h 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-dialogs.h 2019-05-01 13:21:41.000000000 +0000 @@ -17,27 +17,25 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include -#include -#include -#include -#include "cc-network-panel.h" - -void cc_network_panel_create_wifi_network (CcNetworkPanel *panel, - NMClient *client, - NMRemoteSettings *settings); - -void cc_network_panel_connect_to_hidden_network (CcNetworkPanel *panel, - NMClient *client, - NMRemoteSettings *settings); +#ifndef _NETWORK_DIALOGS_H +#define _NETWORK_DIALOGS_H -void cc_network_panel_connect_to_8021x_network (CcNetworkPanel *panel, +#include +#include + +void cc_network_panel_create_wifi_network (GtkWidget *toplevel, + NMClient *client); + +void cc_network_panel_connect_to_hidden_network (GtkWidget *toplevel, + NMClient *client); + +void cc_network_panel_connect_to_8021x_network (GtkWidget *toplevel, NMClient *client, - NMRemoteSettings *settings, NMDevice *device, const gchar *arg_access_point); -void cc_network_panel_connect_to_3g_network (CcNetworkPanel *panel, +void cc_network_panel_connect_to_3g_network (GtkWidget *toplevel, NMClient *client, - NMRemoteSettings *settings, NMDevice *device); + +#endif /* _NETWORK_DIALOGS_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-ethernet.ui unity-control-center-15.04.0+19.04.20190209/panels/network/network-ethernet.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-ethernet.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-ethernet.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,219 @@ + + + + + True + False + emblem-system-symbolic + 1 + + + True + False + 12 + + + True + False + vertical + 6 + + + True + False + end + start + 1 + 48 + network-wired + 6 + + + 0 + 0 + 1 + 1 + + + + + True + False + start + True + + + True + False + 0 + Wired + end + + + + + + + False + False + 0 + + + + + True + False + 0 + Cable unplugged + + + False + False + 1 + + + + + 1 + 0 + 1 + 1 + + + + + True + True + 12 + True + never + in + + + + + + 0 + 1 + 3 + 1 + + + + + True + False + 12 + True + True + 10 + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 2 + 3 + 1 + + + + + True + True + end + center + True + + + 2 + 0 + 1 + 1 + + + + + True + True + 0 + + + + + True + False + 18 + + + _Add Profile… + True + True + True + start + True + + + True + True + 0 + + + + + True + True + True + end + image1 + + + Options… + + + + + + True + True + 1 + + + + + False + True + 1 + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network.gresource.xml unity-control-center-15.04.0+19.04.20190209/panels/network/network.gresource.xml --- unity-control-center-15.04.0+19.04.20190209/panels/network/network.gresource.xml 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network.gresource.xml 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,12 @@ + + + + network.ui + network-proxy.ui + network-vpn.ui + network-wifi.ui + network-simple.ui + network-mobile.ui + network-ethernet.ui + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-mobile.ui unity-control-center-15.04.0+19.04.20190209/panels/network/network-mobile.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-mobile.ui 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-mobile.ui 2019-05-01 13:21:41.000000000 +0000 @@ -1,6 +1,6 @@ - + @@ -9,9 +9,6 @@ - - False - True False @@ -25,70 +22,6 @@ 10 6 - - True - False - end - start - 1 - 48 - network-cellular-connected-symbolic - 6 - - - 0 - 0 - 1 - 1 - - - - - True - False - start - True - 3 - - - True - False - 0 - Mobile Broadband - end - - - - - - - False - False - 0 - - - - - True - False - 0 - Not connected - - - False - False - 1 - - - - - 1 - 0 - 1 - 1 - - - True False @@ -96,7 +29,7 @@ IMEI label_imei @@ -114,7 +47,7 @@ Provider label_provider @@ -203,6 +136,7 @@ False 0 0 + True True @@ -219,13 +153,7 @@ end start - - False - True - True - end - start - + @@ -242,7 +170,7 @@ 1 IP Address @@ -259,7 +187,7 @@ 1 IPv6 Address @@ -276,7 +204,7 @@ 1 Default Route @@ -294,7 +222,7 @@ 0 DNS @@ -311,7 +239,7 @@ 1 Network @@ -336,6 +264,94 @@ + + True + False + 6 + + + True + False + end + start + 1 + 48 + network-cellular-connected + 6 + + + False + True + 0 + + + + + True + False + start + True + 3 + + + True + False + 0 + Mobile Broadband + end + + + + + + + False + False + 0 + + + + + True + False + 0 + Not connected + + + False + False + 1 + + + + + False + True + 1 + + + + + True + True + end + center + + + False + True + 2 + + + + + 0 + 0 + 3 + 1 + + + @@ -356,12 +372,26 @@ 12 - _Options... - False True True True True + + + + True + False + emblem-system-symbolic + 1 + + + + + Options… + + @@ -373,6 +403,4 @@ - - diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-proxy.ui unity-control-center-15.04.0+19.04.20190209/panels/network/network-proxy.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-proxy.ui 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-proxy.ui 2019-05-01 13:21:41.000000000 +0000 @@ -39,9 +39,6 @@ - - False - True False @@ -50,83 +47,13 @@ 10 6 - - True - False - end - start - 1 - 48 - preferences-system-network - 6 - - - 0 - 0 - 1 - 1 - - - - - True - False - start - True - 3 - - - True - False - 0 - Proxy - end - - - - - - - False - False - 0 - - - - - True - False - 0 - Not connected - - - False - False - 1 - - - - - 1 - 0 - 1 - 1 - - - True False end start - - False - True - True - end - start - + @@ -145,7 +72,7 @@ True combobox_proxy_mode @@ -179,7 +106,7 @@ True entry_proxy_url @@ -212,7 +139,7 @@ True entry_proxy_http @@ -231,7 +158,7 @@ True entry_proxy_https @@ -250,7 +177,7 @@ True entry_proxy_ftp @@ -269,7 +196,7 @@ True entry_proxy_socks @@ -280,26 +207,30 @@ - - Apply system wide + True - True - True - False + False + 1 + _Ignore Hosts + True + entry_proxy_ignore + 0 7 - 3 + 1 1 - True + False False 0 - WPAD warning... + WPAD warning… True 50 @@ -332,6 +263,11 @@ 1 True adjustment_proxy_port_http + + + HTTP proxy port + + 2 @@ -383,6 +319,20 @@ + + True + True + + True + + + 1 + 7 + 2 + 1 + + + True True @@ -390,6 +340,11 @@ 1 True adjustment_proxy_port_https + + + HTTPS proxy port + + 2 @@ -406,6 +361,11 @@ 1 True adjustment_proxy_port_ftp + + + FTP proxy port + + 2 @@ -422,6 +382,11 @@ 1 True adjustment_proxy_port_socks + + + Socks proxy port + + 2 @@ -430,9 +395,95 @@ 1 + + + True + False + 6 + + + True + False + end + start + 1 + 48 + preferences-system-network + 6 + + + False + True + 0 + + + + + True + False + start + True + 3 + + + True + False + 0 + Proxy + end + + + + + + + False + False + 0 + + + + + True + False + 0 + Not connected + + + False + False + 1 + + + + + False + True + 1 + + + + + True + True + end + center + + + False + True + 2 + + + + + 0 + 0 + 3 + 1 + + - - diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-simple.ui unity-control-center-15.04.0+19.04.20190209/panels/network/network-simple.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-simple.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-simple.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,340 @@ + + + + + True + False + 12 + 6 + + + True + False + start + vertical + 10 + 6 + + + True + False + end + start + 1 + 48 + network-wired + 6 + + + 0 + 0 + 1 + 1 + + + + + True + False + start + True + 3 + + + True + False + 0 + Wired + end + + + + + + + False + False + 0 + + + + + True + False + 0 + Cable unplugged + + + False + False + 1 + + + + + 1 + 0 + 1 + 1 + + + + + True + False + 20 + vertical + 10 + 6 + True + + + True + False + 1 + Hardware Address + label_mac + + + + 0 + 0 + 1 + 1 + + + + + True + False + 1 + IPv4 Address + label_ipv4 + + + + 0 + 1 + 1 + 1 + + + + + True + False + 1 + IPv6 Address + label_ipv6 + + + + 0 + 2 + 1 + 1 + + + + + True + False + 1 + Default Route + label_route + + + + 0 + 3 + 1 + 1 + + + + + True + False + 1 + 0 + DNS + label_dns + + + + 0 + 4 + 1 + 1 + + + + + True + True + 0 + AA:BB:CC:DD:55:66:77:88 + True + + + 1 + 0 + 1 + 1 + + + + + True + True + 0 + 127.0.0.1 + True + + + 1 + 1 + 1 + 1 + + + + + True + True + 0 + ::1 + True + + + 1 + 2 + 1 + 1 + + + + + True + True + 0 + 127.0.0.1 + True + + + 1 + 3 + 1 + 1 + + + + + True + True + 0 + 0 + 127.0.0.1 + True + True + + + 1 + 4 + 1 + 1 + + + + + 0 + 1 + 3 + 1 + + + + + True + True + end + center + + + Turn device off + + + + + 2 + 0 + 1 + 1 + + + + + True + True + 0 + + + + + True + False + 12 + vertical + + + True + True + True + end + end + True + True + True + + + + True + False + emblem-system-symbolic + 1 + + + + + Options… + + + + + False + True + 0 + + + + + True + True + 1 + + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network.ui unity-control-center-15.04.0+19.04.20190209/panels/network/network.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/network.ui 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network.ui 2019-05-01 13:21:41.000000000 +0000 @@ -17,213 +17,22 @@ 65535 1 - - False - 5 - False - True - - dialog - - - True - False - 12 - 12 - 12 - 12 - vertical - 10 - - - True - False - - - True - False - Select the interface to use for the new service - - - - - - False - False - 0 - - - - - False - False - 0 - - - - - True - False - end - - - gtk-cancel - False - True - True - True - True - - - False - True - 0 - - - - - C_reate... - False - True - True - True - True - True - - - False - False - 1 - - - - - False - True - end - 2 - - - - - True - False - center - 10 - - - True - False - _Interface - True - connection_type_combo - - - False - True - 0 - - - - - True - False - start - start - 12 - 12 - liststore1 - 0 - - - - 0 - - - - - True - True - 1 - - - - - False - True - 1 - - - - - - cancel_button - create_button - - - - - - - - - - - - VPN - vpn - - - - - - - - - - - - - - - - - None - 0 - - - Manual - 1 - - - Automatic - 2 - - - - - - - - - - - - - False - True False 12 + 6 + 6 + 6 + 6 True @@ -238,7 +47,7 @@ True False - 12 + 12 12 12 @@ -348,8 +157,6 @@ - - diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-vpn.ui unity-control-center-15.04.0+19.04.20190209/panels/network/network-vpn.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-vpn.ui 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-vpn.ui 2019-05-01 13:21:41.000000000 +0000 @@ -1,23 +1,6 @@ - - - - - - - - - - VPN - vpn - - - - - False - True False @@ -31,70 +14,6 @@ 10 6 - - True - False - end - start - 1 - 48 - network-vpn - 6 - - - 0 - 0 - 1 - 1 - - - - - True - False - start - True - 3 - - - True - False - 0 - VPN - end - - - - - - - False - False - 0 - - - - - True - False - 0 - Not connected - - - False - False - 1 - - - - - 1 - 0 - 1 - 1 - - - True False @@ -102,7 +21,7 @@ VPN Type label_service_type @@ -120,7 +39,7 @@ Gateway label_gateway @@ -138,7 +57,7 @@ Group Name label_group_name @@ -156,7 +75,7 @@ Group Password label_group_password @@ -174,7 +93,7 @@ Username label_username @@ -205,6 +124,8 @@ True 0 AA:BB:CC:DD:55:66:77:88 + end + 24 True @@ -266,19 +187,106 @@ end start + + + + + 2 + 0 + 1 + 1 + + + + + True + False + True + 6 + + + True + False + end + start + 1 + 48 + network-vpn + 6 + + + False + True + 0 + + + + + True + False + start + True + + + True + False + 0 + VPN + end + + + + + + + False + False + 0 + + + + + True + False + 0 + Not connected + + + False + False + 1 + + + + + True + True + 1 + + + - False True True end - start + center + + + Turn VPN connection off + + + + False + True + 2 + - 2 + 0 0 - 1 + 3 1 @@ -295,8 +303,6 @@ False - _Configure... - False True True True @@ -305,7 +311,22 @@ True True True - 1 + + + + True + False + emblem-system-symbolic + 1 + + + + + Options… + + False @@ -322,8 +343,6 @@ - - diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/network-wifi.ui unity-control-center-15.04.0+19.04.20190209/panels/network/network-wifi.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/network-wifi.ui 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/network-wifi.ui 2019-05-01 13:21:41.000000000 +0000 @@ -1,105 +1,50 @@ - + False 5 + False True - True + 600 + 300 dialog - + False vertical - 14 - - - True - False - 5 - 12 - - - True - False - network-wireless - 6 - - - False - True - 0 - - - - - True - False - Wireless Hotspot - - - - - - - False - True - 1 - - - - - False - True - 0 - - - - - True - False - True - 60 - 60 - - - False - True - 1 - - + 2 - + False + end end - - gtk-cancel + + _Cancel True True True - True + True False True - 0 + 2 - - _Turn On + + _Apply True True - True - True True True False True - 1 + 3 @@ -107,144 +52,48 @@ False True end - 2 + 0 - - - - hotspot-cancel-button - hotspot-turn-on-button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - - - True - True - + True False - vertical - + True - False - 12 - vertical - - - True - False - 12 - 12 - 12 - 12 - - - True - False - start - True - Wireless - - - - - - - False - True - 0 - - - - - True - True - end - start - - - False - True - 1 - - - - - False - False - 0 - - + True + never + in - - 300 + True True - 12 - 12 - True - True - in - never + details_store + False + False + 0 + + + - - True - True - True - True - liststore_network - False - False - 0 - - - none + + + + 10 + + 0 + - - Column + + 20 - - True - True - 1 - @@ -254,502 +103,1622 @@ - - True - horizontal - 6 - - - _Use as Hotspot... - True - True - True - start - 12 - 12 - True - - - False - False - 1 - - - - - Connect to a Hidden Network - True - True - True - start - 12 - 12 - True - - - False - False - 2 - - - - - False - False - - - - - - - True - False - list - - - False - - - - - True - False - 12 - 6 - - + True - False - start - 10 - 6 + True + False + False - + True False - start - True - 3 + vertical - + True False - 0 - Wireless - end - - - - + end + center + 6 + + + True + False + Automatic _Connect + True + automatic_connect_switch + + + False + True + 0 + + + + + True + True + + + False + True + 1 + + False - False + True 0 - + True False - 0 - Not connected - - - False - False - 1 - - - - - 1 - 0 - 1 - 1 - - - - - True - False - vertical - - - _Disconnect - True - True - True - True - end - center + start + 50 + 50 + 12 + 12 True - True - - - False - True - 0 - - - - - _Connect - True - True - True - True + True + 10 + 6 + + + True + False + True + 1 + Signal Strength + + + + 0 + 0 + 1 + 1 + + + + + True + True + True + 0 + Weak + True + + + 1 + 0 + 1 + 1 + + + + + True + False + 1 + Link speed + + + + 0 + 1 + 1 + 1 + + + + + True + True + 0 + 1Mb/sec + True + + + 1 + 1 + 1 + 1 + + + + + True + False + 1 + Security + + + + 0 + 2 + 1 + 1 + + + + + True + False + 1 + IPv4 Address + + + + 0 + 3 + 1 + 1 + + + + + True + False + 1 + IPv6 Address + + + + 0 + 4 + 1 + 1 + + + + + True + False + 1 + Hardware Address + + + + 0 + 5 + 1 + 1 + + + + + True + False + 1 + Default Route + + + + 0 + 6 + 1 + 1 + + + + + True + False + 1 + 0 + DNS + + + + 0 + 7 + 1 + 1 + + + + + True + False + 1 + Last used + + + + 0 + 8 + 1 + 1 + + + + + True + True + 0 + WPA + True + + + 1 + 2 + 1 + 1 + + + + + True + True + 0 + 127.0.0.1 + True + + + 1 + 3 + 1 + 1 + + + + + True + True + 0 + ::1 + True + + + 1 + 4 + 1 + 1 + + + + + True + True + 0 + AA:BB:CC:DD:55:66:77:88 + True + + + 1 + 5 + 1 + 1 + + + + + True + True + 0 + 127.0.0.1 + True + + + 1 + 6 + 1 + 1 + + + + + True + True + 0 + 0 + 127.0.0.1 + True + True + + + 1 + 7 + 1 + 1 + + + + + True + True + 0 + today + True + + + 1 + 8 + 1 + 1 + + - False + True True 1 - - 2 - 0 - 1 - 1 - - - + + True False - 1 - Last used - label_last_used - + details - 0 - 3 - 1 - 1 + False - - True - True - True - 0 - today - - - 1 - 3 - 2 - 1 - - - - + True False - 1 - Hardware Address - label_mac - - - - 0 - 1 - 1 - 1 - - - - - True - True - 0 - AA:BB:CC:DD:55:66:77:88 - True + 50 + 50 + 12 + 12 + True + True + 10 + 6 + + + True + False + 1 + _SSID + True + entry_ssid + + + 0 + 0 + 1 + 1 + + + + + True + False + 1 + _BSSID + True + entry_bssid + + + 0 + 1 + 1 + 1 + + + + + True + False + 1 + S_ecurity + True + combo_sec + + + 0 + 2 + 1 + 1 + + + + + True + False + 1 + _Password + True + entry_password + + + 0 + 3 + 1 + 1 + + + + + True + True + True + + My Home Network + + + 1 + 0 + 1 + 1 + + + + + True + True + True + + + + 1 + 1 + 1 + 1 + + + + + True + False + True + 0 + 1 + + WPA + None + + + + 1 + 2 + 1 + 1 + + + + + True + True + True + False + + blablabla + + + 1 + 3 + 1 + 1 + + + + + Show P_assword + True + True + False + center + True + 0 + True + + + 1 + 4 + 1 + 1 + + + + + True + False + + + 0 + 4 + 1 + 1 + + + + + Make available to other users + True + True + False + end + True + 0 + True + + + 1 + 5 + 1 + 1 + + + + + - 1 - 1 - 2 - 1 + 1 - - + + True False - 1 - Security - label_security - + identity - 0 - 2 - 1 - 1 + 1 + False - + True True - 0 - WPA - True + never + + + True + False + + + True + False + 20 + 20 + 10 + 10 + vertical + 10 + + + True + False + + + True + False + IPv_4 + True + switch_ipv4_ipv4 + + + + + + False + True + 0 + + + + + True + True + end + True + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + + + True + False + _Addresses + True + combo_ipv4_addresses + + + + + + False + True + 0 + + + + + True + False + end + True + 0 + 1 + + Manual + Automatic (DHCP) + Automatic (DHCP) addresses only + Link-local only + Shared with other computers + Disabled + + + + False + True + 1 + + + + + False + True + 1 + + + + + True + False + vertical + + + True + False + Address +section +goes +here + + + False + True + 0 + + + + + False + True + 2 + + + + + True + False + 24 + 6 + 0 + DNS + + + + + + False + True + 3 + + + + + True + False + vertical + + + True + False + DNS +section +goes +here + + + False + True + 0 + + + + + False + True + 4 + + + + + True + False + 24 + 6 + 0 + Routes + + + + + + False + True + 5 + + + + + True + False + vertical + + + True + False + Routes +section +goes +here + + + False + True + 0 + + + + + False + True + 6 + + + + + _Ignore automatically obtained routes + True + True + False + True + 0 + True + + + False + True + 7 + + + + + Use this connection _only for resources on its network + True + True + False + True + 0 + True + + + False + True + 8 + + + + + + - 1 - 2 - 2 - 1 + 2 - - + + True False - 1 - Strength - label_strength - + ipv4 - 0 - 4 - 1 - 1 + 2 + False - + True - True True - 0 - Weak + never + in + + + True + False + + + True + False + vertical + 10 + + + True + False + + + True + False + IPv_6 + True + switch_ipv6_ipv6 + + + + + + False + True + 0 + + + + + True + True + end + True + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + + + True + False + _Addresses + True + combo_ipv6_addresses + + + + + + False + True + 0 + + + + + True + False + end + True + 0 + 1 + + Manual + Automatic (DHCP) + Automatic (DHCP) addresses only + Link-local only + Shared with other computers + Disabled + + + + False + True + 1 + + + + + False + True + 1 + + + + + True + False + vertical + + + True + False + Address +section +goes +here + + + False + True + 0 + + + + + False + True + 2 + + + + + True + False + 24 + 6 + 0 + DNS + + + + + + False + True + 3 + + + + + True + False + vertical + + + True + False + DNS +section +goes +here + + + False + True + 0 + + + + + False + True + 4 + + + + + True + False + 24 + 6 + 0 + Routes + + + + + + False + True + 5 + + + + + True + False + vertical + + + True + False + Routes +section +goes +here + + + False + True + 0 + + + + + False + True + 6 + + + + + _Ignore automatically obtained routes + True + True + False + True + 0 + True + + + False + True + 7 + + + + + Use this connection _only for resources on its network + True + True + False + True + 0 + True + + + False + True + 8 + + + + + + - 1 - 4 - 2 - 1 + 3 - - + + True False - 1 - Link speed - label_speed - + ipv6 - 0 - 5 - 1 - 1 + 3 + False - - True - True - True - 0 - 1Mb/sec - - - 1 - 5 - 2 - 1 - - - - + True False - 1 - IPv4 Address - label_ipv4 - - - - 0 - 6 - 1 - 1 - - - - - True - True - True - 0 - 127.0.0.1 + 50 + 50 + 12 + 12 + True + True + 10 + 6 + + + True + False + 1 + _MAC Address + True + label_hw_mac + + + 0 + 0 + 1 + 1 + + + + + True + False + 1 + _Cloned MAC Address + True + entry_hw_cloned_mac + + + 0 + 1 + 1 + 1 + + + + + True + False + True + 0 + 00:24:16:31:8G:7A + True + + + 1 + 0 + 1 + 1 + + + + + True + True + True + + + + 1 + 1 + 1 + 1 + + - 1 - 6 - 2 - 1 + 4 - - + + True False - 1 - IPv6 Address - label_ipv6 - - - - 0 - 7 - 1 - 1 - - - - - True - True - True - 0 - ::1 + hardware - 1 - 7 - 2 - 1 + 4 + False - + True False - 1 - Default Route - label_route - - - - 0 - 8 - 1 - 1 - - - - - True - True - 0 - 127.0.0.1 - True + 50 + 50 + 12 + 12 + 10 + 10 + + + _Reset + True + True + True + start + True + + + 0 + 0 + 1 + 1 + + + + + _Forget + True + True + True + start + True + + + 0 + 1 + 1 + 1 + + + + + True + False + True + 0 + Reset the settings for this connection to their defaults, but remember as a preferred connection. + True + 40 + + + 1 + 0 + 1 + 1 + + + + + True + False + True + 0 + Remove all details relating to this network and do not try to automatically connect to it. + True + 30 + + + 1 + 1 + 1 + 1 + + - 1 - 8 - 2 - 1 + 5 - - + + True False - 1 - 0 - DNS - label_dns - - - - 0 - 9 - 1 - 1 - - - - - True - True - 0 - 0 - 127.0.0.1 - True - True + reset - 1 - 9 - 2 - 1 + 5 + False + + + True + True + 1 + + + + + True + True + 1 + + + + + + details_cancel_button + details_apply_button + + + + + + + + + + + + Details + 0 + + + Identity + 1 + + + IPv4 + 2 + + + IPv6 + 3 + + + Hardware + 4 + + + Reset + 5 + + + + + False + 5 + False + True + + True + dialog + + + False + vertical + 14 + + + True + False + 5 + 12 + + + True + False + network-wireless + 6 + + + False + True + 0 + + + + + True + False + Wi-Fi Hotspot + + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + True + 60 + 60 + + + False + True + 1 + + + + + False + end + + + _Cancel + True + True + True + True + + + False + True + 0 + + + + + _Turn On + True + True + True + True + True + True + + + False + True + 1 + + + + + False + True + end + 2 + + + + + + hotspot-cancel-button + hotspot-turn-on-button + + + + True + True + False + False + + + True + False + vertical + + + True + False + 18 + vertical - + True False - vertical + 12 + 12 + 12 + 12 + 6 - + True - True - True - start - center + False + network-wireless + 6 + + + False + True + 0 + + + + + True + False True + vertical + + + True + False + 0 + Wi-Fi + + + + + + + False + True + 0 + + - + True False - left + 0 + Connected + + False + True + 1 + False True - 0 + 1 - + + True + True + end + center + True + + + Turn Wi-Fi off + + + + + True + True + 2 + - 0 - 0 - 1 - 1 + True + False + 0 + + + + + 300 + True + True + 12 + 12 + True + True + never + in + + + True + True + 1 @@ -760,85 +1729,75 @@ - + True False - 12 + 12 + 12 + 12 + True + 6 - - _Forget Network + + _Use as Hotspot… True True True start - end True False - True + False 0 - - _Settings... + + _Connect to Hidden Network… + True + True + True + center + True + + + True + False + 1 + + + + + _History True True True end - end - True - True True False - True + False 2 - True + False True 1 - - 1 - - - - - True - False - details - - - 1 - False - - - - - True - False - label - - - 2 - - + True False - hidden + list - 2 False @@ -866,7 +1825,7 @@ True False 0 - Wireless Hotspot + Wi-Fi Hotspot @@ -883,7 +1842,7 @@ True False 0 - Switch off to connect to a wireless network + Switch off to connect to a Wi-Fi network False @@ -926,6 +1885,7 @@ start 10 6 + True True @@ -934,7 +1894,7 @@ Network Name label_hotspot_network_name @@ -952,7 +1912,7 @@ Connected Devices label_hotspot_connected @@ -970,7 +1930,7 @@ Security type label_hotspot_security @@ -985,7 +1945,7 @@ True False 0 - networkname0 + True @@ -1000,7 +1960,7 @@ True False 0 - hughsie-dell-mini, hughsie-work + True @@ -1015,7 +1975,7 @@ True False 0 - WPA Enterprise + True @@ -1030,10 +1990,10 @@ True False 1 - Security key + Password label_hotspot_security_key @@ -1048,7 +2008,7 @@ True False 0 - 0xdeadbeef + True @@ -1067,7 +2027,7 @@ - 3 + 1 @@ -1077,11 +2037,9 @@ hotspot - 3 + 1 False - - diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.c unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.c 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.c 2019-05-01 13:21:41.000000000 +0000 @@ -25,10 +25,7 @@ #include #include #include - -#include -#include -#include +#include #include "panel-common.h" @@ -36,7 +33,7 @@ * panel_device_to_icon_name: **/ const gchar * -panel_device_to_icon_name (NMDevice *device) +panel_device_to_icon_name (NMDevice *device, gboolean symbolic) { const gchar *value = NULL; NMDeviceState state; @@ -44,106 +41,70 @@ switch (nm_device_get_device_type (device)) { case NM_DEVICE_TYPE_ETHERNET: state = nm_device_get_state (device); - if (state == NM_DEVICE_STATE_UNAVAILABLE) { - value = "network-wired-disconnected"; + if (state <= NM_DEVICE_STATE_DISCONNECTED) { + value = symbolic ? "network-wired-disconnected-symbolic" + : "network-wired-disconnected"; } else { - value = "network-wired"; + value = symbolic ? "network-wired-symbolic" + : "network-wired"; } break; case NM_DEVICE_TYPE_WIFI: case NM_DEVICE_TYPE_BT: case NM_DEVICE_TYPE_OLPC_MESH: - value = "network-wireless"; + value = symbolic ? "network-wireless-signal-excellent-symbolic" + : "network-wireless"; break; case NM_DEVICE_TYPE_MODEM: caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) { - value = "network-wireless"; + value = symbolic ? "network-cellular-signal-excellent-symbolic" + : "network-cellular"; + break; } - break; + /* fall thru */ default: + value = symbolic ? "network-idle-symbolic" + : "network-idle"; break; } return value; } /** - * panel_device_to_localized_string: - **/ -const gchar * -panel_device_to_localized_string (NMDevice *device) -{ - const gchar *value = NULL; - NMDeviceModemCapabilities caps; - switch (nm_device_get_device_type (device)) { - case NM_DEVICE_TYPE_UNKNOWN: - /* TRANSLATORS: device type */ - value = _("Unknown"); - break; - case NM_DEVICE_TYPE_ETHERNET: - /* TRANSLATORS: device type */ - value = _("Wired"); - break; - case NM_DEVICE_TYPE_WIFI: - /* TRANSLATORS: device type */ - value = _("Wireless"); - break; - case NM_DEVICE_TYPE_MODEM: - caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); - if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || - (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) { - /* TRANSLATORS: device type */ - value = _("Mobile broadband"); - } - break; - case NM_DEVICE_TYPE_BT: - /* TRANSLATORS: device type */ - value = _("Bluetooth"); - break; - case NM_DEVICE_TYPE_OLPC_MESH: - /* TRANSLATORS: device type */ - value = _("Mesh"); - break; - default: - break; - } - return value; -} - -/** - * panel_device_to_sortable_string: + * panel_device_get_sort_category: * * Try to return order of approximate connection speed. * But sort wifi first, since thats the common case. **/ -const gchar * -panel_device_to_sortable_string (NMDevice *device) +gint +panel_device_get_sort_category (NMDevice *device) { - const gchar *value = NULL; + gint value = 0; NMDeviceModemCapabilities caps; switch (nm_device_get_device_type (device)) { case NM_DEVICE_TYPE_ETHERNET: - value = "2"; + value = 2; break; case NM_DEVICE_TYPE_WIFI: - value = "1"; + value = 1; break; case NM_DEVICE_TYPE_MODEM: caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device)); if ((caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) || (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)) { - value = "3"; + value = 3; } break; case NM_DEVICE_TYPE_BT: - value = "4"; + value = 4; break; case NM_DEVICE_TYPE_OLPC_MESH: - value = "5"; + value = 5; break; default: - value = "6"; + value = 6; break; } return value; @@ -175,19 +136,11 @@ return value; } -/** - * panel_device_state_to_localized_string: - **/ -const gchar * -panel_device_state_to_localized_string (NMDevice *device) +static const gchar * +device_state_to_localized_string (NMDeviceState state) { - NMDeviceType type; - NMDeviceState state; - - type = nm_device_get_device_type (device); - state = nm_device_get_state (device); - const gchar *value = NULL; + switch (state) { case NM_DEVICE_STATE_UNKNOWN: /* TRANSLATORS: device status */ @@ -199,17 +152,10 @@ break; case NM_DEVICE_STATE_UNAVAILABLE: /* TRANSLATORS: device status */ - if (nm_device_get_firmware_missing (device)) - value = _("Firmware missing"); - else if (type == NM_DEVICE_TYPE_ETHERNET && - !nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (device))) - value = _("Cable unplugged"); - else - value = _("Unavailable"); + value = _("Unavailable"); break; case NM_DEVICE_STATE_DISCONNECTED: - /* TRANSLATORS: device status */ - value = _("Disconnected"); + value = NULL; break; case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_CONFIG: @@ -246,7 +192,7 @@ * panel_vpn_state_to_localized_string: **/ const gchar * -panel_vpn_state_to_localized_string (NMVPNConnectionState type) +panel_vpn_state_to_localized_string (NMVpnConnectionState type) { const gchar *value = NULL; switch (type) { @@ -284,17 +230,18 @@ return value; } -/** - * panel_device_state_reason_to_localized_string: - **/ -const gchar * -panel_device_state_reason_to_localized_string (NMDevice *device) +static const gchar * +device_state_reason_to_localized_string (NMDevice *device) { const gchar *value = NULL; NMDeviceStateReason state_reason; - /* we only want the StateReason's we care about */ - nm_device_get_state_reason (device, &state_reason); + /* This only covers NMDeviceStateReasons that explain why a connection + * failed / can't be attempted, and aren't redundant with the state + * (eg, NM_DEVICE_STATE_REASON_CARRIER). + */ + + state_reason = nm_device_get_state_reason (device); switch (state_reason) { case NM_DEVICE_STATE_REASON_CONFIG_FAILED: /* TRANSLATORS: device status reason */ @@ -428,10 +375,6 @@ /* TRANSLATORS: device status reason */ value = _("Connection disappeared"); break; - case NM_DEVICE_STATE_REASON_CARRIER: - /* TRANSLATORS: device status reason */ - value = _("Carrier/link changed"); - break; case NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED: /* TRANSLATORS: device status reason */ value = _("Existing connection was assumed"); @@ -460,10 +403,6 @@ /* TRANSLATORS: device status reason */ value = _("SIM wrong"); break; - case NM_DEVICE_STATE_REASON_INFINIBAND_MODE: - /* TRANSLATORS: device status reason */ - value = _("InfiniBand device does not support connected mode"); - break; case NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED: /* TRANSLATORS: device status reason */ value = _("Connection dependency failed"); @@ -473,9 +412,70 @@ value = ""; break; } + return value; } +static gchar * +device_status_to_localized_string (NMDevice *nm_device, + const gchar *speed) +{ + NMDeviceState state; + GString *string; + const gchar *state_str = NULL, *reason_str = NULL; + + string = g_string_new (NULL); + + state = nm_device_get_state (nm_device); + if (state == NM_DEVICE_STATE_UNAVAILABLE) { + if (nm_device_get_firmware_missing (nm_device)) { + /* TRANSLATORS: device status */ + state_str = _("Firmware missing"); + } else if (NM_IS_DEVICE_ETHERNET (nm_device) && + !nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (nm_device))) { + /* TRANSLATORS: device status */ + state_str = _("Cable unplugged"); + } + } + if (!state_str) + state_str = device_state_to_localized_string (state); + if (state_str) + g_string_append (string, state_str); + + if (state > NM_DEVICE_STATE_UNAVAILABLE && speed) { + if (string->len) + g_string_append (string, " - "); + g_string_append (string, speed); + } else if (state == NM_DEVICE_STATE_UNAVAILABLE || + state == NM_DEVICE_STATE_DISCONNECTED || + state == NM_DEVICE_STATE_DEACTIVATING || + state == NM_DEVICE_STATE_FAILED) { + reason_str = device_state_reason_to_localized_string (nm_device); + if (*reason_str) { + if (string->len) + g_string_append (string, " - "); + g_string_append (string, reason_str); + } + } + + return g_string_free (string, FALSE); +} + +void +panel_set_device_status (GtkBuilder *builder, + const gchar *label_name, + NMDevice *nm_device, + const gchar *speed) +{ + GtkLabel *label; + gchar *status; + + label = GTK_LABEL (gtk_builder_get_object (builder, label_name)); + status = device_status_to_localized_string (nm_device, speed); + gtk_label_set_label (label, status); + g_free (status); +} + gboolean panel_set_device_widget_details (GtkBuilder *builder, const gchar *widget_suffix, @@ -506,6 +506,8 @@ gtk_widget_show (heading); gtk_widget_show (widget); gtk_label_set_label (GTK_LABEL (widget), value); + gtk_label_set_max_width_chars (GTK_LABEL (widget), 50); + gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END); } return TRUE; } @@ -530,95 +532,54 @@ return TRUE; } -static gchar * -get_ipv4_config_address_as_string (NMIP4Config *ip4_config, const char *what) +gchar * +panel_get_ip4_address_as_string (NMIPConfig *ip4_config, const char *what) { - const GSList *list; - struct in_addr addr; - gchar *str = NULL; - gchar tmp[INET_ADDRSTRLEN]; - NMIP4Address *address; - - /* get address */ - list = nm_ip4_config_get_addresses (ip4_config); - if (list == NULL) - goto out; + const gchar *str = NULL; /* we only care about one address */ - address = list->data; - if (!strcmp (what, "address")) - addr.s_addr = nm_ip4_address_get_address (address); - else if (!strcmp (what, "gateway")) - addr.s_addr = nm_ip4_address_get_gateway (address); - else if (!strcmp (what, "netmask")) - addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_address_get_prefix (address)); - else - goto out; - - if (!inet_ntop (AF_INET, &addr, tmp, sizeof(tmp))) - goto out; - if (g_strcmp0 (tmp, "0.0.0.0") == 0) - goto out; - str = g_strdup (tmp); + if (!strcmp (what, "address")) { + GPtrArray *array; + NMIPAddress *address; + + array = nm_ip_config_get_addresses (ip4_config); + if (array->len < 1) + goto out; + address = array->pdata[0]; + str = nm_ip_address_get_address (address); + } else if (!strcmp (what, "gateway")) { + str = nm_ip_config_get_gateway (ip4_config); + } + out: - return str; + return g_strdup (str); } -static gchar * -get_ipv4_config_name_servers_as_string (NMIP4Config *ip4_config) +gchar * +panel_get_ip4_dns_as_string (NMIPConfig *ip4_config) { - const GArray *array; - GString *dns; - struct in_addr addr; - gchar tmp[INET_ADDRSTRLEN]; - int i; - gchar *str = NULL; - - array = nm_ip4_config_get_nameservers (ip4_config); - if (array == NULL || array->len == 0) - goto out; - - dns = g_string_new (NULL); - for (i = 0; i < array->len; i++) { - addr.s_addr = g_array_index (array, guint32, i); - if (inet_ntop (AF_INET, &addr, tmp, sizeof(tmp))) - g_string_append_printf (dns, "%s ", tmp); - } - str = g_string_free (dns, FALSE); -out: - return str; + return g_strjoinv (" ", + (char **) nm_ip_config_get_nameservers (ip4_config)); } -static gchar * -get_ipv6_config_address_as_string (NMIP6Config *ip6_config) +gchar * +panel_get_ip6_address_as_string (NMIPConfig *ip6_config) { - const GSList *list; - const struct in6_addr *addr; - gchar *str = NULL; - gchar tmp[INET6_ADDRSTRLEN]; - NMIP6Address *address; - - /* get address */ - list = nm_ip6_config_get_addresses (ip6_config); - if (list == NULL) - goto out; + GPtrArray *array; + NMIPAddress *address; - /* we only care about one address */ - address = list->data; - addr = nm_ip6_address_get_address (address); - if (addr == NULL) - goto out; - inet_ntop (AF_INET6, addr, tmp, sizeof(tmp)); - str = g_strdup (tmp); -out: - return str; + array = nm_ip_config_get_addresses (ip6_config); + if (array->len < 1) + return NULL; + address = array->pdata[0]; + return g_strdup (nm_ip_address_get_address (address)); } void panel_set_device_widgets (GtkBuilder *builder, NMDevice *device) { - NMIP4Config *ip4_config = NULL; - NMIP6Config *ip6_config = NULL; + NMIPConfig *ip4_config = NULL; + NMIPConfig *ip6_config = NULL; gboolean has_ip4; gboolean has_ip6; gchar *str_tmp; @@ -628,7 +589,7 @@ if (ip4_config != NULL) { /* IPv4 address */ - str_tmp = get_ipv4_config_address_as_string (ip4_config, "address"); + str_tmp = panel_get_ip4_address_as_string (ip4_config, "address"); panel_set_device_widget_details (builder, "ipv4", str_tmp); @@ -636,14 +597,14 @@ g_free (str_tmp); /* IPv4 DNS */ - str_tmp = get_ipv4_config_name_servers_as_string (ip4_config); + str_tmp = panel_get_ip4_dns_as_string (ip4_config); panel_set_device_widget_details (builder, "dns", str_tmp); g_free (str_tmp); /* IPv4 route */ - str_tmp = get_ipv4_config_address_as_string (ip4_config, "gateway"); + str_tmp = panel_get_ip4_address_as_string (ip4_config, "gateway"); panel_set_device_widget_details (builder, "route", str_tmp); @@ -670,7 +631,7 @@ /* get IPv6 parameters */ ip6_config = nm_device_get_ip6_config (device); if (ip6_config != NULL) { - str_tmp = get_ipv6_config_address_as_string (ip6_config); + str_tmp = panel_get_ip6_address_as_string (ip6_config); panel_set_device_widget_details (builder, "ipv6", str_tmp); has_ip6 = str_tmp != NULL; g_free (str_tmp); diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.h unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.h 2019-02-09 02:33:49.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/panel-common.h 2019-05-01 13:21:41.000000000 +0000 @@ -24,19 +24,19 @@ #include #include -#include -#include #include G_BEGIN_DECLS -const gchar *panel_device_to_icon_name (NMDevice *device); -const gchar *panel_device_to_localized_string (NMDevice *device); -const gchar *panel_device_to_sortable_string (NMDevice *device); +const gchar *panel_device_to_icon_name (NMDevice *device, + gboolean symbolic); +gint panel_device_get_sort_category (NMDevice *device); const gchar *panel_ap_mode_to_localized_string (NM80211Mode mode); -const gchar *panel_device_state_to_localized_string (NMDevice *device); -const gchar *panel_vpn_state_to_localized_string (NMVPNConnectionState type); -const gchar *panel_device_state_reason_to_localized_string (NMDevice *device); +const gchar *panel_vpn_state_to_localized_string (NMVpnConnectionState type); +void panel_set_device_status (GtkBuilder *builder, + const gchar *label_name, + NMDevice *nm_device, + const gchar *speed); gboolean panel_set_device_widget_details (GtkBuilder *builder, const gchar *widget_suffix, const gchar *value); @@ -46,8 +46,10 @@ void panel_set_device_widgets (GtkBuilder *builder, NMDevice *device); void panel_unset_device_widgets (GtkBuilder *builder); +gchar *panel_get_ip4_address_as_string (NMIPConfig *config, const gchar *what); +gchar *panel_get_ip4_dns_as_string (NMIPConfig *config); +gchar *panel_get_ip6_address_as_string (NMIPConfig *config); G_END_DECLS #endif /* PANEL_COMMON_H */ - diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,676 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include +#include +#include +#include + +#include "eap-method.h" +#include "nm-utils.h" +#include "utils.h" +#include "helpers.h" + +G_DEFINE_BOXED_TYPE (EAPMethod, eap_method, eap_method_ref, eap_method_unref) + +GtkWidget * +eap_method_get_widget (EAPMethod *method) +{ + g_return_val_if_fail (method != NULL, NULL); + + return method->ui_widget; +} + +gboolean +eap_method_validate (EAPMethod *method, GError **error) +{ + gboolean result; + + g_return_val_if_fail (method != NULL, FALSE); + + g_assert (method->validate); + result = (*(method->validate)) (method, error); + if (!result && error && !*error) + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("undefined error in 802.1X security (wpa-eap)")); + return result; +} + +void +eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group) +{ + g_return_if_fail (method != NULL); + g_return_if_fail (group != NULL); + + g_assert (method->add_to_size_group); + return (*(method->add_to_size_group)) (method, group); +} + +void +eap_method_fill_connection (EAPMethod *method, + NMConnection *connection, + NMSettingSecretFlags flags) +{ + g_return_if_fail (method != NULL); + g_return_if_fail (connection != NULL); + + g_assert (method->fill_connection); + return (*(method->fill_connection)) (method, connection, flags); +} + +void +eap_method_update_secrets (EAPMethod *method, NMConnection *connection) +{ + g_return_if_fail (method != NULL); + g_return_if_fail (connection != NULL); + + if (method->update_secrets) + method->update_secrets (method, connection); +} + +void +eap_method_phase2_update_secrets_helper (EAPMethod *method, + NMConnection *connection, + const char *combo_name, + guint32 column) +{ + GtkWidget *combo; + GtkTreeIter iter; + GtkTreeModel *model; + + g_return_if_fail (method != NULL); + g_return_if_fail (connection != NULL); + g_return_if_fail (combo_name != NULL); + + combo = GTK_WIDGET (gtk_builder_get_object (method->builder, combo_name)); + g_assert (combo); + + /* Let each EAP phase2 method try to update its secrets */ + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + EAPMethod *eap = NULL; + + gtk_tree_model_get (model, &iter, column, &eap, -1); + if (eap) { + eap_method_update_secrets (eap, connection); + eap_method_unref (eap); + } + } while (gtk_tree_model_iter_next (model, &iter)); + } +} + +EAPMethod * +eap_method_init (gsize obj_size, + EMValidateFunc validate, + EMAddToSizeGroupFunc add_to_size_group, + EMFillConnectionFunc fill_connection, + EMUpdateSecretsFunc update_secrets, + EMDestroyFunc destroy, + const char *ui_resource, + const char *ui_widget_name, + const char *default_field, + gboolean phase2) +{ + EAPMethod *method; + GError *error = NULL; + + g_return_val_if_fail (obj_size > 0, NULL); + g_return_val_if_fail (ui_resource != NULL, NULL); + g_return_val_if_fail (ui_widget_name != NULL, NULL); + + method = g_slice_alloc0 (obj_size); + g_assert (method); + + method->refcount = 1; + method->obj_size = obj_size; + method->validate = validate; + method->add_to_size_group = add_to_size_group; + method->fill_connection = fill_connection; + method->update_secrets = update_secrets; + method->default_field = default_field; + method->phase2 = phase2; + + method->builder = gtk_builder_new (); + if (!gtk_builder_add_from_resource (method->builder, ui_resource, &error)) { + g_warning ("Couldn't load UI builder resource %s: %s", + ui_resource, error->message); + eap_method_unref (method); + return NULL; + } + + method->ui_widget = GTK_WIDGET (gtk_builder_get_object (method->builder, ui_widget_name)); + if (!method->ui_widget) { + g_warning ("Couldn't load UI widget '%s' from UI file %s", + ui_widget_name, ui_resource); + eap_method_unref (method); + return NULL; + } + g_object_ref_sink (method->ui_widget); + + method->destroy = destroy; + + return method; +} + + +EAPMethod * +eap_method_ref (EAPMethod *method) +{ + g_return_val_if_fail (method != NULL, NULL); + g_return_val_if_fail (method->refcount > 0, NULL); + + method->refcount++; + return method; +} + +void +eap_method_unref (EAPMethod *method) +{ + g_return_if_fail (method != NULL); + g_return_if_fail (method->refcount > 0); + + method->refcount--; + if (method->refcount == 0) { + if (method->destroy) + method->destroy (method); + + if (method->builder) + g_object_unref (method->builder); + if (method->ui_widget) + g_object_unref (method->ui_widget); + + g_slice_free1 (method->obj_size, method); + } +} + +gboolean +eap_method_validate_filepicker (GtkBuilder *builder, + const char *name, + guint32 item_type, + const char *password, + NMSetting8021xCKFormat *out_format, + GError **error) +{ + GtkWidget *widget; + char *filename; + NMSetting8021x *setting; + gboolean success = TRUE; + + if (item_type == TYPE_PRIVATE_KEY) { + if (!password || *password == '\0') + success = FALSE; + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, name)); + g_assert (widget); + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + if (!filename) { + if (item_type != TYPE_CA_CERT) { + success = FALSE; + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("no file selected")); + } + goto out; + } + + if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + success = FALSE; + goto out; + } + + setting = (NMSetting8021x *) nm_setting_802_1x_new (); + + success = FALSE; + if (item_type == TYPE_PRIVATE_KEY) { + if (nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error)) + success = TRUE; + } else if (item_type == TYPE_CLIENT_CERT) { + if (nm_setting_802_1x_set_client_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error)) + success = TRUE; + } else if (item_type == TYPE_CA_CERT) { + if (nm_setting_802_1x_set_ca_cert (setting, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, out_format, error)) + success = TRUE; + } else + g_warning ("%s: invalid item type %d.", __func__, item_type); + + g_object_unref (setting); + +out: + g_free (filename); + + if (!success && error && !*error) + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("unspecified error validating eap-method file")); + + if (success) + widget_unset_error (widget); + else + widget_set_error (widget); + return success; +} + +static gboolean +file_has_extension (const char *filename, const char *extensions[]) +{ + char *p, *ext; + int i = 0; + gboolean found = FALSE; + + p = strrchr (filename, '.'); + if (!p) + return FALSE; + + ext = g_ascii_strdown (p, -1); + if (ext) { + while (extensions[i]) { + if (!strcmp (ext, extensions[i++])) { + found = TRUE; + break; + } + } + } + g_free (ext); + + return found; +} + +#if !LIBNM_BUILD +static const char * +find_tag (const char *tag, const char *buf, gsize len) +{ + gsize i, taglen; + + taglen = strlen (tag); + if (len < taglen) + return NULL; + + for (i = 0; i < len - taglen + 1; i++) { + if (memcmp (buf + i, tag, taglen) == 0) + return buf + i; + } + return NULL; +} + +static const char *pem_rsa_key_begin = "-----BEGIN RSA PRIVATE KEY-----"; +static const char *pem_dsa_key_begin = "-----BEGIN DSA PRIVATE KEY-----"; +static const char *pem_pkcs8_enc_key_begin = "-----BEGIN ENCRYPTED PRIVATE KEY-----"; +static const char *pem_pkcs8_dec_key_begin = "-----BEGIN PRIVATE KEY-----"; +static const char *pem_cert_begin = "-----BEGIN CERTIFICATE-----"; +static const char *proc_type_tag = "Proc-Type: 4,ENCRYPTED"; +static const char *dek_info_tag = "DEK-Info:"; + +static gboolean +pem_file_is_encrypted (const char *buffer, gsize bytes_read) +{ + /* Check if the private key is encrypted or not by looking for the + * old OpenSSL-style proc-type and dec-info tags. + */ + if (find_tag (proc_type_tag, (const char *) buffer, bytes_read)) { + if (find_tag (dek_info_tag, (const char *) buffer, bytes_read)) + return TRUE; + } + return FALSE; +} + +static gboolean +file_is_der_or_pem (const char *filename, + gboolean privkey, + gboolean *out_privkey_encrypted) +{ + int fd; + unsigned char buffer[8192]; + ssize_t bytes_read; + gboolean success = FALSE; + + fd = open (filename, O_RDONLY); + if (fd < 0) + return FALSE; + + bytes_read = read (fd, buffer, sizeof (buffer) - 1); + if (bytes_read < 400) /* needs to be lower? */ + goto out; + buffer[bytes_read] = '\0'; + + /* Check for DER signature */ + if (bytes_read > 2 && buffer[0] == 0x30 && buffer[1] == 0x82) { + success = TRUE; + goto out; + } + + /* Check for PEM signatures */ + if (privkey) { + if (find_tag (pem_rsa_key_begin, (const char *) buffer, bytes_read)) { + success = TRUE; + if (out_privkey_encrypted) + *out_privkey_encrypted = pem_file_is_encrypted ((const char *) buffer, bytes_read); + goto out; + } + + if (find_tag (pem_dsa_key_begin, (const char *) buffer, bytes_read)) { + success = TRUE; + if (out_privkey_encrypted) + *out_privkey_encrypted = pem_file_is_encrypted ((const char *) buffer, bytes_read); + goto out; + } + + if (find_tag (pem_pkcs8_enc_key_begin, (const char *) buffer, bytes_read)) { + success = TRUE; + if (out_privkey_encrypted) + *out_privkey_encrypted = TRUE; + goto out; + } + + if (find_tag (pem_pkcs8_dec_key_begin, (const char *) buffer, bytes_read)) { + success = TRUE; + if (out_privkey_encrypted) + *out_privkey_encrypted = FALSE; + goto out; + } + } else { + if (find_tag (pem_cert_begin, (const char *) buffer, bytes_read)) { + success = TRUE; + goto out; + } + } + +out: + close (fd); + return success; +} +#endif + +static gboolean +default_filter_privkey (const GtkFileFilterInfo *filter_info, gpointer user_data) +{ + const char *extensions[] = { ".der", ".pem", ".p12", ".key", NULL }; + + if (!filter_info->filename) + return FALSE; + + if (!file_has_extension (filter_info->filename, extensions)) + return FALSE; + + return TRUE; +} + +static gboolean +default_filter_cert (const GtkFileFilterInfo *filter_info, gpointer user_data) +{ + const char *extensions[] = { ".der", ".pem", ".crt", ".cer", NULL }; + + if (!filter_info->filename) + return FALSE; + + if (!file_has_extension (filter_info->filename, extensions)) + return FALSE; + + return TRUE; +} + +GtkFileFilter * +eap_method_default_file_chooser_filter_new (gboolean privkey) +{ + GtkFileFilter *filter; + + filter = gtk_file_filter_new (); + if (privkey) { + gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME, default_filter_privkey, NULL, NULL); + gtk_file_filter_set_name (filter, _("DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)")); + } else { + gtk_file_filter_add_custom (filter, GTK_FILE_FILTER_FILENAME, default_filter_cert, NULL, NULL); + gtk_file_filter_set_name (filter, _("DER or PEM certificates (*.der, *.pem, *.crt, *.cer)")); + } + return filter; +} + +gboolean +eap_method_is_encrypted_private_key (const char *path) +{ + GtkFileFilterInfo info = { .filename = path }; + gboolean is_encrypted; + + if (!default_filter_privkey (&info, NULL)) + return FALSE; + +#if LIBNM_BUILD + is_encrypted = FALSE; + if (!nm_utils_file_is_private_key (path, &is_encrypted)) + return FALSE; +#else + is_encrypted = TRUE; + if ( !file_is_der_or_pem (path, TRUE, &is_encrypted) + && !nm_utils_file_is_pkcs12 (path)) + return FALSE; +#endif + return is_encrypted; +} + +/* Some methods (PEAP, TLS, TTLS) require a CA certificate. The user can choose + * not to provide such a certificate. This method whether the checkbox + * id_ca_cert_not_required_checkbutton is checked or id_ca_cert_chooser has a certificate + * selected. + */ +gboolean +eap_method_ca_cert_required (GtkBuilder *builder, const char *id_ca_cert_not_required_checkbutton, const char *id_ca_cert_chooser) +{ + char *filename; + GtkWidget *widget; + + g_assert (builder && id_ca_cert_not_required_checkbutton && id_ca_cert_chooser); + + widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_not_required_checkbutton)); + g_assert (widget && GTK_IS_TOGGLE_BUTTON (widget)); + + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { + widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_chooser)); + g_assert (widget && GTK_IS_FILE_CHOOSER (widget)); + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + if (!filename) + return TRUE; + g_free (filename); + } + return FALSE; +} + + +void +eap_method_ca_cert_not_required_toggled (GtkBuilder *builder, const char *id_ca_cert_not_required_checkbutton, const char *id_ca_cert_chooser) +{ + char *filename, *filename_old; + gboolean is_not_required; + GtkWidget *widget; + + g_assert (builder && id_ca_cert_not_required_checkbutton && id_ca_cert_chooser); + + widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_not_required_checkbutton)); + g_assert (widget && GTK_IS_TOGGLE_BUTTON (widget)); + is_not_required = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + widget = GTK_WIDGET (gtk_builder_get_object (builder, id_ca_cert_chooser)); + g_assert (widget && GTK_IS_FILE_CHOOSER (widget)); + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + filename_old = g_object_steal_data (G_OBJECT (widget), "filename-old"); + if (is_not_required) { + g_free (filename_old); + filename_old = filename; + filename = NULL; + } else { + g_free (filename); + filename = filename_old; + filename_old = NULL; + } + gtk_widget_set_sensitive (widget, !is_not_required); + if (filename) + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); + else + gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget)); + g_free (filename); + g_object_set_data_full (G_OBJECT (widget), "filename-old", filename_old, g_free); +} + +/* Used as both GSettings keys and GObject data tags */ +#define IGNORE_CA_CERT_TAG "ignore-ca-cert" +#define IGNORE_PHASE2_CA_CERT_TAG "ignore-phase2-ca-cert" + +/** + * eap_method_ca_cert_ignore_set: + * @method: the #EAPMethod object + * @connection: the #NMConnection + * @filename: the certificate file, if any + * @ca_cert_error: %TRUE if an error was encountered loading the given CA + * certificate, %FALSE if not or if a CA certificate is not present + * + * Updates the connection's CA cert ignore value to %TRUE if the "CA certificate + * not required" checkbox is checked. If @ca_cert_error is %TRUE, then the + * connection's CA cert ignore value will always be set to %FALSE, because it + * means that the user selected an invalid certificate (thus he does not want to + * ignore the CA cert).. + */ +void +eap_method_ca_cert_ignore_set (EAPMethod *method, + NMConnection *connection, + const char *filename, + gboolean ca_cert_error) +{ + NMSetting8021x *s_8021x; + gboolean ignore; + + s_8021x = nm_connection_get_setting_802_1x (connection); + if (s_8021x) { + ignore = !ca_cert_error && filename == NULL; + g_object_set_data (G_OBJECT (s_8021x), + method->phase2 ? IGNORE_PHASE2_CA_CERT_TAG : IGNORE_CA_CERT_TAG, + GUINT_TO_POINTER (ignore)); + } +} + +/** + * eap_method_ca_cert_ignore_get: + * @method: the #EAPMethod object + * @connection: the #NMConnection + * + * Returns: %TRUE if a missing CA certificate can be ignored, %FALSE if a CA + * certificate should be required for the connection to be valid. + */ +gboolean +eap_method_ca_cert_ignore_get (EAPMethod *method, NMConnection *connection) +{ + NMSetting8021x *s_8021x; + + s_8021x = nm_connection_get_setting_802_1x (connection); + if (s_8021x) { + return !!g_object_get_data (G_OBJECT (s_8021x), + method->phase2 ? IGNORE_PHASE2_CA_CERT_TAG : IGNORE_CA_CERT_TAG); + } + return FALSE; +} + +static GSettings * +_get_ca_ignore_settings (NMConnection *connection) +{ + GSettings *settings; + char *path = NULL; + const char *uuid; + + g_return_val_if_fail (connection, NULL); + + uuid = nm_connection_get_uuid (connection); + g_return_val_if_fail (uuid && *uuid, NULL); + + path = g_strdup_printf ("/org/gnome/nm-applet/eap/%s/", uuid); + settings = g_settings_new_with_path ("org.gnome.nm-applet.eap", path); + g_free (path); + + return settings; +} + +/** + * eap_method_ca_cert_ignore_save: + * @connection: the connection for which to save CA cert ignore values to GSettings + * + * Reads the CA cert ignore tags from the 802.1x setting GObject data and saves + * then to GSettings if present, using the connection UUID as the index. + */ +void +eap_method_ca_cert_ignore_save (NMConnection *connection) +{ + NMSetting8021x *s_8021x; + GSettings *settings; + gboolean ignore = FALSE, phase2_ignore = FALSE; + + g_return_if_fail (connection); + + s_8021x = nm_connection_get_setting_802_1x (connection); + if (s_8021x) { + ignore = !!g_object_get_data (G_OBJECT (s_8021x), IGNORE_CA_CERT_TAG); + phase2_ignore = !!g_object_get_data (G_OBJECT (s_8021x), IGNORE_PHASE2_CA_CERT_TAG); + } + + settings = _get_ca_ignore_settings (connection); + if (!settings) + return; + + g_settings_set_boolean (settings, IGNORE_CA_CERT_TAG, ignore); + g_settings_set_boolean (settings, IGNORE_PHASE2_CA_CERT_TAG, phase2_ignore); + g_object_unref (settings); +} + +/** + * eap_method_ca_cert_ignore_load: + * @connection: the connection for which to load CA cert ignore values to GSettings + * + * Reads the CA cert ignore tags from the 802.1x setting GObject data and saves + * then to GSettings if present, using the connection UUID as the index. + */ +void +eap_method_ca_cert_ignore_load (NMConnection *connection) +{ + GSettings *settings; + NMSetting8021x *s_8021x; + gboolean ignore, phase2_ignore; + + g_return_if_fail (connection); + + s_8021x = nm_connection_get_setting_802_1x (connection); + if (!s_8021x) + return; + + settings = _get_ca_ignore_settings (connection); + if (!settings) + return; + + ignore = g_settings_get_boolean (settings, IGNORE_CA_CERT_TAG); + phase2_ignore = g_settings_get_boolean (settings, IGNORE_PHASE2_CA_CERT_TAG); + + g_object_set_data (G_OBJECT (s_8021x), + IGNORE_CA_CERT_TAG, + GUINT_TO_POINTER (ignore)); + g_object_set_data (G_OBJECT (s_8021x), + IGNORE_PHASE2_CA_CERT_TAG, + GUINT_TO_POINTER (phase2_ignore)); + g_object_unref (settings); +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,450 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */ + +/* EAP-FAST authentication method (RFC4851) + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2012 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "eap-method.h" +#include "wireless-security.h" +#include "utils.h" +#include "helpers.h" + +#define I_NAME_COLUMN 0 +#define I_METHOD_COLUMN 1 + +struct _EAPMethodFAST { + EAPMethod parent; + + GtkSizeGroup *size_group; + WirelessSecurity *sec_parent; + gboolean is_editor; +}; + +static void +destroy (EAPMethod *parent) +{ + EAPMethodFAST *method = (EAPMethodFAST *) parent; + + if (method->size_group) + g_object_unref (method->size_group); +} + +static gboolean +validate (EAPMethod *parent, GError **error) +{ + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap = NULL; + const char *file; + gboolean provisioning; + gboolean valid = TRUE; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); + g_assert (widget); + provisioning = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); + g_assert (widget); + file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + if (!provisioning && !file) { + widget_set_error (widget); + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-FAST PAC file")); + valid = FALSE; + } else + widget_unset_error (widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); + g_assert (widget); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + valid = eap_method_validate (eap, valid ? error : NULL) && valid; + eap_method_unref (eap); + return valid; +} + +static void +add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) +{ + EAPMethodFAST *method = (EAPMethodFAST *) parent; + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap; + + if (method->size_group) + g_object_unref (method->size_group); + method->size_group = g_object_ref (group); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); + g_assert (widget); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + eap_method_add_to_size_group (eap, group); + eap_method_unref (eap); +} + +static void +fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) +{ + NMSetting8021x *s_8021x; + GtkWidget *widget; + const char *text; + char *filename; + EAPMethod *eap = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean enabled; + int pac_provisioning = 0; + + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + nm_setting_802_1x_add_eap_method (s_8021x, "fast"); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry")); + g_assert (widget); + text = gtk_entry_get_text (GTK_ENTRY (widget)); + if (text && strlen (text)) + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); + g_assert (widget); + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + g_object_set (s_8021x, NM_SETTING_802_1X_PAC_FILE, filename, NULL); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); + enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + if (!enabled) + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "0", NULL); + else { + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); + pac_provisioning = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)); + + switch (pac_provisioning) { + case 0: /* Anonymous */ + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "1", NULL); + break; + case 1: /* Authenticated */ + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "2", NULL); + break; + case 2: /* Both - anonymous and authenticated */ + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "3", NULL); + break; + default: /* Should not happen */ + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING, "1", NULL); + break; + } + } + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + eap_method_fill_connection (eap, connection, flags); + eap_method_unref (eap); +} + +static void +inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) +{ + EAPMethod *parent = (EAPMethod *) user_data; + EAPMethodFAST *method = (EAPMethodFAST *) parent; + GtkWidget *vbox; + EAPMethod *eap = NULL; + GList *elt, *children; + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *eap_widget; + + vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_vbox")); + g_assert (vbox); + + /* Remove any previous wireless security widgets */ + children = gtk_container_get_children (GTK_CONTAINER (vbox)); + for (elt = children; elt; elt = g_list_next (elt)) + gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); + g_list_free (children); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + eap_widget = eap_method_get_widget (eap); + g_assert (eap_widget); + gtk_widget_unparent (eap_widget); + + if (method->size_group) + eap_method_add_to_size_group (eap, method->size_group); + gtk_container_add (GTK_CONTAINER (vbox), eap_widget); + + eap_method_unref (eap); + + wireless_security_changed_cb (combo, method->sec_parent); +} + +static GtkWidget * +inner_auth_combo_init (EAPMethodFAST *method, + NMConnection *connection, + NMSetting8021x *s_8021x, + gboolean secrets_only) +{ + EAPMethod *parent = (EAPMethod *) method; + GtkWidget *combo; + GtkListStore *auth_model; + GtkTreeIter iter; + EAPMethodSimple *em_gtc; + EAPMethodSimple *em_mschap_v2; + guint32 active = 0; + const char *phase2_auth = NULL; + EAPMethodSimpleFlags simple_flags; + + auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); + + if (s_8021x) { + if (nm_setting_802_1x_get_phase2_auth (s_8021x)) + phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x); + else if (nm_setting_802_1x_get_phase2_autheap (s_8021x)) + phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x); + } + + simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2; + if (method->is_editor) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; + if (secrets_only) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; + + em_gtc = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_GTC, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("GTC"), + I_METHOD_COLUMN, em_gtc, + -1); + eap_method_unref (EAP_METHOD (em_gtc)); + + /* Check for defaulting to GTC */ + if (phase2_auth && !strcasecmp (phase2_auth, "gtc")) + active = 0; + + em_mschap_v2 = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("MSCHAPv2"), + I_METHOD_COLUMN, em_mschap_v2, + -1); + eap_method_unref (EAP_METHOD (em_mschap_v2)); + + /* Check for defaulting to MSCHAPv2 */ + if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2")) + active = 1; + + combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); + g_assert (combo); + + gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); + g_object_unref (G_OBJECT (auth_model)); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active); + + g_signal_connect (G_OBJECT (combo), "changed", + (GCallback) inner_auth_combo_changed_cb, + method); + return combo; +} + +static void +update_secrets (EAPMethod *parent, NMConnection *connection) +{ + eap_method_phase2_update_secrets_helper (parent, + connection, + "eap_fast_inner_auth_combo", + I_METHOD_COLUMN); +} + +static void +pac_toggled_cb (GtkWidget *widget, gpointer user_data) +{ + EAPMethod *parent = (EAPMethod *) user_data; + EAPMethodFAST *method = (EAPMethodFAST *) parent; + gboolean enabled = FALSE; + GtkWidget *provision_combo; + + provision_combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); + g_return_if_fail (provision_combo); + + enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + gtk_widget_set_sensitive (provision_combo, enabled); + + wireless_security_changed_cb (widget, method->sec_parent); +} + +EAPMethodFAST * +eap_method_fast_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only) +{ + EAPMethod *parent; + EAPMethodFAST *method; + GtkWidget *widget; + GtkFileFilter *filter; + NMSetting8021x *s_8021x = NULL; + const char *filename; + gboolean provisioning_enabled = TRUE; + + parent = eap_method_init (sizeof (EAPMethodFAST), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/eap-method-fast.ui", + "eap_fast_notebook", + "eap_fast_anon_identity_entry", + FALSE); + if (!parent) + return NULL; + + parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; + method = (EAPMethodFAST *) parent; + method->sec_parent = ws_parent; + method->is_editor = is_editor; + + if (connection) + s_8021x = nm_connection_get_setting_802_1x (connection); + + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); + g_assert (widget); + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); + if (s_8021x) { + const char *fast_prov; + + fast_prov = nm_setting_802_1x_get_phase1_fast_provisioning (s_8021x); + if (fast_prov) { + if (!strcmp (fast_prov, "0")) + provisioning_enabled = FALSE; + else if (!strcmp (fast_prov, "1")) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); + else if (!strcmp (fast_prov, "2")) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1); + else if (!strcmp (fast_prov, "3")) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2); + } + } + gtk_widget_set_sensitive (widget, provisioning_enabled); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), provisioning_enabled); + g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (pac_toggled_cb), parent); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry")); + if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x)) + gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x)); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); + g_assert (widget); + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); + gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), + _("Choose a PAC file")); + g_signal_connect (G_OBJECT (widget), "selection-changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + filter = gtk_file_filter_new (); + gtk_file_filter_add_pattern (filter, "*.pac"); + gtk_file_filter_set_name (filter, _("PAC files (*.pac)")); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); + filter = gtk_file_filter_new (); + gtk_file_filter_add_pattern (filter, "*"); + gtk_file_filter_set_name (filter, _("All files")); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); + + if (connection && s_8021x) { + filename = nm_setting_802_1x_get_pac_file (s_8021x); + if (filename) + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); + } + + widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only); + inner_auth_combo_changed_cb (widget, (gpointer) method); + + if (secrets_only) { + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_anon_identity_entry")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_checkbutton")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_provision_combo")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_pac_file_button")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_fast_inner_auth_combo")); + gtk_widget_hide (widget); + } + + return method; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* vim: set ft=c ts=4 sts=4 sw=4 noexpandtab smartindent: */ + +/* EAP-FAST authentication method (RFC4851) + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2012 Red Hat, Inc. + */ + +#ifndef EAP_METHOD_FAST_H +#define EAP_METHOD_FAST_H + +#include "wireless-security.h" + +typedef struct _EAPMethodFAST EAPMethodFAST; + +EAPMethodFAST *eap_method_fast_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only); + +#endif /* EAP_METHOD_FAST_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-fast.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + Anonymous + + + Authenticated + + + Both + + + + + True + False + False + False + + + True + False + 5 + 2 + 6 + 6 + + + True + False + 1 + Anony_mous identity + True + eap_fast_anon_identity_entry + + + GTK_FILL + + + + + + True + True + True + + + 1 + 2 + + + + + + True + False + 1 + PAC _file + True + eap_fast_pac_file_button + + + 2 + 3 + GTK_FILL + + + + + + True + False + + + 1 + 2 + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + False + + + + + + 2 + 4 + 5 + GTK_FILL + + + + + True + False + 1 + _Inner authentication + True + eap_fast_inner_auth_combo + + + 3 + 4 + GTK_FILL + + + + + + True + False + model8 + + + + 0 + + + + + 1 + 2 + 3 + 4 + GTK_FILL + GTK_FILL + + + + + Allow automatic PAC pro_visioning + True + True + False + True + True + + + 1 + 2 + GTK_FILL + + + + + + True + False + model9 + + + + 0 + + + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,131 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef EAP_METHOD_H +#define EAP_METHOD_H + +typedef struct _EAPMethod EAPMethod; + +typedef void (*EMAddToSizeGroupFunc) (EAPMethod *method, GtkSizeGroup *group); +typedef void (*EMFillConnectionFunc) (EAPMethod *method, NMConnection *connection, NMSettingSecretFlags flags); +typedef void (*EMUpdateSecretsFunc) (EAPMethod *method, NMConnection *connection); +typedef void (*EMDestroyFunc) (EAPMethod *method); +typedef gboolean (*EMValidateFunc) (EAPMethod *method, GError **error); + +struct _EAPMethod { + guint32 refcount; + gsize obj_size; + + GtkBuilder *builder; + GtkWidget *ui_widget; + + const char *default_field; + const char *password_flags_name; + + gboolean phase2; + gboolean secrets_only; + + EMAddToSizeGroupFunc add_to_size_group; + EMFillConnectionFunc fill_connection; + EMUpdateSecretsFunc update_secrets; + EMValidateFunc validate; + EMDestroyFunc destroy; +}; + +#define EAP_METHOD(x) ((EAPMethod *) x) + + +GtkWidget *eap_method_get_widget (EAPMethod *method); + +gboolean eap_method_validate (EAPMethod *method, GError **error); + +void eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group); + +void eap_method_fill_connection (EAPMethod *method, + NMConnection *connection, + NMSettingSecretFlags flags); + +void eap_method_update_secrets (EAPMethod *method, NMConnection *connection); + +EAPMethod *eap_method_ref (EAPMethod *method); + +void eap_method_unref (EAPMethod *method); + +GType eap_method_get_type (void); + +/* Below for internal use only */ + +#include "eap-method-tls.h" +#include "eap-method-leap.h" +#include "eap-method-fast.h" +#include "eap-method-ttls.h" +#include "eap-method-peap.h" +#include "eap-method-simple.h" + +EAPMethod *eap_method_init (gsize obj_size, + EMValidateFunc validate, + EMAddToSizeGroupFunc add_to_size_group, + EMFillConnectionFunc fill_connection, + EMUpdateSecretsFunc update_secrets, + EMDestroyFunc destroy, + const char *ui_resource, + const char *ui_widget_name, + const char *default_field, + gboolean phase2); + +GtkFileFilter * eap_method_default_file_chooser_filter_new (gboolean privkey); + +gboolean eap_method_is_encrypted_private_key (const char *path); + +#define TYPE_CLIENT_CERT 0 +#define TYPE_CA_CERT 1 +#define TYPE_PRIVATE_KEY 2 + +gboolean eap_method_validate_filepicker (GtkBuilder *builder, + const char *name, + guint32 item_type, + const char *password, + NMSetting8021xCKFormat *out_format, + GError **error); + +void eap_method_phase2_update_secrets_helper (EAPMethod *method, + NMConnection *connection, + const char *combo_name, + guint32 column); + +gboolean eap_method_ca_cert_required (GtkBuilder *builder, + const char *id_ca_cert_is_not_required_checkbox, + const char *id_ca_cert_chooser); +void eap_method_ca_cert_not_required_toggled (GtkBuilder *builder, + const char *id_ca_cert_is_not_required_checkbox, + const char *id_ca_cert_chooser); + +void eap_method_ca_cert_ignore_set (EAPMethod *method, + NMConnection *connection, + const char *filename, + gboolean ca_cert_error); +gboolean eap_method_ca_cert_ignore_get (EAPMethod *method, NMConnection *connection); + +void eap_method_ca_cert_ignore_save (NMConnection *connection); +void eap_method_ca_cert_ignore_load (NMConnection *connection); + +#endif /* EAP_METHOD_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,263 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "eap-method.h" +#include "wireless-security.h" +#include "helpers.h" +#include "nma-ui-utils.h" +#include "utils.h" + +struct _EAPMethodLEAP { + EAPMethod parent; + + WirelessSecurity *ws_parent; + + gboolean editing_connection; + + GtkEntry *username_entry; + GtkEntry *password_entry; + GtkToggleButton *show_password; +}; + +static void +show_toggled_cb (GtkToggleButton *button, EAPMethodLEAP *method) +{ + gboolean visible; + + visible = gtk_toggle_button_get_active (button); + gtk_entry_set_visibility (method->password_entry, visible); +} + +static gboolean +validate (EAPMethod *parent, GError **error) +{ + EAPMethodLEAP *method = (EAPMethodLEAP *)parent; + const char *text; + gboolean ret = TRUE; + + text = gtk_entry_get_text (method->username_entry); + if (!text || !strlen (text)) { + widget_set_error (GTK_WIDGET (method->username_entry)); + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-LEAP username")); + ret = FALSE; + } else + widget_unset_error (GTK_WIDGET (method->username_entry)); + + text = gtk_entry_get_text (method->password_entry); + if (!text || !strlen (text)) { + widget_set_error (GTK_WIDGET (method->password_entry)); + if (ret) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-LEAP password")); + ret = FALSE; + } + } else + widget_unset_error (GTK_WIDGET (method->password_entry)); + + return ret; +} + +static void +add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) +{ + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); +} + +static void +fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) +{ + EAPMethodLEAP *method = (EAPMethodLEAP *) parent; + NMSetting8021x *s_8021x; + NMSettingSecretFlags secret_flags; + GtkWidget *passwd_entry; + + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + nm_setting_802_1x_add_eap_method (s_8021x, "leap"); + + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (method->username_entry), NULL); + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (method->password_entry), NULL); + + passwd_entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry")); + g_assert (passwd_entry); + + /* Save 802.1X password flags to the connection */ + secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); + nm_setting_set_secret_flags (NM_SETTING (s_8021x), parent->password_flags_name, + secret_flags, NULL); + + /* Update secret flags and popup when editing the connection */ + if (method->editing_connection) + nma_utils_update_password_storage (passwd_entry, secret_flags, + NM_SETTING (s_8021x), parent->password_flags_name); +} + +static void +update_secrets (EAPMethod *parent, NMConnection *connection) +{ + helper_fill_secret_entry (connection, + parent->builder, + "eap_leap_password_entry", + NM_TYPE_SETTING_802_1X, + (HelperSecretFunc) nm_setting_802_1x_get_password); +} + +/* Set the UI fields for user, password and show_password to the + * values as provided by method->ws_parent. */ +static void +set_userpass_ui (EAPMethodLEAP *method) +{ + if (method->ws_parent->username) + gtk_entry_set_text (method->username_entry, method->ws_parent->username); + else + gtk_entry_set_text (method->username_entry, ""); + + if (method->ws_parent->password && !method->ws_parent->always_ask) + gtk_entry_set_text (method->password_entry, method->ws_parent->password); + else + gtk_entry_set_text (method->password_entry, ""); + + gtk_toggle_button_set_active (method->show_password, method->ws_parent->show_password); +} + +static void +widgets_realized (GtkWidget *widget, EAPMethodLEAP *method) +{ + set_userpass_ui (method); +} + +static void +widgets_unrealized (GtkWidget *widget, EAPMethodLEAP *method) +{ + wireless_security_set_userpass (method->ws_parent, + gtk_entry_get_text (method->username_entry), + gtk_entry_get_text (method->password_entry), + (gboolean) -1, + gtk_toggle_button_get_active (method->show_password)); +} + +static void +destroy (EAPMethod *parent) +{ + EAPMethodLEAP *method = (EAPMethodLEAP *) parent; + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_notebook")); + g_assert (widget); + g_signal_handlers_disconnect_by_data (widget, method); + + g_signal_handlers_disconnect_by_data (method->username_entry, method->ws_parent); + g_signal_handlers_disconnect_by_data (method->password_entry, method->ws_parent); + g_signal_handlers_disconnect_by_data (method->show_password, method); +} + +EAPMethodLEAP * +eap_method_leap_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean secrets_only) +{ + EAPMethodLEAP *method; + EAPMethod *parent; + GtkWidget *widget; + NMSetting8021x *s_8021x = NULL; + + parent = eap_method_init (sizeof (EAPMethodLEAP), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/eap-method-leap.ui", + "eap_leap_notebook", + "eap_leap_username_entry", + FALSE); + if (!parent) + return NULL; + + parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; + method = (EAPMethodLEAP *) parent; + method->editing_connection = secrets_only ? FALSE : TRUE; + method->ws_parent = ws_parent; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_notebook")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "realize", + (GCallback) widgets_realized, + method); + g_signal_connect (G_OBJECT (widget), "unrealize", + (GCallback) widgets_unrealized, + method); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry")); + g_assert (widget); + method->username_entry = GTK_ENTRY (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + if (secrets_only) + gtk_widget_set_sensitive (widget, FALSE); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry")); + g_assert (widget); + method->password_entry = GTK_ENTRY (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + /* Create password-storage popup menu for password entry under entry's secondary icon */ + if (connection) + s_8021x = nm_connection_get_setting_802_1x (connection); + nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name, + FALSE, secrets_only); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapleap")); + g_assert (widget); + method->show_password = GTK_TOGGLE_BUTTON (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) show_toggled_cb, + parent); + + /* Initialize the UI fields with the security settings from method->ws_parent. + * This will be done again when the widget gets realized. It must be done here as well, + * because the outer dialog will ask to 'validate' the connection before the security tab + * is shown/realized (to enable the 'Apply' button). + * As 'validate' accesses the contents of the UI fields, they must be initialized now, even + * if the widgets are not yet visible. */ + set_userpass_ui (method); + + return method; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,35 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2010 Red Hat, Inc. + */ + +#ifndef EAP_METHOD_LEAP_H +#define EAP_METHOD_LEAP_H + +#include "wireless-security.h" + +typedef struct _EAPMethodLEAP EAPMethodLEAP; + +EAPMethodLEAP *eap_method_leap_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean secrets_only); + +#endif /* EAP_METHOD_LEAP_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-leap.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,107 @@ + + + + + True + False + False + False + + + True + False + start + 3 + 2 + 6 + 6 + + + + + + True + False + 1 + _Username + True + eap_leap_username_entry + + + GTK_FILL + + + + + + True + False + 1 + _Password + True + eap_leap_password_entry + + + 1 + 2 + GTK_FILL + + + + + + True + True + False + True + + + 1 + 2 + 1 + 2 + + + + + + Sho_w password + True + True + False + True + True + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + True + + + 1 + 2 + + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,450 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "eap-method.h" +#include "wireless-security.h" +#include "utils.h" + +#define I_NAME_COLUMN 0 +#define I_METHOD_COLUMN 1 + +struct _EAPMethodPEAP { + EAPMethod parent; + + GtkSizeGroup *size_group; + WirelessSecurity *sec_parent; + gboolean is_editor; +}; + +static void +destroy (EAPMethod *parent) +{ + EAPMethodPEAP *method = (EAPMethodPEAP *) parent; + + if (method->size_group) + g_object_unref (method->size_group); +} + +static gboolean +validate (EAPMethod *parent, GError **error) +{ + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap = NULL; + gboolean valid = FALSE; + GError *local = NULL; + + if (!eap_method_validate_filepicker (parent->builder, "eap_peap_ca_cert_button", TYPE_CA_CERT, NULL, NULL, &local)) { + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-PEAP CA certificate: %s"), local->message); + g_clear_error (&local); + return FALSE; + } + if (eap_method_ca_cert_required (parent->builder, "eap_peap_ca_cert_not_required_checkbox", "eap_peap_ca_cert_button")) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-PEAP CA certificate: no certificate specified")); + return FALSE; + } + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); + g_assert (widget); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + valid = eap_method_validate (eap, error); + eap_method_unref (eap); + return valid; +} + +static void +ca_cert_not_required_toggled (GtkWidget *ignored, gpointer user_data) +{ + EAPMethod *parent = user_data; + + eap_method_ca_cert_not_required_toggled (parent->builder, "eap_peap_ca_cert_not_required_checkbox", "eap_peap_ca_cert_button"); +} + +static void +add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) +{ + EAPMethodPEAP *method = (EAPMethodPEAP *) parent; + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap; + + if (method->size_group) + g_object_unref (method->size_group); + method->size_group = g_object_ref (group); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_not_required_checkbox")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); + g_assert (widget); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + eap_method_add_to_size_group (eap, group); + eap_method_unref (eap); +} + +static void +fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) +{ + NMSetting8021x *s_8021x; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GtkWidget *widget; + const char *text; + char *filename; + EAPMethod *eap = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + int peapver_active = 0; + GError *error = NULL; + gboolean ca_cert_error = FALSE; + + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + nm_setting_802_1x_add_eap_method (s_8021x, "peap"); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry")); + g_assert (widget); + text = gtk_entry_get_text (GTK_ENTRY (widget)); + if (text && strlen (text)) + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button")); + g_assert (widget); + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + ca_cert_error = TRUE; + } + eap_method_ca_cert_ignore_set (parent, connection, filename, ca_cert_error); + g_free (filename); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo")); + peapver_active = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)); + switch (peapver_active) { + case 1: /* PEAP v0 */ + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, "0", NULL); + break; + case 2: /* PEAP v1 */ + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, "1", NULL); + break; + default: /* Automatic */ + g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE1_PEAPVER, NULL, NULL); + break; + } + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + eap_method_fill_connection (eap, connection, flags); + eap_method_unref (eap); +} +static void +inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) +{ + EAPMethod *parent = (EAPMethod *) user_data; + EAPMethodPEAP *method = (EAPMethodPEAP *) parent; + GtkWidget *vbox; + EAPMethod *eap = NULL; + GList *elt, *children; + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *eap_widget; + + vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_vbox")); + g_assert (vbox); + + /* Remove any previous wireless security widgets */ + children = gtk_container_get_children (GTK_CONTAINER (vbox)); + for (elt = children; elt; elt = g_list_next (elt)) + gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + eap_widget = eap_method_get_widget (eap); + g_assert (eap_widget); + gtk_widget_unparent (eap_widget); + + if (method->size_group) + eap_method_add_to_size_group (eap, method->size_group); + gtk_container_add (GTK_CONTAINER (vbox), eap_widget); + + eap_method_unref (eap); + + wireless_security_changed_cb (combo, method->sec_parent); +} + +static GtkWidget * +inner_auth_combo_init (EAPMethodPEAP *method, + NMConnection *connection, + NMSetting8021x *s_8021x, + gboolean secrets_only) +{ + EAPMethod *parent = (EAPMethod *) method; + GtkWidget *combo; + GtkListStore *auth_model; + GtkTreeIter iter; + EAPMethodSimple *em_mschap_v2; + EAPMethodSimple *em_md5; + EAPMethodSimple *em_gtc; + guint32 active = 0; + const char *phase2_auth = NULL; + EAPMethodSimpleFlags simple_flags; + + auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); + + if (s_8021x) { + if (nm_setting_802_1x_get_phase2_auth (s_8021x)) + phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x); + else if (nm_setting_802_1x_get_phase2_autheap (s_8021x)) + phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x); + } + + simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2; + if (method->is_editor) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; + if (secrets_only) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; + + em_mschap_v2 = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("MSCHAPv2"), + I_METHOD_COLUMN, em_mschap_v2, + -1); + eap_method_unref (EAP_METHOD (em_mschap_v2)); + + /* Check for defaulting to MSCHAPv2 */ + if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2")) + active = 0; + + em_md5 = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_MD5, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("MD5"), + I_METHOD_COLUMN, em_md5, + -1); + eap_method_unref (EAP_METHOD (em_md5)); + + /* Check for defaulting to MD5 */ + if (phase2_auth && !strcasecmp (phase2_auth, "md5")) + active = 1; + + em_gtc = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_GTC, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("GTC"), + I_METHOD_COLUMN, em_gtc, + -1); + eap_method_unref (EAP_METHOD (em_gtc)); + + /* Check for defaulting to GTC */ + if (phase2_auth && !strcasecmp (phase2_auth, "gtc")) + active = 2; + + combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); + g_assert (combo); + + gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); + g_object_unref (G_OBJECT (auth_model)); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active); + + g_signal_connect (G_OBJECT (combo), "changed", + (GCallback) inner_auth_combo_changed_cb, + method); + return combo; +} + +static void +update_secrets (EAPMethod *parent, NMConnection *connection) +{ + eap_method_phase2_update_secrets_helper (parent, + connection, + "eap_peap_inner_auth_combo", + I_METHOD_COLUMN); +} + +EAPMethodPEAP * +eap_method_peap_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only) +{ + EAPMethod *parent; + EAPMethodPEAP *method; + GtkWidget *widget, *widget_ca_not_required_checkbox; + GtkFileFilter *filter; + NMSetting8021x *s_8021x = NULL; + const char *filename; + + parent = eap_method_init (sizeof (EAPMethodPEAP), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/eap-method-peap.ui", + "eap_peap_notebook", + "eap_peap_anon_identity_entry", + FALSE); + if (!parent) + return NULL; + + parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; + method = (EAPMethodPEAP *) parent; + method->sec_parent = ws_parent; + method->is_editor = is_editor; + + if (connection) + s_8021x = nm_connection_get_setting_802_1x (connection); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_not_required_checkbox")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) ca_cert_not_required_toggled, + parent); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) wireless_security_changed_cb, + ws_parent); + widget_ca_not_required_checkbox = widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button")); + g_assert (widget); + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); + gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), + _("Choose a Certificate Authority certificate")); + g_signal_connect (G_OBJECT (widget), "selection-changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + filter = eap_method_default_file_chooser_filter_new (FALSE); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); + if (connection && s_8021x) { + filename = NULL; + if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) { + filename = nm_setting_802_1x_get_ca_cert_path (s_8021x); + if (filename) + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); + } + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget_ca_not_required_checkbox), + !filename && eap_method_ca_cert_ignore_get (parent, connection)); + } + + widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only); + inner_auth_combo_changed_cb (widget, (gpointer) method); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo")); + g_assert (widget); + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); + if (s_8021x) { + const char *peapver; + + peapver = nm_setting_802_1x_get_phase1_peapver (s_8021x); + if (peapver) { + /* Index 0 is "Automatic" */ + if (!strcmp (peapver, "0")) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1); + else if (!strcmp (peapver, "1")) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2); + } + } + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry")); + if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x)) + gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x)); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + if (secrets_only) { + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_anon_identity_entry")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_button")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_ca_cert_not_required_checkbox")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_inner_auth_combo")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_peap_version_combo")); + gtk_widget_hide (widget); + } + + return method; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2010 Red Hat, Inc. + */ + +#ifndef EAP_METHOD_PEAP_H +#define EAP_METHOD_PEAP_H + +#include "wireless-security.h" + +typedef struct _EAPMethodPEAP EAPMethodPEAP; + +EAPMethodPEAP *eap_method_peap_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only); + +#endif /* EAP_METHOD_PEAP_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-peap.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + Automatic + + + Version 0 + + + Version 1 + + + + + True + False + False + False + + + True + False + 5 + 2 + 6 + 6 + + + True + False + 1 + Anony_mous identity + True + eap_peap_anon_identity_entry + + + GTK_FILL + + + + + + True + True + True + + + 1 + 2 + + + + + + True + False + 1 + C_A certificate + True + eap_peap_ca_cert_button + + + 1 + 2 + GTK_FILL + + + + + + True + False + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + No CA certificate is _required + True + True + False + True + True + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + False + + + + + + 2 + 5 + 6 + GTK_FILL + + + + + True + False + 1 + _Inner authentication + True + eap_peap_inner_auth_combo + + + 4 + 5 + GTK_FILL + + + + + + True + False + model8 + + + + 0 + + + + + 1 + 2 + 4 + 5 + GTK_FILL + GTK_FILL + + + + + True + False + 1 + PEAP _version + True + eap_peap_version_combo + + + 3 + 4 + GTK_FILL + + + + + + True + False + model9 + + + + 0 + + + + + 1 + 2 + 3 + 4 + GTK_FILL + GTK_FILL + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,366 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "eap-method.h" +#include "wireless-security.h" +#include "helpers.h" +#include "nma-ui-utils.h" +#include "utils.h" + +struct _EAPMethodSimple { + EAPMethod parent; + + WirelessSecurity *ws_parent; + + EAPMethodSimpleType type; + EAPMethodSimpleFlags flags; + + GtkEntry *username_entry; + GtkEntry *password_entry; + GtkToggleButton *show_password; + guint idle_func_id; +}; + +static void +show_toggled_cb (GtkToggleButton *button, EAPMethodSimple *method) +{ + gboolean visible; + + visible = gtk_toggle_button_get_active (button); + gtk_entry_set_visibility (method->password_entry, visible); +} + +static gboolean +always_ask_selected (GtkEntry *passwd_entry) +{ + return !!( nma_utils_menu_to_secret_flags (GTK_WIDGET (passwd_entry)) + & NM_SETTING_SECRET_FLAG_NOT_SAVED); +} + +static gboolean +validate (EAPMethod *parent, GError **error) +{ + EAPMethodSimple *method = (EAPMethodSimple *)parent; + const char *text; + gboolean ret = TRUE; + + text = gtk_entry_get_text (method->username_entry); + if (!text || !strlen (text)) { + widget_set_error (GTK_WIDGET (method->username_entry)); + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP username")); + ret = FALSE; + } else + widget_unset_error (GTK_WIDGET (method->username_entry)); + + /* Check if the password should always be requested */ + if (always_ask_selected (method->password_entry)) + widget_unset_error (GTK_WIDGET (method->password_entry)); + else { + text = gtk_entry_get_text (method->password_entry); + if (!text || !strlen (text)) { + widget_set_error (GTK_WIDGET (method->password_entry)); + if (ret) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP password")); + ret = FALSE; + } + } else + widget_unset_error (GTK_WIDGET (method->password_entry)); + } + + return ret; +} + +static void +add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) +{ + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); +} + +typedef struct { + const char *name; + gboolean autheap_allowed; +} EapType; + +/* Indexed by EAP_METHOD_SIMPLE_TYPE_* */ +static const EapType eap_table[EAP_METHOD_SIMPLE_TYPE_LAST] = { + [EAP_METHOD_SIMPLE_TYPE_PAP] = { "pap", FALSE }, + [EAP_METHOD_SIMPLE_TYPE_MSCHAP] = { "mschap", FALSE }, + [EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2] = { "mschapv2", TRUE }, + [EAP_METHOD_SIMPLE_TYPE_PLAIN_MSCHAP_V2] = { "mschapv2", FALSE }, + [EAP_METHOD_SIMPLE_TYPE_MD5] = { "md5", TRUE }, + [EAP_METHOD_SIMPLE_TYPE_PWD] = { "pwd", TRUE }, + [EAP_METHOD_SIMPLE_TYPE_CHAP] = { "chap", FALSE }, + [EAP_METHOD_SIMPLE_TYPE_GTC] = { "gtc", TRUE }, +}; + +static void +fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags prev_flags) +{ + EAPMethodSimple *method = (EAPMethodSimple *) parent; + NMSetting8021x *s_8021x; + gboolean not_saved = FALSE; + NMSettingSecretFlags flags; + const EapType *eap_type; + + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + /* If this is the main EAP method, clear any existing methods because the + * user-selected on will replace it. + */ + if (parent->phase2 == FALSE) + nm_setting_802_1x_clear_eap_methods (s_8021x); + + eap_type = &eap_table[method->type]; + if (parent->phase2) { + /* If the outer EAP method (TLS, TTLS, PEAP, etc) allows inner/phase2 + * EAP methods (which only TTLS allows) *and* the inner/phase2 method + * supports being an inner EAP method, then set PHASE2_AUTHEAP. + * Otherwise the inner/phase2 method goes into PHASE2_AUTH. + */ + if ((method->flags & EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED) && eap_type->autheap_allowed) { + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, eap_type->name, NULL); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, NULL, NULL); + } else { + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, eap_type->name, NULL); + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, NULL, NULL); + } + } else + nm_setting_802_1x_add_eap_method (s_8021x, eap_type->name); + + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (method->username_entry), NULL); + + /* Save the password always ask setting */ + not_saved = always_ask_selected (method->password_entry); + flags = nma_utils_menu_to_secret_flags (GTK_WIDGET (method->password_entry)); + nm_setting_set_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, flags, NULL); + + /* Fill the connection's password if we're in the applet so that it'll get + * back to NM. From the editor though, since the connection isn't going + * back to NM in response to a GetSecrets() call, we don't save it if the + * user checked "Always Ask". + */ + if (!(method->flags & EAP_METHOD_SIMPLE_FLAG_IS_EDITOR) || not_saved == FALSE) + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (method->password_entry), NULL); + + /* Update secret flags and popup when editing the connection */ + if (!(method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY)) { + GtkWidget *passwd_entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")); + g_assert (passwd_entry); + + nma_utils_update_password_storage (passwd_entry, flags, + NM_SETTING (s_8021x), parent->password_flags_name); + } +} + +static void +update_secrets (EAPMethod *parent, NMConnection *connection) +{ + helper_fill_secret_entry (connection, + parent->builder, + "eap_simple_password_entry", + NM_TYPE_SETTING_802_1X, + (HelperSecretFunc) nm_setting_802_1x_get_password); +} + +static gboolean +stuff_changed (EAPMethodSimple *method) +{ + wireless_security_changed_cb (NULL, method->ws_parent); + method->idle_func_id = 0; + return FALSE; +} + +static void +password_storage_changed (GObject *entry, + GParamSpec *pspec, + EAPMethodSimple *method) +{ + gboolean always_ask; + gboolean secrets_only = method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; + + always_ask = always_ask_selected (method->password_entry); + + if (always_ask && !secrets_only) { + /* we always clear this button and do not restore it + * (because we want to hide the password). */ + gtk_toggle_button_set_active (method->show_password, FALSE); + } + + gtk_widget_set_sensitive (GTK_WIDGET (method->show_password), + !always_ask || secrets_only); + + if (!method->idle_func_id) + method->idle_func_id = g_idle_add ((GSourceFunc) stuff_changed, method); +} + +/* Set the UI fields for user, password, always_ask and show_password to the + * values as provided by method->ws_parent. */ +static void +set_userpass_ui (EAPMethodSimple *method) +{ + if (method->ws_parent->username) + gtk_entry_set_text (method->username_entry, method->ws_parent->username); + else + gtk_entry_set_text (method->username_entry, ""); + + if (method->ws_parent->password && !method->ws_parent->always_ask) + gtk_entry_set_text (method->password_entry, method->ws_parent->password); + else + gtk_entry_set_text (method->password_entry, ""); + + gtk_toggle_button_set_active (method->show_password, method->ws_parent->show_password); + password_storage_changed (NULL, NULL, method); +} + +static void +widgets_realized (GtkWidget *widget, EAPMethodSimple *method) +{ + set_userpass_ui (method); +} + +static void +widgets_unrealized (GtkWidget *widget, EAPMethodSimple *method) +{ + wireless_security_set_userpass (method->ws_parent, + gtk_entry_get_text (method->username_entry), + gtk_entry_get_text (method->password_entry), + always_ask_selected (method->password_entry), + gtk_toggle_button_get_active (method->show_password)); +} + +static void +destroy (EAPMethod *parent) +{ + EAPMethodSimple *method = (EAPMethodSimple *) parent; + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_notebook")); + g_assert (widget); + g_signal_handlers_disconnect_by_data (widget, method); + + g_signal_handlers_disconnect_by_data (method->username_entry, method->ws_parent); + g_signal_handlers_disconnect_by_data (method->password_entry, method->ws_parent); + g_signal_handlers_disconnect_by_data (method->password_entry, method); + g_signal_handlers_disconnect_by_data (method->show_password, method); + + nm_clear_g_source (&method->idle_func_id); +} + +EAPMethodSimple * +eap_method_simple_new (WirelessSecurity *ws_parent, + NMConnection *connection, + EAPMethodSimpleType type, + EAPMethodSimpleFlags flags) +{ + EAPMethod *parent; + EAPMethodSimple *method; + GtkWidget *widget; + NMSetting8021x *s_8021x = NULL; + + parent = eap_method_init (sizeof (EAPMethodSimple), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/eap-method-simple.ui", + "eap_simple_notebook", + "eap_simple_username_entry", + flags & EAP_METHOD_SIMPLE_FLAG_PHASE2); + if (!parent) + return NULL; + + parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; + method = (EAPMethodSimple *) parent; + method->ws_parent = ws_parent; + method->flags = flags; + method->type = type; + g_assert (type < EAP_METHOD_SIMPLE_TYPE_LAST); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_notebook")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "realize", + (GCallback) widgets_realized, + method); + g_signal_connect (G_OBJECT (widget), "unrealize", + (GCallback) widgets_unrealized, + method); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry")); + g_assert (widget); + method->username_entry = GTK_ENTRY (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + if (method->flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY) + gtk_widget_set_sensitive (widget, FALSE); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry")); + g_assert (widget); + method->password_entry = GTK_ENTRY (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + /* Create password-storage popup menu for password entry under entry's secondary icon */ + if (connection) + s_8021x = nm_connection_get_setting_802_1x (connection); + nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name, + FALSE, flags & EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY); + + g_signal_connect (method->password_entry, "notify::secondary-icon-name", + G_CALLBACK (password_storage_changed), + method); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple")); + g_assert (widget); + method->show_password = GTK_TOGGLE_BUTTON (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) show_toggled_cb, + method); + + /* Initialize the UI fields with the security settings from method->ws_parent. + * This will be done again when the widget gets realized. It must be done here as well, + * because the outer dialog will ask to 'validate' the connection before the security tab + * is shown/realized (to enable the 'Apply' button). + * As 'validate' accesses the contents of the UI fields, they must be initialized now, even + * if the widgets are not yet visible. */ + set_userpass_ui (method); + + return method; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2010 Red Hat, Inc. + */ + +#ifndef EAP_METHOD_SIMPLE_H +#define EAP_METHOD_SIMPLE_H + +#include "wireless-security.h" + +typedef enum { + /* NOTE: when updating this table, also update eap_methods[] */ + EAP_METHOD_SIMPLE_TYPE_PAP = 0, + EAP_METHOD_SIMPLE_TYPE_MSCHAP, + EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, + EAP_METHOD_SIMPLE_TYPE_PLAIN_MSCHAP_V2, + EAP_METHOD_SIMPLE_TYPE_MD5, + EAP_METHOD_SIMPLE_TYPE_PWD, + EAP_METHOD_SIMPLE_TYPE_CHAP, + EAP_METHOD_SIMPLE_TYPE_GTC, + + /* Boundary value, do not use */ + EAP_METHOD_SIMPLE_TYPE_LAST +} EAPMethodSimpleType; + +typedef enum { + EAP_METHOD_SIMPLE_FLAG_NONE = 0x00, + /* Indicates the EAP method is an inner/phase2 method */ + EAP_METHOD_SIMPLE_FLAG_PHASE2 = 0x01, + /* Set by TTLS to indicate that inner/phase2 EAP is allowed */ + EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED = 0x02, + /* Set from nm-connection-editor or the GNOME network panel */ + EAP_METHOD_SIMPLE_FLAG_IS_EDITOR = 0x04, + /* Set to indicate that this request is only for secrets */ + EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY = 0x08 +} EAPMethodSimpleFlags; + +typedef struct _EAPMethodSimple EAPMethodSimple; + +EAPMethodSimple *eap_method_simple_new (WirelessSecurity *ws_parent, + NMConnection *connection, + EAPMethodSimpleType type, + EAPMethodSimpleFlags flags); + +#endif /* EAP_METHOD_SIMPLE_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-simple.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,120 @@ + + + + + True + False + False + False + + + True + False + start + 3 + 2 + 6 + 6 + + + + + + True + False + 1 + _Username + True + eap_simple_username_entry + + + GTK_FILL + + + + + + True + False + 1 + _Password + True + eap_simple_password_entry + + + 1 + 2 + GTK_FILL + + + + + + True + True + False + True + + + 1 + 2 + 1 + 2 + + + + + + True + True + True + + + 1 + 2 + + + + + + True + False + + + Sho_w password + True + True + False + True + True + + + True + True + 0 + + + + + + + + 1 + 2 + 2 + 3 + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,552 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "eap-method.h" +#include "wireless-security.h" +#include "helpers.h" +#include "nma-ui-utils.h" +#include "utils.h" + +struct _EAPMethodTLS { + EAPMethod parent; + + gboolean editing_connection; +}; + + +static void +show_toggled_cb (GtkCheckButton *button, EAPMethod *method) +{ + GtkWidget *widget; + gboolean visible; + + widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_tls_private_key_password_entry")); + g_assert (widget); + + visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + gtk_entry_set_visibility (GTK_ENTRY (widget), visible); +} + +static gboolean +validate (EAPMethod *parent, GError **error) +{ + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GtkWidget *widget; + const char *password, *identity; + GError *local = NULL; + gboolean ret = TRUE; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); + g_assert (widget); + identity = gtk_entry_get_text (GTK_ENTRY (widget)); + if (!identity || !strlen (identity)) { + widget_set_error (widget); + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing EAP-TLS identity")); + ret = FALSE; + } else { + widget_unset_error (widget); + } + + if (!eap_method_validate_filepicker (parent->builder, "eap_tls_ca_cert_button", TYPE_CA_CERT, NULL, NULL, &local)) { + widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"))); + if (ret) { + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA certificate: %s"), local->message); + ret = FALSE; + } + g_clear_error (&local); + } else if (eap_method_ca_cert_required (parent->builder, "eap_tls_ca_cert_not_required_checkbox", "eap_tls_ca_cert_button")) { + widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button"))); + if (ret) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS CA certificate: no certificate specified")); + ret = FALSE; + } + } + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); + g_assert (widget); + password = gtk_entry_get_text (GTK_ENTRY (widget)); + + if (!eap_method_validate_filepicker (parent->builder, + "eap_tls_private_key_button", + TYPE_PRIVATE_KEY, + password, + &format, + &local)) { + if (ret) { + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS private-key: %s"), local->message); + ret = FALSE; + } + g_clear_error (&local); + widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button"))); + } + + if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + if (!eap_method_validate_filepicker (parent->builder, "eap_tls_user_cert_button", TYPE_CLIENT_CERT, NULL, NULL, &local)) { + if (ret) { + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TLS user-certificate: %s"), local->message); + ret = FALSE; + } + g_clear_error (&local); + widget_set_error (GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button"))); + } + } + + return ret; +} + +static void +ca_cert_not_required_toggled (GtkWidget *ignored, gpointer user_data) +{ + EAPMethod *parent = user_data; + + eap_method_ca_cert_not_required_toggled (parent->builder, "eap_tls_ca_cert_not_required_checkbox", "eap_tls_ca_cert_button"); +} + +static void +add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) +{ + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); +} + +static void +fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) +{ + EAPMethodTLS *method = (EAPMethodTLS *) parent; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021x *s_8021x; + NMSettingSecretFlags secret_flags; + GtkWidget *widget, *passwd_entry; + char *ca_filename, *pk_filename, *cc_filename; + const char *password = NULL; + GError *error = NULL; + gboolean ca_cert_error = FALSE; + + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + if (parent->phase2) + g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL); + else + nm_setting_802_1x_add_eap_method (s_8021x, "tls"); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); + g_assert (widget); + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL); + + /* TLS private key */ + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); + g_assert (widget); + password = gtk_entry_get_text (GTK_ENTRY (widget)); + g_assert (password); + passwd_entry = widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button")); + g_assert (widget); + pk_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + g_assert (pk_filename); + + if (parent->phase2) { + if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read phase2 private key '%s': %s", pk_filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + } + } else { + if (!nm_setting_802_1x_set_private_key (s_8021x, pk_filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read private key '%s': %s", pk_filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + } + } + g_free (pk_filename); + + /* Save 802.1X password flags to the connection */ + secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); + nm_setting_set_secret_flags (NM_SETTING (s_8021x), parent->password_flags_name, + secret_flags, NULL); + + /* Update secret flags and popup when editing the connection */ + if (method->editing_connection) { + nma_utils_update_password_storage (passwd_entry, secret_flags, + NM_SETTING (s_8021x), parent->password_flags_name); + } + + /* TLS client certificate */ + if (format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + /* If the key is pkcs#12 nm_setting_802_1x_set_private_key() already + * set the client certificate for us. + */ + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button")); + g_assert (widget); + cc_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + g_assert (cc_filename); + + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + if (parent->phase2) { + if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read phase2 client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + } + } else { + if (!nm_setting_802_1x_set_client_cert (s_8021x, cc_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read client certificate '%s': %s", cc_filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + } + } + g_free (cc_filename); + } + + /* TLS CA certificate */ + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")); + g_assert (widget); + ca_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + + format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + if (parent->phase2) { + if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read phase2 CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + ca_cert_error = TRUE; + } + } else { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, ca_filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read CA certificate '%s': %s", ca_filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + ca_cert_error = TRUE; + } + } + eap_method_ca_cert_ignore_set (parent, connection, ca_filename, ca_cert_error); + g_free (ca_filename); +} + +static void +private_key_picker_helper (EAPMethod *parent, const char *filename, gboolean changed) +{ + NMSetting8021x *setting; + NMSetting8021xCKFormat cert_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + const char *password; + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); + g_assert (widget); + password = gtk_entry_get_text (GTK_ENTRY (widget)); + + setting = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_setting_802_1x_set_private_key (setting, filename, password, NM_SETTING_802_1X_CK_SCHEME_PATH, &cert_format, NULL); + g_object_unref (setting); + + /* With PKCS#12, the client cert must be the same as the private key */ + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button")); + if (cert_format == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget)); + gtk_widget_set_sensitive (widget, FALSE); + } else if (changed) + gtk_widget_set_sensitive (widget, TRUE); + + /* Warn the user if the private key is unencrypted */ + if (!eap_method_is_encrypted_private_key (filename)) { + GtkWidget *dialog; + GtkWidget *toplevel; + GtkWindow *parent_window = NULL; + + toplevel = gtk_widget_get_toplevel (parent->ui_widget); + if (gtk_widget_is_toplevel (toplevel)) + parent_window = GTK_WINDOW (toplevel); + + dialog = gtk_message_dialog_new (parent_window, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + "%s", + _("Unencrypted private keys are insecure")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", + _("The selected private key does not appear to be protected by a password. This could allow your security credentials to be compromised. Please select a password-protected private key.\n\n(You can password-protect your private key with openssl)")); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } +} + +static void +private_key_picker_file_set_cb (GtkWidget *chooser, gpointer user_data) +{ + EAPMethod *parent = (EAPMethod *) user_data; + char *filename; + + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); + if (filename) + private_key_picker_helper (parent, filename, TRUE); + g_free (filename); +} + +static void reset_filter (GtkWidget *widget, GParamSpec *spec, gpointer user_data) +{ + if (!gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (widget))) { + g_signal_handlers_block_by_func (widget, reset_filter, user_data); + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), GTK_FILE_FILTER (user_data)); + g_signal_handlers_unblock_by_func (widget, reset_filter, user_data); + } +} + +typedef const char * (*PathFunc) (NMSetting8021x *setting); +typedef NMSetting8021xCKScheme (*SchemeFunc) (NMSetting8021x *setting); + +static void +setup_filepicker (GtkBuilder *builder, + const char *name, + const char *title, + WirelessSecurity *ws_parent, + EAPMethod *parent, + NMSetting8021x *s_8021x, + SchemeFunc scheme_func, + PathFunc path_func, + gboolean privkey, + gboolean client_cert) +{ + GtkWidget *widget; + GtkFileFilter *filter; + const char *filename = NULL; + + widget = GTK_WIDGET (gtk_builder_get_object (builder, name)); + g_assert (widget); + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); + gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), title); + + if (s_8021x && path_func && scheme_func) { + if (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) { + filename = path_func (s_8021x); + if (filename) + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); + } + } + + /* Connect a special handler for private keys to intercept PKCS#12 key types + * and desensitize the user cert button. + */ + if (privkey) { + g_signal_connect (G_OBJECT (widget), "selection-changed", + (GCallback) private_key_picker_file_set_cb, + parent); + if (filename) + private_key_picker_helper (parent, filename, FALSE); + } + + g_signal_connect (G_OBJECT (widget), "selection-changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + filter = eap_method_default_file_chooser_filter_new (privkey); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); + + /* For some reason, GTK+ calls set_current_filter (..., NULL) from + * gtkfilechooserdefault.c::show_and_select_files_finished_loading() on our + * dialog; so force-reset the filter to what we want it to be whenever + * it gets cleared. + */ + if (client_cert) + g_signal_connect (G_OBJECT (widget), "notify::filter", (GCallback) reset_filter, filter); +} + +static void +update_secrets (EAPMethod *parent, NMConnection *connection) +{ + NMSetting8021x *s_8021x; + HelperSecretFunc password_func; + SchemeFunc scheme_func; + PathFunc path_func; + const char *filename; + GtkWidget *widget; + + if (parent->phase2) { + password_func = (HelperSecretFunc) nm_setting_802_1x_get_phase2_private_key_password; + scheme_func = nm_setting_802_1x_get_phase2_private_key_scheme; + path_func = nm_setting_802_1x_get_phase2_private_key_path; + } else { + password_func = (HelperSecretFunc) nm_setting_802_1x_get_private_key_password; + scheme_func = nm_setting_802_1x_get_private_key_scheme; + path_func = nm_setting_802_1x_get_private_key_path; + } + + helper_fill_secret_entry (connection, + parent->builder, + "eap_tls_private_key_password_entry", + NM_TYPE_SETTING_802_1X, + password_func); + + /* Set the private key filepicker button path if we have a private key */ + s_8021x = nm_connection_get_setting_802_1x (connection); + if (s_8021x && (scheme_func (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH)) { + filename = path_func (s_8021x); + if (filename) { + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button")); + g_assert (widget); + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); + } + } +} + +EAPMethodTLS * +eap_method_tls_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean phase2, + gboolean secrets_only) +{ + EAPMethodTLS *method; + EAPMethod *parent; + GtkWidget *widget; + NMSetting8021x *s_8021x = NULL; + gboolean ca_not_required = FALSE; + + parent = eap_method_init (sizeof (EAPMethodTLS), + validate, + add_to_size_group, + fill_connection, + update_secrets, + NULL, + "/org/freedesktop/network-manager-applet/eap-method-tls.ui", + "eap_tls_notebook", + "eap_tls_identity_entry", + phase2); + if (!parent) + return NULL; + + parent->password_flags_name = phase2 ? + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD : + NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; + method = (EAPMethodTLS *) parent; + method->editing_connection = secrets_only ? FALSE : TRUE; + + if (connection) + s_8021x = nm_connection_get_setting_802_1x (connection); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) ca_cert_not_required_toggled, + parent); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) wireless_security_changed_cb, + ws_parent); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + if (s_8021x && nm_setting_802_1x_get_identity (s_8021x)) + gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_identity (s_8021x)); + + setup_filepicker (parent->builder, "eap_tls_user_cert_button", + _("Choose your personal certificate"), + ws_parent, parent, s_8021x, + phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme : nm_setting_802_1x_get_client_cert_scheme, + phase2 ? nm_setting_802_1x_get_phase2_client_cert_path : nm_setting_802_1x_get_client_cert_path, + FALSE, TRUE); + setup_filepicker (parent->builder, "eap_tls_ca_cert_button", + _("Choose a Certificate Authority certificate"), + ws_parent, parent, s_8021x, + phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme : nm_setting_802_1x_get_ca_cert_scheme, + phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path : nm_setting_802_1x_get_ca_cert_path, + FALSE, FALSE); + setup_filepicker (parent->builder, "eap_tls_private_key_button", + _("Choose your private key"), + ws_parent, parent, s_8021x, + phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme : nm_setting_802_1x_get_private_key_scheme, + phase2 ? nm_setting_802_1x_get_phase2_private_key_path : nm_setting_802_1x_get_private_key_path, + TRUE, FALSE); + + if (connection && eap_method_ca_cert_ignore_get (parent, connection)) { + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")); + ca_not_required = !gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + } + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), ca_not_required); + + /* Fill secrets, if any */ + if (connection) + update_secrets (parent, connection); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_password_entry")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + /* Create password-storage popup menu for password entry under entry's secondary icon */ + nma_utils_setup_password_storage (widget, 0, (NMSetting *) s_8021x, parent->password_flags_name, + FALSE, secrets_only); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eaptls")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) show_toggled_cb, + parent); + + if (secrets_only) { + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_identity_entry")); + gtk_widget_set_sensitive (widget, FALSE); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_user_cert_button")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_private_key_button")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_button")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_tls_ca_cert_not_required_checkbox")); + gtk_widget_hide (widget); + } + + return method; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2010 Red Hat, Inc. + */ + +#ifndef EAP_METHOD_TLS_H +#define EAP_METHOD_TLS_H + +#include "wireless-security.h" + +typedef struct _EAPMethodTLS EAPMethodTLS; + +EAPMethodTLS *eap_method_tls_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean phase2, + gboolean secrets_only); + +#endif /* EAP_METHOD_TLS_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-tls.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,216 @@ + + + + + True + False + False + False + + + True + False + start + 6 + 2 + 6 + 6 + + + + + + True + False + 1 + I_dentity + True + eap_tls_identity_entry + + + GTK_FILL + + + + + + True + True + True + + + 1 + 2 + + + + + + True + False + 1 + _User certificate + True + eap_tls_user_cert_button + + + 1 + 2 + GTK_FILL + + + + + + True + False + 1 + C_A certificate + True + eap_tls_ca_cert_button + + + 2 + 3 + GTK_FILL + + + + + + True + False + + + 1 + 2 + 2 + 3 + GTK_FILL + GTK_FILL + + + + + No CA certificate is _required + True + True + False + True + True + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + + True + False + 1 + Private _key + True + eap_tls_private_key_button + + + 4 + 5 + GTK_FILL + + + + + + True + False + + + 1 + 2 + 4 + 5 + GTK_FILL + GTK_FILL + + + + + True + False + 1 + _Private key password + True + eap_tls_private_key_password_entry + + + 5 + 6 + GTK_FILL + + + + + + True + True + False + True + + + 1 + 2 + 5 + 6 + + + + + + Sho_w password + True + True + False + True + True + + + 1 + 2 + 6 + 7 + GTK_FILL + + + + + + True + False + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,476 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "eap-method.h" +#include "wireless-security.h" +#include "utils.h" + +#define I_NAME_COLUMN 0 +#define I_METHOD_COLUMN 1 + +struct _EAPMethodTTLS { + EAPMethod parent; + + GtkSizeGroup *size_group; + WirelessSecurity *sec_parent; + gboolean is_editor; +}; + +static void +destroy (EAPMethod *parent) +{ + EAPMethodTTLS *method = (EAPMethodTTLS *) parent; + + if (method->size_group) + g_object_unref (method->size_group); +} + +static gboolean +validate (EAPMethod *parent, GError **error) +{ + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap = NULL; + gboolean valid = FALSE; + GError *local = NULL; + + if (!eap_method_validate_filepicker (parent->builder, "eap_ttls_ca_cert_button", TYPE_CA_CERT, NULL, NULL, &local)) { + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TTLS CA certificate: %s"), local->message); + g_clear_error (&local); + return FALSE; + } + if (eap_method_ca_cert_required (parent->builder, "eap_ttls_ca_cert_not_required_checkbox", "eap_ttls_ca_cert_button")) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid EAP-TTLS CA certificate: no certificate specified")); + return FALSE; + } + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); + g_assert (widget); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + valid = eap_method_validate (eap, error); + eap_method_unref (eap); + return valid; +} + +static void +ca_cert_not_required_toggled (GtkWidget *ignored, gpointer user_data) +{ + EAPMethod *parent = user_data; + + eap_method_ca_cert_not_required_toggled (parent->builder, "eap_ttls_ca_cert_not_required_checkbox", "eap_ttls_ca_cert_button"); +} + +static void +add_to_size_group (EAPMethod *parent, GtkSizeGroup *group) +{ + EAPMethodTTLS *method = (EAPMethodTTLS *) parent; + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap; + + if (method->size_group) + g_object_unref (method->size_group); + method->size_group = g_object_ref (group); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_not_required_checkbox")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_label")); + g_assert (widget); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); + g_assert (widget); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + eap_method_add_to_size_group (eap, group); + eap_method_unref (eap); +} + +static void +fill_connection (EAPMethod *parent, NMConnection *connection, NMSettingSecretFlags flags) +{ + NMSetting8021x *s_8021x; + NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + GtkWidget *widget; + const char *text; + char *filename; + EAPMethod *eap = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + GError *error = NULL; + gboolean ca_cert_error = FALSE; + + s_8021x = nm_connection_get_setting_802_1x (connection); + g_assert (s_8021x); + + nm_setting_802_1x_add_eap_method (s_8021x, "ttls"); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry")); + g_assert (widget); + text = gtk_entry_get_text (GTK_ENTRY (widget)); + if (text && strlen (text)) + g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, text, NULL); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button")); + g_assert (widget); + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + if (!nm_setting_802_1x_set_ca_cert (s_8021x, filename, NM_SETTING_802_1X_CK_SCHEME_PATH, &format, &error)) { + g_warning ("Couldn't read CA certificate '%s': %s", filename, error ? error->message : "(unknown)"); + g_clear_error (&error); + ca_cert_error = TRUE; + } + eap_method_ca_cert_ignore_set (parent, connection, filename, ca_cert_error); + g_free (filename); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + eap_method_fill_connection (eap, connection, flags); + eap_method_unref (eap); +} + +static void +inner_auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) +{ + EAPMethod *parent = (EAPMethod *) user_data; + EAPMethodTTLS *method = (EAPMethodTTLS *) parent; + GtkWidget *vbox; + EAPMethod *eap = NULL; + GList *elt, *children; + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *eap_widget; + + vbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_vbox")); + g_assert (vbox); + + /* Remove any previous wireless security widgets */ + children = gtk_container_get_children (GTK_CONTAINER (vbox)); + for (elt = children; elt; elt = g_list_next (elt)) + gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); + g_list_free (children); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); + gtk_tree_model_get (model, &iter, I_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + eap_widget = eap_method_get_widget (eap); + g_assert (eap_widget); + gtk_widget_unparent (eap_widget); + + if (method->size_group) + eap_method_add_to_size_group (eap, method->size_group); + gtk_container_add (GTK_CONTAINER (vbox), eap_widget); + + eap_method_unref (eap); + + wireless_security_changed_cb (combo, method->sec_parent); +} + +static GtkWidget * +inner_auth_combo_init (EAPMethodTTLS *method, + NMConnection *connection, + NMSetting8021x *s_8021x, + gboolean secrets_only) +{ + EAPMethod *parent = (EAPMethod *) method; + GtkWidget *combo; + GtkListStore *auth_model; + GtkTreeIter iter; + EAPMethodSimple *em_pap; + EAPMethodSimple *em_mschap; + EAPMethodSimple *em_mschap_v2; + EAPMethodSimple *em_plain_mschap_v2; + EAPMethodSimple *em_chap; + EAPMethodSimple *em_md5; + EAPMethodSimple *em_gtc; + guint32 active = 0; + const char *phase2_auth = NULL; + EAPMethodSimpleFlags simple_flags; + + auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); + + if (s_8021x) { + if (nm_setting_802_1x_get_phase2_auth (s_8021x)) + phase2_auth = nm_setting_802_1x_get_phase2_auth (s_8021x); + else if (nm_setting_802_1x_get_phase2_autheap (s_8021x)) + phase2_auth = nm_setting_802_1x_get_phase2_autheap (s_8021x); + } + + simple_flags = EAP_METHOD_SIMPLE_FLAG_PHASE2 | EAP_METHOD_SIMPLE_FLAG_AUTHEAP_ALLOWED; + if (method->is_editor) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; + if (secrets_only) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; + + em_pap = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_PAP, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("PAP"), + I_METHOD_COLUMN, em_pap, + -1); + eap_method_unref (EAP_METHOD (em_pap)); + + /* Check for defaulting to PAP */ + if (phase2_auth && !strcasecmp (phase2_auth, "pap")) + active = 0; + + em_mschap = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_MSCHAP, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("MSCHAP"), + I_METHOD_COLUMN, em_mschap, + -1); + eap_method_unref (EAP_METHOD (em_mschap)); + + /* Check for defaulting to MSCHAP */ + if (phase2_auth && !strcasecmp (phase2_auth, "mschap")) + active = 1; + + em_mschap_v2 = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("MSCHAPv2"), + I_METHOD_COLUMN, em_mschap_v2, + -1); + eap_method_unref (EAP_METHOD (em_mschap_v2)); + + /* Check for defaulting to MSCHAPv2 */ + if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2") && + nm_setting_802_1x_get_phase2_autheap (s_8021x) != NULL) + active = 2; + + em_plain_mschap_v2 = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_PLAIN_MSCHAP_V2, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("MSCHAPv2 (no EAP)"), + I_METHOD_COLUMN, em_plain_mschap_v2, + -1); + eap_method_unref (EAP_METHOD (em_plain_mschap_v2)); + + /* Check for defaulting to plain MSCHAPv2 */ + if (phase2_auth && !strcasecmp (phase2_auth, "mschapv2") && + nm_setting_802_1x_get_phase2_auth (s_8021x) != NULL) + active = 3; + + em_chap = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_CHAP, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("CHAP"), + I_METHOD_COLUMN, em_chap, + -1); + eap_method_unref (EAP_METHOD (em_chap)); + + /* Check for defaulting to CHAP */ + if (phase2_auth && !strcasecmp (phase2_auth, "chap")) + active = 4; + + em_md5 = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_MD5, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("MD5"), + I_METHOD_COLUMN, em_md5, + -1); + eap_method_unref (EAP_METHOD (em_md5)); + + /* Check for defaulting to MD5 */ + if (phase2_auth && !strcasecmp (phase2_auth, "md5")) + active = 5; + + em_gtc = eap_method_simple_new (method->sec_parent, + connection, + EAP_METHOD_SIMPLE_TYPE_GTC, + simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + I_NAME_COLUMN, _("GTC"), + I_METHOD_COLUMN, em_gtc, + -1); + eap_method_unref (EAP_METHOD (em_gtc)); + + /* Check for defaulting to GTC */ + if (phase2_auth && !strcasecmp (phase2_auth, "gtc")) + active = 6; + + combo = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); + g_assert (combo); + + gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); + g_object_unref (G_OBJECT (auth_model)); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active); + + g_signal_connect (G_OBJECT (combo), "changed", + (GCallback) inner_auth_combo_changed_cb, + method); + return combo; +} + +static void +update_secrets (EAPMethod *parent, NMConnection *connection) +{ + eap_method_phase2_update_secrets_helper (parent, + connection, + "eap_ttls_inner_auth_combo", + I_METHOD_COLUMN); +} + +EAPMethodTTLS * +eap_method_ttls_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only) +{ + EAPMethod *parent; + EAPMethodTTLS *method; + GtkWidget *widget, *widget_ca_not_required_checkbox; + GtkFileFilter *filter; + NMSetting8021x *s_8021x = NULL; + const char *filename; + + parent = eap_method_init (sizeof (EAPMethodTTLS), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/eap-method-ttls.ui", + "eap_ttls_notebook", + "eap_ttls_anon_identity_entry", + FALSE); + if (!parent) + return NULL; + + parent->password_flags_name = NM_SETTING_802_1X_PASSWORD; + method = (EAPMethodTTLS *) parent; + method->sec_parent = ws_parent; + method->is_editor = is_editor; + + if (connection) + s_8021x = nm_connection_get_setting_802_1x (connection); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_not_required_checkbox")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) ca_cert_not_required_toggled, + parent); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) wireless_security_changed_cb, + ws_parent); + widget_ca_not_required_checkbox = widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button")); + g_assert (widget); + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE); + gtk_file_chooser_button_set_title (GTK_FILE_CHOOSER_BUTTON (widget), + _("Choose a Certificate Authority certificate")); + g_signal_connect (G_OBJECT (widget), "selection-changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + filter = eap_method_default_file_chooser_filter_new (FALSE); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (widget), filter); + if (connection && s_8021x) { + filename = NULL; + if (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) { + filename = nm_setting_802_1x_get_ca_cert_path (s_8021x); + if (filename) + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), filename); + } + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget_ca_not_required_checkbox), + !filename && eap_method_ca_cert_ignore_get (parent, connection)); + } + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry")); + if (s_8021x && nm_setting_802_1x_get_anonymous_identity (s_8021x)) + gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_802_1x_get_anonymous_identity (s_8021x)); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + ws_parent); + + widget = inner_auth_combo_init (method, connection, s_8021x, secrets_only); + inner_auth_combo_changed_cb (widget, (gpointer) method); + + if (secrets_only) { + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_anon_identity_entry")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_button")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_ca_cert_not_required_checkbox")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_label")); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_ttls_inner_auth_combo")); + gtk_widget_hide (widget); + } + + return method; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,36 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2010 Red Hat, Inc. + */ + +#ifndef EAP_METHOD_TTLS_H +#define EAP_METHOD_TTLS_H + +#include "wireless-security.h" + +typedef struct _EAPMethodTTLS EAPMethodTTLS; + +EAPMethodTTLS *eap_method_ttls_new (WirelessSecurity *ws_parent, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only); + +#endif /* EAP_METHOD_TLS_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/eap-method-ttls.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + True + False + False + False + + + True + False + 4 + 2 + 6 + 6 + + + True + False + 1 + Anony_mous identity + True + eap_ttls_anon_identity_entry + + + GTK_FILL + + + + + + True + True + True + + + 1 + 2 + + + + + + True + False + 1 + C_A certificate + True + eap_ttls_ca_cert_button + + + 1 + 2 + GTK_FILL + + + + + + True + False + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + No CA certificate is _required + True + True + False + True + True + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + False + 1 + _Inner authentication + True + eap_ttls_inner_auth_combo + + + 3 + 4 + GTK_FILL + + + + + + True + False + model6 + + + + 0 + + + + + 1 + 2 + 3 + 4 + GTK_FILL + GTK_FILL + + + + + True + False + 6 + + + + + + 2 + 4 + 5 + GTK_FILL + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,53 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2009 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "helpers.h" + +void +helper_fill_secret_entry (NMConnection *connection, + GtkBuilder *builder, + const char *entry_name, + GType setting_type, + HelperSecretFunc func) +{ + GtkWidget *widget; + NMSetting *setting; + const char *tmp; + + g_return_if_fail (connection != NULL); + g_return_if_fail (builder != NULL); + g_return_if_fail (entry_name != NULL); + g_return_if_fail (func != NULL); + + setting = nm_connection_get_setting (connection, setting_type); + if (setting) { + tmp = (*func) (setting); + if (tmp) { + widget = GTK_WIDGET (gtk_builder_get_object (builder, entry_name)); + g_assert (widget); + gtk_entry_set_text (GTK_ENTRY (widget), tmp); + } + } +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/helpers.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,35 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2009 - 2014 Red Hat, Inc. + */ + +#ifndef _HELPERS_H_ +#define _HELPERS_H_ + +typedef const char * (*HelperSecretFunc)(NMSetting *); + +void helper_fill_secret_entry (NMConnection *connection, + GtkBuilder *builder, + const char *entry_name, + GType setting_type, + HelperSecretFunc func); + +#endif /* _HELPERS_H_ */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/Makefile.am unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/Makefile.am --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/Makefile.am 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/Makefile.am 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,72 @@ +noinst_LTLIBRARIES = libwireless-security.la + +BUILT_SOURCES = \ + wireless-security-resources.h \ + wireless-security-resources.c + +NM_APPLET_SOURCES = \ + wireless-security.h \ + wireless-security.c \ + ws-wep-key.h \ + ws-wep-key.c \ + ws-wpa-psk.h \ + ws-wpa-psk.c \ + ws-leap.h \ + ws-leap.c \ + ws-wpa-eap.h \ + ws-wpa-eap.c \ + ws-dynamic-wep.h \ + ws-dynamic-wep.c \ + eap-method.h \ + eap-method.c \ + eap-method-tls.h \ + eap-method-tls.c \ + eap-method-leap.h \ + eap-method-leap.c \ + eap-method-fast.h \ + eap-method-fast.c \ + eap-method-ttls.h \ + eap-method-ttls.c \ + eap-method-peap.h \ + eap-method-peap.c \ + eap-method-simple.h \ + eap-method-simple.c \ + helpers.h \ + helpers.c + +libwireless_security_la_SOURCES = \ + $(BUILT_SOURCES) \ + $(NM_APPLET_SOURCES) \ + utils.c \ + utils.h \ + nm-default.h + +libwireless_security_la_CPPFLAGS = \ + $(NETWORK_PANEL_CFLAGS) \ + $(NETWORK_MANAGER_CFLAGS) \ + -DUIDIR=\""$(uidir)"\" + +libwireless_security_la_LIBADD = \ + $(NETWORK_PANEL_LIBS) \ + $(NETWORK_MANAGER_LIBS) + +resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/wireless-security.gresource.xml) +wireless-security-resources.c: wireless-security.gresource.xml $(resource_files) + $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name wireless_security $< +wireless-security-resources.h: wireless-security.gresource.xml $(resource_files) + $(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name wireless_security $< + +WIRELESS_SECURITY_DIR=$(top_srcdir)/../network-manager-applet/src/wireless-security +update-from-nma: + FILES="$(NM_APPLET_SOURCES)" DIR="$(WIRELESS_SECURITY_DIR)" $(top_srcdir)/update-from-gsd.sh && \ + patch -p4 < $(srcdir)/nm-connection-editor-to-network-panel.patch && \ + git add $(NM_APPLET_SOURCES) && \ + git commit -m "network: Update wireless-security from network-manager-applet" + FILES="$(resource_files)" DIR="$(WIRELESS_SECURITY_DIR)" $(top_srcdir)/update-from-gsd.sh && \ + patch -p4 < $(srcdir)/nm-connection-editor-ui-to-network-panel.patch && \ + git add $(resource_files) && \ + git commit -m "network: Update wireless-security UI from network-manager-applet" + +EXTRA_DIST = $(resource_files) wireless-security.gresource.xml nm-connection-editor-to-network-panel.patch nm-connection-editor-ui-to-network-panel.patch + +-include $(top_srcdir)/git.mk diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-to-network-panel.patch unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-to-network-panel.patch --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-to-network-panel.patch 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-to-network-panel.patch 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,44 @@ +diff --git a/panels/network/wireless-security/wireless-security.c b/panels/network/wireless-security/wireless-security.c +index 23b8a27..bd233b0 100644 +--- a/panels/network/wireless-security/wireless-security.c ++++ b/panels/network/wireless-security/wireless-security.c +@@ -25,10 +25,25 @@ + #include + + #include "wireless-security.h" ++#include "wireless-security-resources.h" + #include "eap-method.h" + #include "utils.h" + +-G_DEFINE_BOXED_TYPE (WirelessSecurity, wireless_security, wireless_security_ref, wireless_security_unref) ++GType ++wireless_security_get_type (void) ++{ ++ static GType type_id = 0; ++ ++ if (!type_id) { ++ g_resources_register (wireless_security_get_resource ()); ++ ++ type_id = g_boxed_type_register_static ("WirelessSecurity", ++ (GBoxedCopyFunc) wireless_security_ref, ++ (GBoxedFreeFunc) wireless_security_unref); ++ } ++ ++ return type_id; ++} + + GtkWidget * + wireless_security_get_widget (WirelessSecurity *sec) +diff --git a/panels/network/wireless-security/wireless-security.h b/panels/network/wireless-security/wireless-security.h +index cb6553be5..4de618e16 100644 +--- a/panels/network/wireless-security/wireless-security.h ++++ b/panels/network/wireless-security/wireless-security.h +@@ -23,6 +23,8 @@ + #ifndef WIRELESS_SECURITY_H + #define WIRELESS_SECURITY_H + ++#include ++ + typedef struct _WirelessSecurity WirelessSecurity; + + typedef void (*WSChangedFunc) (WirelessSecurity *sec, gpointer user_data); diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-ui-to-network-panel.patch unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-ui-to-network-panel.patch --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-ui-to-network-panel.patch 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-connection-editor-ui-to-network-panel.patch 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,495 @@ +diff --git a/panels/network/wireless-security/eap-method-fast.ui b/panels/network/wireless-security/eap-method-fast.ui +index 4b19a66..5307ddb 100644 +--- a/panels/network/wireless-security/eap-method-fast.ui ++++ b/panels/network/wireless-security/eap-method-fast.ui +@@ -46,8 +46,8 @@ + + True + False +- 0 +- Anony_mous identity: ++ 1 ++ Anony_mous identity + True + eap_fast_anon_identity_entry + +@@ -72,8 +72,8 @@ + + True + False +- 0 +- PAC _file: ++ 1 ++ PAC _file + True + eap_fast_pac_file_button + +@@ -117,8 +117,8 @@ + + True + False +- 0 +- _Inner authentication: ++ 1 ++ _Inner authentication + True + eap_fast_inner_auth_combo + +diff --git a/panels/network/wireless-security/eap-method-leap.ui b/panels/network/wireless-security/eap-method-leap.ui +index 1d1f23d..d4c0625 100644 +--- a/panels/network/wireless-security/eap-method-leap.ui ++++ b/panels/network/wireless-security/eap-method-leap.ui +@@ -22,8 +22,8 @@ + + True + False +- 0 +- _Username: ++ 1 ++ _Username + True + eap_leap_username_entry + +@@ -36,8 +36,8 @@ + + True + False +- 0 +- _Password: ++ 1 ++ _Password + True + eap_leap_password_entry + +diff --git a/panels/network/wireless-security/eap-method-peap.ui b/panels/network/wireless-security/eap-method-peap.ui +index a97123a..2f8b8cd 100644 +--- a/panels/network/wireless-security/eap-method-peap.ui ++++ b/panels/network/wireless-security/eap-method-peap.ui +@@ -46,8 +46,8 @@ + + True + False +- 0 +- Anony_mous identity: ++ 1 ++ Anony_mous identity + True + eap_peap_anon_identity_entry + +@@ -72,8 +72,8 @@ + + True + False +- 0 +- C_A certificate: ++ 1 ++ C_A certificate + True + eap_peap_ca_cert_button + +@@ -135,8 +135,8 @@ + + True + False +- 0 +- _Inner authentication: ++ 1 ++ _Inner authentication + True + eap_peap_inner_auth_combo + +@@ -172,8 +172,8 @@ + + True + False +- 0 +- PEAP _version: ++ 1 ++ PEAP _version + True + eap_peap_version_combo + +diff --git a/panels/network/wireless-security/eap-method-simple.ui b/panels/network/wireless-security/eap-method-simple.ui +index b3318e4..7d95d28 100644 +--- a/panels/network/wireless-security/eap-method-simple.ui ++++ b/panels/network/wireless-security/eap-method-simple.ui +@@ -22,8 +22,8 @@ + + True + False +- 0 +- _Username: ++ 1 ++ _Username + True + eap_simple_username_entry + +@@ -36,8 +36,8 @@ + + True + False +- 0 +- _Password: ++ 1 ++ _Password + True + eap_simple_password_entry + +diff --git a/panels/network/wireless-security/eap-method-tls.ui b/panels/network/wireless-security/eap-method-tls.ui +index 5557593..3c6291b 100644 +--- a/panels/network/wireless-security/eap-method-tls.ui ++++ b/panels/network/wireless-security/eap-method-tls.ui +@@ -22,8 +22,8 @@ + + True + False +- 0 +- I_dentity: ++ 1 ++ I_dentity + True + eap_tls_identity_entry + +@@ -48,8 +48,8 @@ + + True + False +- 0 +- _User certificate: ++ 1 ++ _User certificate + True + eap_tls_user_cert_button + +@@ -64,8 +64,8 @@ + + True + False +- 0 +- C_A certificate: ++ 1 ++ C_A certificate + True + eap_tls_ca_cert_button + +@@ -112,8 +112,8 @@ + + True + False +- 0 +- Private _key: ++ 1 ++ Private _key + True + eap_tls_private_key_button + +@@ -142,8 +142,8 @@ + + True + False +- 0 +- _Private key password: ++ 1 ++ _Private key password + True + eap_tls_private_key_password_entry + +diff --git a/panels/network/wireless-security/eap-method-ttls.ui b/panels/network/wireless-security/eap-method-ttls.ui +index ce00c26..70db9ed 100644 +--- a/panels/network/wireless-security/eap-method-ttls.ui ++++ b/panels/network/wireless-security/eap-method-ttls.ui +@@ -29,8 +29,8 @@ + + True + False +- 0 +- Anony_mous identity: ++ 1 ++ Anony_mous identity + True + eap_ttls_anon_identity_entry + +@@ -55,8 +55,8 @@ + + True + False +- 0 +- C_A certificate: ++ 1 ++ C_A certificate + True + eap_ttls_ca_cert_button + +@@ -103,8 +103,8 @@ + + True + False +- 0 +- _Inner authentication: ++ 1 ++ _Inner authentication + True + eap_ttls_inner_auth_combo + +diff --git a/panels/network/wireless-security/ws-dynamic-wep.ui b/panels/network/wireless-security/ws-dynamic-wep.ui +index 4bd8520..cf31f12 100644 +--- a/panels/network/wireless-security/ws-dynamic-wep.ui ++++ b/panels/network/wireless-security/ws-dynamic-wep.ui +@@ -35,8 +35,8 @@ + + True + False +- 0 +- Au_thentication: ++ 1 ++ Au_thentication + True + dynamic_wep_auth_combo + +diff --git a/panels/network/wireless-security/ws-leap.ui b/panels/network/wireless-security/ws-leap.ui +index dc936ad..b4d9bec 100644 +--- a/panels/network/wireless-security/ws-leap.ui ++++ b/panels/network/wireless-security/ws-leap.ui +@@ -22,8 +22,8 @@ + + True + False +- 0 +- _Username: ++ 1 ++ _Username + True + leap_username_entry + +@@ -36,8 +36,8 @@ + + True + False +- 0 +- _Password: ++ 1 ++ _Password + True + leap_password_entry + +diff --git a/panels/network/wireless-security/ws-wep-key.ui b/panels/network/wireless-security/ws-wep-key.ui +index 62b11a5..c0e5f55 100644 +--- a/panels/network/wireless-security/ws-wep-key.ui ++++ b/panels/network/wireless-security/ws-wep-key.ui +@@ -52,8 +52,8 @@ + + True + False +- 0 +- _Key: ++ 1 ++ _Key + True + wep_key_entry + +@@ -111,8 +111,8 @@ + + True + False +- 0 +- Au_thentication: ++ 1 ++ Au_thentication + True + auth_method_combo + +@@ -148,8 +148,8 @@ + + True + False +- 0 +- WEP inde_x: ++ 1 ++ WEP inde_x + True + key_index_combo + +diff --git a/panels/network/wireless-security/ws-wpa-eap.ui b/panels/network/wireless-security/ws-wpa-eap.ui +index 2da2148..942af88 100644 +--- a/panels/network/wireless-security/ws-wpa-eap.ui ++++ b/panels/network/wireless-security/ws-wpa-eap.ui +@@ -29,8 +29,8 @@ + + True + False +- 0 +- Au_thentication: ++ 1 ++ Au_thentication + True + wpa_eap_auth_combo + +diff --git a/panels/network/wireless-security/ws-wpa-psk.ui b/panels/network/wireless-security/ws-wpa-psk.ui +index 4ec6909..b34720a 100644 +--- a/panels/network/wireless-security/ws-wpa-psk.ui ++++ b/panels/network/wireless-security/ws-wpa-psk.ui +@@ -18,8 +18,8 @@ + + True + False +- 0 +- _Password: ++ 1 ++ _Password + True + wpa_psk_entry + +@@ -46,8 +46,8 @@ + + True + False +- 0 +- _Type: ++ 1 ++ _Type + True + wpa_psk_type_combo + +diff --git a/panels/network/wireless-security/eap-method-fast.ui b/panels/network/wireless-security/eap-method-fast.ui +index 5307ddb..36e74c3 100644 +--- a/panels/network/wireless-security/eap-method-fast.ui ++++ b/panels/network/wireless-security/eap-method-fast.ui +@@ -40,7 +40,7 @@ + False + 5 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/eap-method-leap.ui b/panels/network/wireless-security/eap-method-leap.ui +index d4c0625..c4de1dc 100644 +--- a/panels/network/wireless-security/eap-method-leap.ui ++++ b/panels/network/wireless-security/eap-method-leap.ui +@@ -13,7 +13,7 @@ + start + 3 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/eap-method-peap.ui b/panels/network/wireless-security/eap-method-peap.ui +index 2f8b8cd..d16e00a 100644 +--- a/panels/network/wireless-security/eap-method-peap.ui ++++ b/panels/network/wireless-security/eap-method-peap.ui +@@ -40,7 +40,7 @@ + False + 5 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/eap-method-simple.ui b/panels/network/wireless-security/eap-method-simple.ui +index 7d95d28..af00cb9 100644 +--- a/panels/network/wireless-security/eap-method-simple.ui ++++ b/panels/network/wireless-security/eap-method-simple.ui +@@ -13,7 +13,7 @@ + start + 3 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/eap-method-tls.ui b/panels/network/wireless-security/eap-method-tls.ui +index 3c6291b..0079715 100644 +--- a/panels/network/wireless-security/eap-method-tls.ui ++++ b/panels/network/wireless-security/eap-method-tls.ui +@@ -13,7 +13,7 @@ + start + 6 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/eap-method-ttls.ui b/panels/network/wireless-security/eap-method-ttls.ui +index 70db9ed..df942d9 100644 +--- a/panels/network/wireless-security/eap-method-ttls.ui ++++ b/panels/network/wireless-security/eap-method-ttls.ui +@@ -23,7 +23,7 @@ + False + 4 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/ws-dynamic-wep.ui b/panels/network/wireless-security/ws-dynamic-wep.ui +index cf31f12..d6bc12b 100644 +--- a/panels/network/wireless-security/ws-dynamic-wep.ui ++++ b/panels/network/wireless-security/ws-dynamic-wep.ui +@@ -23,7 +23,7 @@ + False + 3 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/ws-leap.ui b/panels/network/wireless-security/ws-leap.ui +index b4d9bec..06cb645 100644 +--- a/panels/network/wireless-security/ws-leap.ui ++++ b/panels/network/wireless-security/ws-leap.ui +@@ -13,7 +13,7 @@ + start + 3 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/ws-wep-key.ui b/panels/network/wireless-security/ws-wep-key.ui +index c0e5f55..a4e14dc 100644 +--- a/panels/network/wireless-security/ws-wep-key.ui ++++ b/panels/network/wireless-security/ws-wep-key.ui +@@ -46,7 +46,7 @@ + False + 4 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/ws-wpa-eap.ui b/panels/network/wireless-security/ws-wpa-eap.ui +index 942af88..5d71936 100644 +--- a/panels/network/wireless-security/ws-wpa-eap.ui ++++ b/panels/network/wireless-security/ws-wpa-eap.ui +@@ -23,7 +23,7 @@ + False + 2 + 2 +- 12 ++ 6 + 6 + + +diff --git a/panels/network/wireless-security/ws-wpa-psk.ui b/panels/network/wireless-security/ws-wpa-psk.ui +index b34720a..3c689d3 100644 +--- a/panels/network/wireless-security/ws-wpa-psk.ui ++++ b/panels/network/wireless-security/ws-wpa-psk.ui +@@ -12,7 +12,7 @@ + False + 3 + 2 +- 12 ++ 6 + 6 + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-default.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-default.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-default.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/nm-default.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * 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. + * + * (C) Copyright 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_H__ +#define __NM_DEFAULT_H__ + +#define LIBNM_GLIB_BUILD +#define NETWORKMANAGER_COMPILATION + +/*****************************************************************************/ + +/* always include these headers for our internal source files. */ + +#ifndef ___CONFIG_H__ +#define ___CONFIG_H__ +#include +#endif + +#include + +#include + +#include +#include +#include + +static inline gboolean +nm_clear_g_source (guint *id) +{ + if (id && *id) { + g_source_remove (*id); + *id = 0; + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ + +#include + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_H__ */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2015 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "utils.h" + +/** + * Filters the characters from a text that was just input into GtkEditable. + * Returns FALSE, if after filtering no characters were left. TRUE means, + * that valid characters were added and the content of the GtkEditable changed. + **/ +gboolean +utils_filter_editable_on_insert_text (GtkEditable *editable, + const gchar *text, + gint length, + gint *position, + void *user_data, + UtilsFilterGtkEditableFunc validate_character, + gpointer block_func) +{ + int i, count = 0; + gchar *result = g_new (gchar, length+1); + + for (i = 0; i < length; i++) { + if (validate_character (text[i])) + result[count++] = text[i]; + } + result[count] = 0; + + if (count > 0) { + if (block_func) { + g_signal_handlers_block_by_func (G_OBJECT (editable), + G_CALLBACK (block_func), + user_data); + } + gtk_editable_insert_text (editable, result, count, position); + if (block_func) { + g_signal_handlers_unblock_by_func (G_OBJECT (editable), + G_CALLBACK (block_func), + user_data); + } + } + g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text"); + + g_free (result); + + return count > 0; +} + +gboolean +utils_char_is_ascii_print (char character) +{ + return g_ascii_isprint (character); +} diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/utils.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,44 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2015 Red Hat, Inc. + */ + +#include +#include + +gboolean utils_char_is_ascii_print (char character); + +#define NMA_ERROR (g_quark_from_static_string ("nma-error-quark")) + +typedef enum { + NMA_ERROR_GENERIC +} NMAError; + +typedef gboolean (*UtilsFilterGtkEditableFunc) (char character); +gboolean utils_filter_editable_on_insert_text (GtkEditable *editable, + const gchar *text, + gint length, + gint *position, + void *user_data, + UtilsFilterGtkEditableFunc validate_character, + gpointer block_func); + +extern void widget_set_error (GtkWidget *widget); +extern void widget_unset_error (GtkWidget *widget); diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,604 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include + +#include "wireless-security.h" +#include "wireless-security-resources.h" +#include "eap-method.h" +#include "utils.h" + +GType +wireless_security_get_type (void) +{ + static GType type_id = 0; + + if (!type_id) { + g_resources_register (wireless_security_get_resource ()); + + type_id = g_boxed_type_register_static ("WirelessSecurity", + (GBoxedCopyFunc) wireless_security_ref, + (GBoxedFreeFunc) wireless_security_unref); + } + + return type_id; +} + +GtkWidget * +wireless_security_get_widget (WirelessSecurity *sec) +{ + g_return_val_if_fail (sec != NULL, NULL); + + return sec->ui_widget; +} + +void +wireless_security_set_changed_notify (WirelessSecurity *sec, + WSChangedFunc func, + gpointer user_data) +{ + g_return_if_fail (sec != NULL); + + sec->changed_notify = func; + sec->changed_notify_data = user_data; +} + +void +wireless_security_changed_cb (GtkWidget *ignored, gpointer user_data) +{ + WirelessSecurity *sec = WIRELESS_SECURITY (user_data); + + if (sec->changed_notify) + (*(sec->changed_notify)) (sec, sec->changed_notify_data); +} + +gboolean +wireless_security_validate (WirelessSecurity *sec, GError **error) +{ + gboolean result; + + g_return_val_if_fail (sec != NULL, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + + g_assert (sec->validate); + result = (*(sec->validate)) (sec, error); + if (!result && error && !*error) + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Unknown error validating 802.1X security")); + return result; +} + +void +wireless_security_add_to_size_group (WirelessSecurity *sec, GtkSizeGroup *group) +{ + g_return_if_fail (sec != NULL); + g_return_if_fail (group != NULL); + + g_assert (sec->add_to_size_group); + return (*(sec->add_to_size_group)) (sec, group); +} + +void +wireless_security_fill_connection (WirelessSecurity *sec, + NMConnection *connection) +{ + g_return_if_fail (sec != NULL); + g_return_if_fail (connection != NULL); + + g_assert (sec->fill_connection); + return (*(sec->fill_connection)) (sec, connection); +} + +void +wireless_security_update_secrets (WirelessSecurity *sec, NMConnection *connection) +{ + g_return_if_fail (sec != NULL); + g_return_if_fail (connection != NULL); + + if (sec->update_secrets) + sec->update_secrets (sec, connection); +} + +WirelessSecurity * +wireless_security_ref (WirelessSecurity *sec) +{ + g_return_val_if_fail (sec != NULL, NULL); + g_return_val_if_fail (sec->refcount > 0, NULL); + + sec->refcount++; + return sec; +} + +void +wireless_security_unref (WirelessSecurity *sec) +{ + g_return_if_fail (sec != NULL); + g_return_if_fail (sec->refcount > 0); + + sec->refcount--; + if (sec->refcount == 0) { + if (sec->destroy) + sec->destroy (sec); + + g_free (sec->username); + if (sec->password) { + memset (sec->password, 0, strlen (sec->password)); + g_free (sec->password); + } + + if (sec->builder) + g_object_unref (sec->builder); + if (sec->ui_widget) + g_object_unref (sec->ui_widget); + g_slice_free1 (sec->obj_size, sec); + } +} + +WirelessSecurity * +wireless_security_init (gsize obj_size, + WSValidateFunc validate, + WSAddToSizeGroupFunc add_to_size_group, + WSFillConnectionFunc fill_connection, + WSUpdateSecretsFunc update_secrets, + WSDestroyFunc destroy, + const char *ui_resource, + const char *ui_widget_name, + const char *default_field) +{ + WirelessSecurity *sec; + GError *error = NULL; + + g_return_val_if_fail (obj_size > 0, NULL); + g_return_val_if_fail (ui_resource != NULL, NULL); + g_return_val_if_fail (ui_widget_name != NULL, NULL); + + g_type_ensure (WIRELESS_TYPE_SECURITY); + + sec = g_slice_alloc0 (obj_size); + g_assert (sec); + + sec->refcount = 1; + sec->obj_size = obj_size; + + sec->validate = validate; + sec->add_to_size_group = add_to_size_group; + sec->fill_connection = fill_connection; + sec->update_secrets = update_secrets; + sec->default_field = default_field; + + sec->builder = gtk_builder_new (); + if (!gtk_builder_add_from_resource (sec->builder, ui_resource, &error)) { + g_warning ("Couldn't load UI builder resource %s: %s", + ui_resource, error->message); + g_error_free (error); + wireless_security_unref (sec); + return NULL; + } + + sec->ui_widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, ui_widget_name)); + if (!sec->ui_widget) { + g_warning ("Couldn't load UI widget '%s' from UI file %s", + ui_widget_name, ui_resource); + wireless_security_unref (sec); + return NULL; + } + g_object_ref_sink (sec->ui_widget); + + sec->destroy = destroy; + sec->adhoc_compatible = TRUE; + sec->hotspot_compatible = TRUE; + + return sec; +} + +gboolean +wireless_security_adhoc_compatible (WirelessSecurity *sec) +{ + g_return_val_if_fail (sec != NULL, FALSE); + + return sec->adhoc_compatible; +} + +gboolean +wireless_security_hotspot_compatible (WirelessSecurity *sec) +{ + g_return_val_if_fail (sec != NULL, FALSE); + + return sec->hotspot_compatible; +} + +void +wireless_security_set_userpass (WirelessSecurity *sec, + const char *user, + const char *password, + gboolean always_ask, + gboolean show_password) +{ + g_free (sec->username); + sec->username = g_strdup (user); + + if (sec->password) { + memset (sec->password, 0, strlen (sec->password)); + g_free (sec->password); + } + sec->password = g_strdup (password); + + if (always_ask != (gboolean) -1) + sec->always_ask = always_ask; + sec->show_password = show_password; +} + +void +wireless_security_set_userpass_802_1x (WirelessSecurity *sec, + NMConnection *connection) +{ + const char *user = NULL, *password = NULL; + gboolean always_ask = FALSE, show_password = FALSE; + NMSetting8021x *setting; + NMSettingSecretFlags flags; + + if (!connection) + goto set; + + setting = nm_connection_get_setting_802_1x (connection); + if (!setting) + goto set; + + user = nm_setting_802_1x_get_identity (setting); + password = nm_setting_802_1x_get_password (setting); + + if (nm_setting_get_secret_flags (NM_SETTING (setting), NM_SETTING_802_1X_PASSWORD, &flags, NULL)) + always_ask = !!(flags & NM_SETTING_SECRET_FLAG_NOT_SAVED); + +set: + wireless_security_set_userpass (sec, user, password, always_ask, show_password); +} + +void +wireless_security_clear_ciphers (NMConnection *connection) +{ + NMSettingWirelessSecurity *s_wireless_sec; + + g_return_if_fail (connection != NULL); + + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wireless_sec); + + nm_setting_wireless_security_clear_protos (s_wireless_sec); + nm_setting_wireless_security_clear_pairwise (s_wireless_sec); + nm_setting_wireless_security_clear_groups (s_wireless_sec); +} + +void +ws_802_1x_add_to_size_group (WirelessSecurity *sec, + GtkSizeGroup *size_group, + const char *label_name, + const char *combo_name) +{ + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap; + + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, label_name)); + g_assert (widget); + gtk_size_group_add_widget (size_group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); + g_assert (widget); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); + g_assert (eap); + eap_method_add_to_size_group (eap, size_group); + eap_method_unref (eap); +} + +gboolean +ws_802_1x_validate (WirelessSecurity *sec, const char *combo_name, GError **error) +{ + GtkWidget *widget; + GtkTreeModel *model; + GtkTreeIter iter; + EAPMethod *eap = NULL; + gboolean valid = FALSE; + + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); + g_assert (widget); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); + g_assert (eap); + valid = eap_method_validate (eap, error); + eap_method_unref (eap); + return valid; +} + +void +ws_802_1x_auth_combo_changed (GtkWidget *combo, + WirelessSecurity *sec, + const char *vbox_name, + GtkSizeGroup *size_group) +{ + GtkWidget *vbox; + EAPMethod *eap = NULL; + GList *elt, *children; + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *eap_widget; + GtkWidget *eap_default_widget = NULL; + + vbox = GTK_WIDGET (gtk_builder_get_object (sec->builder, vbox_name)); + g_assert (vbox); + + /* Remove any previous wireless security widgets */ + children = gtk_container_get_children (GTK_CONTAINER (vbox)); + for (elt = children; elt; elt = g_list_next (elt)) + gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (elt->data)); + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter); + gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + eap_widget = eap_method_get_widget (eap); + g_assert (eap_widget); + gtk_widget_unparent (eap_widget); + + if (size_group) + eap_method_add_to_size_group (eap, size_group); + gtk_container_add (GTK_CONTAINER (vbox), eap_widget); + + /* Refocus the EAP method's default widget */ + if (eap->default_field) { + eap_default_widget = GTK_WIDGET (gtk_builder_get_object (eap->builder, eap->default_field)); + if (eap_default_widget) + gtk_widget_grab_focus (eap_default_widget); + } + + eap_method_unref (eap); + + wireless_security_changed_cb (combo, WIRELESS_SECURITY (sec)); +} + +GtkWidget * +ws_802_1x_auth_combo_init (WirelessSecurity *sec, + const char *combo_name, + const char *combo_label, + GCallback auth_combo_changed_cb, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only) +{ + GtkWidget *combo, *widget; + GtkListStore *auth_model; + GtkTreeIter iter; + EAPMethodSimple *em_md5; + EAPMethodTLS *em_tls; + EAPMethodLEAP *em_leap; + EAPMethodSimple *em_pwd; + EAPMethodFAST *em_fast; + EAPMethodTTLS *em_ttls; + EAPMethodPEAP *em_peap; + const char *default_method = NULL, *ctype = NULL; + int active = -1, item = 0; + gboolean wired = FALSE; + EAPMethodSimpleFlags simple_flags = EAP_METHOD_SIMPLE_FLAG_NONE; + + /* Grab the default EAP method out of the security object */ + if (connection) { + NMSettingConnection *s_con; + NMSetting8021x *s_8021x; + + s_con = nm_connection_get_setting_connection (connection); + if (s_con) + ctype = nm_setting_connection_get_connection_type (s_con); + if ( (g_strcmp0 (ctype, NM_SETTING_WIRED_SETTING_NAME) == 0) + || nm_connection_get_setting_wired (connection)) + wired = TRUE; + + s_8021x = nm_connection_get_setting_802_1x (connection); + if (s_8021x && nm_setting_802_1x_get_num_eap_methods (s_8021x)) + default_method = nm_setting_802_1x_get_eap_method (s_8021x, 0); + } + + /* initialize WirelessSecurity userpass from connection (clear if no connection) */ + wireless_security_set_userpass_802_1x (sec, connection); + + auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_type ()); + + if (is_editor) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_IS_EDITOR; + if (secrets_only) + simple_flags |= EAP_METHOD_SIMPLE_FLAG_SECRETS_ONLY; + + if (wired) { + em_md5 = eap_method_simple_new (sec, connection, EAP_METHOD_SIMPLE_TYPE_MD5, simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + AUTH_NAME_COLUMN, _("MD5"), + AUTH_METHOD_COLUMN, em_md5, + -1); + eap_method_unref (EAP_METHOD (em_md5)); + if (default_method && (active < 0) && !strcmp (default_method, "md5")) + active = item; + item++; + } + + em_tls = eap_method_tls_new (sec, connection, FALSE, secrets_only); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + AUTH_NAME_COLUMN, _("TLS"), + AUTH_METHOD_COLUMN, em_tls, + -1); + eap_method_unref (EAP_METHOD (em_tls)); + if (default_method && (active < 0) && !strcmp (default_method, "tls")) + active = item; + item++; + + if (!wired) { + em_leap = eap_method_leap_new (sec, connection, secrets_only); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + AUTH_NAME_COLUMN, _("LEAP"), + AUTH_METHOD_COLUMN, em_leap, + -1); + eap_method_unref (EAP_METHOD (em_leap)); + if (default_method && (active < 0) && !strcmp (default_method, "leap")) + active = item; + item++; + } + + em_pwd = eap_method_simple_new (sec, connection, EAP_METHOD_SIMPLE_TYPE_PWD, simple_flags); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + AUTH_NAME_COLUMN, _("PWD"), + AUTH_METHOD_COLUMN, em_pwd, + -1); + eap_method_unref (EAP_METHOD (em_pwd)); + if (default_method && (active < 0) && !strcmp (default_method, "pwd")) + active = item; + item++; + + em_fast = eap_method_fast_new (sec, connection, is_editor, secrets_only); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + AUTH_NAME_COLUMN, _("FAST"), + AUTH_METHOD_COLUMN, em_fast, + -1); + eap_method_unref (EAP_METHOD (em_fast)); + if (default_method && (active < 0) && !strcmp (default_method, "fast")) + active = item; + item++; + + em_ttls = eap_method_ttls_new (sec, connection, is_editor, secrets_only); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + AUTH_NAME_COLUMN, _("Tunneled TLS"), + AUTH_METHOD_COLUMN, em_ttls, + -1); + eap_method_unref (EAP_METHOD (em_ttls)); + if (default_method && (active < 0) && !strcmp (default_method, "ttls")) + active = item; + item++; + + em_peap = eap_method_peap_new (sec, connection, is_editor, secrets_only); + gtk_list_store_append (auth_model, &iter); + gtk_list_store_set (auth_model, &iter, + AUTH_NAME_COLUMN, _("Protected EAP (PEAP)"), + AUTH_METHOD_COLUMN, em_peap, + -1); + eap_method_unref (EAP_METHOD (em_peap)); + if (default_method && (active < 0) && !strcmp (default_method, "peap")) + active = item; + item++; + + combo = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); + g_assert (combo); + + gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (auth_model)); + g_object_unref (G_OBJECT (auth_model)); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active < 0 ? 0 : (guint32) active); + + g_signal_connect (G_OBJECT (combo), "changed", auth_combo_changed_cb, sec); + + if (secrets_only) { + gtk_widget_hide (combo); + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_label)); + gtk_widget_hide (widget); + } + + return combo; +} + +void +ws_802_1x_fill_connection (WirelessSecurity *sec, + const char *combo_name, + NMConnection *connection) +{ + GtkWidget *widget; + NMSettingWirelessSecurity *s_wireless_sec; + NMSetting8021x *s_8021x; + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + EAPMethod *eap = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + + /* Get the EAPMethod object */ + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); + g_assert (eap); + + /* Get previous pasword flags, if any. Otherwise default to agent-owned secrets */ + s_8021x = nm_connection_get_setting_802_1x (connection); + if (s_8021x) + nm_setting_get_secret_flags (NM_SETTING (s_8021x), eap->password_flags_name, &secret_flags, NULL); + else + secret_flags = NM_SETTING_SECRET_FLAG_AGENT_OWNED; + + /* Blow away the old wireless security setting by adding a clear one */ + s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec); + + /* Blow away the old 802.1x setting by adding a clear one */ + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_connection_add_setting (connection, (NMSetting *) s_8021x); + + eap_method_fill_connection (eap, connection, secret_flags); + eap_method_unref (eap); +} + +void +ws_802_1x_update_secrets (WirelessSecurity *sec, + const char *combo_name, + NMConnection *connection) +{ + GtkWidget *widget; + EAPMethod *eap = NULL; + GtkTreeModel *model; + GtkTreeIter iter; + + g_return_if_fail (sec != NULL); + g_return_if_fail (combo_name != NULL); + g_return_if_fail (connection != NULL); + + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, combo_name)); + g_return_if_fail (widget != NULL); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + + /* Let each EAP method try to update its secrets */ + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + gtk_tree_model_get (model, &iter, AUTH_METHOD_COLUMN, &eap, -1); + if (eap) { + eap_method_update_secrets (eap, connection); + eap_method_unref (eap); + } + } while (gtk_tree_model_iter_next (model, &iter)); + } +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.gresource.xml unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.gresource.xml --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.gresource.xml 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.gresource.xml 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,16 @@ + + + + eap-method-leap.ui + eap-method-fast.ui + eap-method-peap.ui + eap-method-simple.ui + eap-method-tls.ui + eap-method-ttls.ui + ws-dynamic-wep.ui + ws-leap.ui + ws-wep-key.ui + ws-wpa-eap.ui + ws-wpa-psk.ui + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/wireless-security.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,154 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef WIRELESS_SECURITY_H +#define WIRELESS_SECURITY_H + +#include + +#define WIRELESS_TYPE_SECURITY (wireless_security_get_type ()) + +typedef struct _WirelessSecurity WirelessSecurity; + +typedef void (*WSChangedFunc) (WirelessSecurity *sec, gpointer user_data); + +typedef void (*WSAddToSizeGroupFunc) (WirelessSecurity *sec, GtkSizeGroup *group); +typedef void (*WSFillConnectionFunc) (WirelessSecurity *sec, NMConnection *connection); +typedef void (*WSUpdateSecretsFunc) (WirelessSecurity *sec, NMConnection *connection); +typedef void (*WSDestroyFunc) (WirelessSecurity *sec); +typedef gboolean (*WSValidateFunc) (WirelessSecurity *sec, GError **error); +typedef GtkWidget * (*WSNagUserFunc) (WirelessSecurity *sec); + +struct _WirelessSecurity { + guint32 refcount; + gsize obj_size; + GtkBuilder *builder; + GtkWidget *ui_widget; + WSChangedFunc changed_notify; + gpointer changed_notify_data; + const char *default_field; + gboolean adhoc_compatible; + gboolean hotspot_compatible; + + char *username, *password; + gboolean always_ask, show_password; + + WSAddToSizeGroupFunc add_to_size_group; + WSFillConnectionFunc fill_connection; + WSUpdateSecretsFunc update_secrets; + WSValidateFunc validate; + WSDestroyFunc destroy; +}; + +#define WIRELESS_SECURITY(x) ((WirelessSecurity *) x) + + +GtkWidget *wireless_security_get_widget (WirelessSecurity *sec); + +void wireless_security_set_changed_notify (WirelessSecurity *sec, + WSChangedFunc func, + gpointer user_data); + +gboolean wireless_security_validate (WirelessSecurity *sec, GError **error); + +void wireless_security_add_to_size_group (WirelessSecurity *sec, + GtkSizeGroup *group); + +void wireless_security_fill_connection (WirelessSecurity *sec, + NMConnection *connection); + +void wireless_security_update_secrets (WirelessSecurity *sec, + NMConnection *connection); + +gboolean wireless_security_adhoc_compatible (WirelessSecurity *sec); + +gboolean wireless_security_hotspot_compatible (WirelessSecurity *sec); + +void wireless_security_set_userpass (WirelessSecurity *sec, + const char *user, + const char *password, + gboolean always_ask, + gboolean show_password); +void wireless_security_set_userpass_802_1x (WirelessSecurity *sec, + NMConnection *connection); + +WirelessSecurity *wireless_security_ref (WirelessSecurity *sec); + +void wireless_security_unref (WirelessSecurity *sec); + +GType wireless_security_get_type (void); + +/* Below for internal use only */ + +#include "ws-wep-key.h" +#include "ws-wpa-psk.h" +#include "ws-leap.h" +#include "ws-wpa-eap.h" +#include "ws-dynamic-wep.h" + +WirelessSecurity *wireless_security_init (gsize obj_size, + WSValidateFunc validate, + WSAddToSizeGroupFunc add_to_size_group, + WSFillConnectionFunc fill_connection, + WSUpdateSecretsFunc update_secrets, + WSDestroyFunc destroy, + const char *ui_resource, + const char *ui_widget_name, + const char *default_field); + +void wireless_security_changed_cb (GtkWidget *entry, gpointer user_data); + +void wireless_security_clear_ciphers (NMConnection *connection); + +#define AUTH_NAME_COLUMN 0 +#define AUTH_METHOD_COLUMN 1 + +GtkWidget *ws_802_1x_auth_combo_init (WirelessSecurity *sec, + const char *combo_name, + const char *combo_label, + GCallback auth_combo_changed_cb, + NMConnection *connection, + gboolean is_editor, + gboolean secrets_only); + +void ws_802_1x_auth_combo_changed (GtkWidget *combo, + WirelessSecurity *sec, + const char *vbox_name, + GtkSizeGroup *size_group); + +gboolean ws_802_1x_validate (WirelessSecurity *sec, const char *combo_name, GError **error); + +void ws_802_1x_add_to_size_group (WirelessSecurity *sec, + GtkSizeGroup *size_group, + const char *label_name, + const char *combo_name); + +void ws_802_1x_fill_connection (WirelessSecurity *sec, + const char *combo_name, + NMConnection *connection); + +void ws_802_1x_update_secrets (WirelessSecurity *sec, + const char *combo_name, + NMConnection *connection); + +#endif /* WIRELESS_SECURITY_H */ + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,132 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "wireless-security.h" +#include "eap-method.h" + +struct _WirelessSecurityDynamicWEP { + WirelessSecurity parent; + + GtkSizeGroup *size_group; +}; + +static void +destroy (WirelessSecurity *parent) +{ + WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent; + + if (sec->size_group) + g_object_unref (sec->size_group); +} + +static gboolean +validate (WirelessSecurity *parent, GError **error) +{ + return ws_802_1x_validate (parent, "dynamic_wep_auth_combo", error); +} + +static void +add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) +{ + WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent; + + if (sec->size_group) + g_object_unref (sec->size_group); + sec->size_group = g_object_ref (group); + + ws_802_1x_add_to_size_group (parent, + sec->size_group, + "dynamic_wep_auth_label", + "dynamic_wep_auth_combo"); +} + +static void +fill_connection (WirelessSecurity *parent, NMConnection *connection) +{ + NMSettingWirelessSecurity *s_wireless_sec; + + ws_802_1x_fill_connection (parent, "dynamic_wep_auth_combo", connection); + + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wireless_sec); + + g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); +} + +static void +auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) +{ + WirelessSecurity *parent = WIRELESS_SECURITY (user_data); + WirelessSecurityDynamicWEP *sec = (WirelessSecurityDynamicWEP *) parent; + + ws_802_1x_auth_combo_changed (combo, + parent, + "dynamic_wep_method_vbox", + sec->size_group); +} + +static void +update_secrets (WirelessSecurity *parent, NMConnection *connection) +{ + ws_802_1x_update_secrets (parent, "dynamic_wep_auth_combo", connection); +} + +WirelessSecurityDynamicWEP * +ws_dynamic_wep_new (NMConnection *connection, + gboolean is_editor, + gboolean secrets_only) +{ + WirelessSecurity *parent; + GtkWidget *widget; + + parent = wireless_security_init (sizeof (WirelessSecurityDynamicWEP), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/ws-dynamic-wep.ui", + "dynamic_wep_notebook", + NULL); + if (!parent) + return NULL; + + parent->adhoc_compatible = FALSE; + parent->hotspot_compatible = FALSE; + + widget = ws_802_1x_auth_combo_init (parent, + "dynamic_wep_auth_combo", + "dynamic_wep_auth_label", + (GCallback) auth_combo_changed_cb, + connection, + is_editor, + secrets_only); + auth_combo_changed_cb (widget, (gpointer) parent); + + return (WirelessSecurityDynamicWEP *) parent; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,32 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef WS_DYNAMIC_WEP_H +#define WS_DYNAMIC_WEP_H + +typedef struct _WirelessSecurityDynamicWEP WirelessSecurityDynamicWEP; + +WirelessSecurityDynamicWEP *ws_dynamic_wep_new (NMConnection *connection, + gboolean is_editor, + gboolean secrets_only); + +#endif /* WS_DYNAMIC_WEP_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-dynamic-wep.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + True + False + False + False + + + True + False + 3 + 2 + 6 + 6 + + + + + + + + + True + False + 1 + Au_thentication + True + dynamic_wep_auth_combo + + + GTK_FILL + + + + + + True + False + model7 + + + + 0 + + + + + 1 + 2 + GTK_FILL + + + + + True + False + 6 + + + + + + 2 + 1 + 2 + GTK_FILL + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,213 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include + +#include "wireless-security.h" +#include "helpers.h" +#include "nma-ui-utils.h" +#include "utils.h" + +struct _WirelessSecurityLEAP { + WirelessSecurity parent; + gboolean editing_connection; + const char *password_flags_name; +}; + +static void +show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec) +{ + GtkWidget *widget; + gboolean visible; + + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "leap_password_entry")); + g_assert (widget); + + visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + gtk_entry_set_visibility (GTK_ENTRY (widget), visible); +} + +static gboolean +validate (WirelessSecurity *parent, GError **error) +{ + GtkWidget *entry; + const char *text; + gboolean ret = TRUE; + + entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry")); + g_assert (entry); + text = gtk_entry_get_text (GTK_ENTRY (entry)); + if (!text || !strlen (text)) { + widget_set_error (entry); + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing leap-username")); + ret = FALSE; + } else + widget_unset_error (entry); + + entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry")); + g_assert (entry); + text = gtk_entry_get_text (GTK_ENTRY (entry)); + if (!text || !strlen (text)) { + widget_set_error (entry); + if (ret) { + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing leap-password")); + ret = FALSE; + } + } else + widget_unset_error (entry); + + return ret; +} + +static void +add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) +{ + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_label")); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_label")); + gtk_size_group_add_widget (group, widget); +} + +static void +fill_connection (WirelessSecurity *parent, NMConnection *connection) +{ + WirelessSecurityLEAP *sec = (WirelessSecurityLEAP *) parent; + NMSettingWirelessSecurity *s_wireless_sec; + NMSettingSecretFlags secret_flags; + GtkWidget *widget, *passwd_entry; + const char *leap_password = NULL, *leap_username = NULL; + + /* Blow away the old security setting by adding a clear one */ + s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry")); + leap_username = gtk_entry_get_text (GTK_ENTRY (widget)); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry")); + passwd_entry = widget; + leap_password = gtk_entry_get_text (GTK_ENTRY (widget)); + + g_object_set (s_wireless_sec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, + NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, leap_password, + NULL); + + /* Save LEAP_PASSWORD_FLAGS to the connection */ + secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); + nm_setting_set_secret_flags (NM_SETTING (s_wireless_sec), sec->password_flags_name, + secret_flags, NULL); + + /* Update secret flags and popup when editing the connection */ + if (sec->editing_connection) + nma_utils_update_password_storage (passwd_entry, secret_flags, + NM_SETTING (s_wireless_sec), sec->password_flags_name); +} + +static void +update_secrets (WirelessSecurity *parent, NMConnection *connection) +{ + helper_fill_secret_entry (connection, + parent->builder, + "leap_password_entry", + NM_TYPE_SETTING_WIRELESS_SECURITY, + (HelperSecretFunc) nm_setting_wireless_security_get_leap_password); +} + +WirelessSecurityLEAP * +ws_leap_new (NMConnection *connection, gboolean secrets_only) +{ + WirelessSecurity *parent; + WirelessSecurityLEAP *sec; + GtkWidget *widget; + NMSettingWirelessSecurity *wsec = NULL; + + parent = wireless_security_init (sizeof (WirelessSecurityLEAP), + validate, + add_to_size_group, + fill_connection, + update_secrets, + NULL, + "/org/freedesktop/network-manager-applet/ws-leap.ui", + "leap_notebook", + "leap_username_entry"); + if (!parent) + return NULL; + + if (connection) { + wsec = nm_connection_get_setting_wireless_security (connection); + if (wsec) { + const char *auth_alg; + + /* Ignore if wireless security doesn't specify LEAP */ + auth_alg = nm_setting_wireless_security_get_auth_alg (wsec); + if (!auth_alg || strcmp (auth_alg, "leap")) + wsec = NULL; + } + } + + parent->adhoc_compatible = FALSE; + parent->hotspot_compatible = FALSE; + sec = (WirelessSecurityLEAP *) parent; + sec->editing_connection = secrets_only ? FALSE : TRUE; + sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_password_entry")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + sec); + + /* Create password-storage popup menu for password entry under entry's secondary icon */ + nma_utils_setup_password_storage (widget, 0, (NMSetting *) wsec, sec->password_flags_name, + FALSE, secrets_only); + + if (wsec) + update_secrets (WIRELESS_SECURITY (sec), connection); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "leap_username_entry")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + sec); + if (wsec) + gtk_entry_set_text (GTK_ENTRY (widget), nm_setting_wireless_security_get_leap_username (wsec)); + + if (secrets_only) + gtk_widget_hide (widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_leap")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) show_toggled_cb, + sec); + + return sec; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef WS_LEAP_H +#define WS_LEAP_H + +typedef struct _WirelessSecurityLEAP WirelessSecurityLEAP; + +WirelessSecurityLEAP * ws_leap_new (NMConnection *connection, gboolean secrets_only); + +#endif /* WS_LEAP_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-leap.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,108 @@ + + + + + True + False + False + False + + + True + False + start + 3 + 2 + 6 + 6 + + + + + + True + False + 1 + _Username + True + leap_username_entry + + + GTK_FILL + + + + + + True + False + 1 + _Password + True + leap_password_entry + + + 1 + 2 + GTK_FILL + + + + + + True + True + False + True + + + 1 + 2 + 1 + 2 + + + + + + Sho_w password + True + True + False + True + True + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + True + True + + + 1 + 2 + + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,364 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include + +#include "wireless-security.h" +#include "utils.h" +#include "helpers.h" +#include "nma-ui-utils.h" + +struct _WirelessSecurityWEPKey { + WirelessSecurity parent; + + gboolean editing_connection; + const char *password_flags_name; + + NMWepKeyType type; + char keys[4][65]; + guint8 cur_index; +}; + +static void +show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec) +{ + GtkWidget *widget; + gboolean visible; + + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "wep_key_entry")); + g_assert (widget); + + visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + gtk_entry_set_visibility (GTK_ENTRY (widget), visible); +} + +static void +key_index_combo_changed_cb (GtkWidget *combo, WirelessSecurity *parent) +{ + WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; + GtkWidget *entry; + const char *key; + int key_index; + + /* Save WEP key for old key index */ + entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); + key = gtk_entry_get_text (GTK_ENTRY (entry)); + if (key) + g_strlcpy (sec->keys[sec->cur_index], key, sizeof (sec->keys[sec->cur_index])); + else + memset (sec->keys[sec->cur_index], 0, sizeof (sec->keys[sec->cur_index])); + + key_index = gtk_combo_box_get_active (GTK_COMBO_BOX (combo)); + g_return_if_fail (key_index <= 3); + g_return_if_fail (key_index >= 0); + + /* Populate entry with key from new index */ + gtk_entry_set_text (GTK_ENTRY (entry), sec->keys[key_index]); + sec->cur_index = key_index; + + wireless_security_changed_cb (combo, parent); +} + +static void +destroy (WirelessSecurity *parent) +{ + WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; + int i; + + for (i = 0; i < 4; i++) + memset (sec->keys[i], 0, sizeof (sec->keys[i])); +} + +static gboolean +validate (WirelessSecurity *parent, GError **error) +{ + WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; + GtkWidget *entry; + const char *key; + int i; + + entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); + g_assert (entry); + + key = gtk_entry_get_text (GTK_ENTRY (entry)); + if (!key) { + widget_set_error (entry); + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("missing wep-key")); + return FALSE; + } + + if (sec->type == NM_WEP_KEY_TYPE_KEY) { + if ((strlen (key) == 10) || (strlen (key) == 26)) { + for (i = 0; i < strlen (key); i++) { + if (!g_ascii_isxdigit (key[i])) { + widget_set_error (entry); + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: key with a length of %zu must contain only hex-digits"), strlen (key)); + return FALSE; + } + } + } else if ((strlen (key) == 5) || (strlen (key) == 13)) { + for (i = 0; i < strlen (key); i++) { + if (!utils_char_is_ascii_print (key[i])) { + widget_set_error (entry); + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: key with a length of %zu must contain only ascii characters"), strlen (key)); + return FALSE; + } + } + } else { + widget_set_error (entry); + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: wrong key length %zu. A key must be either of length 5/13 (ascii) or 10/26 (hex)"), strlen (key)); + return FALSE; + } + } else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) { + if (!*key || (strlen (key) > 64)) { + widget_set_error (entry); + if (!*key) + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: passphrase must be non-empty")); + else + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wep-key: passphrase must be shorter than 64 characters")); + return FALSE; + } + } + widget_unset_error (entry); + + return TRUE; +} + +static void +add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) +{ + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_label")); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_label")); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_label")); + gtk_size_group_add_widget (group, widget); +} + +static void +fill_connection (WirelessSecurity *parent, NMConnection *connection) +{ + WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; + NMSettingWirelessSecurity *s_wsec; + NMSettingSecretFlags secret_flags; + GtkWidget *widget, *passwd_entry; + gint auth_alg; + const char *key; + int i; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_combo")); + auth_alg = gtk_combo_box_get_active (GTK_COMBO_BOX (widget)); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); + passwd_entry = widget; + key = gtk_entry_get_text (GTK_ENTRY (widget)); + g_strlcpy (sec->keys[sec->cur_index], key, sizeof (sec->keys[sec->cur_index])); + + /* Blow away the old security setting by adding a clear one */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, (NMSetting *) s_wsec); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, sec->cur_index, + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, (auth_alg == 1) ? "shared" : "open", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, sec->type, + NULL); + + for (i = 0; i < 4; i++) { + if (strlen (sec->keys[i])) + nm_setting_wireless_security_set_wep_key (s_wsec, i, sec->keys[i]); + } + + /* Save WEP_KEY_FLAGS to the connection */ + secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, secret_flags, NULL); + + /* Update secret flags and popup when editing the connection */ + if (sec->editing_connection) + nma_utils_update_password_storage (passwd_entry, secret_flags, + NM_SETTING (s_wsec), sec->password_flags_name); +} + +static void +wep_entry_filter_cb (GtkEditable *editable, + gchar *text, + gint length, + gint *position, + gpointer data) +{ + WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) data; + + if (sec->type == NM_WEP_KEY_TYPE_KEY) { + utils_filter_editable_on_insert_text (editable, + text, length, position, data, + utils_char_is_ascii_print, + wep_entry_filter_cb); + } +} + +static void +update_secrets (WirelessSecurity *parent, NMConnection *connection) +{ + WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) parent; + NMSettingWirelessSecurity *s_wsec; + GtkWidget *widget; + const char *tmp; + int i; + + s_wsec = nm_connection_get_setting_wireless_security (connection); + for (i = 0; s_wsec && i < 4; i++) { + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, i); + if (tmp) + g_strlcpy (sec->keys[i], tmp, sizeof (sec->keys[i])); + } + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); + if (strlen (sec->keys[sec->cur_index])) + gtk_entry_set_text (GTK_ENTRY (widget), sec->keys[sec->cur_index]); +} + +WirelessSecurityWEPKey * +ws_wep_key_new (NMConnection *connection, + NMWepKeyType type, + gboolean adhoc_create, + gboolean secrets_only) +{ + WirelessSecurity *parent; + WirelessSecurityWEPKey *sec; + GtkWidget *widget; + NMSettingWirelessSecurity *s_wsec = NULL; + NMSetting *setting = NULL; + guint8 default_key_idx = 0; + gboolean is_adhoc = adhoc_create; + gboolean is_shared_key = FALSE; + + parent = wireless_security_init (sizeof (WirelessSecurityWEPKey), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/ws-wep-key.ui", + "wep_key_notebook", + "wep_key_entry"); + if (!parent) + return NULL; + + sec = (WirelessSecurityWEPKey *) parent; + sec->editing_connection = secrets_only ? FALSE : TRUE; + sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_WEP_KEY0; + sec->type = type; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wep_key_entry")); + g_assert (widget); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 28); + + /* Create password-storage popup menu for password entry under entry's secondary icon */ + if (connection) + setting = (NMSetting *) nm_connection_get_setting_wireless_security (connection); + nma_utils_setup_password_storage (widget, 0, setting, sec->password_flags_name, + FALSE, secrets_only); + + if (connection) { + NMSettingWireless *s_wireless; + const char *mode, *auth_alg; + + s_wireless = nm_connection_get_setting_wireless (connection); + mode = s_wireless ? nm_setting_wireless_get_mode (s_wireless) : NULL; + if (mode && !strcmp (mode, "adhoc")) + is_adhoc = TRUE; + + s_wsec = nm_connection_get_setting_wireless_security (connection); + if (s_wsec) { + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + if (auth_alg && !strcmp (auth_alg, "shared")) + is_shared_key = TRUE; + } + } + + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + sec); + g_signal_connect (G_OBJECT (widget), "insert-text", + (GCallback) wep_entry_filter_cb, + sec); + if (sec->type == NM_WEP_KEY_TYPE_KEY) + gtk_entry_set_max_length (GTK_ENTRY (widget), 26); + else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) + gtk_entry_set_max_length (GTK_ENTRY (widget), 64); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_combo")); + if (connection && s_wsec) + default_key_idx = nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec); + + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), default_key_idx); + sec->cur_index = default_key_idx; + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) key_index_combo_changed_cb, + sec); + + /* Key index is useless with adhoc networks */ + if (is_adhoc || secrets_only) { + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "key_index_label")); + gtk_widget_hide (widget); + } + + /* Fill the key entry with the key for that index */ + if (connection) + update_secrets (WIRELESS_SECURITY (sec), connection); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_wep")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) show_toggled_cb, + sec); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_combo")); + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), is_shared_key ? 1 : 0); + + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + sec); + + /* Don't show auth method for adhoc (which always uses open-system) or + * when in "simple" mode. + */ + if (is_adhoc || secrets_only) { + /* Ad-Hoc connections can't use Shared Key auth */ + if (is_adhoc) + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); + gtk_widget_hide (widget); + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "auth_method_label")); + gtk_widget_hide (widget); + } + + return sec; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef WS_WEP_KEY_H +#define WS_WEP_KEY_H + +typedef struct _WirelessSecurityWEPKey WirelessSecurityWEPKey; + +WirelessSecurityWEPKey *ws_wep_key_new (NMConnection *connection, + NMWepKeyType type, + gboolean adhoc_create, + gboolean secrets_only); + +#endif /* WS_WEP_KEY_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wep-key.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,196 @@ + + + + + + + + + + + 1 (Default) + + + 2 + + + 3 + + + 4 + + + + + + + + + + + Open System + + + Shared Key + + + + + True + False + False + False + + + True + False + 4 + 2 + 6 + 6 + + + True + False + 1 + _Key + True + wep_key_entry + + + GTK_FILL + + + + + + True + True + 64 + False + True + + + 1 + 2 + + + + + + True + False + 0 + + + 1 + 2 + GTK_FILL + + + + + + Sho_w key + True + True + False + True + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + False + 1 + Au_thentication + True + auth_method_combo + + + 3 + 4 + GTK_FILL + + + + + + True + False + model3 + + + + 0 + + + + + 1 + 2 + 3 + 4 + GTK_FILL + GTK_FILL + + + + + True + False + 1 + WEP inde_x + True + key_index_combo + + + 2 + 3 + GTK_FILL + + + + + + True + False + model4 + + + + 0 + + + + + 1 + 2 + 2 + 3 + GTK_FILL + GTK_FILL + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,133 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "wireless-security.h" +#include "eap-method.h" + +struct _WirelessSecurityWPAEAP { + WirelessSecurity parent; + + GtkSizeGroup *size_group; +}; + + +static void +destroy (WirelessSecurity *parent) +{ + WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent; + + if (sec->size_group) + g_object_unref (sec->size_group); +} + +static gboolean +validate (WirelessSecurity *parent, GError **error) +{ + return ws_802_1x_validate (parent, "wpa_eap_auth_combo", error); +} + +static void +add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) +{ + WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent; + + if (sec->size_group) + g_object_unref (sec->size_group); + sec->size_group = g_object_ref (group); + + ws_802_1x_add_to_size_group (parent, + sec->size_group, + "wpa_eap_auth_label", + "wpa_eap_auth_combo"); +} + +static void +fill_connection (WirelessSecurity *parent, NMConnection *connection) +{ + NMSettingWirelessSecurity *s_wireless_sec; + + ws_802_1x_fill_connection (parent, "wpa_eap_auth_combo", connection); + + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wireless_sec); + + g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL); +} + +static void +auth_combo_changed_cb (GtkWidget *combo, gpointer user_data) +{ + WirelessSecurity *parent = WIRELESS_SECURITY (user_data); + WirelessSecurityWPAEAP *sec = (WirelessSecurityWPAEAP *) parent; + + ws_802_1x_auth_combo_changed (combo, + parent, + "wpa_eap_method_vbox", + sec->size_group); +} + +static void +update_secrets (WirelessSecurity *parent, NMConnection *connection) +{ + ws_802_1x_update_secrets (parent, "wpa_eap_auth_combo", connection); +} + +WirelessSecurityWPAEAP * +ws_wpa_eap_new (NMConnection *connection, + gboolean is_editor, + gboolean secrets_only) +{ + WirelessSecurity *parent; + GtkWidget *widget; + + parent = wireless_security_init (sizeof (WirelessSecurityWPAEAP), + validate, + add_to_size_group, + fill_connection, + update_secrets, + destroy, + "/org/freedesktop/network-manager-applet/ws-wpa-eap.ui", + "wpa_eap_notebook", + NULL); + if (!parent) + return NULL; + + parent->adhoc_compatible = FALSE; + parent->hotspot_compatible = FALSE; + + widget = ws_802_1x_auth_combo_init (parent, + "wpa_eap_auth_combo", + "wpa_eap_auth_label", + (GCallback) auth_combo_changed_cb, + connection, + is_editor, + secrets_only); + auth_combo_changed_cb (widget, parent); + + return (WirelessSecurityWPAEAP *) parent; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,32 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef WS_WPA_EAP_H +#define WS_WPA_EAP_H + +typedef struct _WirelessSecurityWPAEAP WirelessSecurityWPAEAP; + +WirelessSecurityWPAEAP * ws_wpa_eap_new (NMConnection *connection, + gboolean is_editor, + gboolean secrets_only); + +#endif /* WS_WPA_EAP_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-eap.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + True + False + False + False + + + True + False + 2 + 2 + 6 + 6 + + + True + False + 1 + Au_thentication + True + wpa_eap_auth_combo + + + GTK_FILL + + + + + + True + False + model5 + + + + 0 + + + + + 1 + 2 + GTK_FILL + + + + + True + False + + + + + + 2 + 1 + 2 + GTK_FILL + + + + + + + True + False + + + False + + + + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.c unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.c --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.c 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.c 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,233 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include +#include + +#include "wireless-security.h" +#include "helpers.h" +#include "nma-ui-utils.h" +#include "utils.h" + +#define WPA_PMK_LEN 32 + +struct _WirelessSecurityWPAPSK { + WirelessSecurity parent; + + gboolean editing_connection; + const char *password_flags_name; +}; + +static void +show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec) +{ + GtkWidget *widget; + gboolean visible; + + widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, "wpa_psk_entry")); + g_assert (widget); + + visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + gtk_entry_set_visibility (GTK_ENTRY (widget), visible); +} + +static gboolean +validate (WirelessSecurity *parent, GError **error) +{ + GtkWidget *entry; + const char *key; + gsize len; + int i; + + entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry")); + g_assert (entry); + + key = gtk_entry_get_text (GTK_ENTRY (entry)); + len = key ? strlen (key) : 0; + if ((len < 8) || (len > 64)) { + widget_set_error (entry); + g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wpa-psk: invalid key-length %zu. Must be [8,63] bytes or 64 hex digits"), len); + return FALSE; + } + + if (len == 64) { + /* Hex PSK */ + for (i = 0; i < len; i++) { + if (!isxdigit (key[i])) { + widget_set_error (entry); + g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("invalid wpa-psk: cannot interpret key with 64 bytes as hex")); + return FALSE; + } + } + } + widget_unset_error (entry); + + /* passphrase can be between 8 and 63 characters inclusive */ + + return TRUE; +} + +static void +add_to_size_group (WirelessSecurity *parent, GtkSizeGroup *group) +{ + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_label")); + gtk_size_group_add_widget (group, widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_label")); + gtk_size_group_add_widget (group, widget); +} + +static void +fill_connection (WirelessSecurity *parent, NMConnection *connection) +{ + WirelessSecurityWPAPSK *wpa_psk = (WirelessSecurityWPAPSK *) parent; + GtkWidget *widget, *passwd_entry; + const char *key; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wireless_sec; + NMSettingSecretFlags secret_flags; + const char *mode; + gboolean is_adhoc = FALSE; + + s_wireless = nm_connection_get_setting_wireless (connection); + g_assert (s_wireless); + + mode = nm_setting_wireless_get_mode (s_wireless); + if (mode && !strcmp (mode, "adhoc")) + is_adhoc = TRUE; + + /* Blow away the old security setting by adding a clear one */ + s_wireless_sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, (NMSetting *) s_wireless_sec); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry")); + passwd_entry = widget; + key = gtk_entry_get_text (GTK_ENTRY (widget)); + g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_PSK, key, NULL); + + /* Save PSK_FLAGS to the connection */ + secret_flags = nma_utils_menu_to_secret_flags (passwd_entry); + nm_setting_set_secret_flags (NM_SETTING (s_wireless_sec), NM_SETTING_WIRELESS_SECURITY_PSK, + secret_flags, NULL); + + /* Update secret flags and popup when editing the connection */ + if (wpa_psk->editing_connection) + nma_utils_update_password_storage (passwd_entry, secret_flags, + NM_SETTING (s_wireless_sec), wpa_psk->password_flags_name); + + wireless_security_clear_ciphers (connection); + if (is_adhoc) { + /* Ad-Hoc settings as specified by the supplicant */ + g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL); + nm_setting_wireless_security_add_proto (s_wireless_sec, "wpa"); + nm_setting_wireless_security_add_pairwise (s_wireless_sec, "none"); + + /* Ad-hoc can only have _one_ group cipher... default to TKIP to be more + * compatible for now. Maybe we'll support selecting CCMP later. + */ + nm_setting_wireless_security_add_group (s_wireless_sec, "tkip"); + } else { + g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL); + + /* Just leave ciphers and protocol empty, the supplicant will + * figure that out magically based on the AP IEs and card capabilities. + */ + } +} + +static void +update_secrets (WirelessSecurity *parent, NMConnection *connection) +{ + helper_fill_secret_entry (connection, + parent->builder, + "wpa_psk_entry", + NM_TYPE_SETTING_WIRELESS_SECURITY, + (HelperSecretFunc) nm_setting_wireless_security_get_psk); +} + +WirelessSecurityWPAPSK * +ws_wpa_psk_new (NMConnection *connection, gboolean secrets_only) +{ + WirelessSecurity *parent; + WirelessSecurityWPAPSK *sec; + NMSetting *setting = NULL; + GtkWidget *widget; + + parent = wireless_security_init (sizeof (WirelessSecurityWPAPSK), + validate, + add_to_size_group, + fill_connection, + update_secrets, + NULL, + "/org/freedesktop/network-manager-applet/ws-wpa-psk.ui", + "wpa_psk_notebook", + "wpa_psk_entry"); + if (!parent) + return NULL; + + parent->adhoc_compatible = FALSE; + sec = (WirelessSecurityWPAPSK *) parent; + sec->editing_connection = secrets_only ? FALSE : TRUE; + sec->password_flags_name = NM_SETTING_WIRELESS_SECURITY_PSK; + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_entry")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "changed", + (GCallback) wireless_security_changed_cb, + sec); + gtk_entry_set_width_chars (GTK_ENTRY (widget), 28); + + /* Create password-storage popup menu for password entry under entry's secondary icon */ + if (connection) + setting = (NMSetting *) nm_connection_get_setting_wireless_security (connection); + nma_utils_setup_password_storage (widget, 0, setting, sec->password_flags_name, + FALSE, secrets_only); + + /* Fill secrets, if any */ + if (connection) + update_secrets (WIRELESS_SECURITY (sec), connection); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_wpa")); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", + (GCallback) show_toggled_cb, + sec); + + /* Hide WPA/RSN for now since this can be autodetected by NM and the + * supplicant when connecting to the AP. + */ + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_combo")); + g_assert (widget); + gtk_widget_hide (widget); + + widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "wpa_psk_type_label")); + g_assert (widget); + gtk_widget_hide (widget); + + return sec; +} + diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.h unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.h --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.h 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.h 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager Applet -- allow user control over networking + * + * Dan Williams + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2014 Red Hat, Inc. + */ + +#ifndef WS_WPA_PSK_H +#define WS_WPA_PSK_H + +typedef struct _WirelessSecurityWPAPSK WirelessSecurityWPAPSK; + +WirelessSecurityWPAPSK * ws_wpa_psk_new (NMConnection *connection, gboolean secrets_only); + +#endif /* WS_WEP_KEY_H */ diff -Nru unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.ui unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.ui --- unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.ui 1970-01-01 00:00:00.000000000 +0000 +++ unity-control-center-15.04.0+19.04.20190209/panels/network/wireless-security/ws-wpa-psk.ui 2019-05-01 13:21:41.000000000 +0000 @@ -0,0 +1,117 @@ + + + + + True + False + False + False + + + True + False + 3 + 2 + 6 + 6 + + + True + False + 1 + _Password + True + wpa_psk_entry + + + GTK_FILL + + + + + + True + True + 64 + False + True + + + 1 + 2 + + + + + + True + False + 1 + _Type + True + wpa_psk_type_combo + + + 2 + 3 + GTK_FILL + + + + + + True + False + 0 + + + 1 + 2 + GTK_FILL + + + + + + Sho_w password + True + True + False + True + True + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + False + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + + True + False + + + False + + + +