nm: Split NM plugin and editor widget into separate libs

This will allow the plugin to load the editor widget matching the current
GTK version dynamically.
This commit is contained in:
Tobias Brunner 2022-04-20 09:50:03 +02:00
parent 4f4778d792
commit b404440192
8 changed files with 341 additions and 167 deletions

View File

@ -37,6 +37,9 @@ AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_CHECK_FUNCS(select socket uname)
AC_SEARCH_LIBS([dlopen], [dl dld], [], [ac_cv_search_dlopen=])
AC_SUBST([DL_LIBS], "$ac_cv_search_dlopen")
GETTEXT_PACKAGE=NetworkManager-strongswan
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package])

View File

@ -1,5 +1,6 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
properties/nm-strongswan-plugin.c
properties/nm-strongswan.c
[type: gettext/glade]properties/nm-strongswan-dialog.ui
auth-dialog/main.c

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: NetworkManager-strongswan\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-04-19 17:33+0200\n"
"POT-Creation-Date: 2022-04-20 17:19+0200\n"
"PO-Revision-Date: 2019-12-18 17:10+0100\n"
"Last-Translator: Tobias Brunner\n"
"Language-Team: de <info@strongswan.org>\n"
@ -17,43 +17,67 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../properties/nm-strongswan.c:35
#: ../properties/nm-strongswan-plugin.c:36
msgid "IPsec/IKEv2 (strongswan)"
msgstr "IPsec/IKEv2 (strongswan)"
#: ../properties/nm-strongswan.c:36
#: ../properties/nm-strongswan-plugin.c:37
msgid "IPsec with the IKEv2 key exchange protocol."
msgstr "IPsec mit dem IKEv2 Protokoll."
#: ../properties/nm-strongswan.c:273
#: ../properties/nm-strongswan-plugin.c:80
#, c-format
msgid "unable to determine plugin path: %s"
msgstr "Plugin-Pfad konnte nicht ermittelt werden: %s"
#: ../properties/nm-strongswan-plugin.c:93
#, c-format
msgid "missing plugin file '%s'"
msgstr "Plugin-Datei '%s' fehlt"
#: ../properties/nm-strongswan-plugin.c:98
#, c-format
msgid "unable to load editor plugin: %s"
msgstr "Laden des Editor-Plugins fehlgeschlagen: %s"
#: ../properties/nm-strongswan-plugin.c:108
#, c-format
msgid "cannot load factory %s from plugin: %s"
msgstr "Factory %s konnte nicht aus Plugin geladen werden: %s"
#: ../properties/nm-strongswan-plugin.c:124
msgid "unknown error creating editor instance"
msgstr "Unbekannter Fehler beim Erstellen der Editor-Instanz"
#: ../properties/nm-strongswan.c:255
msgid "(None)"
msgstr "(Nicht festgelegt)"
#: ../properties/nm-strongswan.c:438
#: ../properties/nm-strongswan.c:420
msgid "EAP (Username/Password)"
msgstr "EAP (Benutzername/Passwort)"
#: ../properties/nm-strongswan.c:439
#: ../properties/nm-strongswan.c:421
msgid "Certificate"
msgstr "Zertifikat"
#: ../properties/nm-strongswan.c:440
#: ../properties/nm-strongswan.c:422
msgid "EAP-TLS"
msgstr "EAP-TLS"
#: ../properties/nm-strongswan.c:441
#: ../properties/nm-strongswan.c:423
msgid "Pre-shared key"
msgstr "Pre-shared Key"
#: ../properties/nm-strongswan.c:467
#: ../properties/nm-strongswan.c:449
msgid "Certificate/private key"
msgstr "Zertifikat/Privater Schlüssel"
#: ../properties/nm-strongswan.c:468
#: ../properties/nm-strongswan.c:450
msgid "Certificate/ssh-agent"
msgstr "Zertifikat/ssh-agent"
#: ../properties/nm-strongswan.c:469
#: ../properties/nm-strongswan.c:451
msgid "Smartcard"
msgstr "Smartcard"

View File

@ -1,4 +1,6 @@
nm_plugin_LTLIBRARIES = libnm-vpn-plugin-strongswan.la
nm_plugin_LTLIBRARIES = \
libnm-vpn-plugin-strongswan.la \
libnm-vpn-plugin-strongswan-editor.la
nm-strongswan-resources.h: nm-strongswan-dialog.gresource.xml
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< --target=$@ --sourcedir=$(srcdir) \
@ -8,25 +10,37 @@ nm-strongswan-resources.c: nm-strongswan-dialog.gresource.xml $(shell $(GLIB_COM
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $< --target=$@ --sourcedir=$(srcdir) \
--generate-source --internal
nodist_libnm_vpn_plugin_strongswan_la_SOURCES = \
libnm_vpn_plugin_strongswan_la_SOURCES = \
nm-strongswan-plugin.c \
nm-strongswan-plugin.h
nodist_libnm_vpn_plugin_strongswan_editor_la_SOURCES = \
nm-strongswan-resources.c \
nm-strongswan-resources.h
libnm_vpn_plugin_strongswan_la_SOURCES = \
libnm_vpn_plugin_strongswan_editor_la_SOURCES = \
nm-strongswan.c \
nm-strongswan.h
common_CFLAGS = \
$(GTK_CFLAGS) \
-DG_DISABLE_DEPRECATED \
-DGDK_DISABLE_DEPRECATED
libnm_vpn_plugin_strongswan_la_CFLAGS = \
$(LIBNM_CFLAGS) \
$(common_CFLAGS)
libnm_vpn_plugin_strongswan_editor_la_CFLAGS = \
$(GTK_CFLAGS) \
$(LIBNM_CFLAGS) \
$(LIBNMA_CFLAGS) \
$(common_CFLAGS)
libnm_vpn_plugin_strongswan_la_LIBADD = \
$(LIBNM_LIBS) \
$(DL_LIBS)
libnm_vpn_plugin_strongswan_editor_la_LIBADD = \
$(GTK_LIBS) \
$(LIBNMA_LIBS) \
$(LIBNM_LIBS)
@ -34,6 +48,9 @@ libnm_vpn_plugin_strongswan_la_LIBADD = \
libnm_vpn_plugin_strongswan_la_LDFLAGS = \
-avoid-version
libnm_vpn_plugin_strongswan_editor_la_LDFLAGS = \
-avoid-version
BUILT_SOURCES = \
nm-strongswan-resources.c \
nm-strongswan-resources.h

View File

@ -0,0 +1,199 @@
/*
* Copyright (C) 2013-2020 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
* Copyright (C) 2015 Lubomir Rintel
* Copyright (C) 2005 David Zeuthen
* Copyright (C) 2005-2008 Dan Williams
*
* Based on NetworkManager's vpnc plugin
*
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define _GNU_SOURCE
#include <dlfcn.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <NetworkManager.h>
#include "nm-strongswan-plugin.h"
#define STRONGSWAN_PLUGIN_NAME _("IPsec/IKEv2 (strongswan)")
#define STRONGSWAN_PLUGIN_DESC _("IPsec with the IKEv2 key exchange protocol.")
#define STRONGSWAN_PLUGIN_SERVICE "org.freedesktop.NetworkManager.strongswan"
#define STRONGSWAN_EDITOR_FILE "libnm-vpn-plugin-strongswan-editor.so"
#define STRONGSWAN_EDITOR_FACTORY "strongswan_editor_new"
/************** plugin class **************/
enum {
PROP_0,
PROP_NAME,
PROP_DESC,
PROP_SERVICE
};
static void strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class);
G_DEFINE_TYPE_EXTENDED (StrongswanPluginUi, strongswan_plugin_ui, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_EDITOR_PLUGIN,
strongswan_plugin_ui_interface_init))
static NMVpnEditor *
get_editor (NMVpnEditorPlugin *iface, NMConnection *connection, GError **error)
{
static struct {
NMVpnEditor *(*factory)(NMConnection*, GError**);
void *dl_module;
} cache = {};
NMVpnEditor *editor;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (!error || !*error, NULL);
if (!cache.factory)
{
Dl_info plugin_info;
void *dl_module;
char *module_path = NULL;
char *dirname = NULL;
NMVpnEditor *(*factory)(NMConnection*, GError**);
if (!dladdr(get_editor, &plugin_info))
{
g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
_("unable to determine plugin path: %s"), dlerror());
return NULL;
}
dirname = g_path_get_dirname (plugin_info.dli_fname);
module_path = g_build_filename (dirname, STRONGSWAN_EDITOR_FILE, NULL);
g_free(dirname);
dl_module = dlopen(module_path, RTLD_LAZY | RTLD_LOCAL);
if (!dl_module)
{
if (!g_file_test (module_path, G_FILE_TEST_EXISTS))
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
_("missing plugin file '%s'"), module_path);
g_free(module_path);
return NULL;
}
g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
_("unable to load editor plugin: %s"), dlerror ());
g_free(module_path);
return NULL;
}
g_free(module_path);
factory = dlsym (dl_module, STRONGSWAN_EDITOR_FACTORY);
if (!factory)
{
g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
_("cannot load factory %s from plugin: %s"),
STRONGSWAN_EDITOR_FACTORY, dlerror ());
dlclose (dl_module);
return NULL;
}
cache.factory = factory;
cache.dl_module = dl_module;
}
editor = cache.factory (connection, error);
if (!editor)
{
if (error && !*error)
{
g_set_error_literal (error, NM_VPN_PLUGIN_ERROR,
NM_VPN_PLUGIN_ERROR_FAILED,
_("unknown error creating editor instance"));
return NULL;
}
return NULL;
}
g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), NULL);
return editor;
}
static guint32
get_capabilities (NMVpnEditorPlugin *iface)
{
return NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6;
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, STRONGSWAN_PLUGIN_NAME);
break;
case PROP_DESC:
g_value_set_string (value, STRONGSWAN_PLUGIN_DESC);
break;
case PROP_SERVICE:
g_value_set_string (value, STRONGSWAN_PLUGIN_SERVICE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
strongswan_plugin_ui_class_init (StrongswanPluginUiClass *req_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
object_class->get_property = get_property;
g_object_class_override_property (object_class,
PROP_NAME,
NM_VPN_EDITOR_PLUGIN_NAME);
g_object_class_override_property (object_class,
PROP_DESC,
NM_VPN_EDITOR_PLUGIN_DESCRIPTION);
g_object_class_override_property (object_class,
PROP_SERVICE,
NM_VPN_EDITOR_PLUGIN_SERVICE);
}
static void
strongswan_plugin_ui_init (StrongswanPluginUi *plugin)
{
}
static void
strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class)
{
/* interface implementation */
iface_class->get_editor = get_editor;
iface_class->get_capabilities = get_capabilities;
/* TODO: implement delete_connection to purge associated secrets */
}
G_MODULE_EXPORT NMVpnEditorPlugin *
nm_vpn_editor_plugin_factory (GError **error)
{
g_return_val_if_fail (!error || !*error, NULL);
return g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL);
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2008 Martin Willi
* HSR Hochschule fuer Technik Rapperswil
* Copyright (C) 2008 Dan Williams
*
* Based on NetworkManager's vpnc plugin
*
* 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. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*/
#ifndef _NM_STRONGSWAN_PLUGIN_H_
#define _NM_STRONGSWAN_PLUGIN_H_
#include <glib-object.h>
#define STRONGSWAN_TYPE_PLUGIN_UI (strongswan_plugin_ui_get_type ())
#define STRONGSWAN_PLUGIN_UI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STRONGSWAN_TYPE_PLUGIN_UI, StrongswanPluginUi))
#define STRONGSWAN_PLUGIN_UI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STRONGSWAN_TYPE_PLUGIN_UI, StrongswanPluginUiClass))
#define STRONGSWAN_IS_PLUGIN_UI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STRONGSWAN_TYPE_PLUGIN_UI))
#define STRONGSWAN_IS_PLUGIN_UI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), STRONGSWAN_TYPE_PLUGIN_UI))
#define STRONGSWAN_PLUGIN_UI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STRONGSWAN_TYPE_PLUGIN_UI, StrongswanPluginUiClass))
typedef struct _StrongswanPluginUi StrongswanPluginUi;
typedef struct _StrongswanPluginUiClass StrongswanPluginUiClass;
struct _StrongswanPluginUi {
GObject parent;
};
struct _StrongswanPluginUiClass {
GObjectClass parent;
};
GType strongswan_plugin_ui_get_type (void);
#endif /* _NM_STRONGSWAN_PLUGIN_H_ */

View File

@ -32,28 +32,10 @@
#include "nm-strongswan.h"
#define STRONGSWAN_PLUGIN_NAME _("IPsec/IKEv2 (strongswan)")
#define STRONGSWAN_PLUGIN_DESC _("IPsec with the IKEv2 key exchange protocol.")
#define STRONGSWAN_PLUGIN_SERVICE "org.freedesktop.NetworkManager.strongswan"
#define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan"
#define NM_DBUS_PATH_STRONGSWAN "/org/freedesktop/NetworkManager/strongswan"
#define STRONGSWAN_UI_RESOURCE NM_DBUS_PATH_STRONGSWAN "/nm-strongswan-dialog.ui"
/************** plugin class **************/
enum {
PROP_0,
PROP_NAME,
PROP_DESC,
PROP_SERVICE
};
static void strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class);
G_DEFINE_TYPE_EXTENDED (StrongswanPluginUi, strongswan_plugin_ui, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_EDITOR_PLUGIN,
strongswan_plugin_ui_interface_init))
/************** UI widget class **************/
static void strongswan_plugin_ui_widget_interface_init (NMVpnEditorInterface *iface_class);
@ -749,49 +731,6 @@ update_connection (NMVpnEditor *iface,
return TRUE;
}
static NMVpnEditor *
nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error)
{
NMVpnEditor *object;
StrongswanPluginUiWidgetPrivate *priv;
if (error)
g_return_val_if_fail (*error == NULL, NULL);
object = g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, NULL);
if (!object) {
g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not create strongswan object");
return NULL;
}
priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE ((StrongswanPluginUiWidget*)object);
priv->builder = gtk_builder_new ();
gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE);
if (!gtk_builder_add_from_resource (priv->builder, STRONGSWAN_UI_RESOURCE, error)) {
g_warning ("Couldn't load builder file: %s",
error && *error ? (*error)->message : "(unknown)");
g_object_unref (object);
return NULL;
}
priv->widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "strongswan-vbox") );
if (!priv->widget) {
g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not load UI widget");
g_object_unref (object);
return NULL;
}
g_object_ref_sink (priv->widget);
if (!init_plugin_ui (STRONGSWAN_PLUGIN_UI_WIDGET (object), connection, error)) {
g_object_unref (object);
return NULL;
}
return object;
}
static void
dispose (GObject *object)
{
@ -832,78 +771,45 @@ strongswan_plugin_ui_widget_interface_init (NMVpnEditorInterface *iface_class)
iface_class->update_connection = update_connection;
}
static guint32
get_capabilities (NMVpnEditorPlugin *iface)
NMVpnEditor *
strongswan_editor_new (NMConnection *connection, GError **error)
{
return NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6;
}
NMVpnEditor *object;
StrongswanPluginUiWidgetPrivate *priv;
static NMVpnEditor *
get_editor (NMVpnEditorPlugin *iface, NMConnection *connection, GError **error)
{
return nm_vpn_plugin_ui_widget_interface_new (connection, error);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, STRONGSWAN_PLUGIN_NAME);
break;
case PROP_DESC:
g_value_set_string (value, STRONGSWAN_PLUGIN_DESC);
break;
case PROP_SERVICE:
g_value_set_string (value, STRONGSWAN_PLUGIN_SERVICE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
strongswan_plugin_ui_class_init (StrongswanPluginUiClass *req_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
object_class->get_property = get_property;
g_object_class_override_property (object_class,
PROP_NAME,
NM_VPN_EDITOR_PLUGIN_NAME);
g_object_class_override_property (object_class,
PROP_DESC,
NM_VPN_EDITOR_PLUGIN_DESCRIPTION);
g_object_class_override_property (object_class,
PROP_SERVICE,
NM_VPN_EDITOR_PLUGIN_SERVICE);
}
static void
strongswan_plugin_ui_init (StrongswanPluginUi *plugin)
{
}
static void
strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class)
{
/* interface implementation */
iface_class->get_editor = get_editor;
iface_class->get_capabilities = get_capabilities;
/* TODO: implement delete_connection to purge associated secrets */
}
G_MODULE_EXPORT NMVpnEditorPlugin *
nm_vpn_editor_plugin_factory (GError **error)
{
if (error)
g_return_val_if_fail (*error == NULL, NULL);
return g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL);
object = g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, NULL);
if (!object) {
g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not create strongswan object");
return NULL;
}
priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE ((StrongswanPluginUiWidget*)object);
priv->builder = gtk_builder_new ();
gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE);
if (!gtk_builder_add_from_resource (priv->builder, STRONGSWAN_UI_RESOURCE, error)) {
g_warning ("Couldn't load builder file: %s",
error && *error ? (*error)->message : "(unknown)");
g_object_unref (object);
return NULL;
}
priv->widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "strongswan-vbox") );
if (!priv->widget) {
g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not load UI widget");
g_object_unref (object);
return NULL;
}
g_object_ref_sink (priv->widget);
if (!init_plugin_ui (STRONGSWAN_PLUGIN_UI_WIDGET (object), connection, error)) {
g_object_unref (object);
return NULL;
}
return object;
}

View File

@ -31,27 +31,6 @@ typedef enum
#define STRONGSWAN_TYPE_PLUGIN_UI_ERROR (strongswan_plugin_ui_error_get_type ())
GType strongswan_plugin_ui_error_get_type (void);
#define STRONGSWAN_TYPE_PLUGIN_UI (strongswan_plugin_ui_get_type ())
#define STRONGSWAN_PLUGIN_UI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STRONGSWAN_TYPE_PLUGIN_UI, StrongswanPluginUi))
#define STRONGSWAN_PLUGIN_UI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STRONGSWAN_TYPE_PLUGIN_UI, StrongswanPluginUiClass))
#define STRONGSWAN_IS_PLUGIN_UI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STRONGSWAN_TYPE_PLUGIN_UI))
#define STRONGSWAN_IS_PLUGIN_UI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), STRONGSWAN_TYPE_PLUGIN_UI))
#define STRONGSWAN_PLUGIN_UI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STRONGSWAN_TYPE_PLUGIN_UI, StrongswanPluginUiClass))
typedef struct _StrongswanPluginUi StrongswanPluginUi;
typedef struct _StrongswanPluginUiClass StrongswanPluginUiClass;
struct _StrongswanPluginUi {
GObject parent;
};
struct _StrongswanPluginUiClass {
GObjectClass parent;
};
GType strongswan_plugin_ui_get_type (void);
#define STRONGSWAN_TYPE_PLUGIN_UI_WIDGET (strongswan_plugin_ui_widget_get_type ())
#define STRONGSWAN_PLUGIN_UI_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, StrongswanPluginUiWidget))
#define STRONGSWAN_PLUGIN_UI_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, StrongswanPluginUiWidgetClass))
@ -72,5 +51,6 @@ struct _StrongswanPluginUiWidgetClass {
GType strongswan_plugin_ui_widget_get_type (void);
#endif /* _NM_STRONGSWAN_H_ */
NMVpnEditor *strongswan_editor_new (NMConnection *connection, GError **error);
#endif /* _NM_STRONGSWAN_H_ */