Removed strayed code fragment
[strongswan.git] / src / charon / plugins / nm / gnome / properties / nm-strongswan.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 * Copyright (C) 2005 David Zeuthen
5 * Copyright (C) 2005-2008 Dan Williams
6 *
7 * Based on NetworkManager's vpnc plugin
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <glib.h>
25 #include <glib/gi18n-lib.h>
26 #include <gtk/gtk.h>
27 #include <glade/glade.h>
28
29 #define NM_VPN_API_SUBJECT_TO_CHANGE
30
31 #include <nm-vpn-plugin-ui-interface.h>
32 #include <nm-setting-vpn.h>
33 #include <nm-setting-connection.h>
34 #include <nm-setting-ip4-config.h>
35
36 #include "nm-strongswan.h"
37
38 #define STRONGSWAN_PLUGIN_NAME _("IPsec/IKEv2 (strongswan)")
39 #define STRONGSWAN_PLUGIN_DESC _("IPsec with the IKEv2 key exchange protocol.")
40 #define STRONGSWAN_PLUGIN_SERVICE "org.freedesktop.NetworkManager.strongswan"
41 #define NM_DBUS_SERVICE_STRONGSWAN "org.freedesktop.NetworkManager.strongswan"
42
43 /************** plugin class **************/
44
45 static void strongswan_plugin_ui_interface_init (NMVpnPluginUiInterface *iface_class);
46
47 G_DEFINE_TYPE_EXTENDED (StrongswanPluginUi, strongswan_plugin_ui, G_TYPE_OBJECT, 0,
48 G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_INTERFACE,
49 strongswan_plugin_ui_interface_init))
50
51 /************** UI widget class **************/
52
53 static void strongswan_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface *iface_class);
54
55 G_DEFINE_TYPE_EXTENDED (StrongswanPluginUiWidget, strongswan_plugin_ui_widget, G_TYPE_OBJECT, 0,
56 G_IMPLEMENT_INTERFACE (NM_TYPE_VPN_PLUGIN_UI_WIDGET_INTERFACE,
57 strongswan_plugin_ui_widget_interface_init))
58
59 #define STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, StrongswanPluginUiWidgetPrivate))
60
61 typedef struct {
62 GladeXML *xml;
63 GtkWidget *widget;
64 } StrongswanPluginUiWidgetPrivate;
65
66
67 #define STRONGSWAN_PLUGIN_UI_ERROR strongswan_plugin_ui_error_quark ()
68
69 static GQuark
70 strongswan_plugin_ui_error_quark (void)
71 {
72 static GQuark error_quark = 0;
73
74 if (G_UNLIKELY (error_quark == 0))
75 error_quark = g_quark_from_static_string ("strongswan-plugin-ui-error-quark");
76
77 return error_quark;
78 }
79
80 #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
81
82 GType
83 strongswan_plugin_ui_error_get_type (void)
84 {
85 static GType etype = 0;
86
87 if (etype == 0) {
88 static const GEnumValue values[] = {
89 /* Unknown error. */
90 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_UNKNOWN, "UnknownError"),
91 /* The specified property was invalid. */
92 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY, "InvalidProperty"),
93 /* The specified property was missing and is required. */
94 ENUM_ENTRY (STRONGSWAN_PLUGIN_UI_ERROR_MISSING_PROPERTY, "MissingProperty"),
95 { 0, 0, 0 }
96 };
97 etype = g_enum_register_static ("StrongswanPluginUiError", values);
98 }
99 return etype;
100 }
101
102 static gboolean
103 check_validity (StrongswanPluginUiWidget *self, GError **error)
104 {
105 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
106 GtkWidget *widget;
107 char *str;
108
109 widget = glade_xml_get_widget (priv->xml, "address-entry");
110 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
111 if (!str || !strlen (str)) {
112 g_set_error (error,
113 STRONGSWAN_PLUGIN_UI_ERROR,
114 STRONGSWAN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
115 "address");
116 return FALSE;
117 }
118 return TRUE;
119 }
120
121 static void update_layout (GtkWidget *widget, StrongswanPluginUiWidgetPrivate *priv)
122 {
123 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
124 {
125 default:
126 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
127 /* FALL */
128 case 0:
129 gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-label"));
130 gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-button"));
131 gtk_widget_show (glade_xml_get_widget (priv->xml, "userkey-label"));
132 gtk_widget_show (glade_xml_get_widget (priv->xml, "userkey-button"));
133 gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-label"));
134 gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-entry"));
135 break;
136 case 1:
137 gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-label"));
138 gtk_widget_show (glade_xml_get_widget (priv->xml, "usercert-button"));
139 gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-label"));
140 gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-entry"));
141 gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-label"));
142 gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-button"));
143 break;
144 case 2:
145 gtk_widget_show (glade_xml_get_widget (priv->xml, "user-label"));
146 gtk_widget_show (glade_xml_get_widget (priv->xml, "user-entry"));
147 gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-label"));
148 gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-button"));
149 gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-label"));
150 gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-button"));
151 break;
152 }
153
154 }
155
156 static void
157 settings_changed_cb (GtkWidget *widget, gpointer user_data)
158 {
159 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (user_data);
160 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
161
162 if (widget == glade_xml_get_widget (priv->xml, "method-combo"))
163 {
164 update_layout(glade_xml_get_widget (priv->xml, "method-combo"), priv);
165 }
166 g_signal_emit_by_name (STRONGSWAN_PLUGIN_UI_WIDGET (user_data), "changed");
167 }
168
169 static gboolean
170 init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError **error)
171 {
172 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
173 NMSettingVPN *settings;
174 GtkWidget *widget;
175 const char *value;
176
177 settings = NM_SETTING_VPN(nm_connection_get_setting(connection, NM_TYPE_SETTING_VPN));
178 widget = glade_xml_get_widget (priv->xml, "address-entry");
179 value = nm_setting_vpn_get_data_item (settings, "address");
180 if (value)
181 gtk_entry_set_text (GTK_ENTRY (widget), value);
182 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
183
184 widget = glade_xml_get_widget (priv->xml, "certificate-button");
185 value = nm_setting_vpn_get_data_item (settings, "certificate");
186 if (value)
187 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
188 g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
189
190 widget = glade_xml_get_widget (priv->xml, "user-label");
191 gtk_widget_set_no_show_all (widget, TRUE);
192 widget = glade_xml_get_widget (priv->xml, "user-entry");
193 gtk_widget_set_no_show_all (widget, TRUE);
194 value = nm_setting_vpn_get_data_item (settings, "user");
195 if (value)
196 gtk_entry_set_text (GTK_ENTRY (widget), value);
197 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
198
199 widget = glade_xml_get_widget (priv->xml, "method-combo");
200 gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Certificate/private key"));
201 gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Certificate/ssh-agent"));
202 gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("EAP"));
203 value = nm_setting_vpn_get_data_item (settings, "method");
204 if (value) {
205 if (g_strcmp0 (value, "key") == 0) {
206 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
207 }
208 if (g_strcmp0 (value, "agent") == 0) {
209 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
210 }
211 if (g_strcmp0 (value, "eap") == 0) {
212 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
213 }
214 }
215 if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
216 {
217 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
218 }
219 update_layout (widget, priv);
220 g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (settings_changed_cb), self);
221
222 widget = glade_xml_get_widget (priv->xml, "usercert-label");
223 gtk_widget_set_no_show_all (widget, TRUE);
224 widget = glade_xml_get_widget (priv->xml, "usercert-button");
225 gtk_widget_set_no_show_all (widget, TRUE);
226 value = nm_setting_vpn_get_data_item (settings, "usercert");
227 if (value)
228 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
229 g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
230
231 widget = glade_xml_get_widget (priv->xml, "userkey-label");
232 gtk_widget_set_no_show_all (widget, TRUE);
233 widget = glade_xml_get_widget (priv->xml, "userkey-button");
234 gtk_widget_set_no_show_all (widget, TRUE);
235 value = nm_setting_vpn_get_data_item (settings, "userkey");
236 if (value)
237 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value);
238 g_signal_connect (G_OBJECT (widget), "selection-changed", G_CALLBACK (settings_changed_cb), self);
239
240 widget = glade_xml_get_widget (priv->xml, "virtual-check");
241 value = nm_setting_vpn_get_data_item (settings, "virtual");
242 if (value && strcmp(value, "yes") == 0)
243 {
244 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
245 }
246 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
247
248 widget = glade_xml_get_widget (priv->xml, "encap-check");
249 value = nm_setting_vpn_get_data_item (settings, "encap");
250 if (value && strcmp(value, "yes") == 0)
251 {
252 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
253 }
254 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
255
256 widget = glade_xml_get_widget (priv->xml, "ipcomp-check");
257 value = nm_setting_vpn_get_data_item (settings, "ipcomp");
258 if (value && strcmp(value, "yes") == 0)
259 {
260 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
261 }
262 g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (settings_changed_cb), self);
263
264 return TRUE;
265 }
266
267 static GObject *
268 get_widget (NMVpnPluginUiWidgetInterface *iface)
269 {
270 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface);
271 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
272
273 return G_OBJECT (priv->widget);
274 }
275
276 static gboolean
277 update_connection (NMVpnPluginUiWidgetInterface *iface,
278 NMConnection *connection,
279 GError **error)
280 {
281 StrongswanPluginUiWidget *self = STRONGSWAN_PLUGIN_UI_WIDGET (iface);
282 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (self);
283 NMSettingVPN *settings;
284 GtkWidget *widget;
285 gboolean active;
286 char *str;
287
288 if (!check_validity (self, error))
289 return FALSE;
290 settings = NM_SETTING_VPN (nm_setting_vpn_new ());
291
292 g_object_set (settings, NM_SETTING_VPN_SERVICE_TYPE,
293 NM_DBUS_SERVICE_STRONGSWAN, NULL);
294
295 widget = glade_xml_get_widget (priv->xml, "address-entry");
296 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
297 if (str && strlen (str)) {
298 nm_setting_vpn_add_data_item (settings, "address", str);
299 }
300
301 widget = glade_xml_get_widget (priv->xml, "certificate-button");
302 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
303 if (str) {
304 nm_setting_vpn_add_data_item (settings, "certificate", str);
305 }
306
307 widget = glade_xml_get_widget (priv->xml, "method-combo");
308 switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)))
309 {
310 default:
311 case 0:
312 widget = glade_xml_get_widget (priv->xml, "userkey-button");
313 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
314 if (str) {
315 nm_setting_vpn_add_data_item (settings, "userkey", str);
316 }
317 widget = glade_xml_get_widget (priv->xml, "usercert-button");
318 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
319 if (str) {
320 nm_setting_vpn_add_data_item (settings, "usercert", str);
321 }
322 str = "key";
323 break;
324 case 1:
325 widget = glade_xml_get_widget (priv->xml, "usercert-button");
326 str = (char *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
327 if (str) {
328 nm_setting_vpn_add_data_item (settings, "usercert", str);
329 }
330 str = "agent";
331 break;
332 case 2:
333 widget = glade_xml_get_widget (priv->xml, "user-entry");
334 str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
335 if (str && strlen (str)) {
336 nm_setting_vpn_add_data_item (settings, "user", str);
337 }
338 str = "eap";
339 break;
340 }
341 nm_setting_vpn_add_data_item (settings, "method", str);
342
343 widget = glade_xml_get_widget (priv->xml, "virtual-check");
344 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
345 nm_setting_vpn_add_data_item (settings, "virtual", active ? "yes" : "no");
346
347 widget = glade_xml_get_widget (priv->xml, "encap-check");
348 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
349 nm_setting_vpn_add_data_item (settings, "encap", active ? "yes" : "no");
350
351 widget = glade_xml_get_widget (priv->xml, "ipcomp-check");
352 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
353 nm_setting_vpn_add_data_item (settings, "ipcomp", active ? "yes" : "no");
354
355 nm_connection_add_setting (connection, NM_SETTING (settings));
356 return TRUE;
357 }
358
359 static gboolean
360 save_secrets (NMVpnPluginUiWidgetInterface *iface,
361 NMConnection *connection, GError **error)
362 {
363 /* no secrets to save */
364 return TRUE;
365 }
366
367 static NMVpnPluginUiWidgetInterface *
368 nm_vpn_plugin_ui_widget_interface_new (NMConnection *connection, GError **error)
369 {
370 NMVpnPluginUiWidgetInterface *object;
371 StrongswanPluginUiWidgetPrivate *priv;
372 char *glade_file;
373
374 if (error)
375 g_return_val_if_fail (*error == NULL, NULL);
376
377 object = NM_VPN_PLUGIN_UI_WIDGET_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI_WIDGET, NULL));
378 if (!object) {
379 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not create strongswan object");
380 return NULL;
381 }
382
383 priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (object);
384
385 glade_file = g_strdup_printf ("%s/%s", GLADEDIR, "nm-strongswan-dialog.glade");
386 priv->xml = glade_xml_new (glade_file, "strongswan-vbox", GETTEXT_PACKAGE);
387 if (priv->xml == NULL) {
388 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0,
389 "could not load required resources at %s", glade_file);
390 g_free (glade_file);
391 g_object_unref (object);
392 return NULL;
393 }
394 g_free (glade_file);
395
396 priv->widget = glade_xml_get_widget (priv->xml, "strongswan-vbox");
397 if (!priv->widget) {
398 g_set_error (error, STRONGSWAN_PLUGIN_UI_ERROR, 0, "could not load UI widget");
399 g_object_unref (object);
400 return NULL;
401 }
402 g_object_ref_sink (priv->widget);
403
404 if (!init_plugin_ui (STRONGSWAN_PLUGIN_UI_WIDGET (object), connection, error)) {
405 g_object_unref (object);
406 return NULL;
407 }
408
409 return object;
410 }
411
412 static void
413 dispose (GObject *object)
414 {
415 StrongswanPluginUiWidget *plugin = STRONGSWAN_PLUGIN_UI_WIDGET (object);
416 StrongswanPluginUiWidgetPrivate *priv = STRONGSWAN_PLUGIN_UI_WIDGET_GET_PRIVATE (plugin);
417
418 if (priv->widget)
419 g_object_unref (priv->widget);
420
421 if (priv->xml)
422 g_object_unref (priv->xml);
423
424 G_OBJECT_CLASS (strongswan_plugin_ui_widget_parent_class)->dispose (object);
425 }
426
427 static void
428 strongswan_plugin_ui_widget_class_init (StrongswanPluginUiWidgetClass *req_class)
429 {
430 GObjectClass *object_class = G_OBJECT_CLASS (req_class);
431
432 g_type_class_add_private (req_class, sizeof (StrongswanPluginUiWidgetPrivate));
433
434 object_class->dispose = dispose;
435 }
436
437 static void
438 strongswan_plugin_ui_widget_init (StrongswanPluginUiWidget *plugin)
439 {
440 }
441
442 static void
443 strongswan_plugin_ui_widget_interface_init (NMVpnPluginUiWidgetInterface *iface_class)
444 {
445 /* interface implementation */
446 iface_class->get_widget = get_widget;
447 iface_class->update_connection = update_connection;
448 iface_class->save_secrets = save_secrets;
449 }
450
451 static guint32
452 get_capabilities (NMVpnPluginUiInterface *iface)
453 {
454 return 0;
455 }
456
457 static NMVpnPluginUiWidgetInterface *
458 ui_factory (NMVpnPluginUiInterface *iface, NMConnection *connection, GError **error)
459 {
460 return nm_vpn_plugin_ui_widget_interface_new (connection, error);
461 }
462
463 static void
464 get_property (GObject *object, guint prop_id,
465 GValue *value, GParamSpec *pspec)
466 {
467 switch (prop_id) {
468 case NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME:
469 g_value_set_string (value, STRONGSWAN_PLUGIN_NAME);
470 break;
471 case NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC:
472 g_value_set_string (value, STRONGSWAN_PLUGIN_DESC);
473 break;
474 case NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE:
475 g_value_set_string (value, STRONGSWAN_PLUGIN_SERVICE);
476 break;
477 default:
478 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
479 break;
480 }
481 }
482
483 static void
484 strongswan_plugin_ui_class_init (StrongswanPluginUiClass *req_class)
485 {
486 GObjectClass *object_class = G_OBJECT_CLASS (req_class);
487
488 object_class->get_property = get_property;
489
490 g_object_class_override_property (object_class,
491 NM_VPN_PLUGIN_UI_INTERFACE_PROP_NAME,
492 NM_VPN_PLUGIN_UI_INTERFACE_NAME);
493
494 g_object_class_override_property (object_class,
495 NM_VPN_PLUGIN_UI_INTERFACE_PROP_DESC,
496 NM_VPN_PLUGIN_UI_INTERFACE_DESC);
497
498 g_object_class_override_property (object_class,
499 NM_VPN_PLUGIN_UI_INTERFACE_PROP_SERVICE,
500 NM_VPN_PLUGIN_UI_INTERFACE_SERVICE);
501 }
502
503 static void
504 strongswan_plugin_ui_init (StrongswanPluginUi *plugin)
505 {
506 }
507
508 static void
509 strongswan_plugin_ui_interface_init (NMVpnPluginUiInterface *iface_class)
510 {
511 /* interface implementation */
512 iface_class->ui_factory = ui_factory;
513 iface_class->get_capabilities = get_capabilities;
514 /* TODO: implement delete_connection to purge associated secrets */
515 }
516
517
518 G_MODULE_EXPORT NMVpnPluginUiInterface *
519 nm_vpn_plugin_ui_factory (GError **error)
520 {
521 if (error)
522 g_return_val_if_fail (*error == NULL, NULL);
523
524 return NM_VPN_PLUGIN_UI_INTERFACE (g_object_new (STRONGSWAN_TYPE_PLUGIN_UI, NULL));
525 }
526