configure: Depend on libip4tc instead of libiptc
[strongswan.git] / src / frontends / gnome / properties / nm-strongswan.c
1 /*
2 * Copyright (C) 2015 Lubomir Rintel
3 * Copyright (C) 2013 Tobias Brunner
4 * Copyright (C) 2008 Martin Willi
5 * HSR Hochschule fuer Technik Rapperswil
6 * Copyright (C) 2005 David Zeuthen
7 * Copyright (C) 2005-2008 Dan Williams
8 *
9 * Based on NetworkManager's vpnc plugin
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <glib.h>
27 #include <glib/gi18n-lib.h>
28 #include <gtk/gtk.h>
29
30 #ifdef NM_STRONGSWAN_OLD
31 #define NM_VPN_LIBNM_COMPAT
32 #include <nm-vpn-plugin-ui-interface.h>
33 #include <nm-setting-vpn.h>
34 #include <nm-setting-connection.h>
35 #include <nm-ui-utils.h>
36 #else
37 #include <NetworkManager.h>
38 #include <nma-ui-utils.h>
39 #endif
40
41 #include "nm-strongswan.h"
42
43 #define STRONGSWAN_PLUGIN_NAME _("IPsec/IKEv2 (strongswan)")
44 #define STRONGSWAN_PLUGIN_DESC _("IPsec with the IKEv2 key exchange protocol.")
45 #define STRONGSWAN_PLUGIN_SERVICE "org.freedesktop.NetworkManager.strongswan"
46 #define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan"
47
48 /************** plugin class **************/
49
50 enum {
51 PROP_0,
52 PROP_NAME,
53 PROP_DESC,
54 PROP_SERVICE
55 };
56
57 static void strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class);
58
59 G_DEFINE_TYPE_EXTENDED (StrongswanPluginUi, strongswan_plugin_ui, G_TYPE_OBJECT, 0,
60 G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_EDITOR_PLUGIN,
61 strongswan_plugin_ui_interface_init))
62
63 /************** UI widget class **************/
64
65 static void strongswan_plugin_ui_widget_interface_init (NMVpnEditorInterface *iface_class);
66
67 typedef struct {
68 GtkBuilder *builder;
69 GtkWidget *widget;
70 } StrongswanPluginUiWidgetPrivate;
71
72 G_DEFINE_TYPE_EXTENDED (StrongswanPluginUiWidget, strongswan_plugin_ui_widget, G_TYPE_OBJECT, 0,
73 G_ADD_PRIVATE (StrongswanPluginUiWidget)
74 G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_EDITOR,
75 strongswan_plugin_ui_widget_interface_init))
76
77 #define STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE(o) ((StrongswanPluginUiWidgetPrivate*)strongswan_plugin_ui_widget_get_instance_private(o))
78
79 #define STRONGSWAN_PLUGIN_UI_ERROR strongswan_plugin_ui_error_quark ()
80
81 static GQuark
82 strongswan_plugin_ui_error_quark (void)
83 {
84 static GQuark error_quark = 0;
85
86 if (G_UNLIKELY (error_quark == 0))
87 error_quark = g_quark_from_static_string ("strongswan-plugin-ui-error-quark");
88
89 return error_quark;
90 }
91
92 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
93
94 GType
95 strongswan_plugin_ui_error_get_type (void)
96 {
97 static GType etype = 0;
98
99 if (etype == 0) {
100 static const GEnumValue values[] = {
101 /* Unknown error. */
102 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_UNKNOWN, "UnknownError"),
103 /* The specified property was invalid. */
104 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY, "InvalidProperty"),
105 /* The specified property was missing and is required. */
106 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_MISSING_PROPERTY, "MissingProperty"),
107 { 0, 0, 0 }
108 };
109 etype = g_enum_register_static ("StrongswanPluginUiError", values);
110 }
111 return etype;
112 }
113
114 static gboolean
115 check_validity (StrongswanPluginUiWidget *self, GError **error)
116 {
117 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
118 GtkWidget *widget;
119 char *str;
120
121 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "address-entry"));
122 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
123 if (!str || !strlen (str)) {
124 g_set_error (error,
125 STRONGSWAN_PLUGIN_UI_ERROR,
126 STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
127 "address");
128 return FALSE;
129 }
130 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
131 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
132 {
133 case 4:
134 {
135 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
136 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
137 if (str && strlen (str) < 20) {
138 g_set_error (error,
139 STRONGSWAN_PLUGIN_UI_ERROR,
140 STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
141 "password is too short");
142 return FALSE;
143 }
144 }
145 }
146 return TRUE;
147 }
148
149 static void update_sensitive (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *priv)
150 {
151 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
152 {
153 default:
154 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
155 /* FALL */
156 case 0:
157 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), TRUE);
158 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), TRUE);
159 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), TRUE);
160 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), TRUE);
161 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE);
162 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE);
163 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE);
164 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE);
165 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE);
166 break;
167 case 1:
168 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), TRUE);
169 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), TRUE);
170 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE);
171 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE);
172 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE);
173 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE);
174 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE);
175 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE);
176 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE);
177 break;
178 case 2:
179 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), FALSE);
180 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), FALSE);
181 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), FALSE);
182 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), FALSE);
183 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), FALSE);
184 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), FALSE);
185 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), FALSE);
186 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE);
187 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE);
188 break;
189 case 3:
190 case 4:
191 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-label")), TRUE);
192 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry")), TRUE);
193 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show")), TRUE);
194 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-label")), TRUE);
195 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry")), TRUE);
196 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-label")), FALSE);
197 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button")), FALSE);
198 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-label")), FALSE);
199 gtk_widget_set_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button")), FALSE);
200 break;
201 }
202
203 }
204
205 static void
206 settings_changed_cb (GtkWidget *widget, gpointer user_data)
207 {
208 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (user_data);
209 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
210
211 if (widget == GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")))
212 {
213 update_sensitive (GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo")), priv);
214 }
215 g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data), "changed");
216 }
217
218 static void
219 show_toggled_cb (GtkCheckButton *button, StrongswanPluginUiWidget *self)
220 {
221 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
222 GtkWidget *widget;
223 gboolean visible;
224
225 visible = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
226
227 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
228 gtk_entry_set_visibility (GTK_ENTRY (widget), visible);
229 }
230
231 static void
232 toggle_proposal_cb(GtkCheckButton *button, StrongswanPluginUiWidget *self)
233 {
234 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
235 gboolean visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
236 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(priv->builder, "ike-entry")), visible);
237 gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(priv->builder, "esp-entry")), visible);
238 }
239
240 static void
241 password_storage_changed_cb (GObject *entry, GParamSpec *pspec, gpointer user_data)
242 {
243 settings_changed_cb (NULL, STRONGSWAN_PLUGIN_UI_WIDGET (user_data));
244 }
245
246 static void
247 init_password_icon (StrongswanPluginUiWidget *self, NMSettingVpn *settings,
248 const char *secret_key, const char *entry_name)
249 {
250 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
251 GtkWidget *entry;
252 const char *value = NULL;
253 NMSettingSecretFlags pw_flags = NM_SETTING_SECRET_FLAG_NONE;
254
255 /* If there's already a password and the password type can't be found in
256 * the VPN settings, default to saving it. Otherwise, always ask for it.
257 */
258 entry = GTK_WIDGET (gtk_builder_get_object (priv->builder, entry_name));
259
260 nma_utils_setup_password_storage (entry, 0, NM_SETTING (settings), secret_key, TRUE, FALSE);
261
262 /* If there's no password and no flags in the setting,
263 * initialize flags as "always-ask".
264 */
265 if (settings)
266 {
267 nm_setting_get_secret_flags (NM_SETTING (settings), secret_key, &pw_flags, NULL);
268 }
269
270 value = gtk_entry_get_text (GTK_ENTRY (entry));
271 if ((!value || !*value) && (pw_flags == NM_SETTING_SECRET_FLAG_NONE))
272 {
273 nma_utils_update_password_storage (entry, NM_SETTING_SECRET_FLAG_NOT_SAVED,
274 NM_SETTING (settings), secret_key);
275 }
276
277 g_signal_connect (entry, "notify::secondary-icon-name",
278 G_CALLBACK (password_storage_changed_cb), self);
279 }
280
281 static gboolean
282 init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError **error)
283 {
284 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
285 NMSettingVpn *settings;
286 GtkWidget *widget;
287 const char *value;
288
289 settings = NM_SETTING_VPN(nm_connection_get_setting(connection, NM_TYPE_SETTING_VPN));
290 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "address-entry"));
291 value = nm_setting_vpn_get_data_item (settings, "address");
292 if (value)
293 gtk_entry_set_text (GTK_ENTRY (widget), value);
294 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
295
296 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "certificate-button"));
297 value = nm_setting_vpn_get_data_item (settings, "certificate");
298 if (value)
299 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
300 g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
301
302 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
303 value = nm_setting_vpn_get_data_item (settings, "user");
304 if (value)
305 gtk_entry_set_text (GTK_ENTRY (widget), value);
306 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
307
308 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show"));
309 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (show_toggled_cb), self);
310 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
311 value = nm_setting_vpn_get_secret (settings, "password");
312 if (value)
313 gtk_entry_set_text (GTK_ENTRY (widget), value);
314 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
315 init_password_icon (self, settings, "password", "passwd-entry");
316
317 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
318 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/private key"));
319 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/ssh-agent"));
320 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Smartcard"));
321 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP"));
322 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Pre-shared key"));
323 value = nm_setting_vpn_get_data_item (settings, "method");
324 if (value) {
325 if (g_strcmp0 (value, "key") == 0) {
326 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
327 }
328 if (g_strcmp0 (value, "agent") == 0) {
329 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
330 }
331 if (g_strcmp0 (value, "smartcard") == 0) {
332 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
333 }
334 if (g_strcmp0 (value, "eap") == 0) {
335 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
336 }
337 if (g_strcmp0 (value, "psk") == 0) {
338 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 4);
339 }
340 }
341 if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
342 {
343 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
344 }
345 update_sensitive (widget, priv);
346 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
347
348 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
349 value = nm_setting_vpn_get_data_item (settings, "usercert");
350 if (value)
351 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
352 g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
353
354 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"));
355 value = nm_setting_vpn_get_data_item (settings, "userkey");
356 if (value)
357 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
358 g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
359
360 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "virtual-check"));
361 value = nm_setting_vpn_get_data_item (settings, "virtual");
362 if (value && strcmp(value, "yes") == 0)
363 {
364 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
365 }
366 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
367
368 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "encap-check"));
369 value = nm_setting_vpn_get_data_item (settings, "encap");
370 if (value && strcmp(value, "yes") == 0)
371 {
372 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
373 }
374 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
375
376 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ipcomp-check"));
377 value = nm_setting_vpn_get_data_item (settings, "ipcomp");
378 if (value && strcmp(value, "yes") == 0)
379 {
380 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
381 }
382 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
383
384 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "proposal-check"));
385 value = nm_setting_vpn_get_data_item(settings, "proposal");
386 if (value && strcmp(value, "yes") == 0)
387 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
388 else
389 toggle_proposal_cb(GTK_CHECK_BUTTON(widget), self);
390 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (toggle_proposal_cb), self);
391
392 widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "ike-entry"));
393 value = nm_setting_vpn_get_data_item(settings, "ike");
394 if (value)
395 {
396 value = g_strdelimit (g_strdup (value), ";", ',');
397 gtk_entry_set_text (GTK_ENTRY (widget), value);
398 g_free ((char*)value);
399 }
400 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
401
402 widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "esp-entry"));
403 value = nm_setting_vpn_get_data_item(settings, "esp");
404 if (value)
405 {
406 value = g_strdelimit (g_strdup (value), ";", ',');
407 gtk_entry_set_text (GTK_ENTRY (widget), value);
408 g_free ((char*)value);
409 }
410 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
411
412 return TRUE;
413 }
414
415 static GObject *
416 get_widget (NMVpnEditor *iface)
417 {
418 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface);
419 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
420
421 return G_OBJECT (priv->widget);
422 }
423
424 static void
425 save_password_and_flags (NMSettingVpn *settings, GtkBuilder *builder,
426 const char *entry_name, const char *secret_key)
427 {
428 NMSettingSecretFlags flags;
429 const char *password;
430 GtkWidget *entry;
431
432 /* Get secret flags */
433 entry = GTK_WIDGET (gtk_builder_get_object (builder, entry_name));
434 flags = nma_utils_menu_to_secret_flags (entry);
435
436 /* Save password and convert flags to legacy data items */
437 switch (flags) {
438 case NM_SETTING_SECRET_FLAG_NONE:
439 /* FALL */
440 case NM_SETTING_SECRET_FLAG_AGENT_OWNED:
441 password = gtk_entry_get_text (GTK_ENTRY (entry));
442 if (password && strlen (password))
443 {
444 nm_setting_vpn_add_secret (settings, secret_key, password);
445 }
446 break;
447 default:
448 break;
449 }
450
451 /* Set new secret flags */
452 nm_setting_set_secret_flags (NM_SETTING (settings), secret_key, flags, NULL);
453 }
454
455 static gboolean
456 update_connection (NMVpnEditor *iface,
457 NMConnection *connection,
458 GError **error)
459 {
460 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface);
461 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
462 NMSettingVpn *settings;
463 GtkWidget *widget;
464 gboolean active;
465 char *str;
466
467 if (!check_validity (self, error))
468 return FALSE;
469 settings = NM_SETTING_VPN (nm_setting_vpn_new ());
470
471 g_object_set (settings, NM_SETTING_VPN_SERVICE_TYPE,
472 NM_DBUS_SERVICE_STRONGSWAN, NULL);
473
474 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "address-entry"));
475 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
476 if (str && strlen (str)) {
477 nm_setting_vpn_add_data_item (settings, "address", str);
478 }
479
480 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "certificate-button"));
481 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
482 if (str) {
483 nm_setting_vpn_add_data_item (settings, "certificate", str);
484 }
485
486 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
487 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
488 {
489 default:
490 case 0:
491 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"));
492 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
493 if (str) {
494 nm_setting_vpn_add_data_item (settings, "userkey", str);
495 }
496 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
497 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
498 if (str) {
499 nm_setting_vpn_add_data_item (settings, "usercert", str);
500 }
501 str = "key";
502 break;
503 case 1:
504 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
505 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
506 if (str) {
507 nm_setting_vpn_add_data_item (settings, "usercert", str);
508 }
509 str = "agent";
510 break;
511 case 2:
512 nm_setting_set_secret_flags (NM_SETTING (settings), "password",
513 NM_SETTING_SECRET_FLAG_NOT_SAVED, NULL);
514 str = "smartcard";
515 break;
516 case 3:
517 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
518 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
519 if (str && strlen (str)) {
520 nm_setting_vpn_add_data_item (settings, "user", str);
521 }
522 save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
523 str = "eap";
524 break;
525 case 4:
526 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
527 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
528 if (str && strlen (str)) {
529 nm_setting_vpn_add_data_item (settings, "user", str);
530 }
531 save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
532 str = "psk";
533 break;
534 }
535 nm_setting_vpn_add_data_item (settings, "method", str);
536
537 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "virtual-check"));
538 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
539 nm_setting_vpn_add_data_item (settings, "virtual", active ? "yes" : "no");
540
541 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "encap-check"));
542 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
543 nm_setting_vpn_add_data_item (settings, "encap", active ? "yes" : "no");
544
545 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ipcomp-check"));
546 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
547 nm_setting_vpn_add_data_item (settings, "ipcomp", active ? "yes" : "no");
548
549 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "proposal-check"));
550 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
551 nm_setting_vpn_add_data_item (settings, "proposal", active ? "yes" : "no");
552
553 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ike-entry"));
554 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
555 if (str && strlen (str)) {
556 str = g_strdelimit (g_strdup (str), ",", ';');
557 nm_setting_vpn_add_data_item (settings, "ike", str);
558 g_free (str);
559 }
560
561 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "esp-entry"));
562 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
563 if (str && strlen (str)) {
564 str = g_strdelimit (g_strdup (str), ",", ';');
565 nm_setting_vpn_add_data_item (settings, "esp", str);
566 g_free (str);
567 }
568
569 nm_connection_add_setting (connection, NM_SETTING (settings));
570 return TRUE;
571 }
572
573 static NMVpnEditor *
574 nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error)
575 {
576 NMVpnEditor *object;
577 StrongswanPluginUiWidgetPrivate *priv;
578 char *ui_file;
579
580 if (error)
581 g_return_val_if_fail (*error == NULL, NULL);
582
583 object = g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, NULL);
584 if (!object) {
585 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not create strongswan object");
586 return NULL;
587 }
588
589 priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE ((StrongswanPluginUiWidget*)object);
590 ui_file = g_strdup_printf ("%s/%s", UIDIR, "nm-strongswan-dialog.ui");
591 priv->builder = gtk_builder_new ();
592
593 gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE);
594
595 if (!gtk_builder_add_from_file (priv->builder, ui_file, error)) {
596 g_warning ("Couldn't load builder file: %s",
597 error && *error ? (*error)->message : "(unknown)");
598 g_clear_error (error);
599 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0,
600 "could not load required resources at %s", ui_file);
601 g_free (ui_file);
602 g_object_unref (object);
603 return NULL;
604 }
605 g_free (ui_file);
606
607 priv->widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "strongswan-vbox") );
608 if (!priv->widget) {
609 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not load UI widget");
610 g_object_unref (object);
611 return NULL;
612 }
613 g_object_ref_sink (priv->widget);
614
615 if (!init_plugin_ui (STRONGSWAN_PLUGIN_UI_WIDGET (object), connection, error)) {
616 g_object_unref (object);
617 return NULL;
618 }
619
620 return object;
621 }
622
623 static void
624 dispose (GObject *object)
625 {
626 StrongswanPluginUiWidget *plugin = STRONGSWAN_PLUGIN_UI_WIDGET (object);
627 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (plugin);
628 GtkWidget *widget;
629
630 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
631 g_signal_handlers_disconnect_by_func (G_OBJECT (widget), G_CALLBACK (password_storage_changed_cb), plugin);
632
633 if (priv->widget)
634 g_object_unref (priv->widget);
635
636 if (priv->builder)
637 g_object_unref (priv->builder);
638
639 G_OBJECT_CLASS (strongswan_plugin_ui_widget_parent_class)->dispose (object);
640 }
641
642 static void
643 strongswan_plugin_ui_widget_class_init (StrongswanPluginUiWidgetClass *req_class)
644 {
645 GObjectClass *object_class = G_OBJECT_CLASS (req_class);
646
647 object_class->dispose = dispose;
648 }
649
650 static void
651 strongswan_plugin_ui_widget_init (StrongswanPluginUiWidget *plugin)
652 {
653 }
654
655 static void
656 strongswan_plugin_ui_widget_interface_init (NMVpnEditorInterface *iface_class)
657 {
658 /* interface implementation */
659 iface_class->get_widget = get_widget;
660 iface_class->update_connection = update_connection;
661 }
662
663 static guint32
664 get_capabilities (NMVpnEditorPlugin *iface)
665 {
666 return NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6;
667 }
668
669 static NMVpnEditor *
670 get_editor (NMVpnEditorPlugin *iface, NMConnection *connection, GError **error)
671 {
672 return nm_vpn_plugin_ui_widget_interface_new (connection, error);
673 }
674
675 static void
676 get_property (GObject *object, guint prop_id,
677 GValue *value, GParamSpec *pspec)
678 {
679 switch (prop_id) {
680 case PROP_NAME:
681 g_value_set_string (value, STRONGSWAN_PLUGIN_NAME);
682 break;
683 case PROP_DESC:
684 g_value_set_string (value, STRONGSWAN_PLUGIN_DESC);
685 break;
686 case PROP_SERVICE:
687 g_value_set_string (value, STRONGSWAN_PLUGIN_SERVICE);
688 break;
689 default:
690 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
691 break;
692 }
693 }
694
695 static void
696 strongswan_plugin_ui_class_init (StrongswanPluginUiClass *req_class)
697 {
698 GObjectClass *object_class = G_OBJECT_CLASS (req_class);
699
700 object_class->get_property = get_property;
701
702 g_object_class_override_property (object_class,
703 PROP_NAME,
704 NM_VPN_EDITOR_PLUGIN_NAME);
705
706 g_object_class_override_property (object_class,
707 PROP_DESC,
708 NM_VPN_EDITOR_PLUGIN_DESCRIPTION);
709
710 g_object_class_override_property (object_class,
711 PROP_SERVICE,
712 NM_VPN_EDITOR_PLUGIN_SERVICE);
713 }
714
715 static void
716 strongswan_plugin_ui_init (StrongswanPluginUi *plugin)
717 {
718 }
719
720 static void
721 strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class)
722 {
723 /* interface implementation */
724 iface_class->get_editor = get_editor;
725 iface_class->get_capabilities = get_capabilities;
726 /* TODO: implement delete_connection to purge associated secrets */
727 }
728
729
730 G_MODULE_EXPORT NMVpnEditorPlugin *
731 nm_vpn_editor_plugin_factory (GError **error)
732 {
733 if (error)
734 g_return_val_if_fail (*error == NULL, NULL);
735
736 return g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL);
737 }