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