Blame src/connection-editor/page-8021x-security.c

Packit Service 639700
// SPDX-License-Identifier: GPL-2.0+
Packit fabffb
/* NetworkManager Connection editor -- Connection editor for NetworkManager
Packit fabffb
 *
Packit fabffb
 * Dan Williams <dcbw@redhat.com>
Packit fabffb
 *
Packit fabffb
 * Copyright 2008 - 2014 Red Hat, Inc.
Packit fabffb
 */
Packit fabffb
Packit fabffb
#include "nm-default.h"
Packit fabffb
Packit fabffb
#include <string.h>
Packit fabffb
Packit fabffb
#include "wireless-security.h"
Packit fabffb
#include "page-ethernet.h"
Packit fabffb
#include "page-8021x-security.h"
Packit fabffb
#include "nm-connection-editor.h"
Packit fabffb
Packit fabffb
G_DEFINE_TYPE (CEPage8021xSecurity, ce_page_8021x_security, CE_TYPE_PAGE)
Packit fabffb
Packit fabffb
#define CE_PAGE_8021X_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_8021X_SECURITY, CEPage8021xSecurityPrivate))
Packit fabffb
Packit fabffb
typedef struct {
Packit fabffb
	GtkToggleButton *enabled;
Packit fabffb
	GtkWidget *security_widget;
Packit fabffb
	WirelessSecurity *security;
Packit fabffb
	GtkSizeGroup *group;
Packit fabffb
Packit fabffb
	gboolean initial_have_8021x;
Packit fabffb
} CEPage8021xSecurityPrivate;
Packit fabffb
Packit fabffb
static void
Packit fabffb
stuff_changed (WirelessSecurity *sec, gpointer user_data)
Packit fabffb
{
Packit fabffb
	ce_page_changed (CE_PAGE (user_data));
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
enable_toggled (GtkToggleButton *button, gpointer user_data)
Packit fabffb
{
Packit fabffb
	CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (user_data);
Packit fabffb
	gboolean active = gtk_toggle_button_get_active (priv->enabled);
Packit fabffb
Packit fabffb
	gtk_widget_set_sensitive (priv->security_widget, active);
Packit fabffb
	nm_connection_editor_inter_page_set_value (CE_PAGE (user_data)->editor,
Packit fabffb
	                                           INTER_PAGE_CHANGE_802_1X_ENABLE,
Packit fabffb
	                                           GINT_TO_POINTER (active));
Packit fabffb
	ce_page_changed (CE_PAGE (user_data));
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
finish_setup (CEPage8021xSecurity *self, gpointer user_data)
Packit fabffb
{
Packit fabffb
	CEPage *parent = CE_PAGE (self);
Packit fabffb
	CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (self);
Packit fabffb
	GtkWidget *parent_container;
Packit fabffb
Packit fabffb
	priv->security = (WirelessSecurity *) ws_wpa_eap_new (parent->connection, TRUE, FALSE, NULL);
Packit fabffb
	if (!priv->security) {
Packit fabffb
		g_warning ("Could not load 802.1X user interface.");
Packit fabffb
		return;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	wireless_security_add_to_size_group (priv->security, priv->group);
Packit fabffb
Packit fabffb
	wireless_security_set_changed_notify (priv->security, stuff_changed, self);
Packit fabffb
	priv->security_widget = wireless_security_get_widget (priv->security);
Packit fabffb
	parent_container = gtk_widget_get_parent (priv->security_widget);
Packit fabffb
	if (parent_container)
Packit fabffb
		gtk_container_remove (GTK_CONTAINER (parent_container), priv->security_widget);
Packit fabffb
Packit fabffb
	gtk_toggle_button_set_active (priv->enabled, priv->initial_have_8021x);
Packit fabffb
	g_signal_connect (priv->enabled, "toggled", G_CALLBACK (enable_toggled), self);
Packit fabffb
	gtk_widget_set_sensitive (priv->security_widget, priv->initial_have_8021x);
Packit fabffb
Packit fabffb
	gtk_box_pack_start (GTK_BOX (parent->page), GTK_WIDGET (priv->enabled), FALSE, TRUE, 12);
Packit fabffb
	gtk_box_pack_start (GTK_BOX (parent->page), priv->security_widget, TRUE, TRUE, 0);
Packit fabffb
	gtk_widget_show_all (parent->page);
Packit fabffb
}
Packit fabffb
Packit fabffb
CEPage *
Packit fabffb
ce_page_8021x_security_new (NMConnectionEditor *editor,
Packit fabffb
                            NMConnection *connection,
Packit fabffb
                            GtkWindow *parent_window,
Packit fabffb
                            NMClient *client,
Packit fabffb
                            const char **out_secrets_setting_name,
Packit fabffb
                            GError **error)
Packit fabffb
{
Packit fabffb
	CEPage8021xSecurity *self;
Packit fabffb
	CEPage8021xSecurityPrivate *priv;
Packit fabffb
	CEPage *parent;
Packit fabffb
Packit fabffb
	self = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY,
Packit fabffb
	                                            editor,
Packit fabffb
	                                            connection,
Packit fabffb
	                                            parent_window,
Packit fabffb
	                                            client,
Packit fabffb
	                                            NULL,
Packit fabffb
	                                            NULL,
Packit fabffb
	                                            _("802.1X Security")));
Packit fabffb
	if (!self) {
Packit fabffb
		g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load 802.1X Security user interface."));
Packit fabffb
		return NULL;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	parent = CE_PAGE (self);
Packit fabffb
	priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (self);
Packit fabffb
Packit fabffb
	parent->page = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
Packit fabffb
	g_object_ref_sink (G_OBJECT (parent->page));
Packit fabffb
	gtk_container_set_border_width (GTK_CONTAINER (parent->page), 6);
Packit fabffb
Packit fabffb
	if (nm_connection_get_setting_802_1x (connection))
Packit fabffb
		priv->initial_have_8021x = TRUE;
Packit fabffb
Packit fabffb
	priv->enabled = GTK_TOGGLE_BUTTON (gtk_check_button_new_with_mnemonic (_("Use 802.1_X security for this connection")));
Packit fabffb
Packit fabffb
	priv->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
Packit fabffb
Packit fabffb
	g_signal_connect (self, CE_PAGE_INITIALIZED, G_CALLBACK (finish_setup), NULL);
Packit fabffb
Packit fabffb
	if (priv->initial_have_8021x)
Packit fabffb
		*out_secrets_setting_name = NM_SETTING_802_1X_SETTING_NAME;
Packit fabffb
Packit fabffb
	return CE_PAGE (self);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
clear_widget_errors (GtkWidget *widget,
Packit fabffb
                     gpointer   user_data)
Packit fabffb
{
Packit fabffb
	if (GTK_IS_CONTAINER (widget)) {
Packit fabffb
		gtk_container_forall (GTK_CONTAINER (widget),
Packit fabffb
		                      clear_widget_errors,
Packit fabffb
		                      NULL);
Packit fabffb
	} else {
Packit fabffb
		widget_unset_error (widget);
Packit fabffb
	}
Packit fabffb
}
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error)
Packit fabffb
{
Packit fabffb
	CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (page);
Packit fabffb
	gboolean valid = TRUE;
Packit fabffb
Packit fabffb
	if (gtk_toggle_button_get_active (priv->enabled)) {
Packit fabffb
		NMConnection *tmp_connection;
Packit fabffb
		NMSetting *s_8021x;
Packit fabffb
Packit fabffb
		valid = wireless_security_validate (priv->security, error);
Packit fabffb
		if (valid) {
Packit fabffb
			NMSetting *s_con;
Packit fabffb
Packit fabffb
			/* Here's a nice hack to work around the fact that ws_802_1x_fill_connection needs wireless setting. */
Packit fabffb
			tmp_connection = nm_simple_connection_new ();
Packit fabffb
			nm_connection_add_setting (tmp_connection, nm_setting_wireless_new ());
Packit fabffb
Packit fabffb
			/* temp connection needs a 'connection' setting too, since most of
Packit fabffb
			 * the EAP methods need the UUID for CA cert ignore stuff.
Packit fabffb
			 */
Packit fabffb
			s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
Packit fabffb
			nm_connection_add_setting (tmp_connection, nm_setting_duplicate (s_con));
Packit fabffb
Packit fabffb
			ws_802_1x_fill_connection (priv->security, "wpa_eap_auth_combo", tmp_connection);
Packit fabffb
Packit fabffb
			s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
Packit fabffb
			nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x)));
Packit fabffb
Packit fabffb
			/* Remove the 8021x setting to prevent the clearing of secrets when the
Packit fabffb
			 * simple-connection is destroyed.
Packit fabffb
			 */
Packit fabffb
			nm_connection_remove_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
Packit fabffb
			g_object_unref (tmp_connection);
Packit fabffb
		}
Packit fabffb
	} else {
Packit fabffb
		gtk_container_forall (GTK_CONTAINER (priv->security_widget),
Packit fabffb
		                      clear_widget_errors,
Packit fabffb
		                      NULL);
Packit fabffb
		nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
Packit fabffb
		valid = TRUE;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	return valid;
Packit fabffb
}
Packit fabffb
Packit fabffb
static gboolean
Packit fabffb
inter_page_change (CEPage *page)
Packit fabffb
{
Packit fabffb
	CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (page);
Packit fabffb
	gpointer macsec_mode;
Packit fabffb
Packit fabffb
	if (nm_connection_editor_inter_page_get_value (page->editor,
Packit fabffb
	                                               INTER_PAGE_CHANGE_MACSEC_MODE,
Packit fabffb
	                                               &macsec_mode)) {
Packit fabffb
		gtk_toggle_button_set_active (priv->enabled,
Packit fabffb
		                              GPOINTER_TO_INT (macsec_mode) == NM_SETTING_MACSEC_MODE_EAP);
Packit fabffb
		enable_toggled (priv->enabled, page);
Packit fabffb
	}
Packit fabffb
Packit fabffb
	return TRUE;
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
ce_page_8021x_security_init (CEPage8021xSecurity *self)
Packit fabffb
{
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
dispose (GObject *object)
Packit fabffb
{
Packit fabffb
	CEPage *parent = CE_PAGE (object);
Packit fabffb
	CEPage8021xSecurityPrivate *priv = CE_PAGE_8021X_SECURITY_GET_PRIVATE (object);
Packit fabffb
Packit fabffb
	g_clear_object (&priv->group);
Packit fabffb
Packit fabffb
	if (priv->security_widget) {
Packit fabffb
		gtk_container_remove (GTK_CONTAINER (parent->page), priv->security_widget);
Packit fabffb
		priv->security_widget = NULL;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	if (priv->security) {
Packit fabffb
		wireless_security_unref (priv->security);
Packit fabffb
		priv->security = NULL;
Packit fabffb
	}
Packit fabffb
Packit fabffb
	G_OBJECT_CLASS (ce_page_8021x_security_parent_class)->dispose (object);
Packit fabffb
}
Packit fabffb
Packit fabffb
static void
Packit fabffb
ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class)
Packit fabffb
{
Packit fabffb
	GObjectClass *object_class = G_OBJECT_CLASS (security_class);
Packit fabffb
	CEPageClass *parent_class = CE_PAGE_CLASS (security_class);
Packit fabffb
Packit fabffb
	g_type_class_add_private (object_class, sizeof (CEPage8021xSecurityPrivate));
Packit fabffb
Packit fabffb
	/* virtual methods */
Packit fabffb
	object_class->dispose = dispose;
Packit fabffb
Packit fabffb
	parent_class->ce_page_validate_v = ce_page_validate_v;
Packit fabffb
	parent_class->inter_page_change = inter_page_change;
Packit fabffb
}