1 // gnoMint: a graphical interface for managing a certification authority
2 // Copyright (C) 2006-2009 David Marín Carreño <davefx@gmail.com>
3 //
4 // This file is part of gnoMint.
5 //
6 // gnoMint is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 #include <libintl.h>
21 #include <glib.h>
22 #include <glib/gi18n.h>
23 #include <gtk/gtk.h>
24
25 #include <stdlib.h>
26
27 #include "main.h"
28 #include "ca.h"
29 #include "dialog.h"
30 #include "tls.h"
31 #include "ca_file.h"
32 #include "preferences-gui.h"
33
34 #define GNOMINT_MIME_TYPE "application/x-gnomint"
35
36 GtkBuilder * main_window_gtkb = NULL;
37 GtkBuilder * csr_popup_menu_gtkb = NULL;
38 GtkBuilder * cert_popup_menu_gtkb = NULL;
39
40 gchar * gnomint_current_opened_file = NULL;
41
42 static GtkRecentManager *recent_manager;
43
44 void __recent_add_utf8_filename (const gchar *utf8_filename);
45 void __disable_widget (gchar *widget_name);
46 void __enable_widget (gchar *widget_name);
47 GtkWidget * __recent_create_menu (void);
48 void __recent_add_utf8_filename (const gchar *utf8_filename);
49
50
51
__disable_widget(gchar * widget_name)52 void __disable_widget (gchar *widget_name)
53 {
54 GtkWidget * widget = NULL;
55
56 widget = GTK_WIDGET(gtk_builder_get_object (main_window_gtkb, widget_name));
57
58 gtk_widget_set_sensitive (widget, FALSE);
59 }
60
__enable_widget(gchar * widget_name)61 void __enable_widget (gchar *widget_name)
62 {
63 GtkWidget * widget = NULL;
64
65 widget = GTK_WIDGET(gtk_builder_get_object (main_window_gtkb, widget_name));
66
67 gtk_widget_set_sensitive (widget, TRUE);
68 }
69
70 /*****************************************************************************/
71 /* Create a menu of recent files. */
72 /*****************************************************************************/
__recent_create_menu(void)73 GtkWidget * __recent_create_menu (void)
74 {
75 GtkWidget *recent_menu;
76 GtkRecentFilter *recent_filter;
77
78 recent_menu = gtk_recent_chooser_menu_new_for_manager (recent_manager);
79 gtk_recent_chooser_menu_set_show_numbers (GTK_RECENT_CHOOSER_MENU (recent_menu), FALSE);
80 gtk_recent_chooser_set_show_icons (GTK_RECENT_CHOOSER (recent_menu), TRUE);
81 gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (recent_menu), 4);
82 gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (recent_menu), GTK_RECENT_SORT_MRU);
83 gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (recent_menu), TRUE);
84
85 recent_filter = gtk_recent_filter_new ();
86 gtk_recent_filter_add_mime_type (recent_filter, GNOMINT_MIME_TYPE);
87 gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (recent_menu), recent_filter);
88
89 return recent_menu;
90 }
91
92
main(int argc,char * argv[])93 int main (int argc,
94 char *argv[])
95 {
96 gchar *defaultfile = NULL;
97 GOptionContext *ctx;
98 GError *err = NULL;
99 GOptionEntry entries[] = {
100 { NULL }
101 };
102
103 GtkWidget * recent_menu = NULL;
104 gchar * size_str = NULL;
105
106 #ifdef ENABLE_NLS
107 bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
108 bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
109 textdomain (GETTEXT_PACKAGE);
110 #endif
111
112 g_set_application_name (PACKAGE);
113 g_set_prgname (PACKAGE);
114
115 tls_init ();
116
117 g_thread_init (NULL);
118 gtk_init (&argc, &argv);
119
120 preferences_gui_set_csr_visible_callback (ca_update_csr_view);
121 preferences_gui_set_revoked_visible_callback (ca_update_revoked_view);
122
123 preferences_init (argc, argv);
124
125 ctx = g_option_context_new (_("- A graphical Certification Authority manager"));
126 g_option_context_add_main_entries (ctx, entries, GETTEXT_PACKAGE);
127 if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
128 g_print (_("Failed to initialize: %s\n"), err->message);
129 g_error_free (err);
130 return 1;
131 }
132
133 main_window_gtkb = gtk_builder_new();
134 gtk_builder_add_from_file (main_window_gtkb,
135 g_build_filename (PACKAGE_DATA_DIR, "gnomint", "main_window.ui", NULL),
136 NULL);
137
138 csr_popup_menu_gtkb = gtk_builder_new();
139 gtk_builder_add_from_file (csr_popup_menu_gtkb,
140 g_build_filename (PACKAGE_DATA_DIR, "gnomint", "csr_popup_menu.ui", NULL),
141 NULL);
142
143 cert_popup_menu_gtkb = gtk_builder_new();
144 gtk_builder_add_from_file (cert_popup_menu_gtkb,
145 g_build_filename (PACKAGE_DATA_DIR, "gnomint", "certificate_popup_menu.ui", NULL),
146 NULL);
147
148
149 size_str = preferences_get_size ();
150 if (size_str) {
151 gchar ** result = NULL;
152 guint width, height;
153
154 result = g_strsplit_set (size_str, "(,)", -1);
155
156 if (result[0] && result[1]) {
157 width = atoi (result[1]);
158 if (result[2]) {
159 height = atoi (result[2]);
160 gtk_window_resize (GTK_WINDOW(gtk_builder_get_object(main_window_gtkb, "main_window1")), width, height);
161 }
162
163 }
164
165 g_free (size_str);
166 g_strfreev (result);
167 }
168 ca_update_revoked_view (preferences_get_revoked_visible(), FALSE);
169 ca_update_csr_view (preferences_get_crq_visible(), FALSE);
170
171
172 gtk_builder_connect_signals (main_window_gtkb, NULL);
173 gtk_builder_connect_signals (cert_popup_menu_gtkb, NULL);
174 gtk_builder_connect_signals (csr_popup_menu_gtkb, NULL);
175
176 recent_manager = gtk_recent_manager_get_default ();
177 recent_menu = __recent_create_menu();
178 g_signal_connect (G_OBJECT (recent_menu), "item-activated",
179 G_CALLBACK (on_open_recent_activate), NULL);
180 gtk_menu_item_set_submenu (GTK_MENU_ITEM (gtk_builder_get_object (main_window_gtkb, "openrecentsmenuitem")), recent_menu);
181
182
183 __disable_widget ("new_certificate1");
184 __disable_widget ("save_as1");
185 __disable_widget ("properties1");
186 __disable_widget ("preferences1");
187
188 dialog_establish_refresh_function (ca_refresh_model_callback);
189
190
191 if (argc >= 2 && ca_open (g_strdup(argv[1]), TRUE)) {
192 /* The file has opened OK */
193 __recent_add_utf8_filename (argv[1]);
194 } else {
195 /* No arguments, or failure when opening file */
196 defaultfile = g_build_filename (g_get_home_dir(), ".gnomint", "default.gnomint", NULL);
197 __recent_add_utf8_filename (defaultfile);
198 ca_open (defaultfile, TRUE);
199 }
200
201 gtk_main ();
202
203 return 0;
204 }
205
206
207
on_main_window1_delete(GtkWidget * widget,GdkEvent * event,gpointer user_data)208 G_MODULE_EXPORT gboolean on_main_window1_delete (GtkWidget *widget,
209 GdkEvent *event,
210 gpointer user_data)
211 {
212 GtkWindow *window = GTK_WINDOW(widget);
213 int width, height;
214 gchar *new_size_value;
215
216 gtk_window_get_size (window, &width, &height);
217 new_size_value = g_strdup_printf ("(%d,%d)", width, height);
218
219 preferences_set_size (new_size_value);
220
221 g_free (new_size_value);
222 preferences_deinit();
223
224 exit (0);
225 return TRUE;
226 }
227
__recent_add_utf8_filename(const gchar * utf8_filename)228 void __recent_add_utf8_filename (const gchar *utf8_filename)
229 {
230 GtkRecentData *recent_data;
231 gchar *filename;
232 gchar *uri;
233 gchar *pwd;
234
235 static gchar *groups[2] = {
236 "gnomint",
237 NULL
238 };
239
240
241 recent_data = g_slice_new (GtkRecentData);
242
243 recent_data->display_name = NULL;
244 recent_data->description = NULL;
245 recent_data->mime_type = GNOMINT_MIME_TYPE;
246 recent_data->app_name = (gchar *) g_get_application_name ();
247 recent_data->app_exec = g_strjoin (" ", g_get_prgname (), "%f", NULL);
248 recent_data->groups = groups;
249 recent_data->is_private = FALSE;
250
251 filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
252 if ( filename != NULL )
253 {
254
255 if (! g_path_is_absolute (filename)) {
256 gchar *absolute_filename;
257
258 pwd = g_get_current_dir ();
259 absolute_filename = g_build_filename (pwd, filename, NULL);
260 g_free (pwd);
261 g_free (filename);
262 filename = absolute_filename;
263 }
264
265
266 uri = g_filename_to_uri (filename, NULL, NULL);
267 if ( uri != NULL )
268 {
269
270 gtk_recent_manager_add_full (recent_manager, uri, recent_data);
271 g_free (uri);
272
273 }
274 g_free (filename);
275
276 }
277
278 g_free (recent_data->app_exec);
279 g_slice_free (GtkRecentData, recent_data);
280
281 }
282
on_new1_activate(GtkMenuItem * menuitem,gpointer user_data)283 G_MODULE_EXPORT void on_new1_activate (GtkMenuItem *menuitem, gpointer user_data)
284 {
285 gchar *filename;
286 gchar *error = NULL;
287
288 GtkWidget *dialog, *widget;
289
290 widget = GTK_WIDGET(gtk_builder_get_object (main_window_gtkb, "main_window"));
291
292 dialog = gtk_file_chooser_dialog_new (_("Create new CA database"),
293 GTK_WINDOW(widget),
294 GTK_FILE_CHOOSER_ACTION_SAVE,
295 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
296 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
297 NULL);
298 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
299
300
301 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
302 {
303 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
304 gtk_widget_destroy (dialog);
305 } else {
306 gtk_widget_destroy (dialog);
307 return;
308 }
309
310 if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
311 /* The file already exists. The user has confirmed its overwriting.
312 So we, first, rename it to "filename~", after deleting "filename~" if it already exists */
313
314 gchar *backup_filename = g_strdup_printf ("%s~", filename);
315 if (g_file_test (backup_filename, G_FILE_TEST_EXISTS)) {
316 g_remove (backup_filename);
317 }
318
319 g_rename (filename, backup_filename);
320
321 g_free (backup_filename);
322 }
323
324 error = ca_file_create (filename);
325 if (error) {
326 dialog = gtk_message_dialog_new (GTK_WINDOW(widget),
327 GTK_DIALOG_DESTROY_WITH_PARENT,
328 GTK_MESSAGE_ERROR,
329 GTK_BUTTONS_CLOSE,
330 _("Problem when creating '%s' CA database:\n%s"),
331 filename, error);
332
333 gtk_dialog_run (GTK_DIALOG(dialog));
334
335 return;
336 }
337
338 if (! ca_open (filename, FALSE)) {
339 dialog = gtk_message_dialog_new (GTK_WINDOW(widget),
340 GTK_DIALOG_DESTROY_WITH_PARENT,
341 GTK_MESSAGE_ERROR,
342 GTK_BUTTONS_CLOSE,
343 _("Problem when opening new '%s' CA database"),
344 filename);
345
346 gtk_dialog_run (GTK_DIALOG(dialog));
347
348 gtk_widget_destroy (dialog);
349 } else {
350 __recent_add_utf8_filename (filename);
351 }
352 return;
353
354 }
355
on_open1_activate(GtkMenuItem * menuitem,gpointer user_data)356 G_MODULE_EXPORT void on_open1_activate (GtkMenuItem *menuitem, gpointer user_data)
357 {
358 gchar *filename;
359
360 GtkWidget *dialog, *widget;
361
362 widget = GTK_WIDGET(gtk_builder_get_object (main_window_gtkb, "main_window"));
363
364 dialog = gtk_file_chooser_dialog_new (_("Open CA database"),
365 GTK_WINDOW(widget),
366 GTK_FILE_CHOOSER_ACTION_OPEN,
367 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
368 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
369 NULL);
370
371 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
372 {
373 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
374 gtk_widget_destroy (dialog);
375 } else {
376 gtk_widget_destroy (dialog);
377 return;
378 }
379
380
381
382 if (! ca_open (filename, FALSE)) {
383 dialog = gtk_message_dialog_new (GTK_WINDOW(widget),
384 GTK_DIALOG_DESTROY_WITH_PARENT,
385 GTK_MESSAGE_ERROR,
386 GTK_BUTTONS_CLOSE,
387 _("Problem when opening '%s' CA database"),
388 filename);
389
390 gtk_dialog_run (GTK_DIALOG(dialog));
391
392 gtk_widget_destroy (dialog);
393 } else {
394 __recent_add_utf8_filename (filename);
395 }
396 return;
397 }
398
on_open_recent_activate(GtkRecentChooser * chooser,gpointer user_data)399 void on_open_recent_activate (GtkRecentChooser *chooser, gpointer user_data)
400 {
401 GtkRecentInfo *item;
402 gchar *filename;
403 gchar *utf8_filename = NULL;
404 GtkWidget *dialog;
405 const gchar *uri;
406
407 g_return_if_fail (chooser && GTK_IS_RECENT_CHOOSER(chooser));
408
409 item = gtk_recent_chooser_get_current_item (chooser);
410 if (!item)
411 return;
412
413 uri = gtk_recent_info_get_uri (item);
414
415 filename = g_filename_from_uri (uri, NULL, NULL);
416 if ( filename != NULL )
417 {
418 utf8_filename = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
419 g_free (filename);
420 }
421
422 if (! utf8_filename || ! ca_open (utf8_filename, FALSE)) {
423 dialog = gtk_message_dialog_new (NULL,
424 GTK_DIALOG_DESTROY_WITH_PARENT,
425 GTK_MESSAGE_ERROR,
426 GTK_BUTTONS_CLOSE,
427 _("Problem when opening '%s' CA database"),
428 utf8_filename);
429
430 gtk_dialog_run (GTK_DIALOG(dialog));
431
432 gtk_widget_destroy (dialog);
433 } else {
434 __recent_add_utf8_filename (utf8_filename);
435 }
436
437 gtk_recent_info_unref (item);
438
439
440 return;
441 }
442
443
on_save_as1_activate(GtkMenuItem * menuitem,gpointer user_data)444 G_MODULE_EXPORT void on_save_as1_activate (GtkMenuItem *menuitem, gpointer user_data)
445 {
446 gchar *filename;
447
448 GtkWidget *dialog, *widget;
449
450 widget = GTK_WIDGET(gtk_builder_get_object (main_window_gtkb, "main_window"));
451
452 dialog = gtk_file_chooser_dialog_new (_("Save CA database as..."),
453 GTK_WINDOW(widget),
454 GTK_FILE_CHOOSER_ACTION_SAVE,
455 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
456 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
457 NULL);
458 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
459
460 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
461 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
462 gtk_widget_destroy (dialog);
463 } else {
464 gtk_widget_destroy (dialog);
465 return;
466 }
467
468 if (ca_file_save_as (filename))
469 __recent_add_utf8_filename (filename);
470
471 }
472
473
474
on_quit1_activate(GtkMenuItem * menuitem,gpointer user_data)475 G_MODULE_EXPORT void on_quit1_activate (GtkMenuItem *menuitem, gpointer user_data)
476 {
477 on_main_window1_delete(NULL, NULL, NULL);
478 }
479
480
481
482
483
484 /*
485 *
486 * HELP MENU CALLBACKS
487 *
488 */
489
on_about1_activate(GtkMenuItem * menuitem,gpointer user_data)490 G_MODULE_EXPORT void on_about1_activate (GtkMenuItem *menuitem, gpointer user_data)
491 {
492
493 GtkWidget *widget;
494 gchar *authors[2];
495
496 widget = GTK_WIDGET(gtk_builder_get_object (main_window_gtkb, "main_window"));
497
498 authors[0] = PACKAGE_AUTHORS;
499 authors[1] = NULL;
500
501 gtk_show_about_dialog (GTK_WINDOW(widget),
502 "version", PACKAGE_VERSION,
503 "copyright", PACKAGE_COPYRIGHT,
504 "comments", _("gnoMint is a program for creating and managing Certification Authorities, and their certificates"),
505 "license", _("This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. \n\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."),
506 "wrap_license", TRUE,
507 "website", PACKAGE_WEBSITE,
508 "authors", authors,
509 "translator_credits", _("translator-credits"),
510 NULL);
511 }
512