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. https://bugzilla.gnome.org/show_bug.cgi?id=691285
This commit is contained in:
parent
a7c0a7ae64
commit
8cfe8d10ba
13 changed files with 848 additions and 20 deletions
10
configure.ac
10
configure.ac
|
@ -99,7 +99,7 @@ CANBERRA_REQUIRED_VERSION=0.13
|
||||||
GDKPIXBUF_REQUIRED_VERSION=2.23.0
|
GDKPIXBUF_REQUIRED_VERSION=2.23.0
|
||||||
POLKIT_REQUIRED_VERSION=0.103
|
POLKIT_REQUIRED_VERSION=0.103
|
||||||
GSD_REQUIRED_VERSION=3.7.3
|
GSD_REQUIRED_VERSION=3.7.3
|
||||||
NETWORK_MANAGER_REQUIRED_VERSION=0.9.6.4
|
NETWORK_MANAGER_REQUIRED_VERSION=0.9.7.995
|
||||||
NETWORK_MANAGER_APPLET_REQUIRED_VERSION=0.9.7
|
NETWORK_MANAGER_APPLET_REQUIRED_VERSION=0.9.7
|
||||||
LIBNOTIFY_REQUIRED_VERSION=0.7.3
|
LIBNOTIFY_REQUIRED_VERSION=0.7.3
|
||||||
GNOME_DESKTOP_REQUIRED_VERSION=3.7.5
|
GNOME_DESKTOP_REQUIRED_VERSION=3.7.5
|
||||||
|
@ -179,20 +179,24 @@ AM_CONDITIONAL(HAVE_INTROSPECTION, false)
|
||||||
GDESKTOP_PREFIX=`$PKG_CONFIG --variable prefix gsettings-desktop-schemas`
|
GDESKTOP_PREFIX=`$PKG_CONFIG --variable prefix gsettings-desktop-schemas`
|
||||||
AC_SUBST(GDESKTOP_PREFIX)
|
AC_SUBST(GDESKTOP_PREFIX)
|
||||||
|
|
||||||
# Check for NetworkManager ~0.9
|
|
||||||
PKG_CHECK_MODULES(NETWORK_MANAGER, NetworkManager >= $NETWORK_MANAGER_REQUIRED_VERSION
|
PKG_CHECK_MODULES(NETWORK_MANAGER, NetworkManager >= $NETWORK_MANAGER_REQUIRED_VERSION
|
||||||
libnm-glib >= $NETWORK_MANAGER_REQUIRED_VERSION
|
libnm-glib >= $NETWORK_MANAGER_REQUIRED_VERSION
|
||||||
|
libnm-glib-vpn >= $NETWORK_MANAGER_REQUIRED_VERSION
|
||||||
libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION
|
libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION
|
||||||
libnm-gtk >= $NETWORK_MANAGER_APPLET_REQUIRED_VERSION,
|
libnm-gtk >= $NETWORK_MANAGER_APPLET_REQUIRED_VERSION,
|
||||||
[have_networkmanager=yes], have_networkmanager=no)
|
[have_networkmanager=yes], have_networkmanager=no)
|
||||||
if test "x$have_networkmanager" = xno ; then
|
if test "x$have_networkmanager" = xno ; then
|
||||||
AC_MSG_WARN(*** Network panel will not be built (NetworkManager ~0.9 or newer not found) ***)
|
AC_MSG_WARN(*** Network panel will not be built (NetworkManager $NETWORK_MANAGER_REQUIRED_VERSION or newer not found) ***)
|
||||||
else
|
else
|
||||||
AC_DEFINE(BUILD_NETWORK, 1, [Define to 1 to build the Network panel])
|
AC_DEFINE(BUILD_NETWORK, 1, [Define to 1 to build the Network panel])
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(BUILD_NETWORK, [test x$have_networkmanager = xyes])
|
AM_CONDITIONAL(BUILD_NETWORK, [test x$have_networkmanager = xyes])
|
||||||
if test x${have_networkmanager} = xyes; then
|
if test x${have_networkmanager} = xyes; then
|
||||||
AC_DEFINE(HAVE_NETWORK_MANAGER, 1, [Define to 1 if NetworkManager is available])
|
AC_DEFINE(HAVE_NETWORK_MANAGER, 1, [Define to 1 if NetworkManager is available])
|
||||||
|
NM_VPN_CONFIG_DIR=`$PKG_CONFIG --variable configdir NetworkManager`/VPN
|
||||||
|
NM_VPN_MODULE_DIR=`$PKG_CONFIG --variable plugindir NetworkManager`
|
||||||
|
AC_SUBST(NM_VPN_CONFIG_DIR)
|
||||||
|
AC_SUBST(NM_VPN_MODULE_DIR)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for gnome-bluetooth
|
# Check for gnome-bluetooth
|
||||||
|
|
|
@ -1020,6 +1020,7 @@ panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
|
||||||
"id", id,
|
"id", id,
|
||||||
"connection", connection,
|
"connection", connection,
|
||||||
"client", panel->priv->client,
|
"client", panel->priv->client,
|
||||||
|
"remote-settings", panel->priv->remote_settings,
|
||||||
NULL);
|
NULL);
|
||||||
g_signal_connect_object (net_vpn, "removed",
|
g_signal_connect_object (net_vpn, "removed",
|
||||||
G_CALLBACK (object_removed_cb), panel, 0);
|
G_CALLBACK (object_removed_cb), panel, 0);
|
||||||
|
|
|
@ -25,12 +25,18 @@ libconnection_editor_la_SOURCES = \
|
||||||
ce-page-ethernet.h \
|
ce-page-ethernet.h \
|
||||||
ce-page-ethernet.c \
|
ce-page-ethernet.c \
|
||||||
ce-page-8021x-security.h \
|
ce-page-8021x-security.h \
|
||||||
ce-page-8021x-security.c
|
ce-page-8021x-security.c \
|
||||||
|
ce-page-vpn.h \
|
||||||
|
ce-page-vpn.c \
|
||||||
|
vpn-helpers.h \
|
||||||
|
vpn-helpers.c
|
||||||
|
|
||||||
libconnection_editor_la_CPPFLAGS = \
|
libconnection_editor_la_CPPFLAGS = \
|
||||||
-I$(srcdir)/../wireless-security \
|
-I$(srcdir)/../wireless-security \
|
||||||
$(NETWORK_PANEL_CFLAGS) \
|
$(NETWORK_PANEL_CFLAGS) \
|
||||||
$(NETWORK_MANAGER_CFLAGS)
|
$(NETWORK_MANAGER_CFLAGS) \
|
||||||
|
-DNM_VPN_CONFIG_DIR=\""$(NM_VPN_CONFIG_DIR)"\" \
|
||||||
|
-DNM_VPN_MODULE_DIR=\""$(NM_VPN_MODULE_DIR)"\"
|
||||||
|
|
||||||
libconnection_editor_la_LIBADD = \
|
libconnection_editor_la_LIBADD = \
|
||||||
$(builddir)/../wireless-security/libwireless-security.la \
|
$(builddir)/../wireless-security/libwireless-security.la \
|
||||||
|
|
|
@ -128,7 +128,7 @@ connect_details_page (CEPageDetails *page)
|
||||||
else
|
else
|
||||||
active_ap = NULL;
|
active_ap = NULL;
|
||||||
|
|
||||||
state = nm_device_get_state (page->device);
|
state = page->device ? nm_device_get_state (page->device) : NM_DEVICE_STATE_DISCONNECTED;
|
||||||
|
|
||||||
device_is_active = FALSE;
|
device_is_active = FALSE;
|
||||||
speed = 0;
|
speed = 0;
|
||||||
|
@ -136,7 +136,7 @@ connect_details_page (CEPageDetails *page)
|
||||||
device_is_active = TRUE;
|
device_is_active = TRUE;
|
||||||
if (NM_IS_DEVICE_WIFI (page->device))
|
if (NM_IS_DEVICE_WIFI (page->device))
|
||||||
speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000;
|
speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (page->device)) / 1000;
|
||||||
} else {
|
} else if (page->device) {
|
||||||
NMActiveConnection *ac;
|
NMActiveConnection *ac;
|
||||||
const gchar *p1, *p2;
|
const gchar *p1, *p2;
|
||||||
|
|
||||||
|
|
188
panels/network/connection-editor/ce-page-vpn.c
Normal file
188
panels/network/connection-editor/ce-page-vpn.c
Normal 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);
|
||||||
|
}
|
74
panels/network/connection-editor/ce-page-vpn.h
Normal file
74
panels/network/connection-editor/ce-page-vpn.h
Normal 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 */
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<file preprocess="xml-stripblanks">ip6-page.ui</file>
|
<file preprocess="xml-stripblanks">ip6-page.ui</file>
|
||||||
<file preprocess="xml-stripblanks">reset-page.ui</file>
|
<file preprocess="xml-stripblanks">reset-page.ui</file>
|
||||||
<file preprocess="xml-stripblanks">security-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>
|
<file preprocess="xml-stripblanks">wifi-page.ui</file>
|
||||||
</gresource>
|
</gresource>
|
||||||
</gresources>
|
</gresources>
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "ce-page-reset.h"
|
#include "ce-page-reset.h"
|
||||||
#include "ce-page-ethernet.h"
|
#include "ce-page-ethernet.h"
|
||||||
#include "ce-page-8021x-security.h"
|
#include "ce-page-8021x-security.h"
|
||||||
|
#include "ce-page-vpn.h"
|
||||||
|
|
||||||
#include "egg-list-box/egg-list-box.h"
|
#include "egg-list-box/egg-list-box.h"
|
||||||
|
|
||||||
|
@ -457,6 +458,8 @@ net_connection_editor_set_connection (NetConnectionEditor *editor,
|
||||||
add_page (editor, ce_page_wifi_new (editor->connection, editor->client, editor->settings));
|
add_page (editor, ce_page_wifi_new (editor->connection, editor->client, editor->settings));
|
||||||
else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0)
|
else if (strcmp (type, NM_SETTING_WIRED_SETTING_NAME) == 0)
|
||||||
add_page (editor, ce_page_ethernet_new (editor->connection, editor->client, editor->settings));
|
add_page (editor, ce_page_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));
|
||||||
|
|
||||||
add_page (editor, ce_page_ip4_new (editor->connection, editor->client, editor->settings));
|
add_page (editor, ce_page_ip4_new (editor->connection, editor->client, editor->settings));
|
||||||
add_page (editor, ce_page_ip6_new (editor->connection, editor->client, editor->settings));
|
add_page (editor, ce_page_ip6_new (editor->connection, editor->client, editor->settings));
|
||||||
|
@ -514,7 +517,8 @@ net_connection_editor_new (GtkWindow *parent_window,
|
||||||
}
|
}
|
||||||
if (ap)
|
if (ap)
|
||||||
editor->ap = g_object_ref (ap);
|
editor->ap = g_object_ref (ap);
|
||||||
editor->device = g_object_ref (device);
|
if (device)
|
||||||
|
editor->device = g_object_ref (device);
|
||||||
editor->client = g_object_ref (client);
|
editor->client = g_object_ref (client);
|
||||||
editor->settings = g_object_ref (settings);
|
editor->settings = g_object_ref (settings);
|
||||||
|
|
||||||
|
|
414
panels/network/connection-editor/vpn-helpers.c
Normal file
414
panels/network/connection-editor/vpn-helpers.c
Normal file
|
@ -0,0 +1,414 @@
|
||||||
|
/* -*- 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 {
|
||||||
|
VpnImportSuccessCallback 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)
|
||||||
|
info->callback (connection, info->user_data);
|
||||||
|
else {
|
||||||
|
GtkWidget *err_dialog;
|
||||||
|
char *bname = g_path_get_basename (filename);
|
||||||
|
|
||||||
|
err_dialog = gtk_message_dialog_new (NULL,
|
||||||
|
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_widget_show_all (err_dialog);
|
||||||
|
gtk_window_present (GTK_WINDOW (err_dialog));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_clear_error (&error);
|
||||||
|
g_free (filename);
|
||||||
|
|
||||||
|
out:
|
||||||
|
gtk_widget_hide (dialog);
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
g_free (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_import_chooser (GtkWidget *dialog, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_free (user_data);
|
||||||
|
gtk_widget_destroy (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vpn_import (VpnImportSuccessCallback callback, gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkWidget *dialog;
|
||||||
|
ActionInfo *info;
|
||||||
|
const char *home_folder;
|
||||||
|
|
||||||
|
dialog = gtk_file_chooser_dialog_new (_("Select file to import"),
|
||||||
|
NULL,
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
|
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||||
|
NULL);
|
||||||
|
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;
|
||||||
|
}
|
44
panels/network/connection-editor/vpn-helpers.h
Normal file
44
panels/network/connection-editor/vpn-helpers.h
Normal 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 (*VpnImportSuccessCallback) (NMConnection *connection, gpointer user_data);
|
||||||
|
void vpn_import (VpnImportSuccessCallback callback, gpointer user_data);
|
||||||
|
|
||||||
|
void vpn_export (NMConnection *connection);
|
||||||
|
|
||||||
|
gboolean vpn_supports_ipv6 (NMConnection *connection);
|
||||||
|
|
||||||
|
#endif /* _VPN_HELPERS_H_ */
|
70
panels/network/connection-editor/vpn-page.ui
Normal file
70
panels/network/connection-editor/vpn-page.ui
Normal 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>
|
|
@ -31,6 +31,8 @@
|
||||||
#include "nm-remote-connection.h"
|
#include "nm-remote-connection.h"
|
||||||
#include "nm-setting-vpn.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))
|
#define NET_VPN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_VPN, NetVpnPrivate))
|
||||||
|
|
||||||
struct _NetVpnPrivate
|
struct _NetVpnPrivate
|
||||||
|
@ -381,22 +383,36 @@ edit_connection (GtkButton *button, NetVpn *vpn)
|
||||||
net_object_edit (NET_OBJECT (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
|
static void
|
||||||
vpn_proxy_edit (NetObject *object)
|
vpn_proxy_edit (NetObject *object)
|
||||||
{
|
{
|
||||||
const gchar *uuid;
|
|
||||||
gchar *cmdline;
|
|
||||||
GError *error = NULL;
|
|
||||||
NetVpn *vpn = NET_VPN (object);
|
NetVpn *vpn = NET_VPN (object);
|
||||||
|
GtkWidget *button, *window;
|
||||||
|
NetConnectionEditor *editor;
|
||||||
|
NMClient *client;
|
||||||
|
NMRemoteSettings *settings;
|
||||||
|
|
||||||
uuid = nm_connection_get_uuid (vpn->priv->connection);
|
button = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder,
|
||||||
cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid);
|
"button_options"));
|
||||||
g_debug ("Launching '%s'\n", cmdline);
|
window = gtk_widget_get_toplevel (button);
|
||||||
if (!g_spawn_command_line_async (cmdline, &error)) {
|
|
||||||
g_warning ("Failed to launch nm-connection-editor: %s", error->message);
|
client = net_object_get_client (object);
|
||||||
g_error_free (error);
|
settings = net_object_get_remote_settings (object);
|
||||||
}
|
|
||||||
g_free (cmdline);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -295,7 +295,6 @@
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button_options">
|
<object class="GtkButton" id="button_options">
|
||||||
<property name="label" translatable="yes">_Configure…</property>
|
|
||||||
<property name="use_action_appearance">False</property>
|
<property name="use_action_appearance">False</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
@ -306,6 +305,13 @@
|
||||||
<property name="vexpand">True</property>
|
<property name="vexpand">True</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="xalign">1</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>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue