Merge branch 'nm-remote-id'
[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, "remote-identity-entry"));
303 value = nm_setting_vpn_get_data_item (settings, "remote-identity");
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, "user-entry"));
309 value = nm_setting_vpn_get_data_item (settings, "user");
310 if (value)
311 gtk_entry_set_text (GTK_ENTRY (widget), value);
312 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
313
314 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-show"));
315 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (show_toggled_cb), self);
316 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
317 value = nm_setting_vpn_get_secret (settings, "password");
318 if (value)
319 gtk_entry_set_text (GTK_ENTRY (widget), value);
320 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
321 init_password_icon (self, settings, "password", "passwd-entry");
322
323 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
324 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/private key"));
325 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Certificate/ssh-agent"));
326 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Smartcard"));
327 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("EAP"));
328 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), _("Pre-shared key"));
329 value = nm_setting_vpn_get_data_item (settings, "method");
330 if (value) {
331 if (g_strcmp0 (value, "key") == 0) {
332 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
333 }
334 if (g_strcmp0 (value, "agent") == 0) {
335 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
336 }
337 if (g_strcmp0 (value, "smartcard") == 0) {
338 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
339 }
340 if (g_strcmp0 (value, "eap") == 0) {
341 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
342 }
343 if (g_strcmp0 (value, "psk") == 0) {
344 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 4);
345 }
346 }
347 if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
348 {
349 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
350 }
351 update_sensitive (widget, priv);
352 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
353
354 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
355 value = nm_setting_vpn_get_data_item (settings, "usercert");
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, "userkey-button"));
361 value = nm_setting_vpn_get_data_item (settings, "userkey");
362 if (value)
363 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
364 g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
365
366 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "virtual-check"));
367 value = nm_setting_vpn_get_data_item (settings, "virtual");
368 if (value && strcmp(value, "yes") == 0)
369 {
370 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
371 }
372 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
373
374 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "encap-check"));
375 value = nm_setting_vpn_get_data_item (settings, "encap");
376 if (value && strcmp(value, "yes") == 0)
377 {
378 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
379 }
380 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
381
382 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ipcomp-check"));
383 value = nm_setting_vpn_get_data_item (settings, "ipcomp");
384 if (value && strcmp(value, "yes") == 0)
385 {
386 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
387 }
388 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
389
390 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "proposal-check"));
391 value = nm_setting_vpn_get_data_item(settings, "proposal");
392 if (value && strcmp(value, "yes") == 0)
393 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
394 else
395 toggle_proposal_cb(GTK_CHECK_BUTTON(widget), self);
396 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (toggle_proposal_cb), self);
397
398 widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "ike-entry"));
399 value = nm_setting_vpn_get_data_item(settings, "ike");
400 if (value)
401 {
402 value = g_strdelimit (g_strdup (value), ";", ',');
403 gtk_entry_set_text (GTK_ENTRY (widget), value);
404 g_free ((char*)value);
405 }
406 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
407
408 widget = GTK_WIDGET(gtk_builder_get_object(priv->builder, "esp-entry"));
409 value = nm_setting_vpn_get_data_item(settings, "esp");
410 if (value)
411 {
412 value = g_strdelimit (g_strdup (value), ";", ',');
413 gtk_entry_set_text (GTK_ENTRY (widget), value);
414 g_free ((char*)value);
415 }
416 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
417
418 return TRUE;
419 }
420
421 static GObject *
422 get_widget (NMVpnEditor *iface)
423 {
424 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface);
425 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
426
427 return G_OBJECT (priv->widget);
428 }
429
430 static void
431 save_password_and_flags (NMSettingVpn *settings, GtkBuilder *builder,
432 const char *entry_name, const char *secret_key)
433 {
434 NMSettingSecretFlags flags;
435 const char *password;
436 GtkWidget *entry;
437
438 /* Get secret flags */
439 entry = GTK_WIDGET (gtk_builder_get_object (builder, entry_name));
440 flags = nma_utils_menu_to_secret_flags (entry);
441
442 /* Save password and convert flags to legacy data items */
443 switch (flags) {
444 case NM_SETTING_SECRET_FLAG_NONE:
445 /* FALL */
446 case NM_SETTING_SECRET_FLAG_AGENT_OWNED:
447 password = gtk_entry_get_text (GTK_ENTRY (entry));
448 if (password && strlen (password))
449 {
450 nm_setting_vpn_add_secret (settings, secret_key, password);
451 }
452 break;
453 default:
454 break;
455 }
456
457 /* Set new secret flags */
458 nm_setting_set_secret_flags (NM_SETTING (settings), secret_key, flags, NULL);
459 }
460
461 static gboolean
462 update_connection (NMVpnEditor *iface,
463 NMConnection *connection,
464 GError **error)
465 {
466 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface);
467 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
468 NMSettingVpn *settings;
469 GtkWidget *widget;
470 gboolean active;
471 char *str;
472
473 if (!check_validity (self, error))
474 return FALSE;
475 settings = NM_SETTING_VPN (nm_setting_vpn_new ());
476
477 g_object_set (settings, NM_SETTING_VPN_SERVICE_TYPE,
478 NM_DBUS_SERVICE_STRONGSWAN, NULL);
479
480 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "address-entry"));
481 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
482 if (str && strlen (str)) {
483 nm_setting_vpn_add_data_item (settings, "address", str);
484 }
485
486 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "certificate-button"));
487 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
488 if (str) {
489 nm_setting_vpn_add_data_item (settings, "certificate", str);
490 }
491
492 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "remote-identity-entry"));
493 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
494 if (str && strlen (str)) {
495 nm_setting_vpn_add_data_item (settings, "remote-identity", str);
496 }
497
498 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "method-combo"));
499 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
500 {
501 default:
502 case 0:
503 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "userkey-button"));
504 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
505 if (str) {
506 nm_setting_vpn_add_data_item (settings, "userkey", str);
507 }
508 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
509 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
510 if (str) {
511 nm_setting_vpn_add_data_item (settings, "usercert", str);
512 }
513 str = "key";
514 break;
515 case 1:
516 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "usercert-button"));
517 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
518 if (str) {
519 nm_setting_vpn_add_data_item (settings, "usercert", str);
520 }
521 str = "agent";
522 break;
523 case 2:
524 nm_setting_set_secret_flags (NM_SETTING (settings), "password",
525 NM_SETTING_SECRET_FLAG_NOT_SAVED, NULL);
526 str = "smartcard";
527 break;
528 case 3:
529 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
530 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
531 if (str && strlen (str)) {
532 nm_setting_vpn_add_data_item (settings, "user", str);
533 }
534 save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
535 str = "eap";
536 break;
537 case 4:
538 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "user-entry"));
539 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
540 if (str && strlen (str)) {
541 nm_setting_vpn_add_data_item (settings, "user", str);
542 }
543 save_password_and_flags (settings, priv->builder, "passwd-entry", "password");
544 str = "psk";
545 break;
546 }
547 nm_setting_vpn_add_data_item (settings, "method", str);
548
549 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "virtual-check"));
550 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
551 nm_setting_vpn_add_data_item (settings, "virtual", active ? "yes" : "no");
552
553 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "encap-check"));
554 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
555 nm_setting_vpn_add_data_item (settings, "encap", active ? "yes" : "no");
556
557 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ipcomp-check"));
558 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
559 nm_setting_vpn_add_data_item (settings, "ipcomp", active ? "yes" : "no");
560
561 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "proposal-check"));
562 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
563 nm_setting_vpn_add_data_item (settings, "proposal", active ? "yes" : "no");
564
565 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "ike-entry"));
566 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
567 if (str && strlen (str)) {
568 str = g_strdelimit (g_strdup (str), ",", ';');
569 nm_setting_vpn_add_data_item (settings, "ike", str);
570 g_free (str);
571 }
572
573 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "esp-entry"));
574 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
575 if (str && strlen (str)) {
576 str = g_strdelimit (g_strdup (str), ",", ';');
577 nm_setting_vpn_add_data_item (settings, "esp", str);
578 g_free (str);
579 }
580
581 nm_connection_add_setting (connection, NM_SETTING (settings));
582 return TRUE;
583 }
584
585 static NMVpnEditor *
586 nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error)
587 {
588 NMVpnEditor *object;
589 StrongswanPluginUiWidgetPrivate *priv;
590 char *ui_file;
591
592 if (error)
593 g_return_val_if_fail (*error == NULL, NULL);
594
595 object = g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, NULL);
596 if (!object) {
597 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not create strongswan object");
598 return NULL;
599 }
600
601 priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE ((StrongswanPluginUiWidget*)object);
602 ui_file = g_strdup_printf ("%s/%s", UIDIR, "nm-strongswan-dialog.ui");
603 priv->builder = gtk_builder_new ();
604
605 gtk_builder_set_translation_domain (priv->builder, GETTEXT_PACKAGE);
606
607 if (!gtk_builder_add_from_file (priv->builder, ui_file, error)) {
608 g_warning ("Couldn't load builder file: %s",
609 error && *error ? (*error)->message : "(unknown)");
610 g_clear_error (error);
611 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0,
612 "could not load required resources at %s", ui_file);
613 g_free (ui_file);
614 g_object_unref (object);
615 return NULL;
616 }
617 g_free (ui_file);
618
619 priv->widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "strongswan-vbox") );
620 if (!priv->widget) {
621 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not load UI widget");
622 g_object_unref (object);
623 return NULL;
624 }
625 g_object_ref_sink (priv->widget);
626
627 if (!init_plugin_ui (STRONGSWAN_PLUGIN_UI_WIDGET (object), connection, error)) {
628 g_object_unref (object);
629 return NULL;
630 }
631
632 return object;
633 }
634
635 static void
636 dispose (GObject *object)
637 {
638 StrongswanPluginUiWidget *plugin = STRONGSWAN_PLUGIN_UI_WIDGET (object);
639 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (plugin);
640 GtkWidget *widget;
641
642 widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "passwd-entry"));
643 g_signal_handlers_disconnect_by_func (G_OBJECT (widget), G_CALLBACK (password_storage_changed_cb), plugin);
644
645 if (priv->widget)
646 g_object_unref (priv->widget);
647
648 if (priv->builder)
649 g_object_unref (priv->builder);
650
651 G_OBJECT_CLASS (strongswan_plugin_ui_widget_parent_class)->dispose (object);
652 }
653
654 static void
655 strongswan_plugin_ui_widget_class_init (StrongswanPluginUiWidgetClass *req_class)
656 {
657 GObjectClass *object_class = G_OBJECT_CLASS (req_class);
658
659 object_class->dispose = dispose;
660 }
661
662 static void
663 strongswan_plugin_ui_widget_init (StrongswanPluginUiWidget *plugin)
664 {
665 }
666
667 static void
668 strongswan_plugin_ui_widget_interface_init (NMVpnEditorInterface *iface_class)
669 {
670 /* interface implementation */
671 iface_class->get_widget = get_widget;
672 iface_class->update_connection = update_connection;
673 }
674
675 static guint32
676 get_capabilities (NMVpnEditorPlugin *iface)
677 {
678 return NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6;
679 }
680
681 static NMVpnEditor *
682 get_editor (NMVpnEditorPlugin *iface, NMConnection *connection, GError **error)
683 {
684 return nm_vpn_plugin_ui_widget_interface_new (connection, error);
685 }
686
687 static void
688 get_property (GObject *object, guint prop_id,
689 GValue *value, GParamSpec *pspec)
690 {
691 switch (prop_id) {
692 case PROP_NAME:
693 g_value_set_string (value, STRONGSWAN_PLUGIN_NAME);
694 break;
695 case PROP_DESC:
696 g_value_set_string (value, STRONGSWAN_PLUGIN_DESC);
697 break;
698 case PROP_SERVICE:
699 g_value_set_string (value, STRONGSWAN_PLUGIN_SERVICE);
700 break;
701 default:
702 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
703 break;
704 }
705 }
706
707 static void
708 strongswan_plugin_ui_class_init (StrongswanPluginUiClass *req_class)
709 {
710 GObjectClass *object_class = G_OBJECT_CLASS (req_class);
711
712 object_class->get_property = get_property;
713
714 g_object_class_override_property (object_class,
715 PROP_NAME,
716 NM_VPN_EDITOR_PLUGIN_NAME);
717
718 g_object_class_override_property (object_class,
719 PROP_DESC,
720 NM_VPN_EDITOR_PLUGIN_DESCRIPTION);
721
722 g_object_class_override_property (object_class,
723 PROP_SERVICE,
724 NM_VPN_EDITOR_PLUGIN_SERVICE);
725 }
726
727 static void
728 strongswan_plugin_ui_init (StrongswanPluginUi *plugin)
729 {
730 }
731
732 static void
733 strongswan_plugin_ui_interface_init (NMVpnEditorPluginInterface *iface_class)
734 {
735 /* interface implementation */
736 iface_class->get_editor = get_editor;
737 iface_class->get_capabilities = get_capabilities;
738 /* TODO: implement delete_connection to purge associated secrets */
739 }
740
741
742 G_MODULE_EXPORT NMVpnEditorPlugin *
743 nm_vpn_editor_plugin_factory (GError **error)
744 {
745 if (error)
746 g_return_val_if_fail (*error == NULL, NULL);
747
748 return g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL);
749 }