Adding, editing and deleting connections is now possible in the settings plugin.
[strongswan.git] / src / frontends / maemo / src / strongswan-settings.c
1 /*
2 * Copyright (C) 2010 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <hildon-cp-plugin/hildon-cp-plugin-interface.h>
17 #include <gtk/gtk.h>
18 #include <hildon/hildon.h>
19 #include <hildon/hildon-file-chooser-dialog.h>
20
21 #include <string.h>
22
23 #include "strongswan-connections.h"
24
25 enum {
26 RESPONSE_NEW = 1,
27 RESPONSE_EDIT,
28 RESPONSE_DELETE
29 };
30
31 struct {
32 GtkWidget *dialog;
33 GtkWidget *list;
34 StrongswanConnections *conns;
35 } ListDialog = { 0, };
36
37 /**
38 * Callback to select a certificate
39 */
40 void select_cert(HildonButton *button, gpointer user_data)
41 {
42 GtkWidget *selector = hildon_file_chooser_dialog_new (GTK_WINDOW (user_data), GTK_FILE_CHOOSER_ACTION_OPEN);
43 gtk_widget_show_all (selector);
44 if (gtk_dialog_run (GTK_DIALOG (selector)) == GTK_RESPONSE_OK)
45 {
46 gchar *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (selector));
47 hildon_button_set_value (button, file);
48 g_free(file);
49 }
50 gtk_widget_destroy (selector);
51 }
52
53 /**
54 * Shows a dialog to edit the given connection (or create a new one,
55 * if conn is NULL)
56 */
57 static void
58 edit_connection (gpointer *parent, StrongswanConnection *conn)
59 {
60 GtkWidget *dialog;
61 dialog = gtk_dialog_new_with_buttons (
62 conn ? "Edit Connection" : "New Connection",
63 GTK_WINDOW (parent),
64 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
65 GTK_STOCK_CANCEL,
66 GTK_RESPONSE_CANCEL,
67 GTK_STOCK_SAVE,
68 GTK_RESPONSE_OK,
69 NULL);
70 GtkWidget *vbox = GTK_DIALOG (dialog)->vbox;
71 GtkSizeGroup *group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
72
73 GtkWidget *name = hildon_entry_new (HILDON_SIZE_AUTO);
74 hildon_gtk_entry_set_placeholder_text (GTK_ENTRY (name), "Connection Name");
75 hildon_gtk_entry_set_input_mode (GTK_ENTRY (name),
76 HILDON_GTK_INPUT_MODE_ALPHA |
77 HILDON_GTK_INPUT_MODE_NUMERIC);
78 GtkWidget *ncap = hildon_caption_new (group,
79 "Name",
80 name,
81 NULL,
82 HILDON_CAPTION_OPTIONAL);
83 gtk_box_pack_start (GTK_BOX (vbox), ncap, TRUE, TRUE, 0);
84
85 GtkWidget *host = hildon_entry_new (HILDON_SIZE_AUTO);
86 hildon_gtk_entry_set_placeholder_text (GTK_ENTRY (host), "Hostname / IP");
87 GtkWidget *hcap = hildon_caption_new (group,
88 "Host",
89 host,
90 NULL,
91 HILDON_CAPTION_OPTIONAL);
92 gtk_box_pack_start (GTK_BOX (vbox), hcap, TRUE, TRUE, 0);
93
94 GtkWidget *cert = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT |
95 HILDON_SIZE_AUTO_WIDTH,
96 HILDON_BUTTON_ARRANGEMENT_VERTICAL);
97 hildon_button_set_text (HILDON_BUTTON (cert),
98 "Host or CA Certificate",
99 "None");
100 hildon_button_set_alignment (HILDON_BUTTON (cert), 0, 0.5, 1, 1);
101 g_signal_connect (cert, "clicked", G_CALLBACK (select_cert), dialog);
102 GtkWidget *ccap = hildon_caption_new (group,
103 "Certificate",
104 cert,
105 NULL,
106 HILDON_CAPTION_OPTIONAL);
107 gtk_box_pack_start (GTK_BOX (vbox), ccap, TRUE, TRUE, 0);
108
109 GtkWidget *user = hildon_entry_new (HILDON_SIZE_AUTO);
110 hildon_gtk_entry_set_placeholder_text (GTK_ENTRY (user), "Username");
111 GtkWidget *ucap = hildon_caption_new (group,
112 "Username",
113 user,
114 NULL,
115 HILDON_CAPTION_OPTIONAL);
116 gtk_box_pack_start (GTK_BOX (vbox), ucap, TRUE, TRUE, 0);
117
118 GtkWidget *pass = hildon_entry_new (HILDON_SIZE_AUTO);
119 hildon_gtk_entry_set_placeholder_text (GTK_ENTRY (pass), "Password");
120 hildon_gtk_entry_set_input_mode (GTK_ENTRY (pass),
121 HILDON_GTK_INPUT_MODE_FULL |
122 HILDON_GTK_INPUT_MODE_INVISIBLE);
123 GtkWidget *pcap = hildon_caption_new (group,
124 "Password",
125 pass,
126 NULL,
127 HILDON_CAPTION_OPTIONAL);
128 gtk_box_pack_start (GTK_BOX (vbox), pcap, TRUE, TRUE, 0);
129
130 if (conn)
131 {
132 gchar *c_name, *c_host, *c_cert, *c_user, *c_pass;
133 g_object_get (conn,
134 "name", &c_name,
135 "host", &c_host,
136 "cert", &c_cert,
137 "user", &c_user,
138 "pass", &c_pass,
139 NULL);
140 gtk_entry_set_text (GTK_ENTRY (name), c_name);
141 gtk_entry_set_text (GTK_ENTRY (host), c_host);
142 hildon_button_set_value (HILDON_BUTTON (cert),
143 c_cert ? c_cert : "None");
144 gtk_entry_set_text (GTK_ENTRY (user), c_user);
145 gtk_entry_set_text (GTK_ENTRY (pass), c_pass);
146 g_free (c_name);
147 g_free (c_host);
148 g_free (c_cert);
149 g_free (c_user);
150 g_free (c_pass);
151 }
152
153 gtk_widget_show_all(dialog);
154
155 guint retval = gtk_dialog_run (GTK_DIALOG (dialog));
156 if (retval == GTK_RESPONSE_OK)
157 {
158 const gchar *c_name, *c_cert;
159 c_name = gtk_entry_get_text (GTK_ENTRY (name));
160 if (!conn)
161 {
162 conn = strongswan_connection_new (c_name);
163 }
164 c_cert = hildon_button_get_value (HILDON_BUTTON (cert));
165 c_cert = strcmp (c_cert, "None") ? c_cert : NULL;
166 g_object_set (conn,
167 "name", c_name,
168 "host", gtk_entry_get_text (GTK_ENTRY (host)),
169 "cert", c_cert,
170 "user", gtk_entry_get_text (GTK_ENTRY (user)),
171 "pass", gtk_entry_get_text (GTK_ENTRY (pass)),
172 NULL);
173 strongswan_connections_save_connection (ListDialog.conns, conn);
174 }
175 gtk_widget_destroy (dialog);
176 }
177
178 /**
179 * Creates a dialog showing a list of all connections
180 */
181 static void
182 create_list_dialog (gpointer *parent)
183 {
184 GtkWidget *dialog = gtk_dialog_new_with_buttons (
185 "strongSwan Connections",
186 GTK_WINDOW (parent),
187 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
188 GTK_STOCK_NEW,
189 RESPONSE_NEW,
190 GTK_STOCK_EDIT,
191 RESPONSE_EDIT,
192 GTK_STOCK_DELETE,
193 RESPONSE_DELETE,
194 GTK_STOCK_CLOSE,
195 GTK_RESPONSE_OK,
196 NULL);
197 ListDialog.dialog = dialog;
198 GtkWidget *vbox = GTK_DIALOG (dialog)->vbox;
199
200 ListDialog.conns = strongswan_connections_new ();
201
202 GtkTreeModel *model = strongswan_connections_get_model (ListDialog.conns);
203 ListDialog.list = gtk_tree_view_new_with_model (model);
204 g_object_unref (model);
205
206 GtkTreeSelection *selection;
207 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ListDialog.list));
208 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
209
210 GtkTreeViewColumn *column = gtk_tree_view_column_new ();
211 strongswan_connections_setup_column_renderers (ListDialog.conns,
212 GTK_CELL_LAYOUT (column));
213 gtk_tree_view_append_column (GTK_TREE_VIEW (ListDialog.list), column);
214
215 gtk_box_pack_start (GTK_BOX (vbox),
216 ListDialog.list,
217 TRUE,
218 TRUE,
219 HILDON_MARGIN_DEFAULT);
220 gtk_widget_show_all (dialog);
221 gtk_widget_hide (dialog);
222 }
223
224 /**
225 * Get the name fo the selected connection in the list (or NULL).
226 * The name has to be freed.
227 */
228 static gchar *
229 get_selected (void)
230 {
231 GtkTreeView *tree = GTK_TREE_VIEW(ListDialog.list);
232 GtkTreeSelection *selection;
233 GtkTreeModel *model;
234 GtkTreeIter iter;
235 gchar *name = NULL;
236
237 selection = gtk_tree_view_get_selection (tree);
238 model = gtk_tree_view_get_model (tree);
239 if (gtk_tree_selection_get_selected (selection, &model, &iter))
240 {
241 gtk_tree_model_get(model, &iter, 0, &name, -1);
242 }
243 return name;
244 }
245
246 /**
247 * main callback for control panel plugins
248 */
249 osso_return_t execute(osso_context_t *osso, gpointer data,
250 gboolean user_activated)
251 {
252 gint response;
253
254 create_list_dialog (data);
255
256 if (!user_activated)
257 {
258 /* load state */
259 }
260
261 do
262 {
263 gchar *selected;
264 response = gtk_dialog_run (GTK_DIALOG (ListDialog.dialog));
265 switch (response)
266 {
267 case RESPONSE_NEW:
268 {
269 edit_connection (data, NULL);
270 break;
271 }
272 case RESPONSE_EDIT:
273 {
274 StrongswanConnection *conn;
275 selected = get_selected ();
276 conn = strongswan_connections_get_connection (ListDialog.conns,
277 selected);
278 if (conn)
279 {
280 edit_connection (data, conn);
281 }
282 else
283 {
284 hildon_banner_show_information (NULL, NULL,
285 "Select a connection first");
286 }
287 g_free (selected);
288 break;
289 }
290 case RESPONSE_DELETE:
291 {
292 GtkWidget *confirm;
293 gint retval;
294 gchar *msg;
295 selected = get_selected ();
296 if (!selected)
297 {
298 hildon_banner_show_information (NULL, NULL,
299 "Select a connection first");
300 break;
301 }
302 msg = g_strdup_printf ("Delete connection?\n%s", selected);
303 confirm = hildon_note_new_confirmation (data, msg);
304 retval = gtk_dialog_run (GTK_DIALOG (confirm));
305 if (retval == GTK_RESPONSE_OK)
306 {
307 strongswan_connections_remove_connection (ListDialog.conns,
308 selected);
309 }
310 gtk_widget_destroy (confirm);
311 g_free (msg);
312 g_free (selected);
313 break;
314 }
315 default:
316 break;
317 }
318 }
319 while (response > 0);
320
321 gtk_widget_destroy (ListDialog.dialog);
322 g_object_unref (ListDialog.conns);
323 return OSSO_OK;
324 }
325
326 /**
327 * callback called in case state has to be saved
328 */
329 osso_return_t save_state(osso_context_t *osso, gpointer data)
330 {
331 /* save state */
332 return OSSO_OK;
333 }
334