2 * Copyright (C) 2013 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2005 David Zeuthen
6 * Copyright (C) 2005-2008 Dan Williams
8 * Based on NetworkManager's vpnc plugin
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 #include <glib/gi18n-lib.h>
29 #define NM_VPN_API_SUBJECT_TO_CHANGE
31 #include <nm-vpn-plugin-ui-interface.h>
32 #include <nm-setting-vpn.h>
33 #include <nm-setting-connection.h>
35 #include "nm-strongswan.h"
37 #define STRONGSWAN_PLUGIN_NAME _("IPsec/IKEv2 (strongswan)")
38 #define STRONGSWAN_PLUGIN_DESC _("IPsec with the IKEv2 key exchange protocol.")
39 #define STRONGSWAN_PLUGIN_SERVICE "org.freedesktop.NetworkManager.strongswan"
40 #define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan"
42 /************** plugin class **************/
44 static void strongswan_plugin_ui_interface_init (NMVpnPluginUiInterface
*iface_class
);
46 G_DEFINE_TYPE_EXTENDED (StrongswanPluginUi
, strongswan_plugin_ui
, G_TYPE_OBJECT
, 0,
47 G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_INTERFACE
,
48 strongswan_plugin_ui_interface_init
))
50 /************** UI widget class **************/
52 static void strongswan_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface
*iface_class
);
54 G_DEFINE_TYPE_EXTENDED (StrongswanPluginUiWidget
, strongswan_plugin_ui_widget
, G_TYPE_OBJECT
, 0,
55 G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_WIDGET_INTERFACE
,
56 strongswan_plugin_ui_widget_interface_init
))
58 #define STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, StrongswanPluginUiWidgetPrivate))
63 } StrongswanPluginUiWidgetPrivate
;
66 #define STRONGSWAN_PLUGIN_UI_ERROR strongswan_plugin_ui_error_quark ()
69 strongswan_plugin_ui_error_quark (void)
71 static GQuark error_quark
= 0;
73 if (G_UNLIKELY (error_quark
== 0))
74 error_quark
= g_quark_from_static_string ("strongswan-plugin-ui-error-quark");
79 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
82 strongswan_plugin_ui_error_get_type (void)
84 static GType etype
= 0;
87 static const GEnumValue values
[] = {
89 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_UNKNOWN
, "UnknownError"),
90 /* The specified property was invalid. */
91 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY
, "InvalidProperty"),
92 /* The specified property was missing and is required. */
93 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_MISSING_PROPERTY
, "MissingProperty"),
96 etype
= g_enum_register_static ("StrongswanPluginUiError", values
);
102 check_validity (StrongswanPluginUiWidget
*self
, GError
**error
)
104 StrongswanPluginUiWidgetPrivate
*priv
= STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self
);
108 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "address-entry"));
109 str
= (char *) gtk_entry_get_text (GTK_ENTRY (widget
));
110 if (!str
|| !strlen (str
)) {
112 STRONGSWAN_PLUGIN_UI_ERROR
,
113 STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY
,
120 static void update_layout (GtkWidget
*widget
, StrongswanPluginUiWidgetPrivate
*priv
)
122 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget
)))
125 gtk_combo_box_set_active (GTK_COMBO_BOX (widget
), 0);
128 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-label")));
129 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-button")));
130 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-label")));
131 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-button")));
132 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-label")));
133 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-entry")));
136 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-label")));
137 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-button")));
138 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-label")));
139 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-entry")));
140 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-label")));
141 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-button")));
144 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-label")));
145 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-button")));
146 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-label")));
147 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-entry")));
148 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-label")));
149 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-button")));
153 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-label")));
154 gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-entry")));
155 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-label")));
156 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-button")));
157 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-label")));
158 gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-button")));
165 settings_changed_cb (GtkWidget
*widget
, gpointer user_data
)
167 StrongswanPluginUiWidget
*self
= STRONGSWAN_PLUGIN_UI_WIDGET (user_data
);
168 StrongswanPluginUiWidgetPrivate
*priv
= STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self
);
170 if (widget
== GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "method-combo")))
172 update_layout(GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "method-combo")), priv
);
174 g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data
), "changed");
178 init_plugin_ui (StrongswanPluginUiWidget
*self
, NMConnection
*connection
, GError
**error
)
180 StrongswanPluginUiWidgetPrivate
*priv
= STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self
);
181 NMSettingVPN
*settings
;
185 settings
= NM_SETTING_VPN(nm_connection_get_setting(connection
, NM_TYPE_SETTING_VPN
));
186 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "address-entry"));
187 value
= nm_setting_vpn_get_data_item (settings
, "address");
189 gtk_entry_set_text (GTK_ENTRY (widget
), value
);
190 g_signal_connect (G_OBJECT (widget
), "changed", G_CALLBACK (settings_changed_cb
), self
);
192 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "certificate-button"));
193 value
= nm_setting_vpn_get_data_item (settings
, "certificate");
195 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget
), value
);
196 g_signal_connect (G_OBJECT (widget
), "selection-changed", G_CALLBACK (settings_changed_cb
), self
);
198 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-label"));
199 gtk_widget_set_no_show_all (widget
, TRUE
);
200 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-entry"));
201 gtk_widget_set_no_show_all (widget
, TRUE
);
202 value
= nm_setting_vpn_get_data_item (settings
, "user");
204 gtk_entry_set_text (GTK_ENTRY (widget
), value
);
205 g_signal_connect (G_OBJECT (widget
), "changed", G_CALLBACK (settings_changed_cb
), self
);
207 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "method-combo"));
208 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget
), _("Certificate/private key"));
209 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget
), _("Certificate/ssh-agent"));
210 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget
), _("Smartcard"));
211 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget
), _("EAP"));
212 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget
), _("Pre-shared key"));
213 value
= nm_setting_vpn_get_data_item (settings
, "method");
215 if (g_strcmp0 (value
, "key") == 0) {
216 gtk_combo_box_set_active (GTK_COMBO_BOX (widget
), 0);
218 if (g_strcmp0 (value
, "agent") == 0) {
219 gtk_combo_box_set_active (GTK_COMBO_BOX (widget
), 1);
221 if (g_strcmp0 (value
, "smartcard") == 0) {
222 gtk_combo_box_set_active (GTK_COMBO_BOX (widget
), 2);
224 if (g_strcmp0 (value
, "eap") == 0) {
225 gtk_combo_box_set_active (GTK_COMBO_BOX (widget
), 3);
227 if (g_strcmp0 (value
, "psk") == 0) {
228 gtk_combo_box_set_active (GTK_COMBO_BOX (widget
), 4);
231 if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget
)) == -1)
233 gtk_combo_box_set_active (GTK_COMBO_BOX (widget
), 0);
235 update_layout (widget
, priv
);
236 g_signal_connect (G_OBJECT (widget
), "changed", G_CALLBACK (settings_changed_cb
), self
);
238 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-label"));
239 gtk_widget_set_no_show_all (widget
, TRUE
);
240 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-button"));
241 gtk_widget_set_no_show_all (widget
, TRUE
);
242 value
= nm_setting_vpn_get_data_item (settings
, "usercert");
244 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget
), value
);
245 g_signal_connect (G_OBJECT (widget
), "selection-changed", G_CALLBACK (settings_changed_cb
), self
);
247 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-label"));
248 gtk_widget_set_no_show_all (widget
, TRUE
);
249 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-button"));
250 gtk_widget_set_no_show_all (widget
, TRUE
);
251 value
= nm_setting_vpn_get_data_item (settings
, "userkey");
253 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget
), value
);
254 g_signal_connect (G_OBJECT (widget
), "selection-changed", G_CALLBACK (settings_changed_cb
), self
);
256 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "virtual-check"));
257 value
= nm_setting_vpn_get_data_item (settings
, "virtual");
258 if (value
&& strcmp(value
, "yes") == 0)
260 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), TRUE
);
262 g_signal_connect (G_OBJECT (widget
), "toggled", G_CALLBACK (settings_changed_cb
), self
);
264 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "encap-check"));
265 value
= nm_setting_vpn_get_data_item (settings
, "encap");
266 if (value
&& strcmp(value
, "yes") == 0)
268 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), TRUE
);
270 g_signal_connect (G_OBJECT (widget
), "toggled", G_CALLBACK (settings_changed_cb
), self
);
272 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "ipcomp-check"));
273 value
= nm_setting_vpn_get_data_item (settings
, "ipcomp");
274 if (value
&& strcmp(value
, "yes") == 0)
276 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), TRUE
);
278 g_signal_connect (G_OBJECT (widget
), "toggled", G_CALLBACK (settings_changed_cb
), self
);
284 get_widget (NMVpnPluginUiWidgetInterface
*iface
)
286 StrongswanPluginUiWidget
*self
= STRONGSWAN_PLUGIN_UI_WIDGET (iface
);
287 StrongswanPluginUiWidgetPrivate
*priv
= STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self
);
289 return G_OBJECT (priv
->widget
);
293 update_connection (NMVpnPluginUiWidgetInterface
*iface
,
294 NMConnection
*connection
,
297 StrongswanPluginUiWidget
*self
= STRONGSWAN_PLUGIN_UI_WIDGET (iface
);
298 StrongswanPluginUiWidgetPrivate
*priv
= STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self
);
299 NMSettingVPN
*settings
;
304 if (!check_validity (self
, error
))
306 settings
= NM_SETTING_VPN (nm_setting_vpn_new ());
308 g_object_set (settings
, NM_SETTING_VPN_SERVICE_TYPE
,
309 NM_DBUS_SERVICE_STRONGSWAN
, NULL
);
311 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "address-entry"));
312 str
= (char *) gtk_entry_get_text (GTK_ENTRY (widget
));
313 if (str
&& strlen (str
)) {
314 nm_setting_vpn_add_data_item (settings
, "address", str
);
317 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "certificate-button"));
318 str
= (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget
));
320 nm_setting_vpn_add_data_item (settings
, "certificate", str
);
323 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "method-combo"));
324 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget
)))
328 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "userkey-button"));
329 str
= (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget
));
331 nm_setting_vpn_add_data_item (settings
, "userkey", str
);
333 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-button"));
334 str
= (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget
));
336 nm_setting_vpn_add_data_item (settings
, "usercert", str
);
341 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "usercert-button"));
342 str
= (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget
));
344 nm_setting_vpn_add_data_item (settings
, "usercert", str
);
352 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-entry"));
353 str
= (char *) gtk_entry_get_text (GTK_ENTRY (widget
));
354 if (str
&& strlen (str
)) {
355 nm_setting_vpn_add_data_item (settings
, "user", str
);
360 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "user-entry"));
361 str
= (char *) gtk_entry_get_text (GTK_ENTRY (widget
));
362 if (str
&& strlen (str
)) {
363 nm_setting_vpn_add_data_item (settings
, "user", str
);
368 nm_setting_vpn_add_data_item (settings
, "method", str
);
370 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "virtual-check"));
371 active
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
372 nm_setting_vpn_add_data_item (settings
, "virtual", active
? "yes" : "no");
374 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "encap-check"));
375 active
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
376 nm_setting_vpn_add_data_item (settings
, "encap", active
? "yes" : "no");
378 widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "ipcomp-check"));
379 active
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
380 nm_setting_vpn_add_data_item (settings
, "ipcomp", active
? "yes" : "no");
382 nm_setting_set_secret_flags (NM_SETTING (settings
), "password",
383 NM_SETTING_SECRET_FLAG_AGENT_OWNED
, NULL
);
385 nm_connection_add_setting (connection
, NM_SETTING (settings
));
389 static NMVpnPluginUiWidgetInterface
*
390 nm_vpn_plugin_ui_widget_interface_new (NMConnection
*connection
, GError
**error
)
392 NMVpnPluginUiWidgetInterface
*object
;
393 StrongswanPluginUiWidgetPrivate
*priv
;
397 g_return_val_if_fail (*error
== NULL
, NULL
);
399 object
= NM_VPN_PLUGIN_UI_WIDGET_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET
, NULL
));
401 g_set_error (error
, STRONGSWAN_PLUGIN_UI_ERROR
, 0, "could not create strongswan object");
405 priv
= STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (object
);
406 ui_file
= g_strdup_printf ("%s/%s", UIDIR
, "nm-strongswan-dialog.ui");
407 priv
->builder
= gtk_builder_new ();
409 gtk_builder_set_translation_domain (priv
->builder
, GETTEXT_PACKAGE
);
411 if (!gtk_builder_add_from_file (priv
->builder
, ui_file
, error
)) {
412 g_warning ("Couldn't load builder file: %s",
413 error
&& *error
? (*error
)->message
: "(unknown)");
414 g_clear_error (error
);
415 g_set_error (error
, STRONGSWAN_PLUGIN_UI_ERROR
, 0,
416 "could not load required resources at %s", ui_file
);
418 g_object_unref (object
);
423 priv
->widget
= GTK_WIDGET (gtk_builder_get_object (priv
->builder
, "strongswan-vbox") );
425 g_set_error (error
, STRONGSWAN_PLUGIN_UI_ERROR
, 0, "could not load UI widget");
426 g_object_unref (object
);
429 g_object_ref_sink (priv
->widget
);
431 if (!init_plugin_ui (STRONGSWAN_PLUGIN_UI_WIDGET (object
), connection
, error
)) {
432 g_object_unref (object
);
440 dispose (GObject
*object
)
442 StrongswanPluginUiWidget
*plugin
= STRONGSWAN_PLUGIN_UI_WIDGET (object
);
443 StrongswanPluginUiWidgetPrivate
*priv
= STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (plugin
);
446 g_object_unref (priv
->widget
);
449 g_object_unref (priv
->builder
);
451 G_OBJECT_CLASS (strongswan_plugin_ui_widget_parent_class
)->dispose (object
);
455 strongswan_plugin_ui_widget_class_init (StrongswanPluginUiWidgetClass
*req_class
)
457 GObjectClass
*object_class
= G_OBJECT_CLASS (req_class
);
459 g_type_class_add_private (req_class
, sizeof (StrongswanPluginUiWidgetPrivate
));
461 object_class
->dispose
= dispose
;
465 strongswan_plugin_ui_widget_init (StrongswanPluginUiWidget
*plugin
)
470 strongswan_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface
*iface_class
)
472 /* interface implementation */
473 iface_class
->get_widget
= get_widget
;
474 iface_class
->update_connection
= update_connection
;
478 get_capabilities (NMVpnPluginUiInterface
*iface
)
483 static NMVpnPluginUiWidgetInterface
*
484 ui_factory (NMVpnPluginUiInterface
*iface
, NMConnection
*connection
, GError
**error
)
486 return nm_vpn_plugin_ui_widget_interface_new (connection
, error
);
490 get_property (GObject
*object
, guint prop_id
,
491 GValue
*value
, GParamSpec
*pspec
)
494 case NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME
:
495 g_value_set_string (value
, STRONGSWAN_PLUGIN_NAME
);
497 case NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC
:
498 g_value_set_string (value
, STRONGSWAN_PLUGIN_DESC
);
500 case NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE
:
501 g_value_set_string (value
, STRONGSWAN_PLUGIN_SERVICE
);
504 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
510 strongswan_plugin_ui_class_init (StrongswanPluginUiClass
*req_class
)
512 GObjectClass
*object_class
= G_OBJECT_CLASS (req_class
);
514 object_class
->get_property
= get_property
;
516 g_object_class_override_property (object_class
,
517 NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME
,
518 NM_VPN_PLUGIN_UI_INTERFACE_NAME
);
520 g_object_class_override_property (object_class
,
521 NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC
,
522 NM_VPN_PLUGIN_UI_INTERFACE_DESC
);
524 g_object_class_override_property (object_class
,
525 NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE
,
526 NM_VPN_PLUGIN_UI_INTERFACE_SERVICE
);
530 strongswan_plugin_ui_init (StrongswanPluginUi
*plugin
)
535 strongswan_plugin_ui_interface_init (NMVpnPluginUiInterface
*iface_class
)
537 /* interface implementation */
538 iface_class
->ui_factory
= ui_factory
;
539 iface_class
->get_capabilities
= get_capabilities
;
540 /* TODO: implement delete_connection to purge associated secrets */
544 G_MODULE_EXPORT NMVpnPluginUiInterface
*
545 nm_vpn_plugin_ui_factory (GError
**error
)
548 g_return_val_if_fail (*error
== NULL
, NULL
);
550 return NM_VPN_PLUGIN_UI_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI
, NULL
));