Compare commits

...

13 Commits

Author SHA1 Message Date
Matthias Clasen
aee2cc08f7 network: Implement the new design for wired
This expands the connection editor to cover ethernet,
and adds support for multiple wired profiles.
2012-12-21 21:57:31 -05:00
Matthias Clasen
ea55585aa2 network: Implement the "Reset" button in the connection editor
For now, this has the same effect as canceling and reopening the
dialog. Maybe something else is desired here, but I don't know
where those defaults should come from.
2012-12-14 22:50:57 -05:00
Matthias Clasen
faca283628 network: Listen for permission changes
Also, add a net_connection_editor_run() function to match the
NMConnectionEditor api.
2012-12-14 22:42:34 -05:00
Matthias Clasen
b4b3315d82 Implement the 'Forget' button in the connection-editor 2012-12-14 20:37:13 -05:00
Matthias Clasen
099523b980 network: break out the details dialog
This code is fairly independent of the rest, and we don't want
net-device-wifi.c to become too massive and unmaintainable.

The code in connection-editor/ is fairly similar to
nm-connection-editor, with some simplification because we
currently only edit wireless connections.

The code in wireless-security/ is almost a straight copy
of the same code in nm-connection-editor, with some changes
to the .ui files to make them fit better in the new design.
2012-12-14 19:41:34 -05:00
Matthias Clasen
ccb35a6447 network: Remove more dead code
These callbacks were used by buttons on the now-removed
details tab.
2012-12-09 22:25:56 -05:00
Matthias Clasen
f738cae8cb network: Fix hotspot switch getting out of sync
When the user switches the hotspot switch off, we present a
confirmation dialog which can be canceled. We do keep the
hotspot running in that case, but we forget to set the switch
back to 'on'. Fix that.
2012-12-09 20:41:43 -05:00
Matthias Clasen
63b37d2dc2 network: Remove unused tabs
The details and hidden tabs are never used in the code, so
get rid of them.
2012-12-09 20:01:09 -05:00
Matthias Clasen
febb34f56d network: Turn wifi details into a popup
This is following the new network panel design. This is just
an intermediate step, we still have the 'Settings' button for
launching nm-connection-editor. Eventually, that will be replaced
by full editing support in the new popup.
2012-12-09 19:38:32 -05:00
Matthias Clasen
60abe82abd network: Add status label and icon to wifi header
This is part of the design refresh for the network panel.
2012-12-09 02:17:49 -05:00
Matthias Clasen
dc855b78e1 network: Add a spinner while connecting
This is part of the new listbox-based design for the
network panel.
2012-12-09 02:00:58 -05:00
Matthias Clasen
14b5f940e5 network: no more cell renderers
Now that the list has been converted to a listbox, we don't
need any of these anymore.
2012-12-09 01:26:03 -05:00
Matthias Clasen
5faa92a490 network: Initial listbox conversion
This commit turns the main access point list into a listbox,
and moves out-of-range connections into a History dialog.
2012-12-09 01:23:25 -05:00
92 changed files with 16937 additions and 2741 deletions

View File

@@ -491,6 +491,8 @@ panels/printers/gnome-printers-panel.desktop.in
panels/privacy/Makefile
panels/privacy/gnome-privacy-panel.desktop.in
panels/network/Makefile
panels/network/wireless-security/Makefile
panels/network/connection-editor/Makefile
panels/network/gnome-network-panel.desktop.in
panels/universal-access/Makefile
panels/universal-access/gnome-universal-access-panel.desktop.in

View File

@@ -1,5 +1,7 @@
cappletname = network
SUBDIRS = wireless-security connection-editor
INCLUDES = \
$(PANEL_CFLAGS) \
$(NETWORK_PANEL_CFLAGS) \
@@ -7,6 +9,7 @@ INCLUDES = \
-DGNOMECC_UI_DIR="\"$(uidir)\"" \
-DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
-I$(srcdir)/wireless-security \
$(NULL)
ccpanelsdir = $(PANELS_DIR)
@@ -34,18 +37,6 @@ libnetwork_la_SOURCES = \
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 \
cc-network-panel.c \
@@ -54,7 +45,8 @@ libnetwork_la_SOURCES = \
rfkill-glib.h \
rfkill.h
libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS)
libnetwork_la_LIBADD = $(PANEL_LIBS) $(NETWORK_PANEL_LIBS) $(NETWORK_MANAGER_LIBS) $(builddir)/connection-editor/libconnection-editor.la
libnetwork_la_LDFLAGS = $(PANEL_LDFLAGS)
uidir = $(pkgdatadir)/ui
@@ -64,6 +56,7 @@ dist_ui_DATA = \
network-wifi.ui \
network-simple.ui \
network-mobile.ui \
network-ethernet.ui \
network.ui
@INTLTOOL_DESKTOP_RULE@

View File

@@ -0,0 +1,49 @@
noinst_LTLIBRARIES = libconnection-editor.la
libconnection_editor_la_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-reset.h \
ce-page-reset.c \
ce-page-ethernet.h \
ce-page-ethernet.c \
ce-page-8021x-security.h \
ce-page-8021x-security.c
libconnection_editor_la_CPPFLAGS = \
-I$(srcdir)/../wireless-security \
$(NETWORK_PANEL_CFLAGS) \
$(NETWORK_MANAGER_CFLAGS) \
-DGNOMECC_UI_DIR=\""$(uidir)"\"
libconnection_editor_la_LIBADD = \
$(builddir)/../wireless-security/libwireless-security.la \
$(NETWORK_PANEL_LIBS) \
$(NETWORK_MANAGER_LIBS)
uidir = $(pkgdatadir)/ui
ui_DATA = \
connection-editor.ui \
details-page.ui \
wifi-page.ui \
ip4-page.ui \
ip6-page.ui \
reset-page.ui \
security-page.ui \
ethernet-page.ui
EXTRA_DIST = \
$(ui_DATA)

View File

@@ -0,0 +1,188 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Connection editor -- Connection editor for NetworkManager
*
* Dan Williams <dcbw@redhat.com>
*
* 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 <string.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <NetworkManager.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
#include <nm-setting-8021x.h>
#include <nm-setting-wireless.h>
#include <nm-utils.h>
#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 (GtkToggleButton *button, gpointer user_data)
{
CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (user_data);
gtk_widget_set_sensitive (page->security_widget, gtk_toggle_button_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 *self, gpointer unused, GError *error, gpointer user_data)
{
GtkWidget *parent;
if (error)
return;
self->security = (WirelessSecurity *) ws_wpa_eap_new (CE_PAGE (self)->connection, TRUE, FALSE);
if (!self->security) {
g_warning ("Could not load 802.1x user interface.");
return;
}
wireless_security_set_changed_notify (self->security, stuff_changed, self);
self->security_widget = wireless_security_get_widget (self->security);
parent = gtk_widget_get_parent (self->security_widget);
if (parent)
gtk_container_remove (GTK_CONTAINER (parent), self->security_widget);
gtk_toggle_button_set_active (self->enabled, self->initial_have_8021x);
g_signal_connect (self->enabled, "toggled", G_CALLBACK (enable_toggled), self);
gtk_widget_set_sensitive (self->security_widget, self->initial_have_8021x);
gtk_box_pack_start (GTK_BOX (CE_PAGE (self)->page), GTK_WIDGET (self->enabled), FALSE, TRUE, 12);
gtk_box_pack_start (GTK_BOX (CE_PAGE (self)->page), self->security_widget, TRUE, TRUE, 0);
gtk_widget_show_all (CE_PAGE (self)->page);
}
CEPage *
ce_page_8021x_security_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings)
{
CEPage8021xSecurity *self;
self = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY,
connection,
client,
settings,
NULL,
_("Security")));
CE_PAGE (self)->page = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
g_object_ref_sink (G_OBJECT (CE_PAGE (self)->page));
gtk_container_set_border_width (GTK_CONTAINER (CE_PAGE (self)->page), 6);
if (nm_connection_get_setting_802_1x (connection))
self->initial_have_8021x = TRUE;
self->enabled = GTK_TOGGLE_BUTTON (gtk_check_button_new_with_mnemonic (_("Use 802.1_X security for this connection")));
g_signal_connect (self, "initialized", G_CALLBACK (finish_setup), NULL);
if (self->initial_have_8021x)
CE_PAGE (self)->security_setting = NM_SETTING_802_1X_SETTING_NAME;
return CE_PAGE (self);
}
static gboolean
validate (CEPage *page, NMConnection *connection, GError **error)
{
CEPage8021xSecurity *self = CE_PAGE_8021X_SECURITY (page);
gboolean valid = TRUE;
if (gtk_toggle_button_get_active (self->enabled)) {
NMConnection *tmp_connection;
NMSetting *s_8021x;
/* FIXME: get failed property and error out of wireless security objects */
valid = wireless_security_validate (self->security, NULL);
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_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 (self->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
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Invalid 802.1x security");
} else {
nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
valid = TRUE;
}
return valid;
}
static void
ce_page_8021x_security_init (CEPage8021xSecurity *self)
{
}
static void
dispose (GObject *object)
{
CEPage8021xSecurity *self = CE_PAGE_8021X_SECURITY (object);
if (self->security) {
wireless_security_unref (self->security);
self->security = NULL;
}
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;
}

View File

@@ -0,0 +1,64 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Connection editor -- Connection editor for NetworkManager
*
* Dan Williams <dcbw@redhat.com>
*
* 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 <nm-connection.h>
#include "wireless-security.h"
#include <glib.h>
#include <glib-object.h>
#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;
GtkToggleButton *enabled;
GtkWidget *security_widget;
WirelessSecurity *security;
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,
NMRemoteSettings *settings);
#endif /* __CE_PAGE_8021X_SECURITY_H */

View File

@@ -0,0 +1,276 @@
/* -*- 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 <glib-object.h>
#include <glib/gi18n.h>
#include <nm-utils.h>
#include <nm-device-wifi.h>
#include <nm-device-ethernet.h>
#include "../panel-common.h"
#include "ce-page-details.h"
G_DEFINE_TYPE (CEPageDetails, ce_page_details, CE_TYPE_PAGE)
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 (GObject *sw, GParamSpec *pspec, CEPageDetails *page)
{
gboolean all_users;
NMSettingConnection *sc;
sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
all_users = gtk_switch_get_active (GTK_SWITCH (sw));
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)
{
GtkWidget *widget;
NMSettingConnection *sc;
guint speed;
guint strength;
NMDeviceState state;
NMAccessPoint *active_ap;
const gchar *str;
gboolean device_is_active;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
"auto_connect_switch"));
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);
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
"all_user_switch"));
gtk_switch_set_active (GTK_SWITCH (widget),
nm_setting_connection_get_num_permissions (sc) == 0);
g_signal_connect (widget, "notify::active",
G_CALLBACK (all_user_changed), page);
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 = nm_device_get_state (page->device);
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 {
NMActiveConnection *ac;
const gchar *p1, *p2;
ac = nm_device_get_active_connection (page->device);
p1 = ac ? nm_active_connection_get_connection (ac) : NULL;
p2 = nm_connection_get_path (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);
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);
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);
}
static gboolean
validate (CEPage *page,
NMConnection *connection,
GError **error)
{
return TRUE;
}
static void
ce_page_details_init (CEPageDetails *page)
{
}
static void
ce_page_details_class_init (CEPageDetailsClass *class)
{
CEPageClass *page_class= CE_PAGE_CLASS (class);
page_class->validate = validate;
}
CEPage *
ce_page_details_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings,
NMDevice *device,
NMAccessPoint *ap)
{
CEPageDetails *page;
page = CE_PAGE_DETAILS (ce_page_new (CE_TYPE_PAGE_DETAILS,
connection,
client,
settings,
GNOMECC_UI_DIR "/details-page.ui",
_("Details")));
page->device = device;
page->ap = ap;
connect_details_page (page);
return CE_PAGE (page);
}

View File

@@ -0,0 +1,66 @@
/* -*- 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 <glib-object.h>
#include <gtk/gtk.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;
};
struct _CEPageDetailsClass
{
CEPageClass parent_class;
};
GType ce_page_details_get_type (void);
CEPage *ce_page_details_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings,
NMDevice *device,
NMAccessPoint *ap);
G_END_DECLS
#endif /* __CE_PAGE_DETAILS_H */

View File

@@ -0,0 +1,304 @@
/* -*- 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 <glib-object.h>
#include <glib/gi18n.h>
#include <nm-utils.h>
#include <nm-device-ethernet.h>
#include <net/if_arp.h>
#include "ce-page-ethernet.h"
G_DEFINE_TYPE (CEPageEthernet, ce_page_ethernet, CE_TYPE_PAGE)
enum {
PORT_DEFAULT,
PORT_TP,
PORT_AUI,
PORT_BNC,
PORT_MII
};
enum {
SPEED_DEFAULT,
SPEED_10,
SPEED_100,
SPEED_1000,
SPEED_10000
};
static void
connect_ethernet_page (CEPageEthernet *page)
{
NMSettingWired *setting = page->setting_wired;
const char *port;
const char *duplex;
int port_idx = PORT_DEFAULT;
int speed_idx;
int mtu_def;
char **mac_list;
const GByteArray *s_mac;
char *s_mac_str;
GtkWidget *widget;
const gchar *name;
name = nm_setting_connection_get_id (page->setting_connection);
gtk_entry_set_text (page->name, name);
/* Port */
port = nm_setting_wired_get_port (setting);
if (port) {
if (!strcmp (port, "tp"))
port_idx = PORT_TP;
else if (!strcmp (port, "aui"))
port_idx = PORT_AUI;
else if (!strcmp (port, "bnc"))
port_idx = PORT_BNC;
else if (!strcmp (port, "mii"))
port_idx = PORT_MII;
}
gtk_combo_box_set_active (page->port, port_idx);
/* Speed */
switch (nm_setting_wired_get_speed (setting)) {
case 10:
speed_idx = SPEED_10;
break;
case 100:
speed_idx = SPEED_100;
break;
case 1000:
speed_idx = SPEED_1000;
break;
case 10000:
speed_idx = SPEED_10000;
break;
default:
speed_idx = SPEED_DEFAULT;
break;
}
gtk_combo_box_set_active (page->speed, speed_idx);
/* Duplex */
duplex = nm_setting_wired_get_duplex (setting);
if (duplex && !strcmp (duplex, "half"))
gtk_toggle_button_set_active (page->duplex, FALSE);
else
gtk_toggle_button_set_active (page->duplex, TRUE);
/* Autonegotiate */
gtk_toggle_button_set_active (page->autonegotiate,
nm_setting_wired_get_auto_negotiate (setting));
/* 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 = nm_setting_wired_get_mac_address (setting);
s_mac_str = s_mac ? nm_utils_hwaddr_ntoa (s_mac->data, ARPHRD_ETHER) : NULL;
ce_page_setup_mac_combo (page->device_mac, s_mac_str, mac_list);
g_free (s_mac_str);
g_strfreev (mac_list);
g_signal_connect_swapped (page->device_mac, "changed", G_CALLBACK (ce_page_changed), page);
/* Cloned MAC address */
ce_page_mac_to_entry (nm_setting_wired_get_cloned_mac_address (setting),
ARPHRD_ETHER, page->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_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page);
g_signal_connect_swapped (page->port, "changed", G_CALLBACK (ce_page_changed), page);
g_signal_connect_swapped (page->speed, "changed", G_CALLBACK (ce_page_changed), page);
g_signal_connect_swapped (page->duplex, "toggled", G_CALLBACK (ce_page_changed), page);
g_signal_connect_swapped (page->autonegotiate, "toggled", G_CALLBACK (ce_page_changed), page);
g_signal_connect_swapped (page->mtu, "value-changed", G_CALLBACK (ce_page_changed), page);
/* Hide widgets we don't yet support */
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_port"));
gtk_widget_hide (widget);
gtk_widget_hide (GTK_WIDGET (page->port));
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_speed"));
gtk_widget_hide (widget);
gtk_widget_hide (GTK_WIDGET (page->speed));
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "check_duplex"));
gtk_widget_hide (widget);
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "check_renegotiate"));
gtk_widget_hide (widget);
}
static void
ui_to_setting (CEPageEthernet *page)
{
const char *port;
guint32 speed;
GByteArray *device_mac = NULL;
GByteArray *cloned_mac = NULL;
GtkWidget *entry;
/* Port */
switch (gtk_combo_box_get_active (page->port)) {
case PORT_TP:
port = "tp";
break;
case PORT_AUI:
port = "aui";
break;
case PORT_BNC:
port = "bnc";
break;
case PORT_MII:
port = "mii";
break;
default:
port = NULL;
break;
}
/* Speed */
switch (gtk_combo_box_get_active (page->speed)) {
case SPEED_10:
speed = 10;
break;
case SPEED_100:
speed = 100;
break;
case SPEED_1000:
speed = 1000;
break;
case SPEED_10000:
speed = 10000;
break;
default:
speed = 0;
break;
}
entry = gtk_bin_get_child (GTK_BIN (page->device_mac));
if (entry)
device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
cloned_mac = ce_page_entry_to_mac (page->cloned_mac, ARPHRD_ETHER, NULL);
g_object_set (page->setting_wired,
NM_SETTING_WIRED_MAC_ADDRESS, device_mac,
NM_SETTING_WIRED_CLONED_MAC_ADDRESS, cloned_mac,
NM_SETTING_WIRED_PORT, port,
NM_SETTING_WIRED_SPEED, speed,
NM_SETTING_WIRED_DUPLEX, gtk_toggle_button_get_active (page->duplex) ? "full" : "half",
NM_SETTING_WIRED_AUTO_NEGOTIATE, gtk_toggle_button_get_active (page->autonegotiate),
NM_SETTING_WIRED_MTU, (guint32) gtk_spin_button_get_value_as_int (page->mtu),
NULL);
if (device_mac)
g_byte_array_free (device_mac, TRUE);
if (cloned_mac)
g_byte_array_free (cloned_mac, TRUE);
g_object_set (page->setting_connection,
NM_SETTING_CONNECTION_ID, gtk_entry_get_text (page->name),
NULL);
}
static gboolean
validate (CEPage *page,
NMConnection *connection,
GError **error)
{
CEPageEthernet *self = CE_PAGE_ETHERNET (page);
gboolean invalid = FALSE;
GByteArray *ignore;
GtkWidget *entry;
entry = gtk_bin_get_child (GTK_BIN (self->device_mac));
if (entry) {
ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
if (invalid)
return FALSE;
if (ignore)
g_byte_array_free (ignore, TRUE);
}
ignore = ce_page_entry_to_mac (self->cloned_mac, ARPHRD_ETHER, &invalid);
if (invalid)
return FALSE;
if (ignore)
g_byte_array_free (ignore, TRUE);
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,
NMRemoteSettings *settings)
{
CEPageEthernet *page;
page = CE_PAGE_ETHERNET (ce_page_new (CE_TYPE_PAGE_ETHERNET,
connection,
client,
settings,
GNOMECC_UI_DIR "/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->port = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_port"));
page->speed = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_speed"));
page->duplex = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "check_duplex"));
page->autonegotiate = GTK_TOGGLE_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "check_renegotiate"));
page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_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);
}

View File

@@ -0,0 +1,75 @@
/* -*- 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 <glib-object.h>
#include <nm-setting-wired.h>
#include <gtk/gtk.h>
#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;
GtkComboBox *port;
GtkComboBox *speed;
GtkToggleButton *duplex;
GtkToggleButton *autonegotiate;
GtkSpinButton *mtu;
};
struct _CEPageEthernetClass
{
CEPageClass parent_class;
};
GType ce_page_ethernet_get_type (void);
CEPage *ce_page_ethernet_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* __CE_PAGE_ETHERNET_H */

View File

@@ -0,0 +1,905 @@
/* -*- 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 <errno.h>
#include <stdlib.h>
#include <glib-object.h>
#include <glib/gi18n.h>
#include "ce-page-ip4.h"
#include <nm-utils.h>
#include "egg-list-box/egg-list-box.h"
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 (GtkComboBox *combo, CEPageIP4 *page)
{
gboolean addr_enabled;
gboolean dns_enabled;
gboolean routes_enabled;
guint method;
method = gtk_combo_box_get_active (combo);
switch (method) {
case IP4_METHOD_AUTO:
addr_enabled = FALSE;
dns_enabled = TRUE;
routes_enabled = TRUE;
break;
case IP4_METHOD_MANUAL:
addr_enabled = TRUE;
dns_enabled = TRUE;
routes_enabled = TRUE;
break;
case IP4_METHOD_LINK_LOCAL:
default:
addr_enabled = FALSE;
dns_enabled = FALSE;
routes_enabled = FALSE;
break;
}
gtk_widget_set_sensitive (page->address_list, addr_enabled);
gtk_widget_set_sensitive (page->dns_list, 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
update_separator (GtkWidget **separator,
GtkWidget *child,
GtkWidget *before,
gpointer user_data)
{
if (before == NULL)
return;
if (*separator == NULL)
{
*separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_show (*separator);
g_object_ref_sink (*separator);
}
}
static void
remove_row (GtkButton *button, CEPageIP4 *page)
{
GtkWidget *row;
GtkWidget *list;
row = gtk_widget_get_parent (GTK_WIDGET (button));
list = gtk_widget_get_parent (row);
gtk_container_remove (GTK_CONTAINER (list), row);
ce_page_changed (CE_PAGE (page));
}
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)
{
GtkWidget *row;
GtkWidget *widget;
GtkWidget *delete_button;
GtkWidget *image;
row = gtk_grid_new ();
widget = gtk_label_new (_("Address"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
widget = gtk_label_new (_("Netmask"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
widget = gtk_label_new (_("Gateway"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "address", widget);
gtk_entry_set_text (GTK_ENTRY (widget), address);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "network", widget);
gtk_entry_set_text (GTK_ENTRY (widget), network);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "gateway", widget);
gtk_entry_set_text (GTK_ENTRY (widget), gateway);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
delete_button = gtk_button_new ();
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (delete_button), image);
gtk_grid_attach (GTK_GRID (row), delete_button, 3, 2, 1, 1);
gtk_widget_set_margin_left (row, 10);
gtk_widget_set_margin_right (row, 10);
gtk_widget_set_margin_top (row, 10);
gtk_widget_set_margin_bottom (row, 10);
gtk_widget_set_halign (row, GTK_ALIGN_FILL);
gtk_widget_show_all (row);
gtk_container_add (GTK_CONTAINER (page->address_list), row);
}
static void
add_empty_address_row (CEPageIP4 *page)
{
add_address_row (page, "", "", "");
}
static void
add_address_section (CEPageIP4 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
GtkWidget *row;
GtkWidget *button;
GtkWidget *image;
gint i;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (widget), frame);
page->address_list = list = GTK_WIDGET (egg_list_box_new ());
egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
gtk_container_add (GTK_CONTAINER (frame), list);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "last", GINT_TO_POINTER (TRUE));
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_empty_address_row), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_margin_top (button, 10);
gtk_widget_set_margin_bottom (button, 10);
gtk_widget_set_margin_left (button, 10);
gtk_widget_set_margin_right (button, 10);
gtk_widget_set_halign (button, GTK_ALIGN_END);
gtk_box_pack_start (GTK_BOX (row), button, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
gtk_widget_show_all (frame);
for (i = 0; i < nm_setting_ip4_config_get_num_addresses (page->setting); i++) {
NMIP4Address *addr;
struct in_addr tmp_addr;
gchar address[INET_ADDRSTRLEN + 1];
gchar network[INET_ADDRSTRLEN + 1];
gchar gateway[INET_ADDRSTRLEN + 1];
addr = nm_setting_ip4_config_get_address (page->setting, i);
if (!addr)
continue;
tmp_addr.s_addr = nm_ip4_address_get_address (addr);
(void) inet_ntop (AF_INET, &tmp_addr, &address[0], sizeof (address));
tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_address_get_prefix (addr));
(void) inet_ntop (AF_INET, &tmp_addr, &network[0], sizeof (network));
tmp_addr.s_addr = nm_ip4_address_get_gateway (addr);
(void) inet_ntop (AF_INET, &tmp_addr, &gateway[0], sizeof (gateway));
add_address_row (page, address, network, gateway);
}
if (nm_setting_ip4_config_get_num_addresses (page->setting) == 0)
add_empty_address_row (page);
}
static void
add_dns_row (CEPageIP4 *page,
const gchar *address)
{
GtkWidget *row;
GtkWidget *widget;
GtkWidget *delete_button;
GtkWidget *image;
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
widget = gtk_label_new (_("Address"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "address", widget);
gtk_entry_set_text (GTK_ENTRY (widget), address);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
delete_button = gtk_button_new ();
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (delete_button), image);
gtk_box_pack_start (GTK_BOX (row), delete_button, FALSE, FALSE, 0);
gtk_widget_set_margin_left (row, 10);
gtk_widget_set_margin_right (row, 10);
gtk_widget_set_margin_top (row, 10);
gtk_widget_set_margin_bottom (row, 10);
gtk_widget_set_halign (row, GTK_ALIGN_FILL);
gtk_widget_show_all (row);
gtk_container_add (GTK_CONTAINER (page->dns_list), row);
}
static void
add_empty_dns_row (CEPageIP4 *page)
{
add_dns_row (page, "");
}
static void
add_dns_section (CEPageIP4 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
GtkWidget *row;
GtkWidget *button;
GtkWidget *image;
gint i;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_section"));
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (widget), frame);
page->dns_list = list = GTK_WIDGET (egg_list_box_new ());
egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
gtk_container_add (GTK_CONTAINER (frame), list);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "first", GINT_TO_POINTER (TRUE));
widget = gtk_label_new (_("Automatic"));
gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
widget = gtk_switch_new ();
page->auto_dns = GTK_SWITCH (widget);
gtk_switch_set_active (page->auto_dns, !nm_setting_ip4_config_get_ignore_auto_dns (page->setting));
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_END);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "last", GINT_TO_POINTER (TRUE));
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_empty_dns_row), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_margin_top (button, 10);
gtk_widget_set_margin_bottom (button, 10);
gtk_widget_set_margin_left (button, 10);
gtk_widget_set_margin_right (button, 10);
gtk_widget_set_halign (button, GTK_ALIGN_END);
gtk_box_pack_start (GTK_BOX (row), button, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
gtk_widget_show_all (frame);
for (i = 0; i < nm_setting_ip4_config_get_num_dns (page->setting); i++) {
struct in_addr tmp_addr;
gchar address[INET_ADDRSTRLEN + 1];
tmp_addr.s_addr = nm_setting_ip4_config_get_dns (page->setting, i);
(void) inet_ntop (AF_INET, &tmp_addr, &address[0], sizeof (address));
add_dns_row (page, address);
}
if (nm_setting_ip4_config_get_num_dns (page->setting) == 0)
add_empty_dns_row (page);
}
static void
add_route_row (CEPageIP4 *page,
const gchar *address,
const gchar *netmask,
const gchar *gateway,
gint metric)
{
GtkWidget *row;
GtkWidget *widget;
GtkWidget *delete_button;
GtkWidget *image;
row = gtk_grid_new ();
widget = gtk_label_new (_("Address"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
widget = gtk_label_new (_("Netmask"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
widget = gtk_label_new (_("Gateway"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
widget = gtk_label_new (_("Metric"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 4, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "address", widget);
gtk_entry_set_text (GTK_ENTRY (widget), address);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "netmask", widget);
gtk_entry_set_text (GTK_ENTRY (widget), netmask);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "gateway", widget);
gtk_entry_set_text (GTK_ENTRY (widget), gateway);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), 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_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 4, 1, 1);
delete_button = gtk_button_new ();
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
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_grid_attach (GTK_GRID (row), delete_button, 3, 1, 1, 4);
gtk_widget_set_margin_left (row, 10);
gtk_widget_set_margin_right (row, 10);
gtk_widget_set_margin_top (row, 10);
gtk_widget_set_margin_bottom (row, 10);
gtk_widget_set_halign (row, GTK_ALIGN_FILL);
gtk_widget_show_all (row);
gtk_container_add (GTK_CONTAINER (page->routes_list), row);
}
static void
add_empty_route_row (CEPageIP4 *page)
{
add_route_row (page, "", "", "", 0);
}
static void
add_routes_section (CEPageIP4 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
GtkWidget *row;
GtkWidget *button;
GtkWidget *image;
gint i;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (widget), frame);
page->routes_list = list = GTK_WIDGET (egg_list_box_new ());
egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
gtk_container_add (GTK_CONTAINER (frame), list);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "first", GINT_TO_POINTER (TRUE));
widget = gtk_label_new (_("Automatic"));
gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
widget = gtk_switch_new ();
page->auto_routes = GTK_SWITCH (widget);
gtk_switch_set_active (GTK_SWITCH (widget), !nm_setting_ip4_config_get_ignore_auto_routes (page->setting));
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_END);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "last", GINT_TO_POINTER (TRUE));
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_empty_route_row), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_margin_top (button, 10);
gtk_widget_set_margin_bottom (button, 10);
gtk_widget_set_margin_left (button, 10);
gtk_widget_set_margin_right (button, 10);
gtk_widget_set_halign (button, GTK_ALIGN_END);
gtk_box_pack_start (GTK_BOX (row), button, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
gtk_widget_show_all (frame);
for (i = 0; i < nm_setting_ip4_config_get_num_routes (page->setting); i++) {
NMIP4Route *route;
struct in_addr tmp_addr;
gchar address[INET_ADDRSTRLEN + 1];
gchar netmask[INET_ADDRSTRLEN + 1];
gchar gateway[INET_ADDRSTRLEN + 1];
gint metric;
route = nm_setting_ip4_config_get_route (page->setting, i);
if (!route)
continue;
tmp_addr.s_addr = nm_ip4_route_get_dest (route);
(void) inet_ntop (AF_INET, &tmp_addr, &address[0], sizeof (address));
tmp_addr.s_addr = nm_utils_ip4_prefix_to_netmask (nm_ip4_route_get_prefix (route));
(void) inet_ntop (AF_INET, &tmp_addr, &netmask[0], sizeof (netmask));
tmp_addr.s_addr = nm_ip4_route_get_next_hop (route);
(void) inet_ntop (AF_INET, &tmp_addr, &gateway[0], sizeof (gateway));
metric = nm_ip4_route_get_metric (route);
add_route_row (page, address, netmask, gateway, metric);
}
if (nm_setting_ip4_config_get_num_routes (page->setting) == 0)
add_empty_route_row (page);
}
static void
free_addr (gpointer addr)
{
g_array_free ((GArray *)addr, TRUE);
}
static void
connect_ip4_page (CEPageIP4 *page)
{
GtkWidget *content;
const gchar *str_method;
gboolean disabled;
GtkListStore *store;
GtkTreeIter iter;
guint method;
add_address_section (page);
add_dns_section (page);
add_routes_section (page);
page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "switch_enable"));
str_method = nm_setting_ip4_config_get_method (page->setting);
disabled = g_strcmp0 (str_method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0;
gtk_switch_set_active (page->enabled, !disabled);
g_signal_connect_swapped (page->enabled, "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->enabled, "active",
content, "sensitive",
G_BINDING_SYNC_CREATE);
page->method = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_addresses"));
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT);
gtk_list_store_insert_with_values (store, &iter, -1,
METHOD_COL_NAME, _("Automatic (DHCP)"),
METHOD_COL_METHOD, IP4_METHOD_AUTO,
-1);
gtk_list_store_insert_with_values (store, &iter, -1,
METHOD_COL_NAME, _("Manual"),
METHOD_COL_METHOD, IP4_METHOD_MANUAL,
-1);
gtk_list_store_insert_with_values (store, &iter, -1,
METHOD_COL_NAME, _("Link-Local Only"),
METHOD_COL_METHOD, IP4_METHOD_LINK_LOCAL,
-1);
gtk_combo_box_set_model (page->method, GTK_TREE_MODEL (store));
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_ip4_config_get_never_default (page->setting));
g_signal_connect (page->method, "changed", G_CALLBACK (method_changed), page);
if (method != IP4_METHOD_SHARED && method != IP4_METHOD_DISABLED)
gtk_combo_box_set_active (page->method, method);
}
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)
{
gboolean valid = FALSE;
const gchar *method;
gboolean ignore_auto_dns;
gboolean ignore_auto_routes;
gboolean never_default;
GPtrArray *addresses = NULL;
GArray *dns_servers = NULL;
GPtrArray *routes = NULL;
GList *children, *l;
if (!gtk_switch_get_active (page->enabled)) {
method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
} else {
switch (gtk_combo_box_get_active (page->method)) {
case IP4_METHOD_MANUAL:
method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
break;
case IP4_METHOD_LINK_LOCAL:
method = NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL;
break;
default:
case IP4_METHOD_AUTO:
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
break;
}
}
addresses = g_ptr_array_new_with_free_func (free_addr);
children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
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;
struct in_addr tmp_addr;
struct in_addr tmp_gateway = { 0 };
guint32 prefix;
guint32 empty_val = 0;
GArray *addr;
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")));
text_gateway = gtk_entry_get_text (GTK_ENTRY (g_object_get_data (G_OBJECT (row), "gateway")));
if (!*text_address && !*text_netmask && !*text_gateway) {
/* ignore empty rows */
continue;
}
if (inet_pton (AF_INET, text_address, &tmp_addr) <= 0) {
g_warning ("IPv4 address %s missing or invalid", text_address);
goto out;
}
if (!parse_netmask (text_netmask, &prefix)) {
g_warning ("IPv4 prefix %s is invalid", text_netmask);
goto out;
}
if (text_gateway && inet_pton (AF_INET, text_gateway, &tmp_gateway) <= 0) {
g_warning ("IPv4 gateway %s is invalid", text_gateway);
goto out;
}
addr = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
g_array_append_val (addr, tmp_addr.s_addr);
g_array_append_val (addr, prefix);
if (tmp_gateway.s_addr)
g_array_append_val (addr, tmp_gateway.s_addr);
else
g_array_append_val (addr, empty_val);
g_ptr_array_add (addresses, addr);
}
g_list_free (children);
if (addresses->len == 0) {
g_ptr_array_free (addresses, TRUE);
addresses = NULL;
}
dns_servers = g_array_new (FALSE, FALSE, sizeof (guint));
children = gtk_container_get_children (GTK_CONTAINER (page->dns_list));
for (l = children; l; l = l->next) {
GtkWidget *row = l->data;
GtkEntry *entry;
const gchar *text;
struct in_addr tmp_addr;
entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
if (!entry)
continue;
text = gtk_entry_get_text (entry);
if (!*text) {
/* ignore empty rows */
continue;
}
if (inet_pton (AF_INET, text, &tmp_addr) <= 0) {
g_warning ("IPv4 dns server %s invalid", text);
goto out;
}
g_array_append_val (dns_servers, tmp_addr.s_addr);
}
g_list_free (children);
routes = g_ptr_array_new_with_free_func (free_addr);
children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
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;
struct in_addr tmp_addr = { 0 };
guint32 address, netmask, gateway, metric;
GArray *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 (inet_pton (AF_INET, text_address, &tmp_addr) <= 0) {
g_warning ("IPv4 route address %s invalid", text_address);
goto out;
}
address = tmp_addr.s_addr;
if (!parse_netmask (text_netmask, &netmask)) {
g_warning ("IPv4 route netmask %s invalid", text_netmask);
goto out;
}
if (inet_pton (AF_INET, text_gateway, &tmp_addr) <= 0) {
g_warning ("IPv4 route gateway %s invalid", text_gateway);
goto out;
}
gateway = tmp_addr.s_addr;
metric = 0;
if (*text_metric) {
errno = 0;
metric = strtoul (text_metric, NULL, 10);
if (errno) {
g_warning ("IPv4 route metric %s invalid", text_metric);
goto out;
}
}
route = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 4);
g_array_append_val (route, address);
g_array_append_val (route, netmask);
g_array_append_val (route, gateway);
g_array_append_val (route, metric);
g_ptr_array_add (routes, route);
}
g_list_free (children);
if (routes->len == 0) {
g_ptr_array_free (routes, TRUE);
routes = NULL;
}
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_IP4_CONFIG_METHOD, method,
NM_SETTING_IP4_CONFIG_ADDRESSES, addresses,
NM_SETTING_IP4_CONFIG_DNS, dns_servers,
NM_SETTING_IP4_CONFIG_ROUTES, routes,
NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default,
NULL);
valid = TRUE;
out:
if (addresses)
g_ptr_array_free (addresses, TRUE);
if (dns_servers)
g_array_free (dns_servers, TRUE);
if (routes)
g_ptr_array_free (routes, TRUE);
return valid;
}
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,
NMRemoteSettings *settings)
{
CEPageIP4 *page;
page = CE_PAGE_IP4 (ce_page_new (CE_TYPE_PAGE_IP4,
connection,
client,
settings,
GNOMECC_UI_DIR "/ip4-page.ui",
_("IPv4")));
page->setting = nm_connection_get_setting_ip4_config (connection);
if (!page->setting) {
page->setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ());
nm_connection_add_setting (connection, NM_SETTING (page->setting));
}
connect_ip4_page (page);
return CE_PAGE (page);
}

View File

@@ -0,0 +1,72 @@
/* -*- 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 <glib-object.h>
#include <gtk/gtk.h>
#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;
NMSettingIP4Config *setting;
GtkSwitch *enabled;
GtkComboBox *method;
GtkWidget *address_list;
GtkSwitch *auto_dns;
GtkWidget *dns_list;
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,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* __CE_PAGE_IP4_H */

View File

@@ -0,0 +1,866 @@
/* -*- 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 <errno.h>
#include <stdlib.h>
#include <glib-object.h>
#include <glib/gi18n.h>
#include "ce-page-ip6.h"
#include <nm-utils.h>
#include "egg-list-box/egg-list-box.h"
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 (GtkComboBox *combo, CEPageIP6 *page)
{
gboolean addr_enabled;
gboolean dns_enabled;
gboolean routes_enabled;
guint method;
method = gtk_combo_box_get_active (combo);
switch (method) {
case IP6_METHOD_AUTO:
case IP6_METHOD_DHCP:
addr_enabled = FALSE;
dns_enabled = TRUE;
routes_enabled = TRUE;
break;
case IP6_METHOD_MANUAL:
addr_enabled = TRUE;
dns_enabled = TRUE;
routes_enabled = TRUE;
break;
case IP6_METHOD_LINK_LOCAL:
default:
addr_enabled = FALSE;
dns_enabled = FALSE;
routes_enabled = FALSE;
break;
}
gtk_widget_set_sensitive (page->address_list, addr_enabled);
gtk_widget_set_sensitive (page->dns_list, 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
update_separator (GtkWidget **separator,
GtkWidget *child,
GtkWidget *before,
gpointer user_data)
{
if (before == NULL)
return;
if (*separator == NULL)
{
*separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_show (*separator);
g_object_ref_sink (*separator);
}
}
static void
remove_row (GtkButton *button, CEPageIP6 *page)
{
GtkWidget *row;
GtkWidget *list;
row = gtk_widget_get_parent (GTK_WIDGET (button));
list = gtk_widget_get_parent (row);
gtk_container_remove (GTK_CONTAINER (list), row);
ce_page_changed (CE_PAGE (page));
}
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)
{
GtkWidget *row;
GtkWidget *widget;
GtkWidget *delete_button;
GtkWidget *image;
row = gtk_grid_new ();
widget = gtk_label_new (_("Address"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
widget = gtk_label_new (_("Prefix"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
widget = gtk_label_new (_("Gateway"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "address", widget);
gtk_entry_set_text (GTK_ENTRY (widget), address);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "prefix", widget);
gtk_entry_set_text (GTK_ENTRY (widget), network);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "gateway", widget);
gtk_entry_set_text (GTK_ENTRY (widget), gateway);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
delete_button = gtk_button_new ();
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (delete_button), image);
gtk_grid_attach (GTK_GRID (row), delete_button, 3, 2, 1, 1);
gtk_widget_set_margin_left (row, 10);
gtk_widget_set_margin_right (row, 10);
gtk_widget_set_margin_top (row, 10);
gtk_widget_set_margin_bottom (row, 10);
gtk_widget_set_halign (row, GTK_ALIGN_FILL);
gtk_widget_show_all (row);
gtk_container_add (GTK_CONTAINER (page->address_list), row);
}
static void
add_empty_address_row (CEPageIP6 *page)
{
add_address_row (page, "", "", "");
}
static void
add_address_section (CEPageIP6 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
GtkWidget *row;
GtkWidget *button;
GtkWidget *image;
gint i;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (widget), frame);
page->address_list = list = GTK_WIDGET (egg_list_box_new ());
egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
gtk_container_add (GTK_CONTAINER (frame), list);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "last", GINT_TO_POINTER (TRUE));
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_empty_address_row), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_margin_top (button, 10);
gtk_widget_set_margin_bottom (button, 10);
gtk_widget_set_margin_left (button, 10);
gtk_widget_set_margin_right (button, 10);
gtk_widget_set_halign (button, GTK_ALIGN_END);
gtk_box_pack_start (GTK_BOX (row), button, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
gtk_widget_show_all (frame);
for (i = 0; i < nm_setting_ip6_config_get_num_addresses (page->setting); i++) {
NMIP6Address *addr;
const struct in6_addr *tmp_addr;
gchar address[INET6_ADDRSTRLEN + 1];
gchar network[INET6_ADDRSTRLEN + 1];
gchar gateway[INET6_ADDRSTRLEN + 1];
addr = nm_setting_ip6_config_get_address (page->setting, i);
if (!addr)
continue;
tmp_addr = nm_ip6_address_get_address (addr);
(void) inet_ntop (AF_INET6, tmp_addr, &address[0], sizeof (address));
snprintf (network, sizeof (network), "%u", nm_ip6_address_get_prefix (addr));
tmp_addr = nm_ip6_address_get_gateway (addr);
if (tmp_addr && !IN6_IS_ADDR_UNSPECIFIED (tmp_addr))
(void) inet_ntop (AF_INET6, tmp_addr, &gateway[0], sizeof (gateway));
else
gateway[0] = '\0';
add_address_row (page, address, network, gateway);
}
if (nm_setting_ip6_config_get_num_addresses (page->setting) == 0)
add_empty_address_row (page);
}
static void
add_dns_row (CEPageIP6 *page,
const gchar *address)
{
GtkWidget *row;
GtkWidget *widget;
GtkWidget *delete_button;
GtkWidget *image;
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
widget = gtk_label_new (_("Address"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "address", widget);
gtk_entry_set_text (GTK_ENTRY (widget), address);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
delete_button = gtk_button_new ();
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (delete_button), image);
gtk_box_pack_start (GTK_BOX (row), delete_button, FALSE, FALSE, 0);
gtk_widget_set_margin_left (row, 10);
gtk_widget_set_margin_right (row, 10);
gtk_widget_set_margin_top (row, 10);
gtk_widget_set_margin_bottom (row, 10);
gtk_widget_set_halign (row, GTK_ALIGN_FILL);
gtk_widget_show_all (row);
gtk_container_add (GTK_CONTAINER (page->dns_list), row);
}
static void
add_empty_dns_row (CEPageIP6 *page)
{
add_dns_row (page, "");
}
static void
add_dns_section (CEPageIP6 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
GtkWidget *row;
GtkWidget *button;
GtkWidget *image;
gint i;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "dns_section"));
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (widget), frame);
page->dns_list = list = GTK_WIDGET (egg_list_box_new ());
egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
gtk_container_add (GTK_CONTAINER (frame), list);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "first", GINT_TO_POINTER (TRUE));
widget = gtk_label_new (_("Automatic"));
gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
widget = gtk_switch_new ();
page->auto_dns = GTK_SWITCH (widget);
gtk_switch_set_active (page->auto_dns, !nm_setting_ip6_config_get_ignore_auto_dns (page->setting));
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_END);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "last", GINT_TO_POINTER (TRUE));
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_empty_dns_row), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_margin_top (button, 10);
gtk_widget_set_margin_bottom (button, 10);
gtk_widget_set_margin_left (button, 10);
gtk_widget_set_margin_right (button, 10);
gtk_widget_set_halign (button, GTK_ALIGN_END);
gtk_box_pack_start (GTK_BOX (row), button, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
gtk_widget_show_all (frame);
for (i = 0; i < nm_setting_ip6_config_get_num_dns (page->setting); i++) {
const struct in6_addr *tmp_addr;
gchar address[INET6_ADDRSTRLEN + 1];
tmp_addr = nm_setting_ip6_config_get_dns (page->setting, i);
(void) inet_ntop (AF_INET, tmp_addr, &address[0], sizeof (address));
add_dns_row (page, address);
}
if (nm_setting_ip6_config_get_num_dns (page->setting) == 0)
add_empty_dns_row (page);
}
static void
add_route_row (CEPageIP6 *page,
const gchar *address,
gint prefix,
const gchar *gateway,
gint metric)
{
GtkWidget *row;
GtkWidget *widget;
GtkWidget *delete_button;
GtkWidget *image;
row = gtk_grid_new ();
widget = gtk_label_new (_("Address"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 1, 1, 1);
widget = gtk_label_new (_("Prefix"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 2, 1, 1);
widget = gtk_label_new (_("Gateway"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 3, 1, 1);
widget = gtk_label_new (_("Metric"));
gtk_misc_set_alignment (GTK_MISC (widget), 1, 0.5);
gtk_grid_attach (GTK_GRID (row), widget, 1, 4, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "address", widget);
gtk_entry_set_text (GTK_ENTRY (widget), address);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 1, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "prefix", widget);
if (prefix > 0) {
gchar *s = g_strdup_printf ("%d", prefix);
gtk_entry_set_text (GTK_ENTRY (widget), s);
g_free (s);
}
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 2, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
g_object_set_data (G_OBJECT (row), "gateway", widget);
gtk_entry_set_text (GTK_ENTRY (widget), gateway);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 3, 1, 1);
widget = gtk_entry_new ();
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), 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_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_hexpand (widget, TRUE);
gtk_grid_attach (GTK_GRID (row), widget, 2, 4, 1, 1);
delete_button = gtk_button_new ();
g_signal_connect (delete_button, "clicked", G_CALLBACK (remove_row), page);
image = gtk_image_new_from_icon_name ("user-trash-symbolic", GTK_ICON_SIZE_MENU);
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_grid_attach (GTK_GRID (row), delete_button, 3, 1, 1, 4);
gtk_widget_set_margin_left (row, 10);
gtk_widget_set_margin_right (row, 10);
gtk_widget_set_margin_top (row, 10);
gtk_widget_set_margin_bottom (row, 10);
gtk_widget_set_halign (row, GTK_ALIGN_FILL);
gtk_widget_show_all (row);
gtk_container_add (GTK_CONTAINER (page->routes_list), row);
}
static void
add_empty_route_row (CEPageIP6 *page)
{
add_route_row (page, "", 0, "", 0);
}
static void
add_routes_section (CEPageIP6 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
GtkWidget *row;
GtkWidget *button;
GtkWidget *image;
gint i;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "routes_section"));
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (widget), frame);
page->routes_list = list = GTK_WIDGET (egg_list_box_new ());
egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
egg_list_box_set_sort_func (EGG_LIST_BOX (list), sort_first_last, NULL, NULL);
gtk_container_add (GTK_CONTAINER (frame), list);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "first", GINT_TO_POINTER (TRUE));
widget = gtk_label_new (_("Automatic"));
gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_FILL);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, FALSE, FALSE, 0);
widget = gtk_switch_new ();
page->auto_routes = GTK_SWITCH (widget);
gtk_switch_set_active (GTK_SWITCH (widget), !nm_setting_ip6_config_get_ignore_auto_routes (page->setting));
gtk_widget_set_margin_top (widget, 10);
gtk_widget_set_margin_bottom (widget, 10);
gtk_widget_set_margin_left (widget, 10);
gtk_widget_set_margin_right (widget, 10);
gtk_widget_set_halign (widget, GTK_ALIGN_END);
gtk_widget_set_valign (widget, GTK_ALIGN_CENTER);
gtk_box_pack_start (GTK_BOX (row), widget, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
g_object_set_data (G_OBJECT (row), "last", GINT_TO_POINTER (TRUE));
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_empty_route_row), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_widget_set_margin_top (button, 10);
gtk_widget_set_margin_bottom (button, 10);
gtk_widget_set_margin_left (button, 10);
gtk_widget_set_margin_right (button, 10);
gtk_widget_set_halign (button, GTK_ALIGN_END);
gtk_box_pack_start (GTK_BOX (row), button, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (list), row);
gtk_widget_show_all (frame);
for (i = 0; i < nm_setting_ip6_config_get_num_routes (page->setting); i++) {
NMIP6Route *route;
const struct in6_addr *tmp_addr;
gchar address[INET6_ADDRSTRLEN + 1];
gchar gateway[INET6_ADDRSTRLEN + 1];
gint prefix, metric;
route = nm_setting_ip6_config_get_route (page->setting, i);
if (!route)
continue;
tmp_addr = nm_ip6_route_get_dest (route);
(void) inet_ntop (AF_INET6, tmp_addr, &address[0], sizeof (address));
prefix = nm_ip6_route_get_prefix (route);
tmp_addr = nm_ip6_route_get_next_hop (route);
(void) inet_ntop (AF_INET6, tmp_addr, &gateway[0], sizeof (gateway));
metric = nm_ip6_route_get_metric (route);
add_route_row (page, address, prefix, gateway, metric);
}
if (nm_setting_ip6_config_get_num_routes (page->setting) == 0)
add_empty_route_row (page);
}
static void
connect_ip6_page (CEPageIP6 *page)
{
GtkWidget *content;
const gchar *str_method;
gboolean disabled;
GtkListStore *store;
GtkTreeIter iter;
guint method;
add_address_section (page);
add_dns_section (page);
add_routes_section (page);
page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "switch_enable"));
str_method = nm_setting_ip6_config_get_method (page->setting);
disabled = g_strcmp0 (str_method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) == 0;
gtk_switch_set_active (page->enabled, !disabled);
g_signal_connect_swapped (page->enabled, "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->enabled, "active",
content, "sensitive",
G_BINDING_SYNC_CREATE);
page->method = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_addresses"));
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_UINT);
gtk_list_store_insert_with_values (store, &iter, -1,
METHOD_COL_NAME, _("Automatic"),
METHOD_COL_METHOD, IP6_METHOD_AUTO,
-1);
gtk_list_store_insert_with_values (store, &iter, -1,
METHOD_COL_NAME, _("Automatic, DHCP only"),
METHOD_COL_METHOD, IP6_METHOD_DHCP,
-1);
gtk_list_store_insert_with_values (store, &iter, -1,
METHOD_COL_NAME, _("Manual"),
METHOD_COL_METHOD, IP6_METHOD_MANUAL,
-1);
gtk_list_store_insert_with_values (store, &iter, -1,
METHOD_COL_NAME, _("Link-Local Only"),
METHOD_COL_METHOD, IP6_METHOD_LINK_LOCAL,
-1);
gtk_combo_box_set_model (page->method, GTK_TREE_MODEL (store));
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_ip6_config_get_never_default (page->setting));
g_signal_connect (page->method, "changed", G_CALLBACK (method_changed), page);
if (method != IP6_METHOD_SHARED && method != IP6_METHOD_IGNORE)
gtk_combo_box_set_active (page->method, method);
}
static gboolean
ui_to_setting (CEPageIP6 *page)
{
gboolean valid = FALSE;
const gchar *method;
gboolean ignore_auto_dns;
gboolean ignore_auto_routes;
gboolean never_default;
GList *children, *l;
if (!gtk_switch_get_active (page->enabled)) {
method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
} else {
switch (gtk_combo_box_get_active (page->method)) {
case IP6_METHOD_MANUAL:
method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
break;
case IP6_METHOD_LINK_LOCAL:
method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
break;
case IP6_METHOD_DHCP:
method = NM_SETTING_IP6_CONFIG_METHOD_DHCP;
break;
default:
case IP6_METHOD_AUTO:
method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
break;
}
}
nm_setting_ip6_config_clear_addresses (page->setting);
children = gtk_container_get_children (GTK_CONTAINER (page->address_list));
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;
struct in6_addr tmp_addr;
struct in6_addr tmp_gateway;
guint32 prefix;
gchar *end;
NMIP6Address *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 */
continue;
}
if (inet_pton (AF_INET6, text_address, &tmp_addr) <= 0) {
g_warning ("IPv6 address %s missing or invalid", text_address);
goto out;
}
prefix = strtoul (text_prefix, &end, 10);
if (!end || *end || prefix == 0 || prefix > 128) {
g_warning ("IPv6 prefix %s is invalid", text_prefix);
goto out;
}
if (text_gateway && *text_gateway) {
if (inet_pton (AF_INET6, text_gateway, &tmp_gateway) <= 0) {
g_warning ("IPv6 gateway %s is invalid", text_gateway);
goto out;
}
if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_gateway))
have_gateway = TRUE;
}
addr = nm_ip6_address_new ();
nm_ip6_address_set_address (addr, &tmp_addr);
nm_ip6_address_set_prefix (addr, prefix);
if (have_gateway)
nm_ip6_address_set_gateway (addr, &tmp_gateway);
nm_setting_ip6_config_add_address (page->setting, addr);
}
g_list_free (children);
nm_setting_ip6_config_clear_dns (page->setting);
children = gtk_container_get_children (GTK_CONTAINER (page->dns_list));
for (l = children; l; l = l->next) {
GtkWidget *row = l->data;
GtkEntry *entry;
const gchar *text;
struct in6_addr tmp_addr;
entry = GTK_ENTRY (g_object_get_data (G_OBJECT (row), "address"));
if (!entry)
continue;
text = gtk_entry_get_text (entry);
if (!*text) {
/* ignore empty rows */
continue;
}
if (inet_pton (AF_INET6, text, &tmp_addr) <= 0) {
g_warning ("IPv6 dns server %s invalid", text);
goto out;
}
nm_setting_ip6_config_add_dns (page->setting, &tmp_addr);
}
g_list_free (children);
nm_setting_ip6_config_clear_routes (page->setting);
children = gtk_container_get_children (GTK_CONTAINER (page->routes_list));
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;
struct in6_addr dest, gateway;
guint32 prefix, metric;
gchar *end;
NMIP6Route *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 */
continue;
}
if (inet_pton (AF_INET6, text_address, &dest) <= 0) {
g_warning ("IPv6 route address %s invalid", text_address);
goto out;
}
prefix = strtoul (text_prefix, &end, 10);
if (!end || *end || prefix == 0 || prefix > 128) {
g_warning ("IPv6 route prefix %s invalid", text_prefix);
goto out;
}
if (inet_pton (AF_INET6, text_gateway, &gateway) <= 0) {
g_warning ("IPv6 route gateway %s invalid", text_gateway);
goto out;
}
metric = 0;
if (*text_metric) {
errno = 0;
metric = strtoul (text_metric, NULL, 10);
if (errno) {
g_warning ("IPv6 route metric %s invalid", text_metric);
goto out;
}
}
route = nm_ip6_route_new ();
nm_ip6_route_set_dest (route, &dest);
nm_ip6_route_set_prefix (route, prefix);
nm_ip6_route_set_next_hop (route, &gateway);
nm_ip6_route_set_metric (route, metric);
nm_setting_ip6_config_add_route (page->setting, route);
nm_ip6_route_unref (route);
}
g_list_free (children);
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_IP6_CONFIG_METHOD, method,
NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, ignore_auto_dns,
NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, ignore_auto_routes,
NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default,
NULL);
valid = TRUE;
out:
return valid;
}
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,
NMRemoteSettings *settings)
{
CEPageIP6 *page;
page = CE_PAGE_IP6 (ce_page_new (CE_TYPE_PAGE_IP6,
connection,
client,
settings,
GNOMECC_UI_DIR "/ip6-page.ui",
_("IPv6")));
page->setting = nm_connection_get_setting_ip6_config (connection);
if (!page->setting) {
page->setting = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ());
nm_connection_add_setting (connection, NM_SETTING (page->setting));
}
connect_ip6_page (page);
return CE_PAGE (page);
}

View File

@@ -0,0 +1,72 @@
/* -*- 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 <glib-object.h>
#include <gtk/gtk.h>
#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;
NMSettingIP6Config *setting;
GtkSwitch *enabled;
GtkComboBox *method;
GtkWidget *address_list;
GtkSwitch *auto_dns;
GtkWidget *dns_list;
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,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* __CE_PAGE_IP6_H */

View File

@@ -0,0 +1,97 @@
/* -*- 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 <glib-object.h>
#include <glib/gi18n.h>
#include "net-connection-editor.h"
#include "ce-page-reset.h"
G_DEFINE_TYPE (CEPageReset, ce_page_reset, CE_TYPE_PAGE)
static void
forget_cb (GtkButton *button, CEPageReset *page)
{
net_connection_editor_forget (page->editor);
}
static void
reset_cb (GtkButton *button, CEPageReset *page)
{
net_connection_editor_reset (page->editor);
}
static void
connect_reset_page (CEPageReset *page)
{
GtkWidget *widget;
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_forget"));
g_signal_connect (widget, "clicked", G_CALLBACK (forget_cb), page);
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "button_reset"));
g_signal_connect (widget, "clicked", G_CALLBACK (reset_cb), page);
}
static gboolean
validate (CEPage *page,
NMConnection *connection,
GError **error)
{
return TRUE;
}
static void
ce_page_reset_init (CEPageReset *page)
{
}
static void
ce_page_reset_class_init (CEPageResetClass *class)
{
CEPageClass *page_class= CE_PAGE_CLASS (class);
page_class->validate = validate;
}
CEPage *
ce_page_reset_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings,
NetConnectionEditor *editor)
{
CEPageReset *page;
page = CE_PAGE_RESET (ce_page_new (CE_TYPE_PAGE_RESET,
connection,
client,
settings,
GNOMECC_UI_DIR "/reset-page.ui",
_("Reset")));
page->editor = editor;
connect_reset_page (page);
return CE_PAGE (page);
}

View File

@@ -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 reset.
*
* 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_RESET_H
#define __CE_PAGE_RESET_H
#include <glib-object.h>
#include <gtk/gtk.h>
#include "net-connection-editor.h"
#include "ce-page.h"
G_BEGIN_DECLS
#define CE_TYPE_PAGE_RESET (ce_page_reset_get_type ())
#define CE_PAGE_RESET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_RESET, CEPageReset))
#define CE_PAGE_RESET_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_RESET, CEPageResetClass))
#define CE_IS_PAGE_RESET(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_RESET))
#define CE_IS_PAGE_RESET_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_RESET))
#define CE_PAGE_RESET_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_RESET, CEPageResetClass))
typedef struct _CEPageReset CEPageReset;
typedef struct _CEPageResetClass CEPageResetClass;
struct _CEPageReset
{
CEPage parent;
NetConnectionEditor *editor;
};
struct _CEPageResetClass
{
CEPageClass parent_class;
};
GType ce_page_reset_get_type (void);
CEPage *ce_page_reset_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings,
NetConnectionEditor *editor);
G_END_DECLS
#endif /* __CE_PAGE_RESET_H */

View File

@@ -0,0 +1,480 @@
/* -*- 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 <glib-object.h>
#include <glib/gi18n.h>
#include <nm-utils.h>
#include <nm-connection.h>
#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;
const gchar *security;
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);
security = nm_setting_wireless_get_security (sw);
if (!security || strcmp (security, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != 0)
sws = NULL;
if (sws)
default_type = get_default_type_for_security (sws);
sec_model = gtk_list_store_new (3, G_TYPE_STRING, wireless_security_get_g_type (), 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) {
const GByteArray *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, ssid);
if (valid)
wireless_security_fill_connection (sec, connection);
else
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Invalid Wi-Fi security");
} else {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Missing SSID");
valid = FALSE;
}
if (CE_PAGE_SECURITY (page)->adhoc) {
if (!wireless_security_adhoc_compatible (sec)) {
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN, "Security not compatible with Ad-Hoc mode");
valid = FALSE;
}
}
wireless_security_unref (sec);
} else {
/* No security, unencrypted */
g_object_set (sw, NM_SETTING_WIRELESS_SEC, NULL, NULL);
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,
NMRemoteSettings *settings)
{
CEPageSecurity *page;
const gchar *security;
NMUtilsSecurityType default_type = NMU_SEC_NONE;
NMSettingWirelessSecurity *sws;
page = CE_PAGE_SECURITY (ce_page_new (CE_TYPE_PAGE_SECURITY,
connection,
client,
settings,
GNOMECC_UI_DIR "/security-page.ui",
_("Security")));
sws = nm_connection_get_setting_wireless_security (connection);
security = nm_setting_wireless_get_security (nm_connection_get_setting_wireless (connection));
if (!security || strcmp (security, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != 0)
sws = NULL;
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);
}

View File

@@ -0,0 +1,66 @@
/* -*- 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 <glib-object.h>
#include <gtk/gtk.h>
#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,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* __CE_PAGE_SECURITY_H */

View File

@@ -0,0 +1,221 @@
/* -*- 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 <glib-object.h>
#include <glib/gi18n.h>
#include <nm-setting-wireless.h>
#include <nm-utils.h>
#include <nm-device-wifi.h>
#include <net/if_arp.h>
#include "ce-page-wifi.h"
G_DEFINE_TYPE (CEPageWifi, ce_page_wifi, CE_TYPE_PAGE)
static void
connect_wifi_page (CEPageWifi *page)
{
GtkWidget *widget;
const GByteArray *ssid;
gchar *utf8_ssid;
GPtrArray *bssid_array;
gchar **bssid_list;
const GByteArray *s_bssid;
gchar *s_bssid_str;
gchar **mac_list;
const GByteArray *s_mac;
gchar *s_mac_str;
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 (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 = nm_setting_wireless_get_bssid (page->setting);
s_bssid_str = s_bssid ? nm_utils_hwaddr_ntoa (s_bssid->data, ARPHRD_ETHER) : NULL;
ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_bssid_str, bssid_list);
g_free (s_bssid_str);
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 = nm_setting_wireless_get_mac_address (page->setting);
s_mac_str = s_mac ? nm_utils_hwaddr_ntoa (s_mac->data, ARPHRD_ETHER) : NULL;
ce_page_setup_mac_combo (GTK_COMBO_BOX_TEXT (widget), s_mac_str, mac_list);
g_free (s_mac_str);
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"));
ce_page_mac_to_entry (nm_setting_wireless_get_cloned_mac_address (page->setting),
ARPHRD_ETHER, GTK_ENTRY (widget));
g_signal_connect_swapped (widget, "changed", G_CALLBACK (ce_page_changed), page);
}
static void
ui_to_setting (CEPageWifi *page)
{
GByteArray *ssid;
GByteArray *bssid = NULL;
GByteArray *device_mac = NULL;
GByteArray *cloned_mac = NULL;
GtkWidget *entry;
const gchar *utf8_ssid;
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_byte_array_sized_new (strlen (utf8_ssid));
g_byte_array_append (ssid, (const guint8*)utf8_ssid, strlen (utf8_ssid));
}
entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_bssid")));
bssid = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac")));
device_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
entry = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac"));
cloned_mac = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, NULL);
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_byte_array_free (ssid, TRUE);
if (bssid)
g_byte_array_free (bssid, TRUE);
if (device_mac)
g_byte_array_free (device_mac, TRUE);
if (cloned_mac)
g_byte_array_free (cloned_mac, TRUE);
}
static gboolean
validate (CEPage *page,
NMConnection *connection,
GError **error)
{
GtkWidget *entry;
GByteArray *ignore;
gboolean invalid;
gboolean success;
gchar *security;
NMSettingWireless *setting;
entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_bssid")));
ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
if (invalid)
return FALSE;
if (ignore)
g_byte_array_free (ignore, TRUE);
entry = gtk_bin_get_child (GTK_BIN (gtk_builder_get_object (page->builder, "combo_mac")));
ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
if (invalid)
return FALSE;
if (ignore)
g_byte_array_free (ignore, TRUE);
entry = GTK_WIDGET (gtk_builder_get_object (page->builder, "entry_cloned_mac"));
ignore = ce_page_entry_to_mac (GTK_ENTRY (entry), ARPHRD_ETHER, &invalid);
if (invalid)
return FALSE;
if (ignore)
g_byte_array_free (ignore, TRUE);
ui_to_setting (CE_PAGE_WIFI (page));
/* A hack to not check the wifi security here */
setting = CE_PAGE_WIFI (page)->setting;
security = g_strdup (nm_setting_wireless_get_security (setting));
g_object_set (setting, NM_SETTING_WIRELESS_SEC, NULL, NULL);
success = nm_setting_verify (NM_SETTING (setting), NULL, error);
g_object_set (setting, NM_SETTING_WIRELESS_SEC, security, NULL);
g_free (security);
return success;
}
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,
NMRemoteSettings *settings)
{
CEPageWifi *page;
page = CE_PAGE_WIFI (ce_page_new (CE_TYPE_PAGE_WIFI,
connection,
client,
settings,
GNOMECC_UI_DIR "/wifi-page.ui",
_("Identity")));
page->setting = nm_connection_get_setting_wireless (connection);
connect_wifi_page (page);
return CE_PAGE (page);
}

View File

@@ -0,0 +1,63 @@
/* -*- 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 <glib-object.h>
#include <gtk/gtk.h>
#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,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* __CE_PAGE_WIFI_H */

View File

@@ -0,0 +1,548 @@
/* -*- 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 <string.h>
#include <net/if_arp.h>
#include <netinet/ether.h>
#include <nm-utils.h>
#include <glib/gi18n.h>
#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);
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 ();
}
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,
NMRemoteSettings *settings,
const gchar *ui_file,
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;
page->settings= settings;
if (ui_file) {
if (!gtk_builder_add_from_file (page->builder, ui_file, &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_file);
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);
}
void
ce_page_complete_init (CEPage *page,
const gchar *setting_name,
GHashTable *secrets,
GError *error)
{
GHashTable *setting_hash;
GError *update_error = NULL;
if (error
&& !dbus_g_error_has_name (error, "org.freedesktop.NetworkManager.Settings.InvalidSetting")
&& !dbus_g_error_has_name (error, "org.freedesktop.NetworkManager.AgentManager.NoSecrets")) {
emit_initialized (page, error);
return;
} else if (!setting_name || !secrets || !g_hash_table_size (secrets)) {
/* Success, no secrets */
emit_initialized (page, NULL);
return;
}
setting_hash = g_hash_table_lookup (secrets, setting_name);
if (!setting_hash) {
/* Success, no secrets */
emit_initialized (page, NULL);
return;
}
if (nm_connection_update_secrets (page->connection,
setting_name,
secrets,
&update_error)) {
emit_initialized (page, NULL);
return;
}
if (!update_error) {
g_set_error_literal (&update_error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_UNKNOWN,
"Failed to update connection secrets due to an unknown error.");
}
emit_initialized (page, update_error);
g_clear_error (&update_error);
}
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);
}
}
void
ce_page_mac_to_entry (const GByteArray *mac,
gint type,
GtkEntry *entry)
{
char *str_addr;
g_return_if_fail (entry != NULL);
g_return_if_fail (GTK_IS_ENTRY (entry));
if (!mac || !mac->len)
return;
if (mac->len != nm_utils_hwaddr_len (type))
return;
str_addr = nm_utils_hwaddr_ntoa (mac->data, type);
gtk_entry_set_text (entry, str_addr);
g_free (str_addr);
}
static gboolean
utils_ether_addr_valid (const struct ether_addr *test_addr)
{
guint8 invalid_addr1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
guint8 invalid_addr2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
guint8 invalid_addr3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
guint8 invalid_addr4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */
g_return_val_if_fail (test_addr != NULL, FALSE);
/* Compare the AP address the card has with invalid ethernet MAC addresses. */
if (!memcmp (test_addr->ether_addr_octet, &invalid_addr1, ETH_ALEN))
return FALSE;
if (!memcmp (test_addr->ether_addr_octet, &invalid_addr2, ETH_ALEN))
return FALSE;
if (!memcmp (test_addr->ether_addr_octet, &invalid_addr3, ETH_ALEN))
return FALSE;
if (!memcmp (test_addr->ether_addr_octet, &invalid_addr4, ETH_ALEN))
return FALSE;
if (test_addr->ether_addr_octet[0] & 1) /* Multicast addresses */
return FALSE;
return TRUE;
}
GByteArray *
ce_page_entry_to_mac (GtkEntry *entry,
gint type,
gboolean *invalid)
{
const char *temp, *sp;
char *buf = NULL;
GByteArray *mac;
g_return_val_if_fail (entry != NULL, NULL);
g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
if (invalid)
*invalid = FALSE;
temp = gtk_entry_get_text (entry);
if (!temp || !strlen (temp))
return NULL;
sp = strchr (temp, ' ');
if (sp)
temp = buf = g_strndup (temp, sp - temp);
mac = nm_utils_hwaddr_atoba (temp, type);
g_free (buf);
if (!mac) {
if (invalid)
*invalid = TRUE;
return NULL;
}
if (type == ARPHRD_ETHER && !utils_ether_addr_valid ((struct ether_addr *)mac->data)) {
g_byte_array_free (mac, TRUE);
if (invalid)
*invalid = TRUE;
return NULL;
}
return mac;
}
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 (GSList *connections, const gchar *format)
{
GSList *names = NULL, *l;
gchar *cname = NULL;
gint i = 0;
for (l = connections; l; l = l->next) {
const gchar *id;
id = nm_connection_get_id (NM_CONNECTION (l->data));
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;
temp = g_strdup_printf (format, i);
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;
}

View File

@@ -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 <glib-object.h>
#include <nm-connection.h>
#include <nm-client.h>
#include <nm-remote-settings.h>
#include <gtk/gtk.h>
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;
NMRemoteSettings *settings;
};
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,
NMRemoteSettings *settings,
const gchar *ui_file,
const gchar *title);
void ce_page_complete_init (CEPage *page,
const gchar *setting_name,
GHashTable *secrets,
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);
void ce_page_mac_to_entry (const GByteArray *mac,
gint type,
GtkEntry *entry);
GByteArray *ce_page_entry_to_mac (GtkEntry *entry,
gint type,
gboolean *invalid);
gint ce_get_property_default (NMSetting *setting,
const gchar *property_name);
gint ce_spin_output_with_default (GtkSpinButton *spin,
gpointer user_data);
gchar * ce_page_get_next_available_name (GSList *connections, const gchar *format);
G_END_DECLS
#endif /* __CE_PAGE_H */

View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="details_store">
<columns>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name page -->
<column type="gint"/>
</columns>
</object>
<object class="GtkDialog" id="details_dialog">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="modal">True</property>
<property name="default_width">600</property>
<property name="default_height">300</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area">
<property name="can_focus">False</property>
<property name="valign">end</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="details_cancel_button">
<property name="label">gtk-cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="details_apply_button">
<property name="label" translatable="yes">_Apply</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkScrolledWindow" id="details_sidebar">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="details_page_list">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">details_store</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
<property name="search_column">0</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="details_page_list_selection"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="details_column">
<child>
<object class="GtkCellRendererText" id="details_cell">
<property name="xpad">10</property>
</object>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererText" id="padding_cell">
<property name="xpad">20</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkNotebook" id="details_notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">details_cancel_button</action-widget>
<action-widget response="0">details_apply_button</action-widget>
</action-widgets>
</object>
</interface>

View File

@@ -0,0 +1,402 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkBox" id="page">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="auto_connect_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Automatic _Connect</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">auto_connect_switch</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="auto_connect_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="all_users_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Available to all _users</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">all_user_switch</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="all_user_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_left">50</property>
<property name="margin_right">50</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">10</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="heading_strength">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Signal Strength</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_strength">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label">Weak</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_speed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Link speed</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_speed">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">1Mb/sec</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_security">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Security</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_ipv4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">IPv4 Address</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_ipv6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">IPv6 Address</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Hardware Address</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_route">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Default Route</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_dns">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">DNS</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_last_used">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Last used</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">8</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_security">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">WPA</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_ipv4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">127.0.0.1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_ipv6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">::1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_mac">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">AA:BB:CC:DD:55:66:77:88</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_route">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">127.0.0.1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_dns">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label">127.0.0.1</property>
<property name="wrap">True</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_last_used">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">today</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">8</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,315 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">10000</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkListStore" id="model1">
<columns>
<!-- column-name gchararray1 -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Automatic</col>
</row>
<row>
<col id="0" translatable="yes">Twisted Pair (TP)</col>
</row>
<row>
<col id="0" translatable="yes">Attachment Unit Interface (AUI)</col>
</row>
<row>
<col id="0" translatable="yes">BNC</col>
</row>
<row>
<col id="0" translatable="yes">Media Independent Interface (MII)</col>
</row>
</data>
</object>
<object class="GtkListStore" id="model2">
<columns>
<!-- column-name < -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Automatic</col>
</row>
<row>
<col id="0" translatable="yes">10 Mb/s</col>
</row>
<row>
<col id="0" translatable="yes">100 Mb/s</col>
</row>
<row>
<col id="0" translatable="yes">1 Gb/s</col>
</row>
<row>
<col id="0" translatable="yes">10 Gb/s</col>
</row>
</data>
</object>
<object class="GtkGrid" id="page">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">50</property>
<property name="margin_right">50</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">10</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="heading_mtu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_MTU</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">spin_mtu</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkSpinButton" id="spin_mtu">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="adjustment">adjustment1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_mtu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">bytes</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_cloned_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Cloned MAC Address</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">entry_cloned_mac</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_MAC Address</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_mac</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_cloned_mac">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="combo_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
<child internal-child="entry">
<object class="GtkEntry" id="comboboxtext-entry2">
<property name="can_focus">False</property>
<property name="invisible_char">●</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_port">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Port</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_port</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_speed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Speed</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_speed</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_duplex">
<property name="label" translatable="yes">_Full duplex</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="check_renegotiate">
<property name="label" translatable="yes">_Automatic renegotiation</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="combo_port">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model1</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="combo_speed">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model2</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_name">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Name</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">entry_name</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</interface>

View File

@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkScrolledWindow" id="page">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">20</property>
<property name="margin_right">20</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkBox" id="box5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="heading_enable">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">IPv_4</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">switch_enable</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="switch_enable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="page_content">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkBox" id="box7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="heading_addresses">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Addresses</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_addresses</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="combo_addresses">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="hexpand">True</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="address_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_dns">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="margin_bottom">6</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">DNS</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="dns_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_routes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="margin_bottom">6</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Routes</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="routes_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="never_default_check">
<property name="label" translatable="yes">Use this connection _only for resources on its network</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkScrolledWindow" id="page">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">20</property>
<property name="margin_right">20</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkBox" id="box5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="heading_enable">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">IPv_6</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">switch_enable</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="switch_enable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="page_content">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkBox" id="box7">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="heading_addresses">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Addresses</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_addresses</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="combo_addresses">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="hexpand">True</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="address_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_dns">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="margin_bottom">6</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">DNS</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="dns_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_routes">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="margin_bottom">6</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Routes</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="routes_section">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="never_default_check">
<property name="label" translatable="yes">Use this connection _only for resources on its network</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">7</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -0,0 +1,548 @@
/* -*- 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 <glib-object.h>
#include <glib/gi18n.h>
#include <nm-utils.h>
#include <nm-device-wifi.h>
#include "net-connection-editor.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-reset.h"
#include "ce-page-ethernet.h"
#include "ce-page-8021x-security.h"
#include "egg-list-box/egg-list-box.h"
enum {
DONE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (NetConnectionEditor, net_connection_editor, G_TYPE_OBJECT)
static void
selection_changed (GtkTreeSelection *selection, NetConnectionEditor *editor)
{
GtkWidget *widget;
GtkTreeModel *model;
GtkTreeIter iter;
gint page;
gtk_tree_selection_get_selected (selection, &model, &iter);
gtk_tree_model_get (model, &iter, 1, &page, -1);
widget = GTK_WIDGET (gtk_builder_get_object (editor->builder,
"details_notebook"));
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), page);
}
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)
{
GHashTable *settings;
settings = nm_connection_to_hash (editor->connection, NM_SETTING_HASH_FLAG_ALL);
nm_connection_replace_settings (editor->orig_connection, settings, NULL);
g_hash_table_destroy (settings);
}
static void
update_complete (NetConnectionEditor *editor, GError *error)
{
gtk_widget_hide (editor->window);
g_signal_emit (editor, signals[DONE], 0, !error);
}
static void
updated_connection_cb (NMRemoteConnection *connection,
GError *error,
gpointer data)
{
NetConnectionEditor *editor = data;
nm_connection_clear_secrets (NM_CONNECTION (connection));
update_complete (editor, error);
}
static void
added_connection_cb (NMRemoteSettings *settings,
NMRemoteConnection *connection,
GError *error,
gpointer data)
{
NetConnectionEditor *editor = data;
if (error) {
g_warning ("Failed to add connection: %s", error->message);
/* Leave the editor open */
return;
}
update_complete (editor, error);
}
static void
apply_edits (NetConnectionEditor *editor)
{
update_connection (editor);
if (!nm_remote_settings_get_connection_by_uuid (editor->settings, nm_connection_get_uuid (editor->orig_connection)))
nm_remote_settings_add_connection (editor->settings,
editor->orig_connection,
added_connection_cb,
editor);
else {
nm_remote_connection_commit_changes (NM_REMOTE_CONNECTION (editor->orig_connection),
updated_connection_cb, editor);
}
}
static void
net_connection_editor_init (NetConnectionEditor *editor)
{
GError *error = NULL;
GtkTreeSelection *selection;
editor->builder = gtk_builder_new ();
gtk_builder_add_from_file (editor->builder,
GNOMECC_UI_DIR "/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"));
selection = GTK_TREE_SELECTION (gtk_builder_get_object (editor->builder,
"details_page_list_selection"));
g_signal_connect (selection, "changed",
G_CALLBACK (selection_changed), editor);
}
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);
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->settings);
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);
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_update_title (NetConnectionEditor *editor)
{
NMSettingWireless *sw;
const GByteArray *ssid;
gchar *id;
sw = nm_connection_get_setting_wireless (editor->connection);
if (sw) {
ssid = nm_setting_wireless_get_ssid (sw);
id = nm_utils_ssid_to_utf8 (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_warning ("Invalid setting %s: %s", ce_page_get_title (CE_PAGE (l->data)), error->message);
g_error_free (error);
} else {
g_warning ("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);
}
static void
page_changed (CEPage *page, gpointer user_data)
{
NetConnectionEditor *editor= user_data;
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);
g_idle_add (idle_validate, editor);
}
static void
page_initialized (CEPage *page, GError *error, NetConnectionEditor *editor)
{
GtkNotebook *notebook;
GtkWidget *widget;
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);
gtk_notebook_insert_page (notebook, widget, NULL, 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;
gboolean canceled;
} GetSecretsInfo;
static void
get_secrets_cb (NMRemoteConnection *connection,
GHashTable *secrets,
GError *error,
gpointer user_data)
{
GetSecretsInfo *info = user_data;
if (info->canceled) {
g_free (info);
return;
}
ce_page_complete_init (info->page, info->setting_name, secrets, error);
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 (NM_REMOTE_CONNECTION (editor->orig_connection),
setting_name,
get_secrets_cb,
info);
}
static void
add_page (NetConnectionEditor *editor, CEPage *page)
{
GtkListStore *store;
GtkTreeIter iter;
const gchar *title;
gint position;
store = GTK_LIST_STORE (gtk_builder_get_object (editor->builder,
"details_store"));
title = ce_page_get_title (page);
position = g_slist_length (editor->initializing_pages);
g_object_set_data (G_OBJECT (page), "position", GINT_TO_POINTER (position));
gtk_list_store_insert_with_values (store, &iter, -1,
0, title,
1, position,
-1);
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;
editor->connection = nm_connection_duplicate (connection);
editor->orig_connection = g_object_ref (connection);
net_connection_editor_update_title (editor);
sc = nm_connection_get_setting_connection (connection);
type = nm_setting_connection_get_connection_type (sc);
add_page (editor, ce_page_details_new (editor->connection, editor->client, editor->settings, editor->device, editor->ap));
if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0)
add_page (editor, ce_page_wifi_new (editor->connection, editor->client, editor->settings));
else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0)
add_page (editor, ce_page_ethernet_new (editor->connection, editor->client, editor->settings));
add_page (editor, ce_page_ip4_new (editor->connection, editor->client, editor->settings));
add_page (editor, ce_page_ip6_new (editor->connection, editor->client, editor->settings));
if (strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME) == 0)
add_page (editor, ce_page_security_new (editor->connection, editor->client, editor->settings));
else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0)
add_page (editor, ce_page_8021x_security_new (editor->connection, editor->client, editor->settings));
add_page (editor, ce_page_reset_new (editor->connection, editor->client, editor->settings, editor));
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) {
ce_page_complete_init (page, NULL, NULL, NULL);
} else {
get_secrets_for_page (editor, page, security_setting);
}
}
g_slist_free (pages);
}
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,
NMRemoteSettings *settings)
{
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);
editor->device = g_object_ref (device);
editor->client = g_object_ref (client);
editor->settings = g_object_ref (settings);
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);
net_connection_editor_set_connection (editor, connection);
return editor;
}
void
net_connection_editor_present (NetConnectionEditor *editor)
{
gtk_window_present (GTK_WINDOW (editor->window));
}
static void
forgotten_cb (NMRemoteConnection *connection,
GError *error,
gpointer data)
{
NetConnectionEditor *editor = data;
if (error != NULL) {
g_warning ("Failed to delete conneciton %s: %s",
nm_connection_get_id (NM_CONNECTION (connection)),
error->message);
}
cancel_editing (editor);
}
void
net_connection_editor_forget (NetConnectionEditor *editor)
{
nm_remote_connection_delete (NM_REMOTE_CONNECTION (editor->orig_connection), forgotten_cb, editor);
}
void
net_connection_editor_reset (NetConnectionEditor *editor)
{
GHashTable *settings;
settings = nm_connection_to_hash (editor->orig_connection, NM_SETTING_HASH_FLAG_ALL);
nm_connection_replace_settings (editor->connection, settings, NULL);
g_hash_table_destroy (settings);
}

View File

@@ -0,0 +1,89 @@
/* -*- 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 <glib-object.h>
#include <gtk/gtk.h>
#include <nm-client.h>
#include <nm-access-point.h>
#include <nm-remote-settings.h>
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;
NMRemoteSettings *settings;
NMConnection *connection;
NMConnection *orig_connection;
NMAccessPoint *ap;
GtkBuilder *builder;
GtkWidget *window;
GSList *initializing_pages;
GSList *pages;
guint permission_id;
NMClientPermissionResult can_modify;
};
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,
NMRemoteSettings *settings);
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 */

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkGrid" id="page">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">50</property>
<property name="margin_right">50</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="row_spacing">10</property>
<property name="column_spacing">10</property>
<child>
<object class="GtkButton" id="button_reset">
<property name="label" translatable="yes">_Reset</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">start</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button_forget">
<property name="label" translatable="yes">_Forget</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">start</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_reset">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Reset the settings for this connection to their defaults, but remember as a preferred connection.</property>
<property name="wrap">True</property>
<property name="max_width_chars">40</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_forget">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Remove all details relating to this network and do not try to automatically connect to it.</property>
<property name="wrap">True</property>
<property name="max_width_chars">30</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkGrid" id="page">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">50</property>
<property name="margin_right">50</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">10</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="heading_sec">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">S_ecurity</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_sec</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="combo_sec">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkGrid" id="page">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">50</property>
<property name="margin_right">50</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">10</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="heading_ssid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_SSID</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">entry_ssid</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_bssid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_BSSID</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_bssid</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_ssid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<property name="text" translatable="yes">My Home Network</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_MAC Address</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">combo_mac</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry_cloned_mac">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_cloned_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Cloned MAC Address</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">entry_cloned_mac</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="combo_bssid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="combo_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_entry">True</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
</interface>

View File

@@ -28,9 +28,14 @@
#include <nm-device.h>
#include <nm-device-ethernet.h>
#include <nm-remote-connection.h>
#include <nm-utils.h>
#include "panel-common.h"
#include "egg-list-box/egg-list-box.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)
@@ -51,15 +56,459 @@ device_ethernet_get_speed (NetDeviceSimple *device_simple)
return NULL;
}
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 (net_device_get_nm_device (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);
}
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"));
g_object_ref (vbox);
gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (vbox)), vbox);
gtk_notebook_append_page (notebook, vbox, NULL);
g_object_unref (vbox);
return vbox;
}
static void
add_details_row (GtkWidget *details, gint top, const gchar *heading, const gchar *value)
{
GtkWidget *label;
label = gtk_label_new (heading);
gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_hexpand (label, TRUE);
gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
gtk_grid_attach (GTK_GRID (details), label, 0, top, 1, 1);
label = gtk_label_new (value);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_hexpand (label, TRUE);
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_grid_attach (GTK_GRID (details), 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)
{
NMIP4Config *ip4_config = NULL;
NMIP6Config *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++, _("IP4 Address"), ip4_address);
add_details_row (details, i++, _("IP6 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++, _("IP 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 void
editor_done (NetConnectionEditor *editor,
gboolean success,
NetDeviceEthernet *device)
{
g_object_unref (editor);
populate_ui (device);
}
static void
show_details_for_row (GtkButton *button, NetDeviceEthernet *device)
{
GtkWidget *row;
NMConnection *connection;
GtkWidget *window;
NetConnectionEditor *editor;
NMClient *client;
NMRemoteSettings *settings;
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));
settings = net_object_get_remote_settings (NET_OBJECT (device));
editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings);
g_signal_connect (editor, "done", G_CALLBACK (editor_done), device);
net_connection_editor_run (editor);
}
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 *path1, *path2;
path1 = nm_active_connection_get_connection (aconn);
path2 = nm_connection_get_path (connection);
active = g_strcmp0 (path1, path2) == 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_left (widget, 12);
gtk_widget_set_margin_right (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_widget_set_margin_left (widget, 12);
gtk_widget_set_margin_right (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);
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
populate_ui (NetDeviceEthernet *device)
{
NMRemoteSettings *settings;
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);
settings = net_object_get_remote_settings (NET_OBJECT (device));
connections = valid_connections_for_device (settings, NET_DEVICE (device));
n_connections = g_slist_length (connections);
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);
}
}
static void
remote_settings_read_cb (NMRemoteSettings *settings,
NetDeviceEthernet *device)
{
populate_ui (device);
}
static void
update_separator (GtkWidget **separator,
GtkWidget *child,
GtkWidget *before,
gpointer user_data)
{
if (before == NULL)
return;
if (*separator == NULL)
{
*separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_show (*separator);
g_object_ref_sink (*separator);
}
}
static void
add_profile (GtkButton *button, NetDeviceEthernet *device)
{
NMRemoteSettings *settings;
NMConnection *connection;
NMSettingConnection *sc;
gchar *uuid, *id;
NetConnectionEditor *editor;
GtkWidget *window;
NMClient *client;
NMDevice *nmdev;
GSList *connections;
connection = nm_connection_new ();
sc = NM_SETTING_CONNECTION (nm_setting_connection_new ());
nm_connection_add_setting (connection, NM_SETTING (sc));
uuid = nm_utils_uuid_generate ();
settings = net_object_get_remote_settings (NET_OBJECT (device));
connections = nm_remote_settings_list_connections (settings);
id = ce_page_get_next_available_name (connections, _("Profile %d"));
g_slist_free (connections);
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));
client = net_object_get_client (NET_OBJECT (device));
editor = net_connection_editor_new (GTK_WINDOW (window), connection, nmdev, NULL, client, settings);
g_signal_connect (editor, "done", G_CALLBACK (editor_done), device);
net_connection_editor_run (editor);
}
static void
device_ethernet_constructed (GObject *object)
{
NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
NMRemoteSettings *settings;
GtkWidget *list;
GtkWidget *swin;
device->scrolled_window = swin = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "list"));
device->list = list = GTK_WIDGET (egg_list_box_new ());
egg_list_box_set_selection_mode (EGG_LIST_BOX (list), GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (EGG_LIST_BOX (list), update_separator, NULL, NULL);
egg_list_box_add_to_scrolled (EGG_LIST_BOX (list), GTK_SCROLLED_WINDOW (swin));
gtk_widget_show (list);
device->details = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details"));
device->details_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "details_button"));
g_signal_connect (device->details_button, "clicked",
G_CALLBACK (show_details_for_row), device);
device->add_profile_button = GTK_WIDGET (gtk_builder_get_object (NET_DEVICE_ETHERNET (object)->builder, "add_profile_button"));
g_signal_connect (device->add_profile_button, "clicked",
G_CALLBACK (add_profile), device);
settings = net_object_get_remote_settings (NET_OBJECT (object));
g_signal_connect (settings, "connections-read",
G_CALLBACK (remote_settings_read_cb), object);
}
static void
device_ethernet_finalize (GObject *object)
{
NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
g_object_unref (device->builder);
G_OBJECT_CLASS (net_device_ethernet_parent_class)->finalize (object);
}
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->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_ethernet)
net_device_ethernet_init (NetDeviceEthernet *device)
{
GError *error = NULL;
device->builder = gtk_builder_new ();
gtk_builder_add_from_file (device->builder,
GNOMECC_UI_DIR "/network-ethernet.ui",
&error);
if (error != NULL) {
g_warning ("Could not load interface file: %s", error->message);
g_error_free (error);
return;
}
}

View File

@@ -41,16 +41,23 @@ typedef struct _NetDeviceEthernetClass NetDeviceEthernetClass;
struct _NetDeviceEthernet
{
NetDeviceSimple parent;
NetDeviceEthernetPrivate *priv;
NetDeviceSimple parent;
GtkBuilder *builder;
GtkWidget *list;
GtkWidget *scrolled_window;
GtkWidget *details;
GtkWidget *details_button;
GtkWidget *add_profile_button;
};
struct _NetDeviceEthernetClass
{
NetDeviceSimpleClass parent_class;
NetDeviceSimpleClass parent_class;
};
GType net_device_ethernet_get_type (void);
GType net_device_ethernet_get_type (void);
G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,211 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">emblem-system-symbolic</property>
</object>
<object class="GtkWindow" id="window_tmp">
<property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="vbox6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="spacing">6</property>
<child>
<object class="GtkGrid" id="grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="row_spacing">10</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkImage" id="image_device">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="valign">start</property>
<property name="xalign">1</property>
<property name="pixel_size">48</property>
<property name="icon_name">network-wired</property>
<property name="icon-size">6</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="vbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="hexpand">True</property>
<property name="spacing">3</property>
<child>
<object class="GtkLabel" id="label_device">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label">Wired</property>
<property name="ellipsize">end</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.2"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_status">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label">Cable unplugged</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment_switch">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="valign">start</property>
<child>
<object class="GtkSwitch" id="device_off_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
<property name="valign">start</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="list">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</property>
<property name="margin_top">20</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">3</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="details">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">10</property>
<property name="column_spacing">10</property>
<property name="margin_top">20</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">3</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="actions">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">20</property>
<child>
<object class="GtkButton" id="add_profile_button">
<property name="label" translatable="yes">_Add profile…</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">start</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="details_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">end</property>
<property name="image">image1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkSizeGroup" id="sizegroup1"/>
</interface>

View File

@@ -1,6 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkOffscreenWindow" id="offscreenwindow1">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<object class="GtkWindow" id="window_tmp">
<property name="can_focus">False</property>
<child>
@@ -81,174 +87,6 @@
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Hardware Address</property>
<property name="mnemonic_widget">label_mac</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_ipv4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">IPv4 Address</property>
<property name="mnemonic_widget">label_ipv4</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_ipv6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">IPv6 Address</property>
<property name="mnemonic_widget">label_ipv6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_route">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Default Route</property>
<property name="mnemonic_widget">label_route</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_dns">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">DNS</property>
<property name="mnemonic_widget">label_dns</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_mac">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">AA:BB:CC:DD:55:66:77:88</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_ipv4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">127.0.0.1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_ipv6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">::1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_route">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">127.0.0.1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_dns">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label">127.0.0.1</property>
<property name="wrap">True</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment_switch">
<property name="visible">True</property>
@@ -272,13 +110,189 @@
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">20</property>
<property name="row_spacing">10</property>
<property name="column_spacing">6</property>
<property name="row_homogeneous">True</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkLabel" id="heading_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Hardware Address</property>
<property name="mnemonic_widget">label_mac</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_ipv4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">IPv4 Address</property>
<property name="mnemonic_widget">label_ipv4</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_ipv6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">IPv6 Address</property>
<property name="mnemonic_widget">label_ipv6</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_route">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Default Route</property>
<property name="mnemonic_widget">label_route</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="heading_dns">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="yalign">0</property>
<property name="label" translatable="yes">DNS</property>
<property name="mnemonic_widget">label_dns</property>
<style>
<class name="dim-label"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_mac">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">AA:BB:CC:DD:55:66:77:88</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_ipv4">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">127.0.0.1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_ipv6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">::1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_route">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="label">127.0.0.1</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_dns">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label">127.0.0.1</property>
<property name="wrap">True</property>
<property name="selectable">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">3</property>
<property name="height">1</property>
</packing>
</child>
</object>
<packing>
@@ -321,13 +335,5 @@
</object>
</child>
</object>
<object class="GtkSizeGroup" id="sizegroup1">
<widgets>
<widget name="heading_mac"/>
<widget name="heading_ipv4"/>
<widget name="heading_ipv6"/>
<widget name="heading_route"/>
<widget name="heading_dns"/>
</widgets>
</object>
<object class="GtkSizeGroup" id="sizegroup1"/>
</interface>

File diff suppressed because it is too large Load Diff

View File

@@ -1,144 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
*
* 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 <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "panel-cell-renderer-mode.h"
enum {
PROP_0,
PROP_AP_MODE,
PROP_LAST
};
G_DEFINE_TYPE (PanelCellRendererMode, panel_cell_renderer_mode, GTK_TYPE_CELL_RENDERER_PIXBUF)
static gpointer parent_class = NULL;
/**
* panel_cell_renderer_mode_get_property:
**/
static void
panel_cell_renderer_mode_get_property (GObject *object, guint param_id,
GValue *value, GParamSpec *pspec)
{
PanelCellRendererMode *renderer = PANEL_CELL_RENDERER_MODE (object);
switch (param_id) {
case PROP_AP_MODE:
g_value_set_uint (value, renderer->mode);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
/**
* panel_cell_renderer_set_name:
**/
static void
panel_cell_renderer_set_name (PanelCellRendererMode *renderer)
{
const gchar *icon_name = NULL;
if (renderer->mode == NM_802_11_MODE_ADHOC)
icon_name = "network-workgroup-symbolic";
g_object_set (renderer, "icon-name", icon_name, NULL);
}
/**
* panel_cell_renderer_mode_set_property:
**/
static void
panel_cell_renderer_mode_set_property (GObject *object, guint param_id,
const GValue *value, GParamSpec *pspec)
{
PanelCellRendererMode *renderer = PANEL_CELL_RENDERER_MODE (object);
switch (param_id) {
case PROP_AP_MODE:
renderer->mode = g_value_get_uint (value);
panel_cell_renderer_set_name (renderer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
/**
* panel_cell_renderer_finalize:
**/
static void
panel_cell_renderer_finalize (GObject *object)
{
PanelCellRendererMode *renderer;
renderer = PANEL_CELL_RENDERER_MODE (object);
g_free (renderer->icon_name);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* panel_cell_renderer_mode_class_init:
**/
static void
panel_cell_renderer_mode_class_init (PanelCellRendererModeClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = panel_cell_renderer_finalize;
parent_class = g_type_class_peek_parent (class);
object_class->get_property = panel_cell_renderer_mode_get_property;
object_class->set_property = panel_cell_renderer_mode_set_property;
g_object_class_install_property (object_class, PROP_AP_MODE,
g_param_spec_uint ("ap-mode", NULL,
NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE));
}
/**
* panel_cell_renderer_mode_init:
**/
static void
panel_cell_renderer_mode_init (PanelCellRendererMode *renderer)
{
renderer->mode = 0;
renderer->icon_name = NULL;
}
/**
* panel_cell_renderer_mode_new:
**/
GtkCellRenderer *
panel_cell_renderer_mode_new (void)
{
return g_object_new (PANEL_TYPE_CELL_RENDERER_MODE, NULL);
}

View File

@@ -1,61 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
*
* 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 PANEL_CELL_RENDERER_MODE_H
#define PANEL_CELL_RENDERER_MODE_H
#include <glib-object.h>
#include <gtk/gtk.h>
#include "nm-device.h"
#include "nm-access-point.h"
#define PANEL_TYPE_CELL_RENDERER_MODE (panel_cell_renderer_mode_get_type())
#define PANEL_CELL_RENDERER_MODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_MODE, PanelCellRendererMode))
#define PANEL_CELL_RENDERER_MODE_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_MODE, PanelCellRendererModeClass))
#define PANEL_IS_CELL_RENDERER_MODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_MODE))
#define PANEL_IS_CELL_RENDERER_MODE_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_MODE))
#define PANEL_CELL_RENDERER_MODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_MODE, PanelCellRendererModeClass))
G_BEGIN_DECLS
typedef struct _PanelCellRendererMode PanelCellRendererMode;
typedef struct _PanelCellRendererModeClass PanelCellRendererModeClass;
struct _PanelCellRendererMode
{
GtkCellRendererPixbuf parent;
guint mode;
gchar *icon_name;
};
struct _PanelCellRendererModeClass
{
GtkCellRendererPixbufClass parent_class;
};
GType panel_cell_renderer_mode_get_type (void);
GtkCellRenderer *panel_cell_renderer_mode_new (void);
G_END_DECLS
#endif /* PANEL_CELL_RENDERER_MODE_H */

View File

@@ -1,82 +0,0 @@
/* -*- Pixbuf: C; tab-width: 8; indent-tabs-pixbuf: 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.
*
* Written by Matthias Clasen
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "panel-cell-renderer-pixbuf.h"
enum {
ACTIVATE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (PanelCellRendererPixbuf, panel_cell_renderer_pixbuf, GTK_TYPE_CELL_RENDERER_PIXBUF)
static gint
activate (GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
g_signal_emit (cell, signals[ACTIVATE], 0, path);
return TRUE;
}
static void
panel_cell_renderer_pixbuf_class_init (PanelCellRendererPixbufClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
cell_renderer_class->activate = activate;
signals[ACTIVATE] =
g_signal_new ("activate",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (PanelCellRendererPixbufClass, activate),
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
}
static void
panel_cell_renderer_pixbuf_init (PanelCellRendererPixbuf *renderer)
{
}
GtkCellRenderer *
panel_cell_renderer_pixbuf_new (void)
{
return g_object_new (PANEL_TYPE_CELL_RENDERER_PIXBUF, NULL);
}

View File

@@ -1,61 +0,0 @@
/* -*- Pixbuf: C; tab-width: 8; indent-tabs-pixbuf: 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.
*
* Written by Matthias Clasen
*/
#ifndef PANEL_CELL_RENDERER_PIXBUF_H
#define PANEL_CELL_RENDERER_PIXBUF_H
#include <glib-object.h>
#include <gtk/gtk.h>
#define PANEL_TYPE_CELL_RENDERER_PIXBUF (panel_cell_renderer_pixbuf_get_type())
#define PANEL_CELL_RENDERER_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_PIXBUF, PanelCellRendererPixbuf))
#define PANEL_CELL_RENDERER_PIXBUF_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_PIXBUF, PanelCellRendererPixbufClass))
#define PANEL_IS_CELL_RENDERER_PIXBUF(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_PIXBUF))
#define PANEL_IS_CELL_RENDERER_PIXBUF_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_PIXBUF))
#define PANEL_CELL_RENDERER_PIXBUF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_PIXBUF, PanelCellRendererPixbufClass))
G_BEGIN_DECLS
typedef struct _PanelCellRendererPixbuf PanelCellRendererPixbuf;
typedef struct _PanelCellRendererPixbufClass PanelCellRendererPixbufClass;
struct _PanelCellRendererPixbuf
{
GtkCellRendererPixbuf parent;
};
struct _PanelCellRendererPixbufClass
{
GtkCellRendererPixbufClass parent_class;
void (*activate) (PanelCellRendererPixbuf *pixbuf,
const gchar *path);
};
GType panel_cell_renderer_pixbuf_get_type (void);
GtkCellRenderer *panel_cell_renderer_pixbuf_new (void);
G_END_DECLS
#endif /* PANEL_CELL_RENDERER_PIXBUF_H */

View File

@@ -1,153 +0,0 @@
/* -*- Security: C; tab-width: 8; indent-tabs-security: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2011 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 <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "panel-cell-renderer-security.h"
enum {
PROP_0,
PROP_SECURITY,
PROP_LAST
};
G_DEFINE_TYPE (PanelCellRendererSecurity, panel_cell_renderer_security, GTK_TYPE_CELL_RENDERER_PIXBUF)
static gpointer parent_class = NULL;
/**
* panel_cell_renderer_security_get_property:
**/
static void
panel_cell_renderer_security_get_property (GObject *object, guint param_id,
GValue *value, GParamSpec *pspec)
{
PanelCellRendererSecurity *renderer = PANEL_CELL_RENDERER_SECURITY (object);
switch (param_id) {
case PROP_SECURITY:
g_value_set_uint (value, renderer->security);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
/**
* panel_cell_renderer_set_name:
**/
static void
panel_cell_renderer_set_name (PanelCellRendererSecurity *renderer)
{
const gchar *icon_name = NULL;
if (renderer->security != NM_AP_SEC_UNKNOWN &&
renderer->security != NM_AP_SEC_NONE)
icon_name = "network-wireless-encrypted-symbolic";
if (icon_name != NULL) {
g_object_set (renderer,
"icon-name", icon_name,
NULL);
} else {
g_object_set (renderer,
"icon-name", "",
NULL);
}
}
/**
* panel_cell_renderer_security_set_property:
**/
static void
panel_cell_renderer_security_set_property (GObject *object, guint param_id,
const GValue *value, GParamSpec *pspec)
{
PanelCellRendererSecurity *renderer = PANEL_CELL_RENDERER_SECURITY (object);
switch (param_id) {
case PROP_SECURITY:
renderer->security = g_value_get_uint (value);
panel_cell_renderer_set_name (renderer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
/**
* panel_cell_renderer_finalize:
**/
static void
panel_cell_renderer_finalize (GObject *object)
{
PanelCellRendererSecurity *renderer;
renderer = PANEL_CELL_RENDERER_SECURITY (object);
g_free (renderer->icon_name);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* panel_cell_renderer_security_class_init:
**/
static void
panel_cell_renderer_security_class_init (PanelCellRendererSecurityClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = panel_cell_renderer_finalize;
parent_class = g_type_class_peek_parent (class);
object_class->get_property = panel_cell_renderer_security_get_property;
object_class->set_property = panel_cell_renderer_security_set_property;
g_object_class_install_property (object_class, PROP_SECURITY,
g_param_spec_uint ("security", NULL,
NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE));
}
/**
* panel_cell_renderer_security_init:
**/
static void
panel_cell_renderer_security_init (PanelCellRendererSecurity *renderer)
{
renderer->security = 0;
renderer->icon_name = NULL;
}
/**
* panel_cell_renderer_security_new:
**/
GtkCellRenderer *
panel_cell_renderer_security_new (void)
{
return g_object_new (PANEL_TYPE_CELL_RENDERER_SECURITY, NULL);
}

View File

@@ -1,69 +0,0 @@
/* -*- Security: C; tab-width: 8; indent-tabs-security: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2011 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 PANEL_CELL_RENDERER_SECURITY_H
#define PANEL_CELL_RENDERER_SECURITY_H
#include <glib-object.h>
#include <gtk/gtk.h>
#include "nm-device.h"
#include "nm-access-point.h"
#define PANEL_TYPE_CELL_RENDERER_SECURITY (panel_cell_renderer_security_get_type())
#define PANEL_CELL_RENDERER_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_SECURITY, PanelCellRendererSecurity))
#define PANEL_CELL_RENDERER_SECURITY_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_SECURITY, PanelCellRendererSecurityClass))
#define PANEL_IS_CELL_RENDERER_SECURITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_SECURITY))
#define PANEL_IS_CELL_RENDERER_SECURITY_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_SECURITY))
#define PANEL_CELL_RENDERER_SECURITY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_SECURITY, PanelCellRendererSecurityClass))
G_BEGIN_DECLS
typedef struct _PanelCellRendererSecurity PanelCellRendererSecurity;
typedef struct _PanelCellRendererSecurityClass PanelCellRendererSecurityClass;
typedef enum {
NM_AP_SEC_UNKNOWN,
NM_AP_SEC_NONE,
NM_AP_SEC_WEP,
NM_AP_SEC_WPA,
NM_AP_SEC_WPA2
} NMAccessPointSecurity;
struct _PanelCellRendererSecurity
{
GtkCellRendererPixbuf parent;
guint security;
gchar *icon_name;
};
struct _PanelCellRendererSecurityClass
{
GtkCellRendererPixbufClass parent_class;
};
GType panel_cell_renderer_security_get_type (void);
GtkCellRenderer *panel_cell_renderer_security_new (void);
G_END_DECLS
#endif /* PANEL_CELL_RENDERER_SECURITY_H */

View File

@@ -1,130 +0,0 @@
/* -*- Separator: C; tab-width: 8; indent-tabs-separator: 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.
*
* Written by Matthias Clasen
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "panel-cell-renderer-separator.h"
enum {
PROP_0,
PROP_DRAW,
PROP_LAST
};
G_DEFINE_TYPE (PanelCellRendererSeparator, panel_cell_renderer_separator, GTK_TYPE_CELL_RENDERER)
static void
panel_cell_renderer_separator_get_property (GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
{
PanelCellRendererSeparator *renderer = PANEL_CELL_RENDERER_SEPARATOR (object);
switch (param_id) {
case PROP_DRAW:
g_value_set_boolean (value, renderer->draw);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
panel_cell_renderer_separator_set_property (GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
PanelCellRendererSeparator *renderer = PANEL_CELL_RENDERER_SEPARATOR (object);
switch (param_id) {
case PROP_DRAW:
renderer->draw = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
static void
render (GtkCellRenderer *cell,
cairo_t *cr,
GtkWidget *widget,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
PanelCellRendererSeparator *renderer = PANEL_CELL_RENDERER_SEPARATOR (cell);
GtkStyleContext *context;
gint x, y, w, h, xpad, ypad;
if (!renderer->draw)
return;
context = gtk_widget_get_style_context (widget);
gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
x = cell_area->x + xpad;
y = cell_area->y + ypad;
w = cell_area->width - xpad * 2;
h = cell_area->height - ypad * 2;
gtk_render_line (context, cr, x + w / 2, y, x + w / 2, y + h - 1);
}
static void
panel_cell_renderer_separator_class_init (PanelCellRendererSeparatorClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
object_class->get_property = panel_cell_renderer_separator_get_property;
object_class->set_property = panel_cell_renderer_separator_set_property;
cell_renderer_class->render = render;
g_object_class_install_property (object_class, PROP_DRAW,
g_param_spec_boolean ("draw", "draw", "draw",
TRUE,
G_PARAM_READWRITE));
}
static void
panel_cell_renderer_separator_init (PanelCellRendererSeparator *renderer)
{
renderer->draw = TRUE;
}
GtkCellRenderer *
panel_cell_renderer_separator_new (void)
{
return g_object_new (PANEL_TYPE_CELL_RENDERER_SEPARATOR, NULL);
}

View File

@@ -1,62 +0,0 @@
/* -*- Separator: C; tab-width: 8; indent-tabs-separator: 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.
*
* Written by Matthias Clasen
*/
#ifndef PANEL_CELL_RENDERER_SEPARATOR_H
#define PANEL_CELL_RENDERER_SEPARATOR_H
#include <glib-object.h>
#include <gtk/gtk.h>
#include "nm-device.h"
#include "nm-access-point.h"
#define PANEL_TYPE_CELL_RENDERER_SEPARATOR (panel_cell_renderer_separator_get_type())
#define PANEL_CELL_RENDERER_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_SEPARATOR, PanelCellRendererSeparator))
#define PANEL_CELL_RENDERER_SEPARATOR_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_SEPARATOR, PanelCellRendererSeparatorClass))
#define PANEL_IS_CELL_RENDERER_SEPARATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_SEPARATOR))
#define PANEL_IS_CELL_RENDERER_SEPARATOR_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_SEPARATOR))
#define PANEL_CELL_RENDERER_SEPARATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_SEPARATOR, PanelCellRendererSeparatorClass))
G_BEGIN_DECLS
typedef struct _PanelCellRendererSeparator PanelCellRendererSeparator;
typedef struct _PanelCellRendererSeparatorClass PanelCellRendererSeparatorClass;
struct _PanelCellRendererSeparator
{
GtkCellRenderer parent;
gboolean draw;
};
struct _PanelCellRendererSeparatorClass
{
GtkCellRendererClass parent_class;
};
GType panel_cell_renderer_separator_get_type (void);
GtkCellRenderer *panel_cell_renderer_separator_new (void);
G_END_DECLS
#endif /* PANEL_CELL_RENDERER_SEPARATOR_H */

View File

@@ -1,161 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-signal: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
*
* 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 <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "panel-cell-renderer-signal.h"
enum {
PROP_0,
PROP_SIGNAL,
PROP_LAST
};
G_DEFINE_TYPE (PanelCellRendererSignal, panel_cell_renderer_signal, GTK_TYPE_CELL_RENDERER_PIXBUF)
static gpointer parent_class = NULL;
/**
* panel_cell_renderer_signal_get_property:
**/
static void
panel_cell_renderer_signal_get_property (GObject *object, guint param_id,
GValue *value, GParamSpec *pspec)
{
PanelCellRendererSignal *renderer = PANEL_CELL_RENDERER_SIGNAL (object);
switch (param_id) {
case PROP_SIGNAL:
g_value_set_uint (value, renderer->signal);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
/**
* panel_cell_renderer_set_name:
**/
static void
panel_cell_renderer_set_name (PanelCellRendererSignal *renderer)
{
const gchar *icon_name = NULL;
GIcon *icon;
/* the 'Other...' entry */
if (renderer->signal <= 0) {
g_object_set (renderer, "gicon", NULL, NULL);
return;
}
if (renderer->signal < 20)
icon_name = "network-wireless-signal-none-symbolic";
else if (renderer->signal < 40)
icon_name = "network-wireless-signal-weak-symbolic";
else if (renderer->signal < 50)
icon_name = "network-wireless-signal-ok-symbolic";
else if (renderer->signal < 80)
icon_name = "network-wireless-signal-good-symbolic";
else
icon_name = "network-wireless-signal-excellent-symbolic";
icon = g_themed_icon_new_with_default_fallbacks (icon_name);
g_object_set (renderer, "gicon", icon, NULL);
g_object_unref (icon);
}
/**
* panel_cell_renderer_signal_set_property:
**/
static void
panel_cell_renderer_signal_set_property (GObject *object, guint param_id,
const GValue *value, GParamSpec *pspec)
{
PanelCellRendererSignal *renderer = PANEL_CELL_RENDERER_SIGNAL (object);
switch (param_id) {
case PROP_SIGNAL:
renderer->signal = g_value_get_uint (value);
panel_cell_renderer_set_name (renderer);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
}
}
/**
* panel_cell_renderer_finalize:
**/
static void
panel_cell_renderer_finalize (GObject *object)
{
PanelCellRendererSignal *renderer;
renderer = PANEL_CELL_RENDERER_SIGNAL (object);
g_free (renderer->icon_name);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
* panel_cell_renderer_signal_class_init:
**/
static void
panel_cell_renderer_signal_class_init (PanelCellRendererSignalClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->finalize = panel_cell_renderer_finalize;
parent_class = g_type_class_peek_parent (class);
object_class->get_property = panel_cell_renderer_signal_get_property;
object_class->set_property = panel_cell_renderer_signal_set_property;
g_object_class_install_property (object_class, PROP_SIGNAL,
g_param_spec_uint ("signal", NULL,
NULL,
0, G_MAXUINT, 0,
G_PARAM_READWRITE));
}
/**
* panel_cell_renderer_signal_init:
**/
static void
panel_cell_renderer_signal_init (PanelCellRendererSignal *renderer)
{
renderer->signal = 0;
renderer->icon_name = NULL;
}
/**
* panel_cell_renderer_signal_new:
**/
GtkCellRenderer *
panel_cell_renderer_signal_new (void)
{
return g_object_new (PANEL_TYPE_CELL_RENDERER_SIGNAL, NULL);
}

View File

@@ -1,61 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-signal: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2010 Richard Hughes <richard@hughsie.com>
*
* 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 PANEL_CELL_RENDERER_SIGNAL_H
#define PANEL_CELL_RENDERER_SIGNAL_H
#include <glib-object.h>
#include <gtk/gtk.h>
#include "nm-device.h"
#include "nm-access-point.h"
#define PANEL_TYPE_CELL_RENDERER_SIGNAL (panel_cell_renderer_signal_get_type())
#define PANEL_CELL_RENDERER_SIGNAL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_SIGNAL, PanelCellRendererSignal))
#define PANEL_CELL_RENDERER_SIGNAL_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_SIGNAL, PanelCellRendererSignalClass))
#define PANEL_IS_CELL_RENDERER_SIGNAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_SIGNAL))
#define PANEL_IS_CELL_RENDERER_SIGNAL_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_SIGNAL))
#define PANEL_CELL_RENDERER_SIGNAL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_SIGNAL, PanelCellRendererSignalClass))
G_BEGIN_DECLS
typedef struct _PanelCellRendererSignal PanelCellRendererSignal;
typedef struct _PanelCellRendererSignalClass PanelCellRendererSignalClass;
struct _PanelCellRendererSignal
{
GtkCellRendererPixbuf parent;
guint signal;
gchar *icon_name;
};
struct _PanelCellRendererSignalClass
{
GtkCellRendererPixbufClass parent_class;
};
GType panel_cell_renderer_signal_get_type (void);
GtkCellRenderer *panel_cell_renderer_signal_new (void);
G_END_DECLS
#endif /* PANEL_CELL_RENDERER_SIGNAL_H */

View File

@@ -1,82 +0,0 @@
/* -*- Text: C; tab-width: 8; indent-tabs-text: 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.
*
* Written by Matthias Clasen
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "panel-cell-renderer-text.h"
enum {
ACTIVATE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (PanelCellRendererText, panel_cell_renderer_text, GTK_TYPE_CELL_RENDERER_TEXT)
static gint
activate (GtkCellRenderer *cell,
GdkEvent *event,
GtkWidget *widget,
const gchar *path,
const GdkRectangle *background_area,
const GdkRectangle *cell_area,
GtkCellRendererState flags)
{
g_signal_emit (cell, signals[ACTIVATE], 0, path);
return TRUE;
}
static void
panel_cell_renderer_text_class_init (PanelCellRendererTextClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkCellRendererClass *cell_renderer_class = GTK_CELL_RENDERER_CLASS (class);
cell_renderer_class->activate = activate;
signals[ACTIVATE] =
g_signal_new ("activate",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (PanelCellRendererTextClass, activate),
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
}
static void
panel_cell_renderer_text_init (PanelCellRendererText *renderer)
{
}
GtkCellRenderer *
panel_cell_renderer_text_new (void)
{
return g_object_new (PANEL_TYPE_CELL_RENDERER_TEXT, NULL);
}

View File

@@ -1,61 +0,0 @@
/* -*- Text: C; tab-width: 8; indent-tabs-text: 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.
*
* Written by Matthias Clasen
*/
#ifndef PANEL_CELL_RENDERER_TEXT_H
#define PANEL_CELL_RENDERER_TEXT_H
#include <glib-object.h>
#include <gtk/gtk.h>
#define PANEL_TYPE_CELL_RENDERER_TEXT (panel_cell_renderer_text_get_type())
#define PANEL_CELL_RENDERER_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PANEL_TYPE_CELL_RENDERER_TEXT, PanelCellRendererText))
#define PANEL_CELL_RENDERER_TEXT_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), PANEL_TYPE_CELL_RENDERER_TEXT, PanelCellRendererTextClass))
#define PANEL_IS_CELL_RENDERER_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PANEL_TYPE_CELL_RENDERER_TEXT))
#define PANEL_IS_CELL_RENDERER_TEXT_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), PANEL_TYPE_CELL_RENDERER_TEXT))
#define PANEL_CELL_RENDERER_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_CELL_RENDERER_TEXT, PanelCellRendererTextClass))
G_BEGIN_DECLS
typedef struct _PanelCellRendererText PanelCellRendererText;
typedef struct _PanelCellRendererTextClass PanelCellRendererTextClass;
struct _PanelCellRendererText
{
GtkCellRendererText parent;
};
struct _PanelCellRendererTextClass
{
GtkCellRendererTextClass parent_class;
void (*activate) (PanelCellRendererText *text,
const gchar *path);
};
GType panel_cell_renderer_text_get_type (void);
GtkCellRenderer *panel_cell_renderer_text_new (void);
G_END_DECLS
#endif /* PANEL_CELL_RENDERER_TEXT_H */

View File

@@ -655,3 +655,21 @@ panel_unset_device_widgets (GtkBuilder *builder)
panel_set_device_widget_details (builder, "dns", NULL);
panel_set_device_widget_details (builder, "route", NULL);
}
gchar *
panel_get_ip4_address_as_string (NMIP4Config *ip4, const gchar *what)
{
return get_ipv4_config_address_as_string (ip4, what);
}
gchar *
panel_get_ip4_dns_as_string (NMIP4Config *ip4)
{
return get_ipv4_config_name_servers_as_string (ip4);
}
gchar *
panel_get_ip6_address_as_string (NMIP6Config *ip6)
{
return get_ipv6_config_address_as_string (ip6);
}

View File

@@ -45,6 +45,9 @@ gboolean panel_set_device_widget_header (GtkBuilder *buil
void panel_set_device_widgets (GtkBuilder *builder,
NMDevice *device);
void panel_unset_device_widgets (GtkBuilder *builder);
gchar *panel_get_ip4_address_as_string (NMIP4Config *config, const gchar *what);
gchar *panel_get_ip4_dns_as_string (NMIP4Config *config);
gchar *panel_get_ip6_address_as_string (NMIP6Config *config);
G_END_DECLS

View File

@@ -0,0 +1,59 @@
noinst_LTLIBRARIES = libwireless-security.la
libwireless_security_la_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_CPPFLAGS = \
$(NETWORK_PANEL_CFLAGS) \
$(NETWORK_MANAGER_CFLAGS) \
-DUIDIR=\""$(uidir)"\"
libwireless_security_la_LIBADD = \
$(NETWORK_PANEL_LIBS) \
$(NETWORK_MANAGER_LIBS)
uidir = $(pkgdatadir)/ui
ui_DATA = \
eap-method-leap.ui \
eap-method-fast.ui \
eap-method-peap.ui \
eap-method-simple.ui \
eap-method-tls.ui \
eap-method-ttls.ui \
nag-user-dialog.ui \
ws-dynamic-wep.ui \
ws-leap.ui \
ws-wep-key.ui \
ws-wpa-eap.ui \
ws-wpa-psk.ui
EXTRA_DIST = \
$(ui_DATA)

View File

@@ -0,0 +1,443 @@
/* -*- 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.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
#include "wireless-security.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)
{
GtkWidget *widget;
GtkTreeModel *model;
GtkTreeIter iter;
EAPMethod *eap = NULL;
const char *file;
gboolean provisioning;
gboolean valid = FALSE;
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)
return FALSE;
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);
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)
{
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);
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;
auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_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);
}
em_gtc = eap_method_simple_new (method->sec_parent,
connection,
EAP_METHOD_SIMPLE_TYPE_GTC,
TRUE,
method->is_editor,
secrets_only);
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,
TRUE,
method->is_editor, secrets_only);
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,
UIDIR "/eap-method-fast.ui",
"eap_fast_notebook",
"eap_fast_anon_identity_entry",
FALSE);
if (!parent)
return NULL;
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;
}

View File

@@ -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 */

View File

@@ -0,0 +1,203 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="eap_fast_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table13">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">5</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="eap_fast_anon_identity_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Anony_mous identity</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_fast_anon_identity_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_fast_anon_identity_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_fast_pac_file_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">PAC _file</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_fast_pac_file_button</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="eap_fast_pac_file_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="eap_fast_inner_auth_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_fast_inner_auth_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Inner authentication</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_fast_inner_auth_combo</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="eap_fast_inner_auth_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model8</property>
<child>
<object class="GtkCellRendererText" id="renderer8"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="eap_fast_pac_provision_checkbutton">
<property name="label" translatable="yes">PAC pro_visioning</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="eap_fast_pac_provision_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model9</property>
<child>
<object class="GtkCellRendererText" id="renderer9"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label61">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<object class="GtkListStore" id="model8">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes"> </col>
</row>
</data>
</object>
<object class="GtkListStore" id="model9">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Anonymous</col>
</row>
<row>
<col id="0" translatable="yes">Authenticated</col>
</row>
<row>
<col id="0" translatable="yes">Both</col>
</row>
</data>
</object>
</interface>

View File

@@ -0,0 +1,183 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include <ctype.h>
#include <string.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
#include "wireless-security.h"
#include "helpers.h"
struct _EAPMethodLEAP {
EAPMethod parent;
gboolean new_connection;
};
static void
show_toggled_cb (GtkCheckButton *button, EAPMethod *method)
{
GtkWidget *widget;
gboolean visible;
widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_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 (EAPMethod *parent)
{
GtkWidget *widget;
const char *text;
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry"));
g_assert (widget);
text = gtk_entry_get_text (GTK_ENTRY (widget));
if (!text || !strlen (text))
return FALSE;
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry"));
g_assert (widget);
text = gtk_entry_get_text (GTK_ENTRY (widget));
if (!text || !strlen (text))
return FALSE;
return TRUE;
}
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)
{
EAPMethodLEAP *method = (EAPMethodLEAP *) parent;
NMSetting8021x *s_8021x;
GtkWidget *widget;
s_8021x = nm_connection_get_setting_802_1x (connection);
g_assert (s_8021x);
nm_setting_802_1x_add_eap_method (s_8021x, "leap");
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry"));
g_assert (widget);
g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_password_entry"));
g_assert (widget);
g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
/* Default to agent-owned secrets for new connections */
if (method->new_connection) {
g_object_set (s_8021x,
NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
NM_SETTING_802_1X_SYSTEM_CA_CERTS, TRUE,
NULL);
}
}
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);
}
EAPMethodLEAP *
eap_method_leap_new (WirelessSecurity *ws_parent,
NMConnection *connection,
gboolean secrets_only)
{
EAPMethodLEAP *method;
EAPMethod *parent;
GtkWidget *widget;
parent = eap_method_init (sizeof (EAPMethodLEAP),
validate,
add_to_size_group,
fill_connection,
update_secrets,
NULL,
UIDIR "/eap-method-leap.ui",
"eap_leap_notebook",
"eap_leap_username_entry",
FALSE);
if (!parent)
return NULL;
method = (EAPMethodLEAP *) parent;
method->new_connection = secrets_only ? FALSE : TRUE;
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_leap_username_entry"));
g_assert (widget);
g_signal_connect (G_OBJECT (widget), "changed",
(GCallback) wireless_security_changed_cb,
ws_parent);
if (connection) {
NMSetting8021x *s_8021x;
s_8021x = nm_connection_get_setting_802_1x (connection);
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));
}
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);
g_signal_connect (G_OBJECT (widget), "changed",
(GCallback) wireless_security_changed_cb,
ws_parent);
/* Fill secrets, if any */
if (connection)
update_secrets (parent, connection);
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapleap"));
g_assert (widget);
g_signal_connect (G_OBJECT (widget), "toggled",
(GCallback) show_toggled_cb,
parent);
return method;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 */

View File

@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="eap_leap_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="eap_leap_username_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Username</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_leap_username_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_leap_password_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_leap_password_entry</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_leap_password_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_checkbutton_eapleap">
<property name="label" translatable="yes">Sho_w password</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_leap_username_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label43">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,414 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
#include "wireless-security.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)
{
GtkWidget *widget;
GtkTreeModel *model;
GtkTreeIter iter;
EAPMethod *eap = NULL;
gboolean valid = FALSE;
if (!eap_method_validate_filepicker (parent->builder, "eap_peap_ca_cert_button", TYPE_CA_CERT, NULL, NULL))
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);
eap_method_unref (eap);
return valid;
}
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_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)
{
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;
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);
}
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);
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;
auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_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);
}
em_mschap_v2 = eap_method_simple_new (method->sec_parent,
connection,
EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
TRUE,
method->is_editor,
secrets_only);
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,
TRUE,
method->is_editor,
secrets_only);
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,
TRUE,
method->is_editor,
secrets_only);
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;
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,
UIDIR "/eap-method-peap.ui",
"eap_peap_notebook",
"eap_peap_anon_identity_entry",
FALSE);
if (!parent)
return NULL;
eap_method_nag_init (parent, "eap_peap_ca_cert_button", connection);
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_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) {
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);
}
}
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_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;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 */

View File

@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="model8">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes"> </col>
</row>
</data>
</object>
<object class="GtkListStore" id="model9">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Automatic</col>
</row>
<row>
<col id="0" translatable="yes">Version 0</col>
</row>
<row>
<col id="0" translatable="yes">Version 1</col>
</row>
</data>
</object>
<object class="GtkNotebook" id="eap_peap_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table13">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">5</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="eap_peap_anon_identity_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Anony_mous identity</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_peap_anon_identity_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_peap_anon_identity_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_peap_ca_cert_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">C_A certificate</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_peap_ca_cert_button</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="eap_peap_ca_cert_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="eap_peap_inner_auth_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_peap_inner_auth_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Inner authentication</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_peap_inner_auth_combo</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="eap_peap_inner_auth_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model8</property>
<child>
<object class="GtkCellRendererText" id="renderer8"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_peap_version_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">PEAP _version</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_peap_version_combo</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="eap_peap_version_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model9</property>
<child>
<object class="GtkCellRendererText" id="renderer9"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label61">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,305 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 - 2011 Red Hat, Inc.
*/
#include <ctype.h>
#include <string.h>
#include <nm-setting-8021x.h>
#include <nm-setting-connection.h>
#include "eap-method.h"
#include "wireless-security.h"
#include "helpers.h"
struct _EAPMethodSimple {
EAPMethod parent;
EAPMethodSimpleType type;
gboolean is_editor;
gboolean new_connection;
};
static void
show_toggled_cb (GtkCheckButton *button, EAPMethod *method)
{
GtkWidget *widget;
gboolean visible;
widget = GTK_WIDGET (gtk_builder_get_object (method->builder, "eap_simple_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)
{
GtkWidget *widget;
const char *text;
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry"));
g_assert (widget);
text = gtk_entry_get_text (GTK_ENTRY (widget));
if (!text || !strlen (text))
return FALSE;
/* Check if the password should always be requested */
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask"));
g_assert (widget);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
return TRUE;
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
g_assert (widget);
text = gtk_entry_get_text (GTK_ENTRY (widget));
if (!text || !strlen (text))
return FALSE;
return TRUE;
}
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);
}
static void
fill_connection (EAPMethod *parent, NMConnection *connection)
{
EAPMethodSimple *method = (EAPMethodSimple *) parent;
NMSetting8021x *s_8021x;
GtkWidget *widget;
gboolean not_saved = FALSE;
const char *eap = NULL;
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
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);
switch (method->type) {
case EAP_METHOD_SIMPLE_TYPE_PAP:
eap = "pap";
break;
case EAP_METHOD_SIMPLE_TYPE_MSCHAP:
eap = "mschap";
break;
case EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2:
eap = "mschapv2";
break;
case EAP_METHOD_SIMPLE_TYPE_MD5:
eap = "md5";
break;
case EAP_METHOD_SIMPLE_TYPE_CHAP:
eap = "chap";
break;
case EAP_METHOD_SIMPLE_TYPE_GTC:
eap = "gtc";
break;
default:
g_assert_not_reached ();
break;
}
if (parent->phase2)
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, eap, NULL);
else
nm_setting_802_1x_add_eap_method (s_8021x, eap);
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry"));
g_assert (widget);
g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
/* Save the password always ask setting */
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask"));
g_assert (widget);
not_saved = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
nm_setting_get_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, &flags, NULL);
flags &= ~(NM_SETTING_SECRET_FLAG_NOT_SAVED);
if (not_saved)
flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED;
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->is_editor == FALSE || not_saved == FALSE) {
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
g_assert (widget);
g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
}
/* Default to agent-owned secrets for new connections */
if (method->new_connection && (not_saved == FALSE)) {
g_object_set (s_8021x,
NM_SETTING_802_1X_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
NM_SETTING_802_1X_SYSTEM_CA_CERTS, TRUE,
NULL);
}
}
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 void
password_always_ask_changed (GtkButton *button, EAPMethodSimple *method)
{
EAPMethod *parent = (EAPMethod *) method;
GtkWidget *password_entry;
GtkWidget *show_checkbox;
gboolean always_ask;
always_ask = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
password_entry = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
g_assert (password_entry);
show_checkbox = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple"));
g_assert (show_checkbox);
if (always_ask) {
gtk_entry_set_text (GTK_ENTRY (password_entry), "");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_checkbox), FALSE);
}
gtk_widget_set_sensitive (password_entry, !always_ask);
gtk_widget_set_sensitive (show_checkbox, !always_ask);
}
EAPMethodSimple *
eap_method_simple_new (WirelessSecurity *ws_parent,
NMConnection *connection,
EAPMethodSimpleType type,
gboolean phase2,
gboolean is_editor,
gboolean secrets_only)
{
EAPMethod *parent;
EAPMethodSimple *method;
GtkWidget *widget;
gboolean not_saved = FALSE;
NMSetting8021x *s_8021x = NULL;
parent = eap_method_init (sizeof (EAPMethodSimple),
validate,
add_to_size_group,
fill_connection,
update_secrets,
NULL,
UIDIR "/eap-method-simple.ui",
"eap_simple_notebook",
"eap_simple_username_entry",
phase2);
if (!parent)
return NULL;
method = (EAPMethodSimple *) parent;
method->type = type;
method->is_editor = is_editor;
method->new_connection = secrets_only ? FALSE : TRUE;
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_username_entry"));
g_assert (widget);
g_signal_connect (G_OBJECT (widget), "changed",
(GCallback) wireless_security_changed_cb,
ws_parent);
if (connection) {
s_8021x = nm_connection_get_setting_802_1x (connection);
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));
}
if (secrets_only)
gtk_widget_set_sensitive (widget, FALSE);
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_simple_password_entry"));
g_assert (widget);
g_signal_connect (G_OBJECT (widget), "changed",
(GCallback) wireless_security_changed_cb,
ws_parent);
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "eap_password_always_ask"));
g_assert (widget);
g_signal_connect (G_OBJECT (widget), "toggled",
(GCallback) wireless_security_changed_cb,
ws_parent);
if (is_editor) {
/* We only desensitize the password entry from the editor, because
* from nm-applet if the entry was desensitized, there'd be no way to
* get the password back to NetworkManager when NM asked for it. Since
* the editor only sets up the initial connection though, it's safe to
* do there.
*/
g_signal_connect (G_OBJECT (widget), "toggled",
G_CALLBACK (password_always_ask_changed),
method);
}
if (secrets_only)
gtk_widget_hide (widget);
if (s_8021x) {
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
nm_setting_get_secret_flags (NM_SETTING (s_8021x), NM_SETTING_802_1X_PASSWORD, &flags, NULL);
not_saved = (flags & NM_SETTING_SECRET_FLAG_NOT_SAVED);
}
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), not_saved);
/* Fill secrets if there's a static (ie, not OTP) password */
if (connection && (not_saved == FALSE))
update_secrets (EAP_METHOD (method), connection);
widget = GTK_WIDGET (gtk_builder_get_object (parent->builder, "show_checkbutton_eapsimple"));
g_assert (widget);
g_signal_connect (G_OBJECT (widget), "toggled",
(GCallback) show_toggled_cb,
method);
return method;
}

View File

@@ -0,0 +1,47 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 {
EAP_METHOD_SIMPLE_TYPE_PAP = 0,
EAP_METHOD_SIMPLE_TYPE_MSCHAP,
EAP_METHOD_SIMPLE_TYPE_MSCHAP_V2,
EAP_METHOD_SIMPLE_TYPE_MD5,
EAP_METHOD_SIMPLE_TYPE_CHAP,
EAP_METHOD_SIMPLE_TYPE_GTC
} EAPMethodSimpleType;
typedef struct _EAPMethodSimple EAPMethodSimple;
EAPMethodSimple *eap_method_simple_new (WirelessSecurity *ws_parent,
NMConnection *connection,
EAPMethodSimpleType type,
gboolean phase2,
gboolean is_editor,
gboolean secrets_only);
#endif /* EAP_METHOD_SIMPLE_H */

View File

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="eap_simple_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="eap_simple_username_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Username</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_simple_username_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_simple_password_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_simple_password_entry</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_simple_password_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_simple_username_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="vbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCheckButton" id="eap_password_always_ask">
<property name="label" translatable="yes">As_k for this password every time</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_checkbutton_eapsimple">
<property name="label" translatable="yes">Sho_w password</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"/>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label53">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,481 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
#include "wireless-security.h"
#include "helpers.h"
struct _EAPMethodTLS {
EAPMethod parent;
gboolean new_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)
{
NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
GtkWidget *widget;
const char *password, *identity;
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))
return FALSE;
if (!eap_method_validate_filepicker (parent->builder, "eap_tls_ca_cert_button", TYPE_CA_CERT, NULL, NULL))
return 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 (!password || !strlen (password))
return FALSE;
if (!eap_method_validate_filepicker (parent->builder,
"eap_tls_private_key_button",
TYPE_PRIVATE_KEY,
password,
&format))
return FALSE;
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))
return FALSE;
}
return TRUE;
}
static void
add_to_size_group (EAPMethod *parent, GtkSizeGroup *group)
{
GtkWidget *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)
{
EAPMethodTLS *method = (EAPMethodTLS *) parent;
NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
NMSetting8021x *s_8021x;
GtkWidget *widget;
char *ca_filename, *pk_filename, *cc_filename;
const char *password = NULL;
GError *error = NULL;
const char *secret_flag_prop = NULL;
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);
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);
}
secret_flag_prop = NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS;
} 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);
}
secret_flag_prop = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS;
}
g_free (pk_filename);
/* Default to agent-owned secrets for new connections */
if (method->new_connection) {
g_object_set (s_8021x,
secret_flag_prop, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
NM_SETTING_802_1X_SYSTEM_CA_CERTS, TRUE,
NULL);
}
/* 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);
}
} 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);
}
}
}
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;
parent = eap_method_init (sizeof (EAPMethodTLS),
validate,
add_to_size_group,
fill_connection,
update_secrets,
NULL,
UIDIR "/eap-method-tls.ui",
"eap_tls_notebook",
"eap_tls_identity_entry",
phase2);
if (!parent)
return NULL;
method = (EAPMethodTLS *) parent;
method->new_connection = secrets_only ? FALSE : TRUE;
eap_method_nag_init (parent, "eap_tls_ca_cert_button", connection);
if (connection)
s_8021x = nm_connection_get_setting_802_1x (connection);
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);
/* 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);
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);
}
return method;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 */

View File

@@ -0,0 +1,198 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="eap_tls_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">6</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="eap_tls_identity_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">I_dentity</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_tls_identity_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_tls_identity_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_tls_user_cert_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_User certificate</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_tls_user_cert_button</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_tls_ca_cert_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">C_A certificate</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_tls_ca_cert_button</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="eap_tls_ca_cert_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_tls_private_key_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Private _key</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_tls_private_key_button</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="eap_tls_private_key_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_tls_private_key_password_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Private key password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_tls_private_key_password_entry</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_tls_private_key_password_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_checkbutton_eaptls">
<property name="label" translatable="yes">Sho_w password</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="eap_tls_user_cert_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label34">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,391 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include "config.h"
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
#include "wireless-security.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)
{
GtkWidget *widget;
GtkTreeModel *model;
GtkTreeIter iter;
EAPMethod *eap = NULL;
gboolean valid = FALSE;
if (!eap_method_validate_filepicker (parent->builder, "eap_ttls_ca_cert_button", TYPE_CA_CERT, NULL, NULL))
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);
eap_method_unref (eap);
return valid;
}
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_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)
{
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;
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);
}
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);
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_chap;
guint32 active = 0;
const char *phase2_auth = NULL;
auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_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);
}
em_pap = eap_method_simple_new (method->sec_parent,
connection,
EAP_METHOD_SIMPLE_TYPE_PAP,
TRUE,
method->is_editor,
secrets_only);
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,
TRUE,
method->is_editor,
secrets_only);
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,
TRUE,
method->is_editor, secrets_only);
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 = 2;
em_chap = eap_method_simple_new (method->sec_parent,
connection,
EAP_METHOD_SIMPLE_TYPE_CHAP,
TRUE,
method->is_editor,
secrets_only);
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 = 3;
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;
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,
UIDIR "/eap-method-ttls.ui",
"eap_ttls_notebook",
"eap_ttls_anon_identity_entry",
FALSE);
if (!parent)
return NULL;
eap_method_nag_init (parent, "eap_ttls_ca_cert_button", connection);
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_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) {
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);
}
}
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_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;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 */

View File

@@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="model6">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes"> </col>
</row>
</data>
</object>
<object class="GtkNotebook" id="eap_ttls_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="eap_ttls_anon_identity_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Anony_mous identity</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_ttls_anon_identity_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="eap_ttls_anon_identity_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_ttls_ca_cert_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">C_A certificate</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_ttls_ca_cert_button</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkFileChooserButton" id="eap_ttls_ca_cert_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="eap_ttls_inner_auth_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Inner authentication</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">eap_ttls_inner_auth_combo</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="eap_ttls_inner_auth_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model6</property>
<child>
<object class="GtkCellRendererText" id="renderer6"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="eap_ttls_inner_auth_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label49">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,660 @@
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 - 2012 Red Hat, Inc.
*/
#include "config.h"
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <nm-setting-connection.h>
#include <nm-setting-8021x.h>
#include "eap-method.h"
#include "nm-utils.h"
GType
eap_method_get_g_type (void)
{
static GType type_id = 0;
if (!type_id) {
type_id = g_boxed_type_register_static ("EAPMethod",
(GBoxedCopyFunc) eap_method_ref,
(GBoxedFreeFunc) eap_method_unref);
}
return type_id;
}
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)
{
g_return_val_if_fail (method != NULL, FALSE);
g_assert (method->validate);
return (*(method->validate)) (method);
}
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)
{
g_return_if_fail (method != NULL);
g_return_if_fail (connection != NULL);
g_assert (method->fill_connection);
return (*(method->fill_connection)) (method, connection);
}
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);
}
typedef struct {
EAPMethod *method;
NMConnection *connection;
} NagDialogResponseInfo;
static void
nag_dialog_destroyed (gpointer data, GObject *dialog_ptr)
{
NagDialogResponseInfo *info = (NagDialogResponseInfo *) data;
memset (info, '\0', sizeof (NagDialogResponseInfo));
g_free (info);
}
static GSettings *
_get_ca_ignore_settings (const char *uuid)
{
GSettings *settings;
char *path = 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;
}
static void
_set_ignore_ca_cert (const char *uuid, gboolean phase2, gboolean ignore)
{
GSettings *settings;
const char *key;
g_return_if_fail (uuid != NULL);
settings = _get_ca_ignore_settings (uuid);
key = phase2 ? "ignore-phase2-ca-cert" : "ignore-ca-cert";
g_settings_set_boolean (settings, key, ignore);
g_object_unref (settings);
}
static void
nag_dialog_response_cb (GtkDialog *nag_dialog,
gint response,
gpointer user_data)
{
NagDialogResponseInfo *info = (NagDialogResponseInfo *) user_data;
EAPMethod *method = (EAPMethod *) info->method;
NMConnection *connection = (NMConnection *) info->connection;
GtkWidget *widget;
if (response == GTK_RESPONSE_NO) {
/* Grab the value of the "don't bother me" checkbox */
widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "ignore_checkbox"));
g_assert (widget);
method->ignore_ca_cert = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
/* And save it */
_set_ignore_ca_cert (nm_connection_get_uuid (connection),
method->phase2,
method->ignore_ca_cert);
}
gtk_widget_hide (GTK_WIDGET (nag_dialog));
}
static gboolean
nag_dialog_delete_event_cb (GtkDialog *nag_dialog, GdkEvent *e, gpointer user_data)
{
// FIXME?: By emitting response signal, dismissing nag dialog with upper right "x" icon,
// Alt-F4, or Esc would have the same behaviour as clicking "Ignore" button.
//g_signal_emit_by_name (nag_dialog, "response", GTK_RESPONSE_NO, user_data);
return TRUE; /* do not destroy */
}
GtkWidget *
eap_method_nag_user (EAPMethod *method)
{
GtkWidget *widget;
char *filename = NULL;
g_return_val_if_fail (method != NULL, NULL);
if (!method->nag_dialog || method->ignore_ca_cert)
return NULL;
/* Checkbox should be unchecked each time dialog comes up */
widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "ignore_checkbox"));
g_assert (widget);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE);
/* Nag the user if the CA Cert is blank, since it's a security risk. */
widget = GTK_WIDGET (gtk_builder_get_object (method->builder, method->ca_cert_chooser));
g_assert (widget);
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
if (filename != NULL) {
g_free (filename);
return NULL;
}
gtk_window_present (GTK_WINDOW (method->nag_dialog));
return method->nag_dialog;
}
#define NAG_DIALOG_UI UIDIR "/nag-user-dialog.ui"
static gboolean
_get_ignore_ca_cert (const char *uuid, gboolean phase2)
{
GSettings *settings;
const char *key;
gboolean ignore = FALSE;
g_return_val_if_fail (uuid != NULL, FALSE);
settings = _get_ca_ignore_settings (uuid);
key = phase2 ? "ignore-phase2-ca-cert" : "ignore-ca-cert";
ignore = g_settings_get_boolean (settings, key);
g_object_unref (settings);
return ignore;
}
gboolean
eap_method_nag_init (EAPMethod *method,
const char *ca_cert_chooser,
NMConnection *connection)
{
GtkWidget *dialog, *widget;
NagDialogResponseInfo *info;
GError *error = NULL;
char *text;
g_return_val_if_fail (method != NULL, FALSE);
g_return_val_if_fail (ca_cert_chooser != NULL, FALSE);
method->nag_builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (method->nag_builder, NAG_DIALOG_UI, &error)) {
g_warning ("Couldn't load UI builder file " NAG_DIALOG_UI ": %s",
error->message);
g_error_free (error);
return FALSE;
}
method->ca_cert_chooser = g_strdup (ca_cert_chooser);
if (connection) {
NMSettingConnection *s_con;
const char *uuid;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
uuid = nm_setting_connection_get_uuid (s_con);
g_assert (uuid);
/* Figure out if the user wants to ignore missing CA cert */
method->ignore_ca_cert = _get_ignore_ca_cert (uuid, method->phase2);
}
info = g_malloc0 (sizeof (NagDialogResponseInfo));
info->method = method;
info->connection = connection;
dialog = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "nag_user_dialog"));
g_assert (dialog);
g_signal_connect (dialog, "response", G_CALLBACK (nag_dialog_response_cb), info);
g_signal_connect (dialog, "delete-event", G_CALLBACK (nag_dialog_delete_event_cb), info);
g_object_weak_ref (G_OBJECT (dialog), nag_dialog_destroyed, info);
widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "content_label"));
g_assert (widget);
text = g_strdup_printf ("<span weight=\"bold\" size=\"larger\">%s</span>\n\n%s",
_("No Certificate Authority certificate chosen"),
_("Not using a Certificate Authority (CA) certificate can result in connections to insecure, rogue Wi-Fi networks. Would you like to choose a Certificate Authority certificate?"));
gtk_label_set_markup (GTK_LABEL (widget), text);
g_free (text);
widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "ignore_button"));
gtk_button_set_label (GTK_BUTTON (widget), _("Ignore"));
g_assert (widget);
widget = GTK_WIDGET (gtk_builder_get_object (method->nag_builder, "change_button"));
gtk_button_set_label (GTK_BUTTON (widget), _("Choose CA Certificate"));
g_assert (widget);
method->nag_dialog = dialog;
return TRUE;
}
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_file,
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_file != 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->destroy = destroy;
method->default_field = default_field;
method->phase2 = phase2;
method->builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (method->builder, ui_file, &error)) {
g_warning ("Couldn't load UI builder file %s: %s",
ui_file, 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_file);
eap_method_unref (method);
return NULL;
}
g_object_ref_sink (method->ui_widget);
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->nag_dialog)
gtk_widget_destroy (method->nag_dialog);
if (method->nag_builder)
g_object_unref (method->nag_builder);
g_free (method->ca_cert_chooser);
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)
{
GtkWidget *widget;
char *filename;
NMSetting8021x *setting;
gboolean success = FALSE;
GError *error = NULL;
if (item_type == TYPE_PRIVATE_KEY) {
g_return_val_if_fail (password != NULL, FALSE);
g_return_val_if_fail (strlen (password), 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)
return (item_type == TYPE_CA_CERT) ? TRUE : FALSE;
if (!g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
goto out;
setting = (NMSetting8021x *) nm_setting_802_1x_new ();
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)) {
g_warning ("Error: couldn't verify private key: %d %s",
error ? error->code : -1, error ? error->message : "(none)");
g_clear_error (&error);
} else
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)) {
g_warning ("Error: couldn't verify client certificate: %d %s",
error ? error->code : -1, error ? error->message : "(none)");
g_clear_error (&error);
} else
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)) {
g_warning ("Error: couldn't verify CA certificate: %d %s",
error ? error->code : -1, error ? error->message : "(none)");
g_clear_error (&error);
} else
success = TRUE;
} else
g_warning ("%s: invalid item type %d.", __func__, item_type);
g_object_unref (setting);
out:
g_free (filename);
return success;
}
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
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;
}
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;
}
static gboolean
default_filter_privkey (const GtkFileFilterInfo *filter_info, gpointer user_data)
{
const char *extensions[] = { ".der", ".pem", ".p12", NULL };
gboolean require_encrypted = !!user_data;
gboolean is_encrypted = TRUE;
if (!filter_info->filename)
return FALSE;
if (!file_has_extension (filter_info->filename, extensions))
return FALSE;
if ( !file_is_der_or_pem (filter_info->filename, TRUE, &is_encrypted)
&& !nm_utils_file_is_pkcs12 (filter_info->filename))
return FALSE;
return require_encrypted ? is_encrypted : 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;
if (!file_is_der_or_pem (filter_info->filename, FALSE, NULL))
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)"));
} 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 };
return default_filter_privkey (&info, (gpointer) TRUE);
}

View File

@@ -0,0 +1,128 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 - 2012 Red Hat, Inc.
*/
#ifndef EAP_METHOD_H
#define EAP_METHOD_H
#include <glib.h>
#include <gtk/gtk.h>
#include <nm-connection.h>
#include <nm-setting-8021x.h>
typedef struct _EAPMethod EAPMethod;
typedef void (*EMAddToSizeGroupFunc) (EAPMethod *method, GtkSizeGroup *group);
typedef void (*EMFillConnectionFunc) (EAPMethod *method, NMConnection *connection);
typedef void (*EMUpdateSecretsFunc) (EAPMethod *method, NMConnection *connection);
typedef void (*EMDestroyFunc) (EAPMethod *method);
typedef gboolean (*EMValidateFunc) (EAPMethod *method);
struct _EAPMethod {
guint32 refcount;
gsize obj_size;
GtkBuilder *builder;
GtkWidget *ui_widget;
GtkBuilder *nag_builder;
char *ca_cert_chooser;
const char *default_field;
GtkWidget *nag_dialog;
gboolean phase2;
gboolean secrets_only;
gboolean ignore_ca_cert;
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);
void eap_method_add_to_size_group (EAPMethod *method, GtkSizeGroup *group);
void eap_method_fill_connection (EAPMethod *method, NMConnection *connection);
void eap_method_update_secrets (EAPMethod *method, NMConnection *connection);
GtkWidget * eap_method_nag_user (EAPMethod *method);
EAPMethod *eap_method_ref (EAPMethod *method);
void eap_method_unref (EAPMethod *method);
GType eap_method_get_g_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_file,
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);
gboolean eap_method_nag_init (EAPMethod *method,
const char *ca_cert_chooser,
NMConnection *connection);
void eap_method_phase2_update_secrets_helper (EAPMethod *method,
NMConnection *connection,
const char *combo_name,
guint32 column);
#endif /* EAP_METHOD_H */

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 2009 Red Hat, Inc.
*/
#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);
}
}
}

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 2009 Red Hat, Inc.
*/
#ifndef _HELPERS_H_
#define _HELPERS_H_
#include <glib.h>
#include <gtk/gtk.h>
#include <nm-connection.h>
#include <nm-setting.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_ */

View File

@@ -0,0 +1,191 @@
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.6 -->
<!-- interface-naming-policy toplevel-contextual -->
<object class="GtkDialog" id="nag_user_dialog">
<property name="border_width">5</property>
<property name="modal">True</property>
<property name="window_position">center</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox2">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">14</property>
<child>
<object class="GtkHBox" id="hbox5">
<property name="visible">True</property>
<property name="border_width">5</property>
<property name="spacing">12</property>
<child>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="yalign">0</property>
<property name="stock">gtk-dialog-warning</property>
<property name="icon-size">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="content_vbox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkLabel" id="content_label">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="label">alert text</property>
<property name="use_markup">True</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="ignore_checkbox">
<property name="label" translatable="yes">Don't _warn me again</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area2">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="ignore_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<child>
<object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<object class="GtkHBox" id="hbox4">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="stock">gtk-no</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label57">
<property name="visible">True</property>
<property name="label" translatable="yes">No</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="change_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<child>
<object class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<object class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="stock">gtk-ok</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label56">
<property name="visible">True</property>
<property name="label" translatable="yes">Yes</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-9">ignore_button</action-widget>
<action-widget response="-8">change_button</action-widget>
</action-widgets>
</object>
</interface>

View File

@@ -0,0 +1,551 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 - 2012 Red Hat, Inc.
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-8021x.h>
#include "wireless-security.h"
#include "eap-method.h"
GType
wireless_security_get_g_type (void)
{
static GType type_id = 0;
if (!type_id) {
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, const GByteArray *ssid)
{
g_return_val_if_fail (sec != NULL, FALSE);
g_assert (sec->validate);
return (*(sec->validate)) (sec, ssid);
}
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);
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_file,
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_file != NULL, NULL);
g_return_val_if_fail (ui_widget_name != NULL, NULL);
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->destroy = destroy;
sec->default_field = default_field;
sec->builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (sec->builder, ui_file, &error)) {
g_warning ("Couldn't load UI builder file %s: %s",
ui_file, 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_file);
wireless_security_unref (sec);
return NULL;
}
g_object_ref_sink (sec->ui_widget);
sec->adhoc_compatible = TRUE;
return sec;
}
GtkWidget *
wireless_security_nag_user (WirelessSecurity *sec)
{
g_return_val_if_fail (sec != NULL, NULL);
if (sec->nag_user)
return (*(sec->nag_user)) (sec);
return NULL;
}
gboolean
wireless_security_adhoc_compatible (WirelessSecurity *sec)
{
g_return_val_if_fail (sec != NULL, FALSE);
return sec->adhoc_compatible;
}
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)
{
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);
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;
EAPMethodFAST *em_fast;
EAPMethodTTLS *em_ttls;
EAPMethodPEAP *em_peap;
const char *default_method = NULL, *ctype = NULL;
int active = -1, item = 0;
gboolean wired = FALSE;
/* 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);
}
auth_model = gtk_list_store_new (2, G_TYPE_STRING, eap_method_get_g_type ());
if (wired) {
em_md5 = eap_method_simple_new (sec,
connection,
EAP_METHOD_SIMPLE_TYPE_MD5,
FALSE,
is_editor,
secrets_only);
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_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;
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
NMSetting8021x *s_8021x;
EAPMethod *eap = NULL;
GtkTreeModel *model;
GtkTreeIter iter;
s_wireless = nm_connection_get_setting_wireless (connection);
g_assert (s_wireless);
g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
/* 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);
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);
eap_method_fill_connection (eap, connection);
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));
}
}
GtkWidget *
ws_802_1x_nag_user (WirelessSecurity *sec,
const char *combo_name)
{
GtkTreeModel *model;
GtkTreeIter iter;
EAPMethod *eap = NULL;
GtkWidget *widget;
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_return_val_if_fail (eap != NULL, NULL);
widget = eap_method_nag_user (eap);
eap_method_unref (eap);
return widget;
}

View File

@@ -0,0 +1,147 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 WIRELESS_SECURITY_H
#define WIRELESS_SECURITY_H
#include <glib.h>
#include <gtk/gtk.h>
#include <nm-connection.h>
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, const GByteArray *ssid);
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;
WSAddToSizeGroupFunc add_to_size_group;
WSFillConnectionFunc fill_connection;
WSUpdateSecretsFunc update_secrets;
WSValidateFunc validate;
WSNagUserFunc nag_user;
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, const GByteArray *ssid);
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);
GtkWidget * wireless_security_nag_user (WirelessSecurity *sec);
gboolean wireless_security_adhoc_compatible (WirelessSecurity *sec);
WirelessSecurity *wireless_security_ref (WirelessSecurity *sec);
void wireless_security_unref (WirelessSecurity *sec);
GType wireless_security_get_g_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_file,
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);
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);
GtkWidget * ws_802_1x_nag_user (WirelessSecurity *sec,
const char *combo_name);
#endif /* WIRELESS_SECURITY_H */

View File

@@ -0,0 +1,143 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
#include <nm-setting-wireless.h>
#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, const GByteArray *ssid)
{
return ws_802_1x_validate (parent, "dynamic_wep_auth_combo");
}
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);
nm_setting_wireless_security_add_pairwise (s_wireless_sec, "wep40");
nm_setting_wireless_security_add_pairwise (s_wireless_sec, "wep104");
nm_setting_wireless_security_add_group (s_wireless_sec, "wep40");
nm_setting_wireless_security_add_group (s_wireless_sec, "wep104");
}
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 GtkWidget *
nag_user (WirelessSecurity *parent)
{
return ws_802_1x_nag_user (parent, "dynamic_wep_auth_combo");
}
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,
UIDIR "/ws-dynamic-wep.ui",
"dynamic_wep_notebook",
NULL);
if (!parent)
return NULL;
parent->nag_user = nag_user;
parent->adhoc_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;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 WS_DYNAMIC_WEP_H
#define WS_DYNAMIC_WEP_H
#include <nm-connection.h>
typedef struct _WirelessSecurityDynamicWEP WirelessSecurityDynamicWEP;
WirelessSecurityDynamicWEP *ws_dynamic_wep_new (NMConnection *connection,
gboolean is_editor,
gboolean secrets_only);
#endif /* WS_DYNAMIC_WEP_H */

View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="model7">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes"> </col>
</row>
</data>
</object>
<object class="GtkNotebook" id="dynamic_wep_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table12">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="dynamic_wep_auth_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Au_thentication</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">dynamic_wep_auth_combo</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="dynamic_wep_auth_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model7</property>
<child>
<object class="GtkCellRendererText" id="renderer7"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="dynamic_wep_method_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label55">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,192 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include <string.h>
#include <nm-setting-wireless.h>
#include "wireless-security.h"
#include "helpers.h"
struct _WirelessSecurityLEAP {
WirelessSecurity parent;
gboolean new_connection;
};
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, const GByteArray *ssid)
{
GtkWidget *entry;
const char *text;
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))
return FALSE;
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))
return FALSE;
return TRUE;
}
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;
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
GtkWidget *widget;
const char *leap_password = NULL, *leap_username = NULL;
s_wireless = nm_connection_get_setting_wireless (connection);
g_assert (s_wireless);
g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, 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"));
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);
/* Default to agent-owned secrets for new connections */
if (sec->new_connection) {
g_object_set (s_wireless_sec,
NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, NM_SETTING_SECRET_FLAG_AGENT_OWNED,
NULL);
}
}
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,
UIDIR "/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;
sec = (WirelessSecurityLEAP *) parent;
sec->new_connection = secrets_only ? FALSE : TRUE;
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);
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;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 WS_LEAP_H
#define WS_LEAP_H
#include <nm-connection.h>
typedef struct _WirelessSecurityLEAP WirelessSecurityLEAP;
WirelessSecurityLEAP * ws_leap_new (NMConnection *connection, gboolean secrets_only);
#endif /* WS_LEAP_H */

View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="leap_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="leap_username_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Username</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">leap_username_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="leap_password_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">leap_password_entry</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="leap_password_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_checkbutton_leap">
<property name="label" translatable="yes">Sho_w password</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="leap_username_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="GtkLabel1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,349 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include <ctype.h>
#include <string.h>
#include <nm-setting-wireless.h>
#include <nm-setting-wireless-security.h>
#include "wireless-security.h"
struct _WirelessSecurityWEPKey {
WirelessSecurity parent;
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)
strcpy (sec->keys[sec->cur_index], key);
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, const GByteArray *ssid)
{
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)
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 (!isxdigit (key[i]))
return FALSE;
}
} else if ((strlen (key) == 5) || (strlen (key) == 13)) {
for (i = 0; i < strlen (key); i++) {
if (!isascii (key[i]))
return FALSE;
}
} else {
return FALSE;
}
} else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) {
if (!strlen (key) || (strlen (key) > 64))
return FALSE;
}
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;
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wsec;
GtkWidget *widget;
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"));
key = gtk_entry_get_text (GTK_ENTRY (widget));
strcpy (sec->keys[sec->cur_index], key);
s_wireless = nm_connection_get_setting_wireless (connection);
g_assert (s_wireless);
g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
/* 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]);
}
}
static void
wep_entry_filter_cb (GtkEntry * entry,
const gchar *text,
gint length,
gint * position,
gpointer data)
{
WirelessSecurityWEPKey *sec = (WirelessSecurityWEPKey *) data;
GtkEditable *editable = GTK_EDITABLE (entry);
int i, count = 0;
gchar *result;
result = g_malloc0 (length + 1);
if (sec->type == NM_WEP_KEY_TYPE_KEY) {
for (i = 0; i < length; i++) {
if (isxdigit(text[i]) || isascii(text[i]))
result[count++] = text[i];
}
} else if (sec->type == NM_WEP_KEY_TYPE_PASSPHRASE) {
for (i = 0; i < length; i++)
result[count++] = text[i];
}
if (count > 0) {
g_signal_handlers_block_by_func (G_OBJECT (editable),
G_CALLBACK (wep_entry_filter_cb),
data);
gtk_editable_insert_text (editable, result, count, position);
g_signal_handlers_unblock_by_func (G_OBJECT (editable),
G_CALLBACK (wep_entry_filter_cb),
data);
}
g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
g_free (result);
}
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)
strcpy (sec->keys[i], tmp);
}
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;
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,
UIDIR "/ws-wep-key.ui",
"wep_key_notebook",
"wep_key_entry");
if (!parent)
return NULL;
sec = (WirelessSecurityWEPKey *) parent;
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);
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;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 WS_WEP_KEY_H
#define WS_WEP_KEY_H
#include <nm-setting-wireless-security.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 */

View File

@@ -0,0 +1,196 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="model4">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">1 (Default)</col>
</row>
<row>
<col id="0" translatable="yes">2</col>
</row>
<row>
<col id="0" translatable="yes">3</col>
</row>
<row>
<col id="0" translatable="yes">4</col>
</row>
</data>
</object>
<object class="GtkListStore" id="model3">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes">Open System</col>
</row>
<row>
<col id="0" translatable="yes">Shared Key</col>
</row>
</data>
</object>
<object class="GtkNotebook" id="wep_key_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="table6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">4</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="wep_key_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Key</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">wep_key_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="wep_key_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="visibility">False</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label31">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_checkbutton_wep">
<property name="label" translatable="yes">Sho_w key</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="auth_method_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Au_thentication</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">auth_method_combo</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="auth_method_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model3</property>
<child>
<object class="GtkCellRendererText" id="renderer3"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="key_index_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">WEP inde_x</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">key_index_combo</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="key_index_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model4</property>
<child>
<object class="GtkCellRendererText" id="renderer4"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label23">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,139 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include <glib/gi18n.h>
#include <ctype.h>
#include <string.h>
#include <nm-setting-wireless.h>
#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, const GByteArray *ssid)
{
return ws_802_1x_validate (parent, "wpa_eap_auth_combo");
}
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 GtkWidget *
nag_user (WirelessSecurity *parent)
{
return ws_802_1x_nag_user (parent, "wpa_eap_auth_combo");
}
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,
UIDIR "/ws-wpa-eap.ui",
"wpa_eap_notebook",
NULL);
if (!parent)
return NULL;
parent->nag_user = nag_user;
parent->adhoc_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;
}

View File

@@ -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 <dcbw@redhat.com>
*
* 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 WS_WPA_EAP_H
#define WS_WPA_EAP_H
#include <nm-connection.h>
typedef struct _WirelessSecurityWPAEAP WirelessSecurityWPAEAP;
WirelessSecurityWPAEAP * ws_wpa_eap_new (NMConnection *connection,
gboolean is_editor,
gboolean secrets_only);
#endif /* WS_WPA_EAP_H */

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkListStore" id="model5">
<columns>
<!-- column-name gchararray -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0" translatable="yes"> </col>
</row>
</data>
</object>
<object class="GtkNotebook" id="wpa_eap_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="wpa_eap_table">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">2</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="wpa_eap_auth_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Au_thentication</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">wpa_eap_auth_combo</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="wpa_eap_auth_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">model5</property>
<child>
<object class="GtkCellRendererText" id="renderer5"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
<child>
<object class="GtkVBox" id="wpa_eap_method_vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="GtkLabel3">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>

View File

@@ -0,0 +1,200 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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.
*/
#include <ctype.h>
#include <string.h>
#include <nm-setting-wireless.h>
#include "wireless-security.h"
#include "helpers.h"
#define WPA_PMK_LEN 32
struct _WirelessSecurityWPAPSK {
WirelessSecurity parent;
};
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, const GByteArray *ssid)
{
GtkWidget *entry;
const char *key;
guint32 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 = strlen (key);
if ((len < 8) || (len > 64))
return FALSE;
if (len == 64) {
/* Hex PSK */
for (i = 0; i < len; i++) {
if (!isxdigit (key[i]))
return FALSE;
}
}
/* 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)
{
GtkWidget *widget;
const char *key;
NMSettingWireless *s_wireless;
NMSettingWirelessSecurity *s_wireless_sec;
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;
g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, 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, "wpa_psk_entry"));
key = gtk_entry_get_text (GTK_ENTRY (widget));
g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_PSK, key, NULL);
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;
GtkWidget *widget;
parent = wireless_security_init (sizeof (WirelessSecurityWPAPSK),
validate,
add_to_size_group,
fill_connection,
update_secrets,
NULL,
UIDIR "/ws-wpa-psk.ui",
"wpa_psk_notebook",
"wpa_psk_entry");
if (!parent)
return NULL;
parent->adhoc_compatible = FALSE;
sec = (WirelessSecurityWPAPSK *) parent;
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);
/* 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;
}

View File

@@ -0,0 +1,31 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager Applet -- allow user control over networking
*
* Dan Williams <dcbw@redhat.com>
*
* 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 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 */

View File

@@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="wpa_psk_notebook">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkTable" id="wpa_psk_table">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="wpa_psk_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Password</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">wpa_psk_entry</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="wpa_psk_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="max_length">64</property>
<property name="visibility">False</property>
<property name="activates_default">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="wpa_psk_type_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Type</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">wpa_psk_type_combo</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label32">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="show_checkbutton_wpa">
<property name="label" translatable="yes">Sho_w password</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="wpa_psk_type_combo">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options">GTK_FILL</property>
</packing>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="GtkLabel2">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</interface>