5462450242e387a864ed98200df511194f8a5f09
[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_AUTOCAP |
77 HILDON_GTK_INPUT_MODE_ALPHA |
78 HILDON_GTK_INPUT_MODE_NUMERIC);
79 GtkWidget *ncap = hildon_caption_new (group,
80 "Name",
81 name,
82 NULL,
83 HILDON_CAPTION_OPTIONAL);
84 gtk_box_pack_start (GTK_BOX (vbox), ncap, TRUE, TRUE, 0);
85
86 GtkWidget *host = hildon_entry_new (HILDON_SIZE_AUTO);
87 hildon_gtk_entry_set_placeholder_text (GTK_ENTRY (host), "Hostname / IP");
88 hildon_gtk_entry_set_input_mode (GTK_ENTRY (host),
89 HILDON_GTK_INPUT_MODE_FULL);
90 GtkWidget *hcap = hildon_caption_new (group,
91 "Host",
92 host,
93 NULL,
94 HILDON_CAPTION_OPTIONAL);
95 gtk_box_pack_start (GTK_BOX (vbox), hcap, TRUE, TRUE, 0);
96
97 GtkWidget *cert = hildon_button_new (HILDON_SIZE_FINGER_HEIGHT |
98 HILDON_SIZE_AUTO_WIDTH,
99 HILDON_BUTTON_ARRANGEMENT_VERTICAL);
100 hildon_button_set_text (HILDON_BUTTON (cert),
101 "Host or CA Certificate",
102 "None");
103 hildon_button_set_alignment (HILDON_BUTTON (cert), 0, 0.5, 1, 1);
104 g_signal_connect (cert, "clicked", G_CALLBACK (select_cert), dialog);
105 GtkWidget *ccap = hildon_caption_new (group,
106 "Certificate",
107 cert,
108 NULL,
109 HILDON_CAPTION_OPTIONAL);
110 gtk_box_pack_start (GTK_BOX (vbox), ccap, TRUE, TRUE, 0);
111
112 GtkWidget *user = hildon_entry_new (HILDON_SIZE_AUTO);
113 hildon_gtk_entry_set_placeholder_text (GTK_ENTRY (user), "Username");
114 hildon_gtk_entry_set_input_mode (GTK_ENTRY (user),
115 HILDON_GTK_INPUT_MODE_FULL);
116 GtkWidget *ucap = hildon_caption_new (group,
117 "Username",
118 user,
119 NULL,
120 HILDON_CAPTION_OPTIONAL);
121 gtk_box_pack_start (GTK_BOX (vbox), ucap, TRUE, TRUE, 0);
122
123 GtkWidget *pass = hildon_entry_new (HILDON_SIZE_AUTO);
124 hildon_gtk_entry_set_placeholder_text (GTK_ENTRY (pass), "Password");
125 hildon_gtk_entry_set_input_mode (GTK_ENTRY (pass),
126 HILDON_GTK_INPUT_MODE_FULL |
127 HILDON_GTK_INPUT_MODE_INVISIBLE);
128 GtkWidget *pcap = hildon_caption_new (group,
129 "Password",
130 pass,
131 NULL,
132 HILDON_CAPTION_OPTIONAL);
133 gtk_box_pack_start (GTK_BOX (vbox), pcap, TRUE, TRUE, 0);
134
135 if (conn)
136 {
137 gchar *c_name, *c_host, *c_cert, *c_user, *c_pass;
138 g_object_get (conn,
139 "name", &c_name,
140 "host", &c_host,
141 "cert", &c_cert,
142 "user", &c_user,
143 "pass", &c_pass,
144 NULL);
145 gtk_entry_set_text (GTK_ENTRY (name), c_name);
146 gtk_entry_set_text (GTK_ENTRY (host), c_host);
147 hildon_button_set_value (HILDON_BUTTON (cert),
148 c_cert ? c_cert : "None");
149 gtk_entry_set_text (GTK_ENTRY (user), c_user);
150 gtk_entry_set_text (GTK_ENTRY (pass), c_pass);
151 g_free (c_name);
152 g_free (c_host);
153 g_free (c_cert);
154 g_free (c_user);
155 g_free (c_pass);
156 }
157
158 gtk_widget_show_all(dialog);
159
160 guint retval = gtk_dialog_run (GTK_DIALOG (dialog));
161 if (retval == GTK_RESPONSE_OK)
162 {
163 const gchar *c_name, *c_cert;
164 c_name = gtk_entry_get_text (GTK_ENTRY (name));
165 if (!conn)
166 {
167 conn = strongswan_connection_new (c_name);
168 }
169 c_cert = hildon_button_get_value (HILDON_BUTTON (cert));
170 c_cert = strcmp (c_cert, "None") ? c_cert : NULL;
171 g_object_set (conn,
172 "name", c_name,
173 "host", gtk_entry_get_text (GTK_ENTRY (host)),
174 "cert", c_cert,
175 "user", gtk_entry_get_text (GTK_ENTRY (user)),
176 "pass", gtk_entry_get_text (GTK_ENTRY (pass)),
177 NULL);
178 strongswan_connections_save_connection (ListDialog.conns, conn);
179 }
180 gtk_widget_destroy (dialog);
181 }
182
183 /**
184 * Creates a dialog showing a list of all connections
185 */
186 static void
187 create_list_dialog (gpointer *parent)
188 {
189 GtkWidget *dialog = gtk_dialog_new_with_buttons (
190 "strongSwan Connections",
191 GTK_WINDOW (parent),
192 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR,
193 GTK_STOCK_NEW,
194 RESPONSE_NEW,
195 GTK_STOCK_EDIT,
196 RESPONSE_EDIT,
197 GTK_STOCK_DELETE,
198 RESPONSE_DELETE,
199 GTK_STOCK_CLOSE,
200 GTK_RESPONSE_OK,
201 NULL);
202 ListDialog.dialog = dialog;
203 GtkWidget *vbox = GTK_DIALOG (dialog)->vbox;
204
205 ListDialog.conns = strongswan_connections_new ();
206
207 GtkTreeModel *model = strongswan_connections_get_model (ListDialog.conns);
208 ListDialog.list = gtk_tree_view_new_with_model (model);
209 g_object_unref (model);
210
211 GtkTreeSelection *selection;
212 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ListDialog.list));
213 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
214
215 GtkTreeViewColumn *column = gtk_tree_view_column_new ();
216 strongswan_connections_setup_column_renderers (ListDialog.conns,
217 GTK_CELL_LAYOUT (column));
218 gtk_tree_view_append_column (GTK_TREE_VIEW (ListDialog.list), column);
219
220 gtk_box_pack_start (GTK_BOX (vbox),
221 ListDialog.list,
222 TRUE,
223 TRUE,
224 HILDON_MARGIN_DEFAULT);
225 gtk_widget_show_all (dialog);
226 gtk_widget_hide (dialog);
227 }
228
229 /**
230 * Get the name fo the selected connection in the list (or NULL).
231 * The name has to be freed.
232 */
233 static gchar *
234 get_selected (void)
235 {
236 GtkTreeView *tree = GTK_TREE_VIEW(ListDialog.list);
237 GtkTreeSelection *selection;
238 GtkTreeModel *model;
239 GtkTreeIter iter;
240 gchar *name = NULL;
241
242 selection = gtk_tree_view_get_selection (tree);
243 model = gtk_tree_view_get_model (tree);
244 if (gtk_tree_selection_get_selected (selection, &model, &iter))
245 {
246 gtk_tree_model_get(model, &iter, 0, &name, -1);
247 }
248 return name;
249 }
250
251 /**
252 * main callback for control panel plugins
253 */
254 osso_return_t execute(osso_context_t *osso, gpointer data,
255 gboolean user_activated)
256 {
257 gint response;
258
259 create_list_dialog (data);
260
261 if (!user_activated)
262 {
263 /* load state */
264 }
265
266 do
267 {
268 gchar *selected;
269 response = gtk_dialog_run (GTK_DIALOG (ListDialog.dialog));
270 switch (response)
271 {
272 case RESPONSE_NEW:
273 {
274 edit_connection (data, NULL);
275 break;
276 }
277 case RESPONSE_EDIT:
278 {
279 StrongswanConnection *conn;
280 selected = get_selected ();
281 conn = strongswan_connections_get_connection (ListDialog.conns,
282 selected);
283 if (conn)
284 {
285 edit_connection (data, conn);
286 }
287 else
288 {
289 hildon_banner_show_information (NULL, NULL,
290 "Select a connection first");
291 }
292 g_free (selected);
293 break;
294 }
295 case RESPONSE_DELETE:
296 {
297 GtkWidget *confirm;
298 gint retval;
299 gchar *msg;
300 selected = get_selected ();
301 if (!selected)
302 {
303 hildon_banner_show_information (NULL, NULL,
304 "Select a connection first");
305 break;
306 }
307 msg = g_strdup_printf ("Delete connection?\n%s", selected);
308 confirm = hildon_note_new_confirmation (data, msg);
309 retval = gtk_dialog_run (GTK_DIALOG (confirm));
310 if (retval == GTK_RESPONSE_OK)
311 {
312 strongswan_connections_remove_connection (ListDialog.conns,
313 selected);
314 }
315 gtk_widget_destroy (confirm);
316 g_free (msg);
317 g_free (selected);
318 break;
319 }
320 default:
321 break;
322 }
323 }
324 while (response > 0);
325
326 gtk_widget_destroy (ListDialog.dialog);
327 g_object_unref (ListDialog.conns);
328 return OSSO_OK;
329 }
330
331 /**
332 * callback called in case state has to be saved
333 */
334 osso_return_t save_state(osso_context_t *osso, gpointer data)
335 {
336 /* save state */
337 return OSSO_OK;
338 }
339