// SPDX-License-Identifier: GPL-2.0+ /* NetworkManager Connection editor -- Connection editor for NetworkManager * * Dan Williams * * Copyright 2008 - 2014 Red Hat, Inc. */ #include "nm-default.h" #include #include "page-ppp.h" #include "ppp-auth-methods-dialog.h" #include "nm-connection-editor.h" G_DEFINE_TYPE (CEPagePpp, ce_page_ppp, CE_TYPE_PAGE) #define CE_PAGE_PPP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CE_TYPE_PAGE_PPP, CEPagePppPrivate)) #define COL_NAME 0 #define COL_VALUE 1 #define COL_TAG 2 #define TAG_EAP 0 #define TAG_PAP 1 #define TAG_CHAP 2 #define TAG_MSCHAP 3 #define TAG_MSCHAPV2 4 typedef struct { NMSettingPpp *setting; GtkLabel *auth_methods_label; GtkButton *auth_methods_button; gboolean refuse_eap; gboolean refuse_pap; gboolean refuse_chap; gboolean refuse_mschap; gboolean refuse_mschapv2; guint orig_lcp_echo_failure; guint orig_lcp_echo_interval; GtkToggleButton *use_mppe; GtkToggleButton *mppe_require_128; GtkToggleButton *use_mppe_stateful; GtkToggleButton *allow_bsdcomp; GtkToggleButton *allow_deflate; GtkToggleButton *use_vj_comp; GtkToggleButton *send_ppp_echo; GtkWindowGroup *window_group; gboolean window_added; char *connection_id; } CEPagePppPrivate; static void ppp_private_init (CEPagePpp *self) { CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); GtkBuilder *builder; builder = CE_PAGE (self)->builder; priv->auth_methods_label = GTK_LABEL (gtk_builder_get_object (builder, "auth_methods_label")); priv->auth_methods_button = GTK_BUTTON (gtk_builder_get_object (builder, "auth_methods_button")); priv->use_mppe = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ppp_use_mppe")); priv->mppe_require_128 = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ppp_require_mppe_128")); priv->use_mppe_stateful = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ppp_use_stateful_mppe")); priv->allow_bsdcomp = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ppp_allow_bsdcomp")); priv->allow_deflate = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ppp_allow_deflate")); priv->use_vj_comp = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ppp_usevj")); priv->send_ppp_echo = GTK_TOGGLE_BUTTON (gtk_builder_get_object (builder, "ppp_send_echo_packets")); } static void use_mppe_toggled_cb (GtkToggleButton *widget, CEPagePpp *self) { CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); if (gtk_toggle_button_get_active (widget)) { gtk_widget_set_sensitive (GTK_WIDGET (priv->mppe_require_128), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (priv->use_mppe_stateful), TRUE); } else { gtk_widget_set_sensitive (GTK_WIDGET (priv->mppe_require_128), FALSE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->mppe_require_128), FALSE); gtk_widget_set_sensitive (GTK_WIDGET (priv->use_mppe_stateful), FALSE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->use_mppe_stateful), FALSE); } ce_page_changed (CE_PAGE (self)); } static void add_one_auth_method (GString *string, const char *name, gboolean allowed) { if (allowed) { if (string->len) g_string_append (string, ", "); g_string_append (string, name); } } static void update_auth_methods_list (CEPagePpp *self) { CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); GString *list; list = g_string_new (""); add_one_auth_method (list, _("EAP"), !priv->refuse_eap); add_one_auth_method (list, _("PAP"), !priv->refuse_pap); add_one_auth_method (list, _("CHAP"), !priv->refuse_chap); add_one_auth_method (list, _("MSCHAPv2"), !priv->refuse_mschapv2); add_one_auth_method (list, _("MSCHAP"), !priv->refuse_mschap); /* Translators: "none" refers to authentication methods */ gtk_label_set_text (priv->auth_methods_label, list->len ? list->str : _("none")); g_string_free (list, TRUE); } static void auth_methods_dialog_close_cb (GtkWidget *dialog, gpointer user_data) { gtk_widget_hide (dialog); /* gtk_widget_destroy() will remove the window from the window group */ gtk_widget_destroy (dialog); } static void auth_methods_dialog_response_cb (GtkWidget *dialog, gint response, gpointer user_data) { CEPagePpp *self = CE_PAGE_PPP (user_data); CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); if (response == GTK_RESPONSE_OK) { ppp_auth_methods_dialog_get_methods (dialog, &priv->refuse_eap, &priv->refuse_pap, &priv->refuse_chap, &priv->refuse_mschap, &priv->refuse_mschapv2); ce_page_changed (CE_PAGE (self)); update_auth_methods_list (self); } auth_methods_dialog_close_cb (dialog, NULL); } static void auth_methods_button_clicked_cb (GtkWidget *button, gpointer user_data) { CEPagePpp *self = CE_PAGE_PPP (user_data); CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); GtkWidget *dialog, *toplevel; char *tmp; toplevel = gtk_widget_get_toplevel (CE_PAGE (self)->page); g_return_if_fail (gtk_widget_is_toplevel (toplevel)); dialog = ppp_auth_methods_dialog_new (priv->refuse_eap, priv->refuse_pap, priv->refuse_chap, priv->refuse_mschap, priv->refuse_mschapv2); if (!dialog) { g_warning ("%s: failed to create the PPP authentication methods dialog!", __func__); return; } gtk_window_group_add_window (priv->window_group, GTK_WINDOW (dialog)); if (!priv->window_added) { gtk_window_group_add_window (priv->window_group, GTK_WINDOW (toplevel)); priv->window_added = TRUE; } gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (toplevel)); tmp = g_strdup_printf (_("Editing PPP authentication methods for %s"), priv->connection_id); gtk_window_set_title (GTK_WINDOW (dialog), tmp); g_free (tmp); g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (auth_methods_dialog_response_cb), self); gtk_widget_show_all (dialog); } static void populate_ui (CEPagePpp *self, NMConnection *connection) { CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); NMSettingPpp *setting = priv->setting; gboolean require_mppe, require_mppe_128, mppe_stateful, nobsdcomp, nodeflate, no_vj_comp; g_object_get (setting, NM_SETTING_PPP_REFUSE_PAP, &priv->refuse_pap, NM_SETTING_PPP_REFUSE_CHAP, &priv->refuse_chap, NM_SETTING_PPP_REFUSE_MSCHAPV2, &priv->refuse_mschapv2, NM_SETTING_PPP_REFUSE_MSCHAP, &priv->refuse_mschap, NM_SETTING_PPP_REFUSE_EAP, &priv->refuse_eap, NM_SETTING_PPP_REQUIRE_MPPE, &require_mppe, NM_SETTING_PPP_REQUIRE_MPPE_128, &require_mppe_128, NM_SETTING_PPP_MPPE_STATEFUL, &mppe_stateful, NM_SETTING_PPP_NOBSDCOMP, &nobsdcomp, NM_SETTING_PPP_NODEFLATE, &nodeflate, NM_SETTING_PPP_NO_VJ_COMP, &no_vj_comp, NM_SETTING_PPP_LCP_ECHO_INTERVAL, &priv->orig_lcp_echo_interval, NM_SETTING_PPP_LCP_ECHO_FAILURE, &priv->orig_lcp_echo_failure, NULL); update_auth_methods_list (self); g_signal_connect (priv->auth_methods_button, "clicked", G_CALLBACK (auth_methods_button_clicked_cb), self); gtk_toggle_button_set_active (priv->use_mppe, require_mppe); g_signal_connect (priv->use_mppe, "toggled", G_CALLBACK (use_mppe_toggled_cb), self); use_mppe_toggled_cb (priv->use_mppe, self); gtk_toggle_button_set_active (priv->mppe_require_128, require_mppe_128); g_signal_connect_swapped (priv->mppe_require_128, "toggled", G_CALLBACK (ce_page_changed), self); gtk_toggle_button_set_active (priv->use_mppe_stateful, mppe_stateful); g_signal_connect_swapped (priv->use_mppe_stateful, "toggled", G_CALLBACK (ce_page_changed), self); gtk_toggle_button_set_active (priv->allow_bsdcomp, !nobsdcomp); g_signal_connect_swapped (priv->allow_bsdcomp, "toggled", G_CALLBACK (ce_page_changed), self); gtk_toggle_button_set_active (priv->allow_deflate, !nodeflate); g_signal_connect_swapped (priv->allow_deflate, "toggled", G_CALLBACK (ce_page_changed), self); gtk_toggle_button_set_active (priv->use_vj_comp, !no_vj_comp); g_signal_connect_swapped (priv->use_vj_comp, "toggled", G_CALLBACK (ce_page_changed), self); gtk_toggle_button_set_active (priv->send_ppp_echo, (priv->orig_lcp_echo_interval > 0) ? TRUE : FALSE); g_signal_connect_swapped (priv->send_ppp_echo, "toggled", G_CALLBACK (ce_page_changed), self); } static void finish_setup (CEPagePpp *self, gpointer user_data) { populate_ui (self, CE_PAGE (self)->connection); } CEPage * ce_page_ppp_new (NMConnectionEditor *editor, NMConnection *connection, GtkWindow *parent_window, NMClient *client, const char **out_secrets_setting_name, GError **error) { CEPagePpp *self; CEPagePppPrivate *priv; NMSettingConnection *s_con; self = CE_PAGE_PPP (ce_page_new (CE_TYPE_PAGE_PPP, editor, connection, parent_window, client, "/org/gnome/nm_connection_editor/ce-page-ppp.ui", "PppPage", _("PPP Settings"))); if (!self) { g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("Could not load PPP user interface.")); return NULL; } ppp_private_init (self); priv = CE_PAGE_PPP_GET_PRIVATE (self); priv->setting = nm_connection_get_setting_ppp (connection); if (!priv->setting) { priv->setting = NM_SETTING_PPP (nm_setting_ppp_new ()); nm_connection_add_setting (connection, NM_SETTING (priv->setting)); } priv->window_group = gtk_window_group_new (); s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); priv->connection_id = g_strdup (nm_setting_connection_get_id (s_con)); g_signal_connect (self, CE_PAGE_INITIALIZED, G_CALLBACK (finish_setup), NULL); *out_secrets_setting_name = NM_SETTING_PPP_SETTING_NAME; return CE_PAGE (self); } static void ui_to_setting (CEPagePpp *self) { CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); gboolean require_mppe; gboolean require_mppe_128; gboolean mppe_stateful; gboolean nobsdcomp; gboolean nodeflate; gboolean no_vj_comp; guint lcp_echo_failure = 0, lcp_echo_interval = 0; require_mppe = gtk_toggle_button_get_active (priv->use_mppe); require_mppe_128 = gtk_toggle_button_get_active (priv->mppe_require_128); mppe_stateful = gtk_toggle_button_get_active (priv->use_mppe_stateful); nobsdcomp = !gtk_toggle_button_get_active (priv->allow_bsdcomp); nodeflate = !gtk_toggle_button_get_active (priv->allow_deflate); no_vj_comp = !gtk_toggle_button_get_active (priv->use_vj_comp); if (gtk_toggle_button_get_active (priv->send_ppp_echo)) { if (priv->orig_lcp_echo_failure && priv->orig_lcp_echo_interval) { lcp_echo_failure = priv->orig_lcp_echo_failure; lcp_echo_interval = priv->orig_lcp_echo_interval; } else { /* Set defaults */ lcp_echo_failure = 5; lcp_echo_interval = 30; } } g_object_set (priv->setting, NM_SETTING_PPP_REFUSE_EAP, priv->refuse_eap, NM_SETTING_PPP_REFUSE_PAP, priv->refuse_pap, NM_SETTING_PPP_REFUSE_CHAP, priv->refuse_chap, NM_SETTING_PPP_REFUSE_MSCHAP, priv->refuse_mschap, NM_SETTING_PPP_REFUSE_MSCHAPV2, priv->refuse_mschapv2, NM_SETTING_PPP_NOBSDCOMP, nobsdcomp, NM_SETTING_PPP_NODEFLATE, nodeflate, NM_SETTING_PPP_NO_VJ_COMP, no_vj_comp, NM_SETTING_PPP_REQUIRE_MPPE, require_mppe, NM_SETTING_PPP_REQUIRE_MPPE_128, require_mppe_128, NM_SETTING_PPP_MPPE_STATEFUL, mppe_stateful, NM_SETTING_PPP_LCP_ECHO_FAILURE, lcp_echo_failure, NM_SETTING_PPP_LCP_ECHO_INTERVAL, lcp_echo_interval, NULL); } static gboolean ce_page_validate_v (CEPage *page, NMConnection *connection, GError **error) { CEPagePpp *self = CE_PAGE_PPP (page); CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (self); ui_to_setting (self); return nm_setting_verify (NM_SETTING (priv->setting), NULL, error); } static void ce_page_ppp_init (CEPagePpp *self) { } static void dispose (GObject *object) { CEPagePppPrivate *priv = CE_PAGE_PPP_GET_PRIVATE (object); g_clear_object (&priv->window_group); g_clear_pointer (&priv->connection_id, g_free); G_OBJECT_CLASS (ce_page_ppp_parent_class)->dispose (object); } static void ce_page_ppp_class_init (CEPagePppClass *ppp_class) { GObjectClass *object_class = G_OBJECT_CLASS (ppp_class); CEPageClass *parent_class = CE_PAGE_CLASS (ppp_class); g_type_class_add_private (object_class, sizeof (CEPagePppPrivate)); /* virtual methods */ parent_class->ce_page_validate_v = ce_page_validate_v; object_class->dispose = dispose; }