Compare commits

...

46 Commits

Author SHA1 Message Date
Dan Winship
b82986e14b network: add integrated "Add New Connection"
New VPN connections are created within the control center; other types
currently hit the nm-connection-editor fallback.
2013-01-23 13:47:01 -05:00
Dan Winship
6db506e049 network: fall back to nm-connection-editor for unknown types
If asked to create or edit an unrecognized type, hand it off to
nm-connection-editor.
2013-01-23 13:45:28 -05:00
Dan Winship
11e6e24c58 network: add VPN support to the connection editor
Unfortunately, the VPN plugins provide their own .ui files for their
editor pages, so we can't make them look competely GNOME-3-ish. But
the code does try to fix them up a little bit by realigning the
labels.

vpn-helpers.[ch] is nearly identical to network-manager-applet's,
but eventually this code will move into libnm-gtk.
2013-01-23 13:44:12 -05:00
Dan Winship
4bbe8af757 network: add git.mk to subdir Makefile.ams 2013-01-23 13:41:49 -05:00
Bastien Nocera
03b53092e0 network: Remove single function helpers
And export the necessary functions directly.
2013-01-23 13:41:49 -05:00
Bastien Nocera
224437b978 network: Add context for "Forget" button
And add a translator comment for it.
2013-01-23 13:41:49 -05:00
Bastien Nocera
8c4f4beab0 network: Use stock button for "Close" 2013-01-23 13:41:49 -05:00
Bastien Nocera
dc31faf266 network: Remove dead code 2013-01-23 13:41:49 -05:00
Bastien Nocera
aeb8f31abe network: Write IPv6 instead of IP if IPv6 is the only address 2013-01-23 13:41:49 -05:00
Bastien Nocera
b2be832657 network: IPv4 and IPv6 not IP4 and IP6 2013-01-23 13:41:49 -05:00
Bastien Nocera
17d1f84481 network: Script the update from nm-applet 2013-01-23 13:41:49 -05:00
Matthias Clasen
87aaf960bd networking: Cosmetics
Make the headings on the wifi and wired pages line up
more closely.
2013-01-23 13:41:48 -05:00
Matthias Clasen
e3a4acc2e1 networking: Make wired device off switch work better 2013-01-23 13:41:48 -05:00
Matthias Clasen
4accf8fe55 networking: Use same wifi device name throughout
The device list is using the 'disambiguated' name that
nm is giving us. Use the same in the wifi page heading,
instead of hardcoding 'Wi-Fi'.
2013-01-23 13:41:48 -05:00
Matthias Clasen
9078bad90c network: Update device icons on state changes
The wired icon depends on the state, so should update it
when the state changes.
2013-01-23 13:41:48 -05:00
Matthias Clasen
9b7f29ad29 network: Remove an unused function 2013-01-23 13:41:48 -05:00
Matthias Clasen
870730d12d network: Fix status updates for ethernet
The generic NetDeviceSimple code for updating headers according
to device status does not trigger for ethernet anymore, so we
have to do it ourselves. This also fixes the device off switch
to have to expected effect.
2013-01-23 13:41:48 -05:00
Matthias Clasen
a8f3466950 network: Fix sizing issues of the profile list
Make it so that the list starts to scroll when there's more
than 4 profiles.
2013-01-23 13:41:48 -05:00
Matthias Clasen
696294b739 network: Fix capitalization
It should be 'Add Profile', not 'Add profile'.
Based on review feedback.
2013-01-23 13:41:48 -05:00
Matthias Clasen
92463278af network: Improve editor for new profiles
Make the window title 'New Profile' and replace the Apply
button with an Add button if the connection is a new one.
Based on review feedback.
2013-01-23 13:41:48 -05:00
Matthias Clasen
5820a94765 Network: Update the label for ethernet security
It is 802.1x, not 8021x. Also, add a mnemonic to the label.
2013-01-23 13:41:48 -05:00
Matthias Clasen
5af76d605a network: Improve layout of the ethernet identity page
Move the 'bytes' label out to a third column, and hide
it if the MTU is set to automatic. Based on review feedback.
2013-01-23 13:41:48 -05:00
Matthias Clasen
8b1bcc3145 network: Remove non-supported ethernet config
These controls were hidden, but messed up the layout of the page.
So just remove them ofr now.
2013-01-23 13:41:47 -05:00
Matthias Clasen
eaaa5917b9 network: Fix up formatting of wired security page
This makes the wired security page work much the same
way as the wireless one.
2013-01-23 13:41:47 -05:00
Matthias Clasen
ee1362e62e network: Improve the reset page
Add more padding, and tweak the wording.
Based on review feedback.
2013-01-23 13:41:47 -05:00
Matthias Clasen
da50b86e2b network: Make ip6 page match ip4
This applies the same changes to the ip6 list that have
been made to the ip4 page.
2013-01-23 13:41:47 -05:00
Matthias Clasen
dc0b12719d network: Redo dns and routes sections
Move the automatic switches out of the lists, desensitize delete
buttons for the last item, and switch to inline toolbars for the
add button. Also use 'Server' as the label for DNS servers.
Based on review feedback.
2013-01-23 13:41:47 -05:00
Matthias Clasen
c5e0b9b95b network: Redo IPv4 address section
Hide the address list entirely unless the mode is manual.
Turn the + row into an inline toolbar. Make the delete buttons
insensitive if there's only one row. Based on review feedback.
2013-01-23 13:41:47 -05:00
Matthias Clasen
2ce8855c81 network: Avoid resizing due to security changes
Add a poor mans solution to this problem, by putting the security
content (which we've copied 1-1 from nm and done want to change
too much) in a notebook, with suitable placeholders in another tab.
2013-01-23 13:41:47 -05:00
Matthias Clasen
8cfd9828ee network: Move 'connect automatically' and 'available to others'
These are misplaced and misaligned on the Details page. Move them
to Identity and turn them into checkboxes. Based on review feedback.
2013-01-23 13:41:47 -05:00
Matthias Clasen
702de921b3 network: Shorten cloned mac label
Given that it is right below the 'MAC Address', 'Cloned Address'
seems clear enough, and 'Cloned MAC Address' was just too long.
Based on review feedback.
2013-01-23 13:41:47 -05:00
Matthias Clasen
6840049bba network: Fix capitalization of Last Used
Based on review feedback.
2013-01-23 13:41:47 -05:00
Matthias Clasen
c8e35b4641 network: move security tab to second position
This is based on review feedback.
2013-01-23 13:41:47 -05:00
Matthias Clasen
8d6b09fad3 network: Implement the new design for wired
This expands the connection editor to cover ethernet,
and adds support for multiple wired profiles.
2013-01-23 13:41:46 -05:00
Matthias Clasen
860345c595 network: Implement "Reset" 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.
2013-01-23 13:41:46 -05:00
Matthias Clasen
ac39a16eac network: Listen for permission changes
Also, add a net_connection_editor_run() function to match the
NMConnectionEditor api.
2013-01-23 13:41:46 -05:00
Matthias Clasen
3f57e92adc network: Implement 'Forget' in the connection-editor 2013-01-23 13:41:46 -05:00
Matthias Clasen
87c9b6160f 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.
2013-01-23 13:41:44 -05:00
Matthias Clasen
aecc8bc7ad network: Remove more dead code
These callbacks were used by buttons on the now-removed
details tab.
2013-01-23 13:31:18 -05:00
Matthias Clasen
78f3a4e270 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.
2013-01-23 13:31:17 -05:00
Matthias Clasen
78026958b3 network: Remove unused tabs
The details and hidden tabs are never used in the code, so
get rid of them.
2013-01-23 13:31:17 -05:00
Matthias Clasen
af3825dcc1 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.
2013-01-23 13:31:17 -05:00
Matthias Clasen
96f4975849 network: Add status label and icon to wifi header
This is part of the design refresh for the network panel.
2013-01-23 13:31:17 -05:00
Matthias Clasen
72fee9c38f network: Add a spinner while connecting
This is part of the new listbox-based design for the
network panel.
2013-01-23 13:31:17 -05:00
Matthias Clasen
8a00eee8a2 network: no more cell renderers
Now that the list has been converted to a listbox, we don't
need any of these anymore.
2013-01-23 13:31:17 -05:00
Matthias Clasen
9fe4ba8e54 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.
2013-01-23 13:31:17 -05:00
105 changed files with 19230 additions and 2827 deletions

View File

@@ -176,6 +176,7 @@ AC_SUBST(GDESKTOP_PREFIX)
# Check for NetworkManager ~0.9
PKG_CHECK_MODULES(NETWORK_MANAGER, NetworkManager >= $NETWORK_MANAGER_REQUIRED_VERSION
libnm-glib >= $NETWORK_MANAGER_REQUIRED_VERSION
libnm-glib-vpn >= $NETWORK_MANAGER_REQUIRED_VERSION
libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION
libnm-gtk >= $NETWORK_MANAGER_APPLET_REQUIRED_VERSION,
[have_networkmanager=yes], have_networkmanager=no)
@@ -187,6 +188,15 @@ fi
AM_CONDITIONAL(BUILD_NETWORK, [test x$have_networkmanager = xyes])
if test x${have_networkmanager} = xyes; then
AC_DEFINE(HAVE_NETWORK_MANAGER, 1, [Define to 1 if NetworkManager is available])
nm_prefix=`$PKG_CONFIG --variable prefix NetworkManager`
if test "$nm_prefix" = "/usr"; then
NM_VPN_CONFIG_DIR=/etc/NetworkManager/VPN
else
NM_VPN_CONFIG_DIR=$nm_prefix/etc/NetworkManager/VPN
fi
NM_VPN_MODULE_DIR=`$PKG_CONFIG --variable libdir NetworkManager`/NetworkManager
AC_SUBST(NM_VPN_CONFIG_DIR)
AC_SUBST(NM_VPN_MODULE_DIR)
fi
# Check for gnome-bluetooth
@@ -492,6 +502,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/notifications/Makefile
panels/notifications/gnome-notifications-panel.desktop.in

View File

@@ -1,10 +1,13 @@
cappletname = network
SUBDIRS = wireless-security connection-editor
INCLUDES = \
$(PANEL_CFLAGS) \
$(NETWORK_PANEL_CFLAGS) \
$(NETWORK_MANAGER_CFLAGS) \
-DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
-I$(srcdir)/wireless-security \
$(NULL)
noinst_LTLIBRARIES = libnetwork.la
@@ -35,18 +38,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 \
@@ -55,7 +46,9 @@ 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)
resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/network.gresource.xml)
cc-network-resources.c: network.gresource.xml $(resource_files)

View File

@@ -46,6 +46,7 @@
#include "panel-common.h"
#include "network-dialogs.h"
#include "connection-editor/net-connection-editor.h"
CC_PANEL_REGISTER (CcNetworkPanel, cc_network_panel)
@@ -98,7 +99,7 @@ enum {
PROP_ARGV
};
static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id);
static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out);
static void handle_argv (CcNetworkPanel *panel);
static void
@@ -599,6 +600,28 @@ handle_argv (CcNetworkPanel *panel)
g_debug ("Could not handle argv operation, no matching device yet?");
}
static void
state_changed_cb (NMDevice *device,
NMDeviceState new_state,
NMDeviceState old_state,
NMDeviceStateReason reason,
CcNetworkPanel *panel)
{
GtkListStore *store;
GtkTreeIter iter;
if (!find_in_model_by_id (panel, nm_device_get_udi (device), &iter)) {
return;
}
store = GTK_LIST_STORE (gtk_builder_get_object (panel->priv->builder,
"liststore_devices"));
gtk_list_store_set (store, &iter,
PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device),
-1);
}
static gboolean
panel_add_device (CcNetworkPanel *panel, NMDevice *device)
{
@@ -612,7 +635,7 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
GType device_g_type;
/* do we have an existing object with this id? */
if (find_in_model_by_id (panel, nm_device_get_udi (device)) != NULL)
if (find_in_model_by_id (panel, nm_device_get_udi (device), NULL) != NULL)
goto out;
type = nm_device_get_device_type (device);
@@ -672,6 +695,8 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
PANEL_DEVICES_COLUMN_SORT, panel_device_to_sortable_string (device),
PANEL_DEVICES_COLUMN_OBJECT, net_device,
-1);
g_signal_connect (device, "state-changed",
G_CALLBACK (state_changed_cb), panel);
out:
return FALSE;
@@ -939,7 +964,7 @@ out:
}
static NetObject *
find_in_model_by_id (CcNetworkPanel *panel, const gchar *id)
find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out)
{
gboolean ret;
NetObject *object_tmp;
@@ -968,6 +993,8 @@ find_in_model_by_id (CcNetworkPanel *panel, const gchar *id)
}
} while (object == NULL && gtk_tree_model_iter_next (model, &iter));
out:
if (iter_out)
*iter_out = iter;
return object;
}
@@ -984,7 +1011,7 @@ panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
/* does already exist */
id = nm_connection_get_path (connection);
if (find_in_model_by_id (panel, id) != NULL)
if (find_in_model_by_id (panel, id, NULL) != NULL)
return;
/* add as a virtual object */
@@ -994,6 +1021,7 @@ panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
"id", id,
"connection", connection,
"client", panel->priv->client,
"remote-settings", panel->priv->remote_settings,
NULL);
g_signal_connect_object (net_vpn, "removed",
G_CALLBACK (object_removed_cb), panel, 0);
@@ -1123,46 +1151,26 @@ panel_check_network_manager_version (CcNetworkPanel *panel)
return ret;
}
static void
editor_done (NetConnectionEditor *editor,
gboolean success,
gpointer user_data)
{
g_object_unref (editor);
}
static void
add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel)
{
GtkWidget *dialog;
gint response;
NetConnectionEditor *editor;
GtkWindow *toplevel;
dialog = GTK_WIDGET (gtk_builder_get_object (panel->priv->builder,
"connection_type_dialog"));
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel))));
response = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_hide (dialog);
if (response == GTK_RESPONSE_OK) {
GtkComboBox *combo;
GtkTreeModel *model;
GtkTreeIter iter;
gchar *type;
gchar *cmdline;
GError *error;
combo = GTK_COMBO_BOX (gtk_builder_get_object (panel->priv->builder,
"connection_type_combo"));
model = gtk_combo_box_get_model (combo);
gtk_combo_box_get_active_iter (combo, &iter);
type = NULL;
gtk_tree_model_get (model, &iter, 1, &type, -1);
cmdline = g_strdup_printf ("nm-connection-editor --create --type %s", type);
g_debug ("Launching '%s'\n", cmdline);
error = NULL;
if (!g_spawn_command_line_async (cmdline, &error)) {
g_warning ("Failed to launch nm-connection-editor: %s", error->message);
g_error_free (error);
}
g_free (cmdline);
g_free (type);
}
toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
editor = net_connection_editor_new (toplevel, NULL, NULL, NULL,
panel->priv->client,
panel->priv->remote_settings);
g_signal_connect (editor, "done", G_CALLBACK (editor_done), panel);
net_connection_editor_run (editor);
}
static void

View File

@@ -0,0 +1,295 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="page">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkGrid" id="grid">
<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">802.1x _Security</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">8021x_switch</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="GtkSwitch" id="8021x_switch">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</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>
</child>
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 1</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
<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">6</property>
<child>
<object class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">35</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="GtkEntry" id="entry2">
<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">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry3">
<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">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry4">
<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">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry5">
<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">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry6">
<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">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry7">
<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">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry8">
<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">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry9">
<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">8</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry10">
<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">9</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Anony_mous identity</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="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Inner _authentication</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>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 2</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child type="tab">
<placeholder/>
</child>
</object>
</interface>

View File

@@ -0,0 +1,55 @@
noinst_LTLIBRARIES = libconnection-editor.la
BUILT_SOURCES = \
net-connection-editor-resources.c \
net-connection-editor-resources.h
libconnection_editor_la_SOURCES = \
$(BUILT_SOURCES) \
net-connection-editor.h \
net-connection-editor.c \
ce-page.h \
ce-page.c \
ce-page-details.h \
ce-page-details.c \
ce-page-wifi.h \
ce-page-wifi.c \
ce-page-ip4.h \
ce-page-ip4.c \
ce-page-ip6.h \
ce-page-ip6.c \
ce-page-security.h \
ce-page-security.c \
ce-page-reset.h \
ce-page-reset.c \
ce-page-ethernet.h \
ce-page-ethernet.c \
ce-page-8021x-security.h \
ce-page-8021x-security.c \
ce-page-vpn.h \
ce-page-vpn.c \
vpn-helpers.h \
vpn-helpers.c
libconnection_editor_la_CPPFLAGS = \
-I$(srcdir)/../wireless-security \
$(NETWORK_PANEL_CFLAGS) \
$(NETWORK_MANAGER_CFLAGS) \
-DNM_VPN_CONFIG_DIR=\""$(NM_VPN_CONFIG_DIR)"\" \
-DNM_VPN_MODULE_DIR=\""$(NM_VPN_MODULE_DIR)"\"
libconnection_editor_la_LIBADD = \
$(builddir)/../wireless-security/libwireless-security.la \
$(NETWORK_PANEL_LIBS) \
$(NETWORK_MANAGER_LIBS)
resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/connection-editor.gresource.xml)
net-connection-editor-resources.c: connection-editor.gresource.xml $(resource_files)
$(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name net_connection_editor $<
net-connection-editor-resources.h: connection-editor.gresource.xml $(resource_files)
$(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name net_connection_editor $<
EXTRA_DIST = \
$(resource_files)
-include $(top_srcdir)/git.mk

View File

@@ -0,0 +1,194 @@
/* -*- 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 (GObject *sw, GParamSpec *pspec, gpointer user_data)
{
CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (user_data);
gtk_widget_set_sensitive (page->security_widget, gtk_switch_get_active (page->enabled));
ce_page_changed (CE_PAGE (page));
}
static void
stuff_changed (WirelessSecurity *sec, gpointer user_data)
{
ce_page_changed (CE_PAGE (user_data));
}
static void
finish_setup (CEPage8021xSecurity *page, gpointer unused, GError *error, gpointer user_data)
{
GtkWidget *parent;
GtkWidget *vbox;
GtkWidget *heading;
if (error)
return;
vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox"));
heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec"));
page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
page->security = (WirelessSecurity *) ws_wpa_eap_new (CE_PAGE (page)->connection, TRUE, FALSE);
if (!page->security) {
g_warning ("Could not load 802.1x user interface.");
return;
}
wireless_security_set_changed_notify (page->security, stuff_changed, page);
page->security_widget = wireless_security_get_widget (page->security);
parent = gtk_widget_get_parent (page->security_widget);
if (parent)
gtk_container_remove (GTK_CONTAINER (parent), page->security_widget);
gtk_switch_set_active (page->enabled, page->initial_have_8021x);
g_signal_connect (page->enabled, "notify::active", G_CALLBACK (enable_toggled), page);
gtk_widget_set_sensitive (page->security_widget, page->initial_have_8021x);
gtk_size_group_add_widget (page->group, heading);
wireless_security_add_to_size_group (page->security, page->group);
gtk_container_add (GTK_CONTAINER (vbox), page->security_widget);
}
CEPage *
ce_page_8021x_security_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings)
{
CEPage8021xSecurity *page;
page = CE_PAGE_8021X_SECURITY (ce_page_new (CE_TYPE_PAGE_8021X_SECURITY,
connection,
client,
settings,
"/org/gnome/control-center/network/8021x-security-page.ui",
_("Security")));
if (nm_connection_get_setting_802_1x (connection))
page->initial_have_8021x = TRUE;
page->enabled = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "8021x_switch"));
g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL);
if (page->initial_have_8021x)
CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME;
return CE_PAGE (page);
}
static gboolean
validate (CEPage *cepage, NMConnection *connection, GError **error)
{
CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (cepage);
gboolean valid = TRUE;
if (gtk_switch_get_active (page->enabled)) {
NMConnection *tmp_connection;
NMSetting *s_8021x;
/* FIXME: get failed property and error out of wireless security objects */
valid = wireless_security_validate (page->security, 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 (page->security, "wpa_eap_auth_combo", tmp_connection);
s_8021x = nm_connection_get_setting (tmp_connection, NM_TYPE_SETTING_802_1X);
nm_connection_add_setting (connection, NM_SETTING (g_object_ref (s_8021x)));
g_object_unref (tmp_connection);
} else
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 *page)
{
}
static void
dispose (GObject *object)
{
CEPage8021xSecurity *page = CE_PAGE_8021X_SECURITY (object);
if (page->security) {
wireless_security_unref (page->security);
page->security = NULL;
}
g_clear_object (&page->group);
G_OBJECT_CLASS (ce_page_8021x_security_parent_class)->dispose (object);
}
static void
ce_page_8021x_security_class_init (CEPage8021xSecurityClass *security_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (security_class);
CEPageClass *parent_class = CE_PAGE_CLASS (security_class);
/* virtual methods */
object_class->dispose = dispose;
parent_class->validate = validate;
}

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;
GtkSwitch *enabled;
GtkWidget *security_widget;
WirelessSecurity *security;
GtkSizeGroup *group;
gboolean initial_have_8021x;
};
struct CEPage8021xSecurityClass {
CEPageClass parent;
};
GType ce_page_8021x_security_get_type (void);
CEPage *ce_page_8021x_security_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings);
#endif /* __CE_PAGE_8021X_SECURITY_H */

View File

@@ -0,0 +1,247 @@
/* -*- 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
connect_details_page (CEPageDetails *page)
{
guint speed;
guint strength;
NMDeviceState state;
NMAccessPoint *active_ap;
const gchar *str;
gboolean device_is_active;
if (NM_IS_DEVICE_WIFI (page->device))
active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (page->device));
else
active_ap = NULL;
state = page->device ? nm_device_get_state (page->device) : NM_DEVICE_STATE_DISCONNECTED;
device_is_active = FALSE;
speed = 0;
if (active_ap && page->ap == active_ap && state != NM_DEVICE_STATE_UNAVAILABLE) {
device_is_active = TRUE;
if (NM_IS_DEVICE_WIFI (page->device))
speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000;
} else if (page->device) {
NMActiveConnection *ac;
const gchar *p1, *p2;
ac = nm_device_get_active_connection (page->device);
p1 = ac ? nm_active_connection_get_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,
"/org/gnome/control-center/network/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,214 @@
/* -*- 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)
static void
all_user_changed (GtkToggleButton *b, CEPageEthernet *page)
{
gboolean all_users;
NMSettingConnection *sc;
sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
all_users = gtk_toggle_button_get_active (b);
g_object_set (sc, "permissions", NULL, NULL);
if (!all_users)
nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL);
}
static void
mtu_changed (GtkSpinButton *mtu, CEPageEthernet *page)
{
if (gtk_spin_button_get_value_as_int (mtu) == 0)
gtk_widget_hide (page->mtu_label);
else
gtk_widget_show (page->mtu_label);
}
static void
connect_ethernet_page (CEPageEthernet *page)
{
NMSettingWired *setting = page->setting_wired;
NMSettingConnection *sc;
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);
/* 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 (page->mtu, "value-changed",
G_CALLBACK (mtu_changed), page);
mtu_changed (page->mtu, page);
g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page);
g_signal_connect_swapped (page->mtu, "value-changed", G_CALLBACK (ce_page_changed), page);
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
"auto_connect_check"));
sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
g_object_bind_property (sc, "autoconnect",
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
"all_user_check"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
nm_setting_connection_get_num_permissions (sc) == 0);
g_signal_connect (widget, "toggled",
G_CALLBACK (all_user_changed), page);
}
static void
ui_to_setting (CEPageEthernet *page)
{
GByteArray *device_mac = NULL;
GByteArray *cloned_mac = NULL;
GtkWidget *entry;
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_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,
"/org/gnome/control-center/network/ethernet-page.ui",
_("Identity")));
page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name"));
page->device_mac = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_mac"));
page->cloned_mac = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_cloned_mac"));
page->mtu = GTK_SPIN_BUTTON (gtk_builder_get_object (CE_PAGE (page)->builder, "spin_mtu"));
page->mtu_label = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "label_mtu"));
page->setting_connection = nm_connection_get_setting_connection (connection);
page->setting_wired = nm_connection_get_setting_wired (connection);
connect_ethernet_page (page);
return CE_PAGE (page);
}

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 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;
GtkSpinButton *mtu;
GtkWidget *mtu_label;
};
struct _CEPageEthernetClass
{
CEPageClass parent_class;
};
GType ce_page_ethernet_get_type (void);
CEPage *ce_page_ethernet_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* __CE_PAGE_ETHERNET_H */

View File

@@ -0,0 +1,898 @@
/* -*- 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;
GtkWidget *widget;
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;
}
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
gtk_widget_set_visible (widget, addr_enabled);
gtk_widget_set_sensitive (page->dns_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
update_row_sensitivity (CEPageIP4 *page, GtkWidget *list)
{
GList *children, *l;
gint rows = 0;
children = gtk_container_get_children (GTK_CONTAINER (list));
for (l = children; l; l = l->next) {
GtkWidget *row = l->data;
GtkWidget *button;
button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
if (button != NULL)
rows++;
}
for (l = children; l; l = l->next) {
GtkWidget *row = l->data;
GtkWidget *button;
button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
if (button != NULL)
gtk_widget_set_sensitive (button, rows > 1);
}
g_list_free (children);
}
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));
update_row_sensitivity (page, list);
}
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);
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
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);
update_row_sensitivity (page, page->address_list);
}
static void
add_empty_address_row (CEPageIP4 *page)
{
add_address_row (page, "", "", "");
}
static void
add_section_toolbar (CEPageIP4 *page, GtkWidget *section, GCallback add_cb)
{
GtkWidget *toolbar;
GtkToolItem *item;
GtkStyleContext *context;
GtkWidget *box;
GtkWidget *button;
GtkWidget *image;
toolbar = gtk_toolbar_new ();
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
context = gtk_widget_get_style_context (toolbar);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
gtk_container_add (GTK_CONTAINER (section), toolbar);
item = gtk_separator_tool_item_new ();
gtk_tool_item_set_expand (item, TRUE);
gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 0);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
item = gtk_tool_item_new ();
gtk_container_add (GTK_CONTAINER (item), box);
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_cb), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_container_add (GTK_CONTAINER (box), button);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 1);
}
static void
add_address_section (CEPageIP4 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
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);
add_section_toolbar (page, widget, G_CALLBACK (add_empty_address_row));
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);
gtk_widget_show_all (widget);
}
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 (_("Server"));
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);
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
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);
update_row_sensitivity (page, page->dns_list);
}
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;
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);
page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch"));
gtk_switch_set_active (page->auto_dns, !nm_setting_ip4_config_get_ignore_auto_dns (page->setting));
add_section_toolbar (page, widget, G_CALLBACK (add_empty_dns_row));
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);
gtk_widget_show_all (widget);
}
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);
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
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);
update_row_sensitivity (page, page->routes_list);
}
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;
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);
page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
gtk_switch_set_active (page->auto_routes, !nm_setting_ip4_config_get_ignore_auto_routes (page->setting));
add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row));
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);
gtk_widget_show_all (widget);
}
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,
"/org/gnome/control-center/network/ip4-page.ui",
_("IPv4")));
page->setting = nm_connection_get_setting_ip4_config (connection);
if (!page->setting) {
page->setting = NM_SETTING_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,859 @@
/* -*- 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;
GtkWidget *widget;
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;
}
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "address_section"));
gtk_widget_set_visible (widget, addr_enabled);
gtk_widget_set_sensitive (page->dns_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
update_row_sensitivity (CEPageIP6 *page, GtkWidget *list)
{
GList *children, *l;
gint rows = 0;
children = gtk_container_get_children (GTK_CONTAINER (list));
for (l = children; l; l = l->next) {
GtkWidget *row = l->data;
GtkWidget *button;
button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
if (button != NULL)
rows++;
}
for (l = children; l; l = l->next) {
GtkWidget *row = l->data;
GtkWidget *button;
button = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "delete-button"));
if (button != NULL)
gtk_widget_set_sensitive (button, rows > 1);
}
g_list_free (children);
}
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));
update_row_sensitivity (page, list);
}
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);
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
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);
update_row_sensitivity (page, page->address_list);
}
static void
add_empty_address_row (CEPageIP6 *page)
{
add_address_row (page, "", "", "");
}
static void
add_section_toolbar (CEPageIP6 *page, GtkWidget *section, GCallback add_cb)
{
GtkWidget *toolbar;
GtkToolItem *item;
GtkStyleContext *context;
GtkWidget *box;
GtkWidget *button;
GtkWidget *image;
toolbar = gtk_toolbar_new ();
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
context = gtk_widget_get_style_context (toolbar);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_INLINE_TOOLBAR);
gtk_container_add (GTK_CONTAINER (section), toolbar);
item = gtk_separator_tool_item_new ();
gtk_tool_item_set_expand (item, TRUE);
gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 0);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
item = gtk_tool_item_new ();
gtk_container_add (GTK_CONTAINER (item), box);
button = gtk_button_new ();
g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_cb), page);
image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_image (GTK_BUTTON (button), image);
gtk_container_add (GTK_CONTAINER (box), button);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (item), 1);
}
static void
add_address_section (CEPageIP6 *page)
{
GtkWidget *widget;
GtkWidget *frame;
GtkWidget *list;
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);
add_section_toolbar (page, widget, G_CALLBACK (add_empty_address_row));
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);
gtk_widget_show_all (widget);
}
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 (_("Server"));
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);
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
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);
update_row_sensitivity (page, page->dns_list);
}
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;
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);
page->auto_dns = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_dns_switch"));
gtk_switch_set_active (page->auto_dns, !nm_setting_ip6_config_get_ignore_auto_dns (page->setting));
add_section_toolbar (page, widget, G_CALLBACK (add_empty_dns_row));
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);
gtk_widget_show_all (widget);
}
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);
g_object_set_data (G_OBJECT (row), "delete-button", delete_button);
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);
update_row_sensitivity (page, page->routes_list);
}
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;
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);
page->auto_routes = GTK_SWITCH (gtk_builder_get_object (CE_PAGE (page)->builder, "auto_routes_switch"));
gtk_switch_set_active (page->auto_routes, !nm_setting_ip6_config_get_ignore_auto_routes (page->setting));
add_section_toolbar (page, widget, G_CALLBACK (add_empty_route_row));
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);
gtk_widget_show_all (widget);
}
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,
"/org/gnome/control-center/network/ip6-page.ui",
_("IPv6")));
page->setting = nm_connection_get_setting_ip6_config (connection);
if (!page->setting) {
page->setting = NM_SETTING_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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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,188 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2013 Red Hat, Inc
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <glib-object.h>
#include <glib/gi18n.h>
#include <nm-utils.h>
#include "ce-page-vpn.h"
#include "vpn-helpers.h"
G_DEFINE_TYPE (CEPageVpn, ce_page_vpn, CE_TYPE_PAGE)
/* Hack to make the plugin-provided editor widget fit in better with
* the control center by changing
*
* Foo: [__________]
* Bar baz: [__________]
*
* to
*
* Foo [__________]
* Bar baz [__________]
*/
static void
vpn_gnome3ify_editor (GtkWidget *widget)
{
if (GTK_IS_CONTAINER (widget)) {
GList *children, *iter;
children = gtk_container_get_children (GTK_CONTAINER (widget));
for (iter = children; iter; iter = iter->next)
vpn_gnome3ify_editor (iter->data);
g_list_free (children);
} else if (GTK_IS_LABEL (widget)) {
const char *text;
gfloat xalign, yalign;
char *newtext;
int len;
gtk_misc_get_alignment (GTK_MISC (widget), &xalign, &yalign);
if (xalign != 0.0)
return;
text = gtk_label_get_text (GTK_LABEL (widget));
len = strlen (text);
if (len < 2 || text[len - 1] != ':')
return;
newtext = g_strndup (text, len - 1);
gtk_label_set_text (GTK_LABEL (widget), newtext);
g_free (newtext);
gtk_misc_set_alignment (GTK_MISC (widget), 1.0, yalign);
}
}
static void
load_vpn_plugin (CEPageVpn *page, NMConnection *connection)
{
CEPage *parent = CE_PAGE (page);
GtkWidget *ui_widget, *failure;
page->ui = nm_vpn_plugin_ui_interface_ui_factory (page->plugin, connection, NULL);
if (!page->ui) {
page->plugin = NULL;
return;
}
ui_widget = GTK_WIDGET (nm_vpn_plugin_ui_widget_interface_get_widget (page->ui));
if (!ui_widget) {
g_clear_object (&page->ui);
page->plugin = NULL;
return;
}
vpn_gnome3ify_editor (ui_widget);
failure = GTK_WIDGET (gtk_builder_get_object (parent->builder, "failure_label"));
gtk_widget_destroy (failure);
gtk_box_pack_start (page->box, ui_widget, TRUE, TRUE, 0);
gtk_widget_show_all (ui_widget);
g_signal_connect_swapped (page->ui, "changed", G_CALLBACK (ce_page_changed), page);
}
static void
connect_vpn_page (CEPageVpn *page)
{
const gchar *name;
name = nm_setting_connection_get_id (page->setting_connection);
gtk_entry_set_text (page->name, name);
g_signal_connect_swapped (page->name, "changed", G_CALLBACK (ce_page_changed), page);
}
static gboolean
validate (CEPage *page,
NMConnection *connection,
GError **error)
{
CEPageVpn *self = CE_PAGE_VPN (page);
g_object_set (self->setting_connection,
NM_SETTING_CONNECTION_ID, gtk_entry_get_text (self->name),
NULL);
if (!nm_setting_verify (NM_SETTING (self->setting_connection), NULL, error))
return FALSE;
if (!self->ui)
return TRUE;
return nm_vpn_plugin_ui_widget_interface_update_connection (self->ui, connection, error);
}
static void
ce_page_vpn_init (CEPageVpn *page)
{
}
static void
dispose (GObject *object)
{
CEPageVpn *page = CE_PAGE_VPN (object);
g_clear_object (&page->ui);
G_OBJECT_CLASS (ce_page_vpn_parent_class)->dispose (object);
}
static void
ce_page_vpn_class_init (CEPageVpnClass *class)
{
CEPageClass *page_class = CE_PAGE_CLASS (class);
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = dispose;
page_class->validate = validate;
}
CEPage *
ce_page_vpn_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings)
{
CEPageVpn *page;
const char *vpn_type;
page = CE_PAGE_VPN (ce_page_new (CE_TYPE_PAGE_VPN,
connection,
client,
settings,
"/org/gnome/control-center/network/vpn-page.ui",
_("Identity")));
page->name = GTK_ENTRY (gtk_builder_get_object (CE_PAGE (page)->builder, "entry_name"));
page->box = GTK_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "page"));
page->setting_connection = nm_connection_get_setting_connection (connection);
page->setting_vpn = nm_connection_get_setting_vpn (connection);
vpn_type = nm_setting_vpn_get_service_type (page->setting_vpn);
page->plugin = vpn_get_plugin_by_service (vpn_type);
if (page->plugin)
load_vpn_plugin (page, connection);
connect_vpn_page (page);
return CE_PAGE (page);
}

View File

@@ -0,0 +1,74 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2013 Red Hat, Inc.
*
* Licensed under the GNU General Public License Version 2
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more vpn.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __CE_PAGE_VPN_H
#define __CE_PAGE_VPN_H
#include <glib-object.h>
#include <nm-setting-wired.h>
#define NM_VPN_API_SUBJECT_TO_CHANGE
#include <nm-vpn-plugin-ui-interface.h>
#include <gtk/gtk.h>
#include "ce-page.h"
G_BEGIN_DECLS
#define CE_TYPE_PAGE_VPN (ce_page_vpn_get_type ())
#define CE_PAGE_VPN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), CE_TYPE_PAGE_VPN, CEPageVpn))
#define CE_PAGE_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), CE_TYPE_PAGE_VPN, CEPageVpnClass))
#define CE_IS_PAGE_VPN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), CE_TYPE_PAGE_VPN))
#define CE_IS_PAGE_VPN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), CE_TYPE_PAGE_VPN))
#define CE_PAGE_VPN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), CE_TYPE_PAGE_VPN, CEPageVpnClass))
typedef struct _CEPageVpn CEPageVpn;
typedef struct _CEPageVpnClass CEPageVpnClass;
struct _CEPageVpn
{
CEPage parent;
NMSettingConnection *setting_connection;
NMSettingVPN *setting_vpn;
GtkEntry *name;
GtkBox *box;
NMVpnPluginUiInterface *plugin;
NMVpnPluginUiWidgetInterface *ui;
};
struct _CEPageVpnClass
{
CEPageClass parent_class;
};
GType ce_page_vpn_get_type (void);
CEPage *ce_page_vpn_new (NMConnection *connection,
NMClient *client,
NMRemoteSettings *settings);
G_END_DECLS
#endif /* __CE_PAGE_VPN_H */

View File

@@ -0,0 +1,250 @@
/* -*- 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
all_user_changed (GtkToggleButton *b, CEPageWifi *page)
{
gboolean all_users;
NMSettingConnection *sc;
sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
all_users = gtk_toggle_button_get_active (b);
g_object_set (sc, "permissions", NULL, NULL);
if (!all_users)
nm_setting_connection_add_permission (sc, "user", g_get_user_name (), NULL);
}
static void
connect_wifi_page (CEPageWifi *page)
{
NMSettingConnection *sc;
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);
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
"auto_connect_check"));
sc = nm_connection_get_setting_connection (CE_PAGE (page)->connection);
g_object_bind_property (sc, "autoconnect",
widget, "active",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
widget = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder,
"all_user_check"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget),
nm_setting_connection_get_num_permissions (sc) == 0);
g_signal_connect (widget, "toggled",
G_CALLBACK (all_user_changed), page);
}
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,
"/org/gnome/control-center/network/wifi-page.ui",
_("Identity")));
page->setting = nm_connection_get_setting_wireless (connection);
connect_wifi_page (page);
return CE_PAGE (page);
}

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_resource,
const gchar *title)
{
CEPage *page;
GError *error = NULL;
page = CE_PAGE (g_object_new (type,
"connection", connection,
NULL));
page->title = g_strdup (title);
page->client = client;
page->settings= settings;
if (ui_resource) {
if (!gtk_builder_add_from_resource (page->builder, ui_resource, &error)) {
g_warning ("Couldn't load builder file: %s", error->message);
g_error_free (error);
g_object_unref (page);
return NULL;
}
page->page = GTK_WIDGET (gtk_builder_get_object (page->builder, "page"));
if (!page->page) {
g_warning ("Couldn't load page widget from %s", ui_resource);
g_object_unref (page);
return NULL;
}
g_object_ref_sink (page->page);
}
return page;
}
static void
emit_initialized (CEPage *page,
GError *error)
{
page->initialized = TRUE;
g_signal_emit (page, signals[INITIALIZED], 0, error);
}
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_resource,
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,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/control-center/network">
<file preprocess="xml-stripblanks">8021x-security-page.ui</file>
<file preprocess="xml-stripblanks">connection-editor.ui</file>
<file preprocess="xml-stripblanks">details-page.ui</file>
<file preprocess="xml-stripblanks">ethernet-page.ui</file>
<file preprocess="xml-stripblanks">ip4-page.ui</file>
<file preprocess="xml-stripblanks">ip6-page.ui</file>
<file preprocess="xml-stripblanks">reset-page.ui</file>
<file preprocess="xml-stripblanks">security-page.ui</file>
<file preprocess="xml-stripblanks">vpn-page.ui</file>
<file preprocess="xml-stripblanks">wifi-page.ui</file>
</gresource>
</gresources>

View File

@@ -0,0 +1,206 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<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="GtkNotebook" id="details_toplevel_notebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<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>
</child>
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">page 1</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkBox" id="details_add_connection_outer_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="details_add_connection_inner_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkFrame" id="details_add_connection_frame">
<property name="width_request">300</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label">page 2</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</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>
<object class="GtkListStore" id="details_store">
<columns>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name page -->
<column type="gint"/>
</columns>
</object>
</interface>

View File

@@ -0,0 +1,310 @@
<?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="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>
</interface>

View File

@@ -0,0 +1,273 @@
<?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_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>
<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">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>
<child internal-child="entry">
<object class="GtkEntry" id="comboboxtext-entry">
<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">1</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">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<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">M_TU</property>
<property name="use_underline">True</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="GtkLabel" id="heading_cloned_mac">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">_Cloned Address</property>
<property name="use_underline">True</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="auto_connect_check">
<property name="label" translatable="yes">Connect _automatically</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="valign">end</property>
<property name="vexpand">True</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="all_user_check">
<property name="label" translatable="yes">Make available to other _users</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">0</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_mtu">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">bytes</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<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="invisible_char_set">True</property>
<property name="adjustment">adjustment1</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>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkLabel" id="filler">
<property name="visible">True</property>
<property name="can_focus">False</property>
</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>
</object>
<object class="GtkSizeGroup" id="sizegroup1">
<widgets>
<widget name="label_mtu"/>
<widget name="filler"/>
</widgets>
</object>
</interface>

View File

@@ -0,0 +1,296 @@
<?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="GtkBox" id="box1">
<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="spacing">6</property>
<child>
<object class="GtkLabel" id="heading_dns">
<property name="visible">True</property>
<property name="can_focus">False</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">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<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">Automatic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="auto_dns_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</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="GtkBox" id="box3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="margin_bottom">5</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="heading_routes">
<property name="visible">True</property>
<property name="can_focus">False</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">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<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">Automatic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="auto_routes_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">2</property>
</packing>
</child>
</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,302 @@
<?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="GtkBox" id="box1">
<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="spacing">6</property>
<child>
<object class="GtkLabel" id="heading_dns">
<property name="visible">True</property>
<property name="can_focus">False</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">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<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">Automatic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="auto_dns_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</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="GtkBox" id="box3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">24</property>
<property name="margin_bottom">5</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="heading_routes">
<property name="visible">True</property>
<property name="can_focus">False</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">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<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">Automatic</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkSwitch" id="auto_routes_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">2</property>
</packing>
</child>
</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>
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
</interface>

View File

@@ -0,0 +1,957 @@
/* -*- 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 "net-connection-editor-resources.h"
#include "ce-page-details.h"
#include "ce-page-wifi.h"
#include "ce-page-ip4.h"
#include "ce-page-ip6.h"
#include "ce-page-security.h"
#include "ce-page-reset.h"
#include "ce-page-ethernet.h"
#include "ce-page-8021x-security.h"
#include "ce-page-vpn.h"
#include "vpn-helpers.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 (editor->is_new_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_resource (editor->builder,
"/org/gnome/control-center/network/connection-editor.ui",
&error);
if (error != NULL) {
g_warning ("Could not load ui file: %s", error->message);
g_error_free (error);
return;
}
editor->window = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_dialog"));
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);
g_resources_register (net_connection_editor_get_resource ());
object_class->finalize = net_connection_editor_finalize;
signals[DONE] = g_signal_new ("done",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NetConnectionEditorClass, done),
NULL, NULL,
NULL,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
}
static void
net_connection_editor_error_dialog (NetConnectionEditor *editor,
const char *primary_text,
const char *secondary_text)
{
GtkWidget *dialog;
GtkWindow *parent;
if (gtk_widget_is_visible (editor->window))
parent = GTK_WINDOW (editor->window);
else
parent = GTK_WINDOW (editor->parent_window);
dialog = gtk_message_dialog_new (parent,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
primary_text);
if (secondary_text) {
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", secondary_text);
}
g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL);
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_dialog_run (GTK_DIALOG (dialog));
}
static void
net_connection_editor_do_fallback (NetConnectionEditor *editor, const gchar *type)
{
gchar *cmdline;
GError *error = NULL;
if (editor->is_new_connection) {
cmdline = g_strdup_printf ("nm-connection-editor --type='%s' --create", type);
} else {
cmdline = g_strdup_printf ("nm-connection-editor --edit='%s'",
nm_connection_get_uuid (editor->connection));
}
g_spawn_command_line_async (cmdline, &error);
g_free (cmdline);
if (error) {
net_connection_editor_error_dialog (editor,
_("Unable to open connection editor"),
error->message);
g_error_free (error);
}
g_signal_emit (editor, signals[DONE], 0, FALSE);
}
static void
net_connection_editor_update_title (NetConnectionEditor *editor)
{
gchar *id;
if (editor->is_new_connection) {
if (editor->device) {
id = g_strdup (_("New Profile"));
} else {
/* Leave it set to "Add New Connection" */
return;
}
} else {
NMSettingWireless *sw;
sw = nm_connection_get_setting_wireless (editor->connection);
if (sw) {
const GByteArray *ssid;
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;
GtkTreeSelection *selection;
GtkTreePath *path;
editor->is_new_connection = !nm_remote_settings_get_connection_by_uuid (editor->settings,
nm_connection_get_uuid (connection));
if (editor->is_new_connection) {
GtkWidget *button;
button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button"));
gtk_button_set_label (GTK_BUTTON (button), _("_Add"));
}
editor->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);
if (!editor->is_new_connection)
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_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));
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));
else if (strcmp (type, NM_SETTING_VPN_SETTING_NAME) == 0)
add_page (editor, ce_page_vpn_new (editor->connection, editor->client, editor->settings));
else {
/* Unsupported type */
net_connection_editor_do_fallback (editor, type);
return;
}
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 (!editor->is_new_connection)
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);
selection = GTK_TREE_SELECTION (gtk_builder_get_object (editor->builder,
"details_page_list_selection"));
path = gtk_tree_path_new_first ();
gtk_tree_selection_select_path (selection, path);
gtk_tree_path_free (path);
}
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);
}
}
typedef struct {
const char *name;
GType (*type_func) (void);
} NetConnectionType;
static const NetConnectionType connection_types[] = {
{ N_("VPN"), nm_setting_vpn_get_type },
{ N_("Bond"), nm_setting_bond_get_type },
{ N_("Bridge"), nm_setting_bridge_get_type },
{ N_("VLAN"), nm_setting_vlan_get_type }
};
static const NetConnectionType *vpn_connection_type = &connection_types[0];
static NMConnection *
complete_connection_for_type (NetConnectionEditor *editor, NMConnection *connection,
const NetConnectionType *connection_type)
{
NMSettingConnection *s_con;
NMSetting *s_type;
GType connection_gtype;
if (!connection)
connection = nm_connection_new ();
s_con = nm_connection_get_setting_connection (connection);
if (!s_con) {
s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
nm_connection_add_setting (connection, NM_SETTING (s_con));
}
if (!nm_setting_connection_get_uuid (s_con)) {
gchar *uuid = nm_utils_uuid_generate ();
g_object_set (s_con,
NM_SETTING_CONNECTION_UUID, uuid,
NULL);
g_free (uuid);
}
if (!nm_setting_connection_get_id (s_con)) {
GSList *connections;
gchar *id, *id_pattern;
connections = nm_remote_settings_list_connections (editor->settings);
id_pattern = g_strdup_printf ("%s %%d", _(connection_type->name));
id = ce_page_get_next_available_name (connections, id_pattern);
g_object_set (s_con,
NM_SETTING_CONNECTION_ID, id,
NULL);
g_free (id);
g_free (id_pattern);
g_slist_free (connections);
}
connection_gtype = connection_type->type_func ();
s_type = nm_connection_get_setting (connection, connection_gtype);
if (!s_type) {
s_type = g_object_new (connection_gtype, NULL);
nm_connection_add_setting (connection, s_type);
}
if (!nm_setting_connection_get_connection_type (s_con)) {
g_object_set (s_con,
NM_SETTING_CONNECTION_TYPE, nm_setting_get_name (s_type),
NULL);
}
return connection;
}
static gint
sort_vpn_plugins (gconstpointer a, gconstpointer b)
{
NMVpnPluginUiInterface *aa = NM_VPN_PLUGIN_UI_INTERFACE (a);
NMVpnPluginUiInterface *bb = NM_VPN_PLUGIN_UI_INTERFACE (b);
char *aa_desc = NULL, *bb_desc = NULL;
int ret;
g_object_get (aa, NM_VPN_PLUGIN_UI_INTERFACE_NAME, &aa_desc, NULL);
g_object_get (bb, NM_VPN_PLUGIN_UI_INTERFACE_NAME, &bb_desc, NULL);
ret = g_strcmp0 (aa_desc, bb_desc);
g_free (aa_desc);
g_free (bb_desc);
return ret;
}
static void
finish_add_connection (NetConnectionEditor *editor, NMConnection *connection)
{
GtkNotebook *notebook;
GtkBin *frame;
frame = GTK_BIN (gtk_builder_get_object (editor->builder, "details_add_connection_frame"));
gtk_widget_destroy (gtk_bin_get_child (frame));
notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_toplevel_notebook"));
gtk_notebook_set_current_page (notebook, 0);
gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")));
if (connection)
net_connection_editor_set_connection (editor, connection);
}
static void
vpn_import_complete (NMConnection *connection, gpointer user_data)
{
NetConnectionEditor *editor = user_data;
if (!connection) {
/* The import code shows its own error dialogs. */
g_signal_emit (editor, signals[DONE], 0, FALSE);
return;
}
complete_connection_for_type (editor, connection, vpn_connection_type);
finish_add_connection (editor, connection);
}
static void
vpn_type_activated (EggListBox *list, GtkWidget *row, NetConnectionEditor *editor)
{
const char *service_name = g_object_get_data (G_OBJECT (row), "service_name");
NMConnection *connection;
NMSettingVPN *s_vpn;
NMSettingConnection *s_con;
if (!strcmp (service_name, "import")) {
vpn_import (GTK_WINDOW (editor->window), vpn_import_complete, editor);
return;
}
connection = complete_connection_for_type (editor, NULL, vpn_connection_type);
s_vpn = nm_connection_get_setting_vpn (connection);
g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_name, NULL);
/* Mark the connection as private to this user, and non-autoconnect */
s_con = nm_connection_get_setting_connection (connection);
g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL);
nm_setting_connection_add_permission (s_con, "user", g_get_user_name (), NULL);
finish_add_connection (editor, connection);
}
static void
select_vpn_type (NetConnectionEditor *editor, EggListBox *list)
{
GHashTable *vpn_plugins;
GHashTableIter vpn_iter;
gpointer service_name, vpn_plugin;
GList *children, *plugin_list, *iter;
GtkWidget *row, *name_label, *desc_label;
GError *error = NULL;
/* Get the available VPN types */
vpn_plugins = vpn_get_plugins (&error);
if (!vpn_plugins) {
net_connection_editor_error_dialog (editor,
_("Could not load VPN plugins"),
error->message);
g_error_free (error);
finish_add_connection (editor, NULL);
g_signal_emit (editor, signals[DONE], 0, FALSE);
return;
}
plugin_list = NULL;
g_hash_table_iter_init (&vpn_iter, vpn_plugins);
while (g_hash_table_iter_next (&vpn_iter, &service_name, &vpn_plugin))
plugin_list = g_list_prepend (plugin_list, vpn_plugin);
plugin_list = g_list_sort (plugin_list, sort_vpn_plugins);
/* Remove the previous menu contents */
children = gtk_container_get_children (GTK_CONTAINER (list));
for (iter = children; iter; iter = iter->next)
gtk_widget_destroy (iter->data);
/* Add the VPN types */
for (iter = plugin_list; iter; iter = iter->next) {
char *name, *desc, *desc_markup, *service_name;
g_object_get (iter->data,
"name", &name,
"desc", &desc,
"service", &service_name,
NULL);
// FIXME: can't hardcode fgcolor
desc_markup = g_markup_printf_escaped ("<span size='smaller' fgcolor='#7f7f7f'>%s</span>", desc);
row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_widget_set_margin_left (row, 12);
gtk_widget_set_margin_right (row, 12);
gtk_widget_set_margin_top (row, 12);
gtk_widget_set_margin_bottom (row, 12);
name_label = gtk_label_new (name);
gtk_misc_set_alignment (GTK_MISC (name_label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (row), name_label, FALSE, TRUE, 0);
desc_label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (desc_label), desc_markup);
gtk_label_set_line_wrap (GTK_LABEL (desc_label), TRUE);
gtk_misc_set_alignment (GTK_MISC (desc_label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (row), desc_label, FALSE, TRUE, 0);
g_free (name);
g_free (desc);
g_free (desc_markup);
gtk_widget_show_all (row);
g_object_set_data_full (G_OBJECT (row), "service_name", service_name, g_free);
gtk_container_add (GTK_CONTAINER (list), row);
}
/* Import */
row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_widget_set_margin_left (row, 12);
gtk_widget_set_margin_right (row, 12);
gtk_widget_set_margin_top (row, 12);
gtk_widget_set_margin_bottom (row, 12);
name_label = gtk_label_new (_("Import from file…"));
gtk_misc_set_alignment (GTK_MISC (name_label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (row), name_label, FALSE, TRUE, 0);
gtk_widget_show_all (row);
g_object_set_data (G_OBJECT (row), "service_name", "import");
gtk_container_add (GTK_CONTAINER (list), row);
g_signal_connect (list, "child-activated",
G_CALLBACK (vpn_type_activated), editor);
}
static void
connection_type_activated (EggListBox *list, GtkWidget *row, NetConnectionEditor *editor)
{
const NetConnectionType *connection_type = g_object_get_data (G_OBJECT (row), "connection_type");
NMConnection *connection;
g_signal_handlers_disconnect_by_func (list, G_CALLBACK (connection_type_activated), editor);
if (connection_type == vpn_connection_type) {
select_vpn_type (editor, list);
return;
}
connection = complete_connection_for_type (editor, NULL, connection_type);
finish_add_connection (editor, connection);
}
static void
net_connection_editor_add_connection (NetConnectionEditor *editor)
{
GtkNotebook *notebook;
GtkContainer *frame;
EggListBox *list;
int i;
notebook = GTK_NOTEBOOK (gtk_builder_get_object (editor->builder, "details_toplevel_notebook"));
frame = GTK_CONTAINER (gtk_builder_get_object (editor->builder, "details_add_connection_frame"));
list = egg_list_box_new ();
egg_list_box_set_selection_mode (list, GTK_SELECTION_NONE);
egg_list_box_set_separator_funcs (list, update_separator, NULL, NULL);
g_signal_connect (list, "child-activated",
G_CALLBACK (connection_type_activated), editor);
for (i = 0; i < G_N_ELEMENTS (connection_types); i++) {
GtkWidget *row, *label;
row = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
label = gtk_label_new (_(connection_types[i].name));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_widget_set_margin_left (label, 12);
gtk_widget_set_margin_right (label, 12);
gtk_widget_set_margin_top (label, 12);
gtk_widget_set_margin_bottom (label, 12);
gtk_box_pack_start (GTK_BOX (row), label, FALSE, TRUE, 0);
g_object_set_data (G_OBJECT (row), "connection_type", (gpointer) &connection_types[i]);
gtk_container_add (GTK_CONTAINER (list), row);
}
gtk_widget_show_all (GTK_WIDGET (list));
gtk_container_add (frame, GTK_WIDGET (list));
gtk_notebook_set_current_page (notebook, 1);
gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (editor->builder, "details_apply_button")));
gtk_window_set_title (GTK_WINDOW (editor->window), _("Add Network Connection"));
}
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);
if (device)
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);
if (connection)
net_connection_editor_set_connection (editor, connection);
else
net_connection_editor_add_connection (editor);
return editor;
}
void
net_connection_editor_present (NetConnectionEditor *editor)
{
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,90 @@
/* -*- 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;
gboolean is_new_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">20</property>
<property name="column_spacing">20</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">center</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">center</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 network, including passwords, but remember it as a preferred network</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</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,294 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkNotebook" id="page">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
<object class="GtkGrid" id="grid">
<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>
</child>
<child type="tab">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 1</property>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
<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">6</property>
<child>
<object class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">35</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="GtkEntry" id="entry2">
<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">1</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry3">
<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">2</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry4">
<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">3</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry5">
<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">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry6">
<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">5</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry7">
<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">6</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry8">
<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">7</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry9">
<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">8</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="entry10">
<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">9</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Anony_mous identity</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="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Inner _authentication</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>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">page 2</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child type="tab">
<placeholder/>
</child>
</object>
</interface>

View File

@@ -0,0 +1,416 @@
/* -*- 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 Red Hat, Inc.
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#include <gmodule.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <nm-connection.h>
#include <nm-setting-connection.h>
#include <nm-setting-vpn.h>
#include "vpn-helpers.h"
#define NM_VPN_API_SUBJECT_TO_CHANGE
#include "nm-vpn-plugin-ui-interface.h"
static GHashTable *plugins = NULL;
NMVpnPluginUiInterface *
vpn_get_plugin_by_service (const char *service)
{
g_return_val_if_fail (service != NULL, NULL);
if (!plugins) {
vpn_get_plugins (NULL);
if (!plugins)
return NULL;
}
return g_hash_table_lookup (plugins, service);
}
GHashTable *
vpn_get_plugins (GError **error)
{
GDir *dir;
const char *f;
if (error)
g_return_val_if_fail (*error == NULL, NULL);
if (plugins)
return plugins;
dir = g_dir_open (NM_VPN_CONFIG_DIR, 0, error);
if (!dir)
return NULL;
plugins = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free, (GDestroyNotify) g_object_unref);
while ((f = g_dir_read_name (dir))) {
char *path = NULL, *service = NULL;
char *so_path = NULL, *so_name = NULL;
GKeyFile *keyfile = NULL;
GModule *module;
NMVpnPluginUiFactory factory = NULL;
if (!g_str_has_suffix (f, ".name"))
continue;
path = g_strdup_printf ("%s/%s", NM_VPN_CONFIG_DIR, f);
keyfile = g_key_file_new ();
if (!g_key_file_load_from_file (keyfile, path, 0, NULL))
goto next;
service = g_key_file_get_string (keyfile, "VPN Connection", "service", NULL);
if (!service)
goto next;
so_path = g_key_file_get_string (keyfile, "GNOME", "properties", NULL);
if (!so_path)
goto next;
/* Remove any path and extension components, then reconstruct path
* to the SO in LIBDIR
*/
so_name = g_path_get_basename (so_path);
g_free (so_path);
so_path = g_build_filename (NM_VPN_MODULE_DIR, so_name, NULL);
g_free (so_name);
module = g_module_open (so_path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
if (!module) {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Cannot load the VPN plugin which provides the "
"service '%s'.", service);
goto next;
}
if (g_module_symbol (module, "nm_vpn_plugin_ui_factory", (gpointer) &factory)) {
NMVpnPluginUiInterface *plugin;
GError *factory_error = NULL;
gboolean success = FALSE;
plugin = factory (&factory_error);
if (plugin) {
char *plug_name = NULL, *plug_service = NULL;
/* Validate plugin properties */
g_object_get (G_OBJECT (plugin),
NM_VPN_PLUGIN_UI_INTERFACE_NAME, &plug_name,
NM_VPN_PLUGIN_UI_INTERFACE_SERVICE, &plug_service,
NULL);
if (!plug_name || !strlen (plug_name)) {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "cannot load VPN plugin in '%s': missing plugin name",
g_module_name (module));
} else if (!plug_service || strcmp (plug_service, service)) {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "cannot load VPN plugin in '%s': invalid service name",
g_module_name (module));
} else {
/* Success! */
g_object_set_data_full (G_OBJECT (plugin), "gmodule", module,
(GDestroyNotify) g_module_close);
g_hash_table_insert (plugins, g_strdup (service), plugin);
success = TRUE;
}
g_free (plug_name);
g_free (plug_service);
} else {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "cannot load VPN plugin in '%s': %s",
g_module_name (module), g_module_error ());
}
if (!success)
g_module_close (module);
} else {
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "cannot locate nm_vpn_plugin_ui_factory() in '%s': %s",
g_module_name (module), g_module_error ());
g_module_close (module);
}
next:
g_free (so_path);
g_free (service);
g_key_file_free (keyfile);
g_free (path);
}
g_dir_close (dir);
return plugins;
}
typedef struct {
VpnImportCallback callback;
gpointer user_data;
} ActionInfo;
static void
import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
{
char *filename = NULL;
ActionInfo *info = (ActionInfo *) user_data;
GHashTableIter iter;
gpointer key;
NMVpnPluginUiInterface *plugin;
NMConnection *connection = NULL;
GError *error = NULL;
if (response != GTK_RESPONSE_ACCEPT)
goto out;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
if (!filename) {
g_warning ("%s: didn't get a filename back from the chooser!", __func__);
goto out;
}
g_hash_table_iter_init (&iter, plugins);
while (!connection && g_hash_table_iter_next (&iter, &key, (gpointer *)&plugin)) {
g_clear_error (&error);
connection = nm_vpn_plugin_ui_interface_import (plugin, filename, &error);
}
if (!connection) {
GtkWidget *err_dialog;
char *bname = g_path_get_basename (filename);
err_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
_("Cannot import VPN connection"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog),
_("The file '%s' could not be read or does not contain recognized VPN connection information\n\nError: %s."),
bname, error ? error->message : "unknown error");
g_free (bname);
g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL);
g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_dialog_run (GTK_DIALOG (err_dialog));
}
g_clear_error (&error);
g_free (filename);
out:
gtk_widget_hide (dialog);
gtk_widget_destroy (dialog);
info->callback (connection, info->user_data);
g_free (info);
}
static void
destroy_import_chooser (GtkWidget *dialog, gpointer user_data)
{
ActionInfo *info = (ActionInfo *) user_data;
gtk_widget_destroy (dialog);
info->callback (NULL, info->user_data);
g_free (info);
}
void
vpn_import (GtkWindow *parent, VpnImportCallback callback, gpointer user_data)
{
GtkWidget *dialog;
ActionInfo *info;
const char *home_folder;
dialog = gtk_file_chooser_dialog_new (_("Select file to import"),
parent,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
home_folder = g_get_home_dir ();
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder);
info = g_malloc0 (sizeof (ActionInfo));
info->callback = callback;
info->user_data = user_data;
g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (destroy_import_chooser), info);
g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (import_vpn_from_file_cb), info);
gtk_widget_show_all (dialog);
gtk_window_present (GTK_WINDOW (dialog));
}
static void
export_vpn_to_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
{
NMConnection *connection = NM_CONNECTION (user_data);
char *filename = NULL;
GError *error = NULL;
NMVpnPluginUiInterface *plugin;
NMSettingConnection *s_con = NULL;
NMSettingVPN *s_vpn = NULL;
const char *service_type;
const char *id = NULL;
gboolean success = FALSE;
if (response != GTK_RESPONSE_ACCEPT)
goto out;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
if (!filename) {
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "no filename");
goto done;
}
if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
int replace_response;
GtkWidget *replace_dialog;
char *bname;
bname = g_path_get_basename (filename);
replace_dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_CANCEL,
_("A file named \"%s\" already exists."),
bname);
gtk_dialog_add_buttons (GTK_DIALOG (replace_dialog), _("_Replace"), GTK_RESPONSE_OK, NULL);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (replace_dialog),
_("Do you want to replace %s with the VPN connection you are saving?"), bname);
g_free (bname);
replace_response = gtk_dialog_run (GTK_DIALOG (replace_dialog));
gtk_widget_destroy (replace_dialog);
if (replace_response != GTK_RESPONSE_OK)
goto out;
}
s_con = nm_connection_get_setting_connection (connection);
id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
if (!id) {
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "connection setting invalid");
goto done;
}
s_vpn = nm_connection_get_setting_vpn (connection);
service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL;
if (!service_type) {
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, "VPN setting invalid");
goto done;
}
plugin = vpn_get_plugin_by_service (service_type);
if (plugin)
success = nm_vpn_plugin_ui_interface_export (plugin, filename, connection, &error);
done:
if (!success) {
GtkWidget *err_dialog;
char *bname = filename ? g_path_get_basename (filename) : g_strdup ("(none)");
err_dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
_("Cannot export VPN connection"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog),
_("The VPN connection '%s' could not be exported to %s.\n\nError: %s."),
id ? id : "(unknown)", bname, error ? error->message : "unknown error");
g_free (bname);
g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL);
g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show_all (err_dialog);
gtk_window_present (GTK_WINDOW (err_dialog));
}
out:
if (error)
g_error_free (error);
g_object_unref (connection);
gtk_widget_hide (dialog);
gtk_widget_destroy (dialog);
}
void
vpn_export (NMConnection *connection)
{
GtkWidget *dialog;
NMVpnPluginUiInterface *plugin;
NMSettingVPN *s_vpn = NULL;
const char *service_type;
const char *home_folder;
s_vpn = nm_connection_get_setting_vpn (connection);
service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL;
if (!service_type) {
g_warning ("%s: invalid VPN connection!", __func__);
return;
}
dialog = gtk_file_chooser_dialog_new (_("Export VPN connection..."),
NULL,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
home_folder = g_get_home_dir ();
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder);
plugin = vpn_get_plugin_by_service (service_type);
if (plugin) {
char *suggested = NULL;
suggested = nm_vpn_plugin_ui_interface_get_suggested_name (plugin, connection);
if (suggested) {
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), suggested);
g_free (suggested);
}
}
g_signal_connect (G_OBJECT (dialog), "close", G_CALLBACK (gtk_widget_destroy), NULL);
g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (export_vpn_to_file_cb), g_object_ref (connection));
gtk_widget_show_all (dialog);
gtk_window_present (GTK_WINDOW (dialog));
}
gboolean
vpn_supports_ipv6 (NMConnection *connection)
{
NMSettingVPN *s_vpn;
const char *service_type;
NMVpnPluginUiInterface *plugin;
guint32 capabilities;
s_vpn = nm_connection_get_setting_vpn (connection);
g_return_val_if_fail (s_vpn != NULL, FALSE);
service_type = nm_setting_vpn_get_service_type (s_vpn);
g_return_val_if_fail (service_type != NULL, FALSE);
plugin = vpn_get_plugin_by_service (service_type);
g_return_val_if_fail (plugin != NULL, FALSE);
capabilities = nm_vpn_plugin_ui_interface_get_capabilities (plugin);
return (capabilities & NM_VPN_PLUGIN_UI_CAPABILITY_IPV6) != 0;
}

View File

@@ -0,0 +1,44 @@
/* -*- 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 Red Hat, Inc.
*/
#ifndef _VPN_HELPERS_H_
#define _VPN_HELPERS_H_
#include <glib.h>
#include <gtk/gtk.h>
#include <nm-connection.h>
#define NM_VPN_API_SUBJECT_TO_CHANGE
#include <nm-vpn-plugin-ui-interface.h>
GHashTable *vpn_get_plugins (GError **error);
NMVpnPluginUiInterface *vpn_get_plugin_by_service (const char *service);
typedef void (*VpnImportCallback) (NMConnection *connection, gpointer user_data);
void vpn_import (GtkWindow *parent, VpnImportCallback callback, gpointer user_data);
void vpn_export (NMConnection *connection);
gboolean vpn_supports_ipv6 (NMConnection *connection);
#endif /* _VPN_HELPERS_H_ */

View File

@@ -0,0 +1,70 @@
<?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="margin_left">50</property>
<property name="margin_right">50</property>
<property name="margin_top">12</property>
<property name="margin_bottom">12</property>
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<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>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</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>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="failure_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">(Error: unable to load VPN connection editor)</property>
<attributes>
<attribute name="style" value="italic"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<object class="GtkSizeGroup" id="sizegroup1"/>
</interface>

View File

@@ -0,0 +1,186 @@
<?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 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>
<child internal-child="entry">
<object class="GtkEntry" id="comboboxtext-entry2">
<property name="can_focus">False</property>
</object>
</child>
</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>
<child internal-child="entry">
<object class="GtkEntry" id="comboboxtext-entry4">
<property name="can_focus">False</property>
</object>
</child>
</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="GtkCheckButton" id="auto_connect_check">
<property name="label" translatable="yes">Connect _automatically</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="valign">end</property>
<property name="vexpand">True</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">2</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="all_user_check">
<property name="label" translatable="yes">Make available to _other users</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">0</property>
<property name="top_attach">5</property>
<property name="width">2</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,589 @@ 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++, _("IPv4 Address"), ip4_address);
add_details_row (details, i++, _("IPv6 Address"), ip6_address);
} else if (ip4_address) {
add_details_row (details, i++, _("IP Address"), ip4_address);
} else if (ip6_address) {
add_details_row (details, i++, _("IPv6 Address"), ip6_address);
}
add_details_row (details, i++, _("Hardware Address"),
nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)));
if (ip4_route)
add_details_row (details, i++, _("Default Route"), ip4_route);
if (ip4_dns)
add_details_row (details, i++, _("DNS"), ip4_dns);
if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) {
gchar *last_used;
last_used = get_last_used_string (connection);
add_details_row (details, i++, _("Last used"), last_used);
g_free (last_used);
}
g_free (ip4_address);
g_free (ip4_route);
g_free (ip4_dns);
g_free (ip6_address);
}
static void populate_ui (NetDeviceEthernet *device);
static gboolean
device_state_to_off_switch (NMDeviceState state)
{
switch (state) {
case NM_DEVICE_STATE_UNMANAGED:
case NM_DEVICE_STATE_UNAVAILABLE:
case NM_DEVICE_STATE_DISCONNECTED:
case NM_DEVICE_STATE_DEACTIVATING:
case NM_DEVICE_STATE_FAILED:
return FALSE;
default:
return TRUE;
}
}
static void
device_ethernet_refresh_ui (NetDeviceEthernet *device)
{
NMDevice *nm_device;
NMDeviceState state;
GtkWidget *widget;
GString *status;
gchar *speed = NULL;
nm_device = net_device_get_nm_device (NET_DEVICE (device));
widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "label_device"));
gtk_label_set_label (GTK_LABEL (widget), net_object_get_title (NET_OBJECT (device)));
widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "image_device"));
gtk_image_set_from_icon_name (GTK_IMAGE (widget),
panel_device_to_icon_name (nm_device),
GTK_ICON_SIZE_DIALOG);
widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "device_off_switch"));
state = nm_device_get_state (nm_device);
gtk_widget_set_visible (widget,
state != NM_DEVICE_STATE_UNAVAILABLE
&& state != NM_DEVICE_STATE_UNMANAGED);
device->updating_device = TRUE;
gtk_switch_set_active (GTK_SWITCH (widget), device_state_to_off_switch (state));
device->updating_device = FALSE;
widget = GTK_WIDGET (gtk_builder_get_object (device->builder, "label_status"));
status = g_string_new (panel_device_state_to_localized_string (nm_device));
if (state != NM_DEVICE_STATE_UNAVAILABLE)
speed = net_device_simple_get_speed (NET_DEVICE_SIMPLE (device));
if (speed)
g_string_append_printf (status, " - %s", speed);
gtk_label_set_label (GTK_LABEL (widget), status->str);
g_string_free (status, TRUE);
populate_ui (device);
}
static void
editor_done (NetConnectionEditor *editor,
gboolean success,
NetDeviceEthernet *device)
{
g_object_unref (editor);
device_ethernet_refresh_ui (device);
}
static void
show_details_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
connection_removed (NMRemoteConnection *connection,
NetDeviceEthernet *device)
{
device_ethernet_refresh_ui (device);
}
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));
for (l = connections; l; l = l->next) {
NMConnection *connection = l->data;
if (!g_object_get_data (G_OBJECT (connection), "removed_signal_handler")) {
g_signal_connect (connection, "removed",
G_CALLBACK (connection_removed), device);
g_object_set_data (G_OBJECT (connection), "removed_signal_handler", GINT_TO_POINTER (TRUE));
}
}
n_connections = g_slist_length (connections);
if (n_connections > 4) {
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_widget_set_vexpand (device->scrolled_window, TRUE);
} else {
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (device->scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_NEVER);
gtk_widget_set_vexpand (device->scrolled_window, FALSE);
}
if (n_connections > 1) {
gtk_widget_hide (device->details);
gtk_widget_hide (device->details_button);
for (l = connections; l; l = l->next) {
NMConnection *connection = l->data;
add_row (device, connection);
}
gtk_widget_show (device->scrolled_window);
} else if (n_connections == 1) {
connection = connections->data;
gtk_widget_hide (device->scrolled_window);
add_details (device->details, net_device_get_nm_device (NET_DEVICE (device)), connection);
gtk_widget_show_all (device->details);
gtk_widget_show (device->details_button);
g_object_set_data (G_OBJECT (device->details_button), "row", device->details_button);
g_object_set_data (G_OBJECT (device->details_button), "connection", connection);
} else {
gtk_widget_hide (device->scrolled_window);
gtk_widget_hide (device->details);
gtk_widget_hide (device->details_button);
}
}
static void
remote_settings_read_cb (NMRemoteSettings *settings,
NetDeviceEthernet *device)
{
device_ethernet_refresh_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_off_toggled (GtkSwitch *sw,
GParamSpec *pspec,
NetDeviceEthernet *device)
{
NMClient *client;
NMDevice *nm_device;
NMConnection *connection;
NMActiveConnection *a;
if (device->updating_device)
return;
client = net_object_get_client (NET_OBJECT (device));
nm_device = net_device_get_nm_device (NET_DEVICE (device));
if (gtk_switch_get_active (sw)) {
connection = net_device_get_find_connection (NET_DEVICE (device));
if (connection != NULL) {
nm_client_activate_connection (client,
connection,
nm_device,
NULL, NULL, NULL);
}
} else {
a = nm_device_get_active_connection (nm_device);
if (a) {
nm_client_deactivate_connection (client, a);
}
}
}
static void
device_ethernet_constructed (GObject *object)
{
NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
NMRemoteSettings *settings;
GtkWidget *list;
GtkWidget *swin;
GtkWidget *widget;
widget = GTK_WIDGET (gtk_builder_get_object (device->builder,
"device_off_switch"));
g_signal_connect (widget, "notify::active",
G_CALLBACK (device_off_toggled), device);
device->scrolled_window = swin = GTK_WIDGET (gtk_builder_get_object (device->builder, "list"));
device->list = list = GTK_WIDGET (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
device_ethernet_refresh (NetObject *object)
{
NetDeviceEthernet *device = NET_DEVICE_ETHERNET (object);
device_ethernet_refresh_ui (device);
}
static void
net_device_ethernet_class_init (NetDeviceEthernetClass *klass)
{
NetDeviceSimpleClass *simple_class = NET_DEVICE_SIMPLE_CLASS (klass);
NetObjectClass *obj_class = NET_OBJECT_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
simple_class->get_speed = device_ethernet_get_speed;
obj_class->refresh = device_ethernet_refresh;
obj_class->add_to_notebook = device_ethernet_add_to_notebook;
object_class->constructed = device_ethernet_constructed;
object_class->finalize = device_ethernet_finalize;
}
static void
net_device_ethernet_init (NetDeviceEthernet *device_ethernet)
net_device_ethernet_init (NetDeviceEthernet *device)
{
GError *error = NULL;
device->builder = gtk_builder_new ();
gtk_builder_add_from_resource (device->builder,
"/org/gnome/control-center/network/network-ethernet.ui",
&error);
if (error != NULL) {
g_warning ("Could not load interface file: %s", error->message);
g_error_free (error);
return;
}
}

View File

@@ -41,16 +41,24 @@ 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;
gboolean updating_device;
};
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

@@ -31,6 +31,8 @@
#include "nm-remote-connection.h"
#include "nm-setting-vpn.h"
#include "connection-editor/net-connection-editor.h"
#define NET_VPN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_VPN, NetVpnPrivate))
struct _NetVpnPrivate
@@ -381,22 +383,36 @@ edit_connection (GtkButton *button, NetVpn *vpn)
net_object_edit (NET_OBJECT (vpn));
}
static void
editor_done (NetConnectionEditor *editor,
gboolean success,
NetVpn *vpn)
{
g_object_unref (editor);
net_object_refresh (NET_OBJECT (vpn));
}
static void
vpn_proxy_edit (NetObject *object)
{
const gchar *uuid;
gchar *cmdline;
GError *error = NULL;
NetVpn *vpn = NET_VPN (object);
GtkWidget *button, *window;
NetConnectionEditor *editor;
NMClient *client;
NMRemoteSettings *settings;
uuid = nm_connection_get_uuid (vpn->priv->connection);
cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid);
g_debug ("Launching '%s'\n", cmdline);
if (!g_spawn_command_line_async (cmdline, &error)) {
g_warning ("Failed to launch nm-connection-editor: %s", error->message);
g_error_free (error);
}
g_free (cmdline);
button = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder,
"button_options"));
window = gtk_widget_get_toplevel (button);
client = net_object_get_client (object);
settings = net_object_get_remote_settings (object);
editor = net_connection_editor_new (GTK_WINDOW (window),
vpn->priv->connection,
NULL, NULL, client, settings);
g_signal_connect (editor, "done", G_CALLBACK (editor_done), vpn);
net_connection_editor_run (editor);
}
/**

View File

@@ -0,0 +1,216 @@
<?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>
<child>
<object class="GtkGrid" id="grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</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="halign">start</property>
<property name="valign">center</property>
<property name="hexpand">True</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="GtkScrolledWindow" id="list">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_top">12</property>
<property name="hexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</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="margin_top">12</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">10</property>
<property name="column_spacing">10</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<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>
<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">center</property>
<property name="hexpand">True</property>
</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>
</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">18</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>

View File

@@ -295,7 +295,6 @@
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="button_options">
<property name="label" translatable="yes">_Configure…</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -306,6 +305,13 @@
<property name="vexpand">True</property>
<property name="use_underline">True</property>
<property name="xalign">1</property>
<child>
<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>
</child>
</object>
<packing>
<property name="expand">False</property>

File diff suppressed because it is too large Load Diff

View File

@@ -7,5 +7,6 @@
<file preprocess="xml-stripblanks">network-wifi.ui</file>
<file preprocess="xml-stripblanks">network-simple.ui</file>
<file preprocess="xml-stripblanks">network-mobile.ui</file>
<file preprocess="xml-stripblanks">network-ethernet.ui</file>
</gresource>
</gresources>

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

@@ -488,8 +488,8 @@ panel_set_device_widget_header (GtkBuilder *builder,
return TRUE;
}
static gchar *
get_ipv4_config_address_as_string (NMIP4Config *ip4_config, const char *what)
gchar *
panel_get_ip4_address_as_string (NMIP4Config *ip4_config, const char *what)
{
const GSList *list;
struct in_addr addr;
@@ -522,8 +522,8 @@ out:
return str;
}
static gchar *
get_ipv4_config_name_servers_as_string (NMIP4Config *ip4_config)
gchar *
panel_get_ip4_dns_as_string (NMIP4Config *ip4_config)
{
const GArray *array;
GString *dns;
@@ -547,8 +547,8 @@ out:
return str;
}
static gchar *
get_ipv6_config_address_as_string (NMIP6Config *ip6_config)
gchar *
panel_get_ip6_address_as_string (NMIP6Config *ip6_config)
{
const GSList *list;
const struct in6_addr *addr;
@@ -586,7 +586,7 @@ panel_set_device_widgets (GtkBuilder *builder, NMDevice *device)
if (ip4_config != NULL) {
/* IPv4 address */
str_tmp = get_ipv4_config_address_as_string (ip4_config, "address");
str_tmp = panel_get_ip4_address_as_string (ip4_config, "address");
panel_set_device_widget_details (builder,
"ipv4",
str_tmp);
@@ -594,14 +594,14 @@ panel_set_device_widgets (GtkBuilder *builder, NMDevice *device)
g_free (str_tmp);
/* IPv4 DNS */
str_tmp = get_ipv4_config_name_servers_as_string (ip4_config);
str_tmp = panel_get_ip4_dns_as_string (ip4_config);
panel_set_device_widget_details (builder,
"dns",
str_tmp);
g_free (str_tmp);
/* IPv4 route */
str_tmp = get_ipv4_config_address_as_string (ip4_config, "gateway");
str_tmp = panel_get_ip4_address_as_string (ip4_config, "gateway");
panel_set_device_widget_details (builder,
"route",
str_tmp);
@@ -628,7 +628,7 @@ panel_set_device_widgets (GtkBuilder *builder, NMDevice *device)
/* get IPv6 parameters */
ip6_config = nm_device_get_ip6_config (device);
if (ip6_config != NULL) {
str_tmp = get_ipv6_config_address_as_string (ip6_config);
str_tmp = panel_get_ip6_address_as_string (ip6_config);
panel_set_device_widget_details (builder, "ipv6", str_tmp);
has_ip6 = str_tmp != NULL;
g_free (str_tmp);

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,65 @@
noinst_LTLIBRARIES = libwireless-security.la
BUILT_SOURCES = \
wireless-security-resources.h \
wireless-security-resources.c
NM_APPLET_SOURCES = \
wireless-security.h \
wireless-security.c \
ws-wep-key.h \
ws-wep-key.c \
ws-wpa-psk.h \
ws-wpa-psk.c \
ws-leap.h \
ws-leap.c \
ws-wpa-eap.h \
ws-wpa-eap.c \
ws-dynamic-wep.h \
ws-dynamic-wep.c \
eap-method.h \
eap-method.c \
eap-method-tls.h \
eap-method-tls.c \
eap-method-leap.h \
eap-method-leap.c \
eap-method-fast.h \
eap-method-fast.c \
eap-method-ttls.h \
eap-method-ttls.c \
eap-method-peap.h \
eap-method-peap.c \
eap-method-simple.h \
eap-method-simple.c \
helpers.h \
helpers.c
libwireless_security_la_SOURCES = \
$(BUILT_SOURCES) \
$(NM_APPLET_SOURCES)
libwireless_security_la_CPPFLAGS = \
$(NETWORK_PANEL_CFLAGS) \
$(NETWORK_MANAGER_CFLAGS) \
-DUIDIR=\""$(uidir)"\"
libwireless_security_la_LIBADD = \
$(NETWORK_PANEL_LIBS) \
$(NETWORK_MANAGER_LIBS)
resource_files = $(shell glib-compile-resources --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/wireless-security.gresource.xml)
wireless-security-resources.c: wireless-security.gresource.xml $(resource_files)
$(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name wireless_security $<
wireless-security-resources.h: wireless-security.gresource.xml $(resource_files)
$(AM_V_GEN) glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name wireless_security $<
WIRELESS_SECURITY_DIR=$(top_srcdir)/../network-manager-applet/src/wireless-security
WIRELESS_SECURITY_FILES=$(NM_APPLET_SOURCES)
update-from-nma:
FILES="$(WIRELESS_SECURITY_FILES)" DIR="$(WIRELESS_SECURITY_DIR)" $(top_srcdir)/update-from-gsd.sh && changed=true ; \
patch -p0 < $(srcdir)/nm-connection-editor-to-network-panel.patch ; \
git commit -m "network: Update wireless-security from network-manager-applet" $(WIRELESS_SECURITY_FILES)
EXTRA_DIST = $(resource_files) nm-connection-editor-to-network-panel.patch
-include $(top_srcdir)/git.mk

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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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 "/org/gnome/control-center/network/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_resource (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_resource,
const char *ui_widget_name,
const char *default_field,
gboolean phase2)
{
EAPMethod *method;
GError *error = NULL;
g_return_val_if_fail (obj_size > 0, NULL);
g_return_val_if_fail (ui_resource != NULL, NULL);
g_return_val_if_fail (ui_widget_name != NULL, NULL);
method = g_slice_alloc0 (obj_size);
g_assert (method);
method->refcount = 1;
method->obj_size = obj_size;
method->validate = validate;
method->add_to_size_group = add_to_size_group;
method->fill_connection = fill_connection;
method->update_secrets = update_secrets;
method->destroy = destroy;
method->default_field = default_field;
method->phase2 = phase2;
method->builder = gtk_builder_new ();
if (!gtk_builder_add_from_resource (method->builder, ui_resource, &error)) {
g_warning ("Couldn't load UI builder file %s: %s",
ui_resource, error->message);
eap_method_unref (method);
return NULL;
}
method->ui_widget = GTK_WIDGET (gtk_builder_get_object (method->builder, ui_widget_name));
if (!method->ui_widget) {
g_warning ("Couldn't load UI widget '%s' from UI file %s",
ui_widget_name, ui_resource);
eap_method_unref (method);
return NULL;
}
g_object_ref_sink (method->ui_widget);
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_resource,
const char *ui_widget_name,
const char *default_field,
gboolean phase2);
GtkFileFilter * eap_method_default_file_chooser_filter_new (gboolean privkey);
gboolean eap_method_is_encrypted_private_key (const char *path);
#define TYPE_CLIENT_CERT 0
#define TYPE_CA_CERT 1
#define TYPE_PRIVATE_KEY 2
gboolean eap_method_validate_filepicker (GtkBuilder *builder,
const char *name,
guint32 item_type,
const char *password,
NMSetting8021xCKFormat *out_format);
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,260 @@
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method.c 2012-12-11 15:51:57.191216362 +0100
+++ eap-method.c 2013-01-09 17:58:22.167402957 +0100
@@ -203,7 +203,7 @@ eap_method_nag_user (EAPMethod *method)
return method->nag_dialog;
}
-#define NAG_DIALOG_UI UIDIR "/nag-user-dialog.ui"
+#define NAG_DIALOG_UI "/org/gnome/control-center/network/nag-user-dialog.ui"
static gboolean
_get_ignore_ca_cert (const char *uuid, gboolean phase2)
@@ -237,7 +237,7 @@ eap_method_nag_init (EAPMethod *method,
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)) {
+ if (!gtk_builder_add_from_resource (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);
@@ -328,7 +328,7 @@ eap_method_init (gsize obj_size,
EMFillConnectionFunc fill_connection,
EMUpdateSecretsFunc update_secrets,
EMDestroyFunc destroy,
- const char *ui_file,
+ const char *ui_resource,
const char *ui_widget_name,
const char *default_field,
gboolean phase2)
@@ -337,7 +337,7 @@ eap_method_init (gsize obj_size,
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_resource != NULL, NULL);
g_return_val_if_fail (ui_widget_name != NULL, NULL);
method = g_slice_alloc0 (obj_size);
@@ -354,9 +354,9 @@ eap_method_init (gsize obj_size,
method->phase2 = phase2;
method->builder = gtk_builder_new ();
- if (!gtk_builder_add_from_file (method->builder, ui_file, &error)) {
+ if (!gtk_builder_add_from_resource (method->builder, ui_resource, &error)) {
g_warning ("Couldn't load UI builder file %s: %s",
- ui_file, error->message);
+ ui_resource, error->message);
eap_method_unref (method);
return NULL;
}
@@ -364,7 +364,7 @@ eap_method_init (gsize obj_size,
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);
+ ui_widget_name, ui_resource);
eap_method_unref (method);
return NULL;
}
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method-fast.c 2012-12-11 15:47:51.346453837 +0100
+++ eap-method-fast.c 2013-01-09 17:58:22.165402936 +0100
@@ -343,7 +343,7 @@ eap_method_fast_new (WirelessSecurity *w
fill_connection,
update_secrets,
destroy,
- UIDIR "/eap-method-fast.ui",
+ "/org/gnome/control-center/network/eap-method-fast.ui",
"eap_fast_notebook",
"eap_fast_anon_identity_entry",
FALSE);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method.h 2012-12-11 15:51:57.191216362 +0100
+++ eap-method.h 2013-01-09 17:58:22.167402957 +0100
@@ -96,7 +96,7 @@ EAPMethod *eap_method_init (gsize obj_si
EMFillConnectionFunc fill_connection,
EMUpdateSecretsFunc update_secrets,
EMDestroyFunc destroy,
- const char *ui_file,
+ const char *ui_resource,
const char *ui_widget_name,
const char *default_field,
gboolean phase2);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method-leap.c 2012-12-11 15:51:57.190216351 +0100
+++ eap-method-leap.c 2013-01-09 17:58:22.166402947 +0100
@@ -136,7 +136,7 @@ eap_method_leap_new (WirelessSecurity *w
fill_connection,
update_secrets,
NULL,
- UIDIR "/eap-method-leap.ui",
+ "/org/gnome/control-center/network/eap-method-leap.ui",
"eap_leap_notebook",
"eap_leap_username_entry",
FALSE);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method-peap.c 2012-12-11 15:51:57.190216351 +0100
+++ eap-method-peap.c 2013-01-09 17:58:22.166402947 +0100
@@ -327,7 +327,7 @@ eap_method_peap_new (WirelessSecurity *w
fill_connection,
update_secrets,
destroy,
- UIDIR "/eap-method-peap.ui",
+ "/org/gnome/control-center/network/eap-method-peap.ui",
"eap_peap_notebook",
"eap_peap_anon_identity_entry",
FALSE);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method-simple.c 2012-12-11 15:51:57.190216351 +0100
+++ eap-method-simple.c 2013-01-09 17:58:22.166402947 +0100
@@ -229,7 +229,7 @@ eap_method_simple_new (WirelessSecurity
fill_connection,
update_secrets,
NULL,
- UIDIR "/eap-method-simple.ui",
+ "/org/gnome/control-center/network/eap-method-simple.ui",
"eap_simple_notebook",
"eap_simple_username_entry",
phase2);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method-tls.c 2012-12-11 15:51:57.190216351 +0100
+++ eap-method-tls.c 2013-01-09 17:58:22.167402957 +0100
@@ -401,7 +401,7 @@ eap_method_tls_new (WirelessSecurity *ws
fill_connection,
update_secrets,
NULL,
- UIDIR "/eap-method-tls.ui",
+ "/org/gnome/control-center/network/eap-method-tls.ui",
"eap_tls_notebook",
"eap_tls_identity_entry",
phase2);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/eap-method-ttls.c 2012-12-11 15:51:57.190216351 +0100
+++ eap-method-ttls.c 2013-01-09 17:58:22.167402957 +0100
@@ -327,7 +327,7 @@ eap_method_ttls_new (WirelessSecurity *w
fill_connection,
update_secrets,
destroy,
- UIDIR "/eap-method-ttls.ui",
+ "/org/gnome/control-center/network/eap-method-ttls.ui",
"eap_ttls_notebook",
"eap_ttls_anon_identity_entry",
FALSE);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/wireless-security.c 2012-12-11 15:51:57.191216362 +0100
+++ wireless-security.c 2013-01-09 17:58:22.168402968 +0100
@@ -35,6 +35,7 @@
#include <nm-setting-8021x.h>
#include "wireless-security.h"
+#include "wireless-security-resources.h"
#include "eap-method.h"
GType
@@ -43,6 +44,8 @@ wireless_security_get_g_type (void)
static GType type_id = 0;
if (!type_id) {
+ g_resources_register (wireless_security_get_resource ());
+
type_id = g_boxed_type_register_static ("WirelessSecurity",
(GBoxedCopyFunc) wireless_security_ref,
(GBoxedFreeFunc) wireless_security_unref);
@@ -155,7 +158,7 @@ wireless_security_init (gsize obj_size,
WSFillConnectionFunc fill_connection,
WSUpdateSecretsFunc update_secrets,
WSDestroyFunc destroy,
- const char *ui_file,
+ const char *ui_resource,
const char *ui_widget_name,
const char *default_field)
{
@@ -163,7 +166,7 @@ wireless_security_init (gsize obj_size,
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_resource != NULL, NULL);
g_return_val_if_fail (ui_widget_name != NULL, NULL);
sec = g_slice_alloc0 (obj_size);
@@ -180,9 +183,9 @@ wireless_security_init (gsize obj_size,
sec->default_field = default_field;
sec->builder = gtk_builder_new ();
- if (!gtk_builder_add_from_file (sec->builder, ui_file, &error)) {
+ if (!gtk_builder_add_from_resource (sec->builder, ui_resource, &error)) {
g_warning ("Couldn't load UI builder file %s: %s",
- ui_file, error->message);
+ ui_resource, error->message);
g_error_free (error);
wireless_security_unref (sec);
return NULL;
@@ -191,7 +194,7 @@ wireless_security_init (gsize obj_size,
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);
+ ui_widget_name, ui_resource);
wireless_security_unref (sec);
return NULL;
}
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/wireless-security.h 2012-12-11 15:51:57.191216362 +0100
+++ wireless-security.h 2013-01-09 17:58:22.168402968 +0100
@@ -101,7 +101,7 @@ WirelessSecurity *wireless_security_init
WSFillConnectionFunc fill_connection,
WSUpdateSecretsFunc update_secrets,
WSDestroyFunc destroy,
- const char *ui_file,
+ const char *ui_resource,
const char *ui_widget_name,
const char *default_field);
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/ws-dynamic-wep.c 2012-12-11 15:51:57.191216362 +0100
+++ ws-dynamic-wep.c 2013-01-09 17:58:22.168402968 +0100
@@ -120,7 +120,7 @@ ws_dynamic_wep_new (NMConnection *connec
fill_connection,
update_secrets,
destroy,
- UIDIR "/ws-dynamic-wep.ui",
+ "/org/gnome/control-center/network/ws-dynamic-wep.ui",
"dynamic_wep_notebook",
NULL);
if (!parent)
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/ws-leap.c 2012-12-11 15:51:57.192216374 +0100
+++ ws-leap.c 2013-01-09 17:58:22.168402968 +0100
@@ -140,7 +140,7 @@ ws_leap_new (NMConnection *connection, g
fill_connection,
update_secrets,
NULL,
- UIDIR "/ws-leap.ui",
+ "/org/gnome/control-center/network/ws-leap.ui",
"leap_notebook",
"leap_username_entry");
if (!parent)
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/ws-wep-key.c 2012-12-11 15:51:57.192216374 +0100
+++ ws-wep-key.c 2013-01-09 17:58:22.168402968 +0100
@@ -257,7 +257,7 @@ ws_wep_key_new (NMConnection *connection
fill_connection,
update_secrets,
destroy,
- UIDIR "/ws-wep-key.ui",
+ "/org/gnome/control-center/network/ws-wep-key.ui",
"wep_key_notebook",
"wep_key_entry");
if (!parent)
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/ws-wpa-eap.c 2012-12-11 15:51:57.192216374 +0100
+++ ws-wpa-eap.c 2013-01-09 17:58:22.169402979 +0100
@@ -116,7 +116,7 @@ ws_wpa_eap_new (NMConnection *connection
fill_connection,
update_secrets,
destroy,
- UIDIR "/ws-wpa-eap.ui",
+ "/org/gnome/control-center/network/ws-wpa-eap.ui",
"wpa_eap_notebook",
NULL);
if (!parent)
--- /home/hadess/Projects/jhbuild/network-manager-applet/src/wireless-security/ws-wpa-psk.c 2012-12-11 15:51:57.192216374 +0100
+++ ws-wpa-psk.c 2013-01-09 17:58:22.169402979 +0100
@@ -157,7 +157,7 @@ ws_wpa_psk_new (NMConnection *connection
fill_connection,
update_secrets,
NULL,
- UIDIR "/ws-wpa-psk.ui",
+ "/org/gnome/control-center/network/ws-wpa-psk.ui",
"wpa_psk_notebook",
"wpa_psk_entry");
if (!parent)

View File

@@ -0,0 +1,554 @@
/* -*- 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 "wireless-security-resources.h"
#include "eap-method.h"
GType
wireless_security_get_g_type (void)
{
static GType type_id = 0;
if (!type_id) {
g_resources_register (wireless_security_get_resource ());
type_id = g_boxed_type_register_static ("WirelessSecurity",
(GBoxedCopyFunc) wireless_security_ref,
(GBoxedFreeFunc) wireless_security_unref);
}
return type_id;
}
GtkWidget *
wireless_security_get_widget (WirelessSecurity *sec)
{
g_return_val_if_fail (sec != NULL, NULL);
return sec->ui_widget;
}
void
wireless_security_set_changed_notify (WirelessSecurity *sec,
WSChangedFunc func,
gpointer user_data)
{
g_return_if_fail (sec != NULL);
sec->changed_notify = func;
sec->changed_notify_data = user_data;
}
void
wireless_security_changed_cb (GtkWidget *ignored, gpointer user_data)
{
WirelessSecurity *sec = WIRELESS_SECURITY (user_data);
if (sec->changed_notify)
(*(sec->changed_notify)) (sec, sec->changed_notify_data);
}
gboolean
wireless_security_validate (WirelessSecurity *sec, 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_resource,
const char *ui_widget_name,
const char *default_field)
{
WirelessSecurity *sec;
GError *error = NULL;
g_return_val_if_fail (obj_size > 0, NULL);
g_return_val_if_fail (ui_resource != NULL, NULL);
g_return_val_if_fail (ui_widget_name != NULL, NULL);
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_resource (sec->builder, ui_resource, &error)) {
g_warning ("Couldn't load UI builder file %s: %s",
ui_resource, error->message);
g_error_free (error);
wireless_security_unref (sec);
return NULL;
}
sec->ui_widget = GTK_WIDGET (gtk_builder_get_object (sec->builder, ui_widget_name));
if (!sec->ui_widget) {
g_warning ("Couldn't load UI widget '%s' from UI file %s",
ui_widget_name, ui_resource);
wireless_security_unref (sec);
return NULL;
}
g_object_ref_sink (sec->ui_widget);
sec->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,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/control-center/network">
<file preprocess="xml-stripblanks">eap-method-leap.ui</file>
<file preprocess="xml-stripblanks">eap-method-fast.ui</file>
<file preprocess="xml-stripblanks">eap-method-peap.ui</file>
<file preprocess="xml-stripblanks">eap-method-simple.ui</file>
<file preprocess="xml-stripblanks">eap-method-tls.ui</file>
<file preprocess="xml-stripblanks">eap-method-ttls.ui</file>
<file preprocess="xml-stripblanks">nag-user-dialog.ui</file>
<file preprocess="xml-stripblanks">ws-dynamic-wep.ui</file>
<file preprocess="xml-stripblanks">ws-leap.ui</file>
<file preprocess="xml-stripblanks">ws-wep-key.ui</file>
<file preprocess="xml-stripblanks">ws-wpa-eap.ui</file>
<file preprocess="xml-stripblanks">ws-wpa-psk.ui</file>
</gresource>
</gresources>

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_resource,
const char *ui_widget_name,
const char *default_field);
void wireless_security_changed_cb (GtkWidget *entry, gpointer user_data);
void wireless_security_clear_ciphers (NMConnection *connection);
#define AUTH_NAME_COLUMN 0
#define AUTH_METHOD_COLUMN 1
GtkWidget *ws_802_1x_auth_combo_init (WirelessSecurity *sec,
const char *combo_name,
const char *combo_label,
GCallback auth_combo_changed_cb,
NMConnection *connection,
gboolean is_editor,
gboolean secrets_only);
void ws_802_1x_auth_combo_changed (GtkWidget *combo,
WirelessSecurity *sec,
const char *vbox_name,
GtkSizeGroup *size_group);
gboolean ws_802_1x_validate (WirelessSecurity *sec, const char *combo_name);
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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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,
"/org/gnome/control-center/network/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;
}

Some files were not shown because too many files have changed in this diff Show More