RSSyl: Allow use of .netrc by libcurl. Bug/enhancement #3309, by Vincent Pelletier
[claws.git] / src / plugins / pgpcore / prefs_gpg.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 2004-2012 the Claws Mail team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  * 
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #include "claws-features.h"
23 #endif
24
25 #include <gtk/gtk.h>
26 #include <glib.h>
27 #include <glib/gi18n.h>
28
29 #include "defs.h"
30 #include "gtk/gtkutils.h"
31 #include "utils.h" 
32 #include "prefs.h"
33 #include "prefs_gtk.h"
34 #include "prefs_gpg.h"
35 #include "sgpgme.h"
36
37 struct GPGConfig prefs_gpg;
38
39 static PrefParam param[] = {
40         /* Privacy */
41         {"auto_check_signatures", "FALSE",
42          &prefs_gpg.auto_check_signatures, P_BOOL,
43          NULL, NULL, NULL},
44         {"autocompletion", "FALSE",
45          &prefs_gpg.autocompletion, P_BOOL,
46          NULL, NULL, NULL},
47         {"use_gpg_agent", "TRUE", &prefs_gpg.use_gpg_agent, P_BOOL,
48          NULL, NULL, NULL},
49         {"store_passphrase", "FALSE", &prefs_gpg.store_passphrase, P_BOOL,
50          NULL, NULL, NULL},
51         {"store_passphrase_timeout", "0",
52          &prefs_gpg.store_passphrase_timeout, P_INT,
53          NULL, NULL, NULL},
54         {"passphrase_grab", "FALSE", &prefs_gpg.passphrase_grab, P_BOOL,
55          NULL, NULL, NULL},
56         {"gpg_warning", "TRUE", &prefs_gpg.gpg_warning, P_BOOL,
57          NULL, NULL, NULL},
58         {"gpg_ask_create_key", "TRUE", &prefs_gpg.gpg_ask_create_key, P_BOOL,
59          NULL, NULL, NULL},
60         {"skip_encryption_warning", "", &prefs_gpg.skip_encryption_warning, P_STRING,
61          NULL, NULL, NULL},
62
63         {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
64 };
65
66 static gchar *saved_gpg_agent_info = NULL;
67
68 struct GPGPage
69 {
70         PrefsPage page;
71
72         GtkWidget *checkbtn_auto_check_signatures;
73         GtkWidget *checkbtn_autocompletion;
74         GtkWidget *checkbtn_use_gpg_agent;
75         GtkWidget *checkbtn_store_passphrase;  
76         GtkWidget *spinbtn_store_passphrase;  
77         GtkWidget *checkbtn_passphrase_grab;  
78         GtkWidget *checkbtn_gpg_warning;
79 };
80
81 static void prefs_gpg_create_widget_func(PrefsPage *_page,
82                                          GtkWindow *window,
83                                          gpointer data)
84 {
85         struct GPGPage *page = (struct GPGPage *) _page;
86         struct GPGConfig *config;
87
88         GtkWidget *checkbtn_use_gpg_agent;
89         GtkWidget *checkbtn_passphrase_grab;
90         GtkWidget *checkbtn_store_passphrase;
91         GtkWidget *checkbtn_auto_check_signatures;
92         GtkWidget *checkbtn_autocompletion;
93         GtkWidget *checkbtn_gpg_warning;
94         GtkWidget *hbox1;
95         GtkWidget *vbox1, *vbox2;
96         GtkWidget *label_expire1;
97         GtkAdjustment *spinbtn_store_passphrase_adj;
98         GtkWidget *spinbtn_store_passphrase;
99         GtkWidget *label_expire2;
100         GtkWidget *frame_passphrase;
101
102         vbox1 = gtk_vbox_new (FALSE, VSPACING);
103         gtk_widget_show (vbox1);
104         gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER);
105
106         vbox2 = gtk_vbox_new (FALSE, 0);
107         gtk_widget_show (vbox2);
108         gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
109
110         PACK_CHECK_BUTTON (vbox2, checkbtn_auto_check_signatures,
111                         _("Automatically check signatures"));
112
113         PACK_CHECK_BUTTON (vbox2, checkbtn_autocompletion,
114                         _("Use keyring for address autocompletion"));
115
116         vbox2 = gtkut_get_options_frame(vbox1, &frame_passphrase, _("Passphrase"));
117
118         PACK_CHECK_BUTTON (vbox2, checkbtn_use_gpg_agent,
119                         _("Use gpg-agent to manage passwords"));
120         if (saved_gpg_agent_info == NULL)
121                 gtk_widget_set_sensitive(checkbtn_use_gpg_agent, FALSE);
122
123         PACK_CHECK_BUTTON (vbox2, checkbtn_store_passphrase,
124                         _("Store passphrase in memory"));
125
126         SET_TOGGLE_SENSITIVITY_REVERSE(checkbtn_use_gpg_agent, checkbtn_store_passphrase);
127
128         hbox1 = gtk_hbox_new (FALSE, 8);
129         gtk_widget_show (hbox1);
130         gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0);
131
132         SET_TOGGLE_SENSITIVITY_REVERSE(checkbtn_use_gpg_agent, hbox1);
133
134         label_expire1 = gtk_label_new(_("Expire after"));
135         gtk_widget_show (label_expire1);
136         gtk_box_pack_start (GTK_BOX (hbox1), label_expire1, FALSE, FALSE, 0);
137
138         spinbtn_store_passphrase_adj =
139             GTK_ADJUSTMENT(gtk_adjustment_new(1, 0, 1440, 1, 10, 0));
140         spinbtn_store_passphrase =
141             gtk_spin_button_new(GTK_ADJUSTMENT
142                                 (spinbtn_store_passphrase_adj), 1, 0);
143         gtk_widget_show(spinbtn_store_passphrase);
144         gtk_box_pack_start(GTK_BOX(hbox1), spinbtn_store_passphrase, FALSE,
145                            FALSE, 0);
146         gtk_widget_set_size_request(spinbtn_store_passphrase, 64, -1);
147         CLAWS_SET_TIP(spinbtn_store_passphrase,
148                              _
149                              ("Setting to '0' will store the passphrase for the whole session"));
150         gtk_spin_button_set_numeric(GTK_SPIN_BUTTON
151                                     (spinbtn_store_passphrase), TRUE);
152
153         label_expire2 = gtk_label_new(_("minute(s)"));
154         gtk_widget_show(label_expire2);
155         gtk_box_pack_start(GTK_BOX(hbox1), label_expire2, FALSE, FALSE, 0);
156         gtk_misc_set_alignment(GTK_MISC(label_expire2), 0.0, 0.5);
157
158         SET_TOGGLE_SENSITIVITY (checkbtn_store_passphrase, label_expire1);
159         SET_TOGGLE_SENSITIVITY (checkbtn_store_passphrase, spinbtn_store_passphrase);
160         SET_TOGGLE_SENSITIVITY (checkbtn_store_passphrase, label_expire2);
161
162         PACK_CHECK_BUTTON (vbox2, checkbtn_passphrase_grab,
163                         _("Grab input while entering a passphrase"));
164
165         vbox2 = gtk_vbox_new (FALSE, 0);
166         gtk_widget_show (vbox2);
167         gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
168
169         PACK_CHECK_BUTTON (vbox2, checkbtn_gpg_warning,
170                         _("Display warning on start-up if GnuPG doesn't work"));
171
172         config = prefs_gpg_get_config();
173
174         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_auto_check_signatures), config->auto_check_signatures);
175         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_autocompletion), config->autocompletion);
176         if (!getenv("GPG_AGENT_INFO"))
177                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_use_gpg_agent), FALSE);
178         else
179                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_use_gpg_agent), config->use_gpg_agent);
180         if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbtn_use_gpg_agent)))
181                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_store_passphrase), config->store_passphrase);
182         gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbtn_store_passphrase), (float) config->store_passphrase_timeout);
183         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_passphrase_grab), config->passphrase_grab);
184         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_gpg_warning), config->gpg_warning);
185
186         page->checkbtn_auto_check_signatures = checkbtn_auto_check_signatures;
187         page->checkbtn_autocompletion = checkbtn_autocompletion;
188         page->checkbtn_store_passphrase = checkbtn_store_passphrase;
189         page->spinbtn_store_passphrase = spinbtn_store_passphrase;
190         page->checkbtn_passphrase_grab = checkbtn_passphrase_grab;
191         page->checkbtn_gpg_warning = checkbtn_gpg_warning;
192         page->checkbtn_use_gpg_agent = checkbtn_use_gpg_agent;
193         page->page.widget = vbox1;
194 }
195
196 static void prefs_gpg_destroy_widget_func(PrefsPage *_page)
197 {
198 }
199
200 static void prefs_gpg_save_func(PrefsPage *_page)
201 {
202         struct GPGPage *page = (struct GPGPage *) _page;
203         GPGConfig *config = prefs_gpg_get_config();
204
205         config->auto_check_signatures =
206                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_auto_check_signatures));
207         config->autocompletion =
208                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_autocompletion));
209         config->use_gpg_agent = 
210                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_use_gpg_agent));
211         config->store_passphrase = 
212                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_store_passphrase));
213         config->store_passphrase_timeout = 
214                 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(page->spinbtn_store_passphrase));
215         config->passphrase_grab = 
216                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_passphrase_grab));
217         config->gpg_warning = 
218                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_gpg_warning));
219
220         prefs_gpg_enable_agent(config->use_gpg_agent);
221
222         prefs_gpg_save_config();
223 }
224
225 struct GPGAccountPage
226 {
227         PrefsPage page;
228
229         GtkWidget *key_default;
230         GtkWidget *key_by_from;
231         GtkWidget *key_custom;
232         GtkWidget *keyid;
233         GtkWidget *keyid_label;
234         GtkWidget *new_key_label;
235         GtkWidget *new_key_btn;
236         GtkWidget *new_key_box;
237
238         PrefsAccount *account;
239 };
240
241 void key_custom_toggled(GtkToggleButton *togglebutton, gpointer user_data)
242 {
243         struct GPGAccountPage *page = (struct GPGAccountPage *) user_data;
244         gboolean active;
245
246         active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom));
247         gtk_widget_set_sensitive(GTK_WIDGET(page->keyid_label), active);
248         gtk_widget_set_sensitive(GTK_WIDGET(page->keyid), active);
249         if (!active)
250                 gtk_editable_delete_text(GTK_EDITABLE(page->keyid), 0, -1);
251 }
252
253 static void prefs_gpg_update_sens(struct GPGAccountPage *page)
254 {
255         gboolean active;
256         active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom));
257         if (sgpgme_has_secret_key()) {
258                 gtk_widget_hide(page->new_key_box);
259                 gtk_widget_set_sensitive(page->key_default, TRUE);
260                 gtk_widget_set_sensitive(page->key_by_from, TRUE);
261                 gtk_widget_set_sensitive(page->key_custom, TRUE);
262                 gtk_widget_set_sensitive(page->keyid, active);
263                 gtk_widget_set_sensitive(page->keyid_label, active);
264         } else {
265                 gtk_widget_show(page->new_key_box);
266                 gtk_widget_set_sensitive(page->key_default, FALSE);
267                 gtk_widget_set_sensitive(page->key_by_from, FALSE);
268                 gtk_widget_set_sensitive(page->key_custom, FALSE);
269                 gtk_widget_set_sensitive(page->keyid, FALSE);
270                 gtk_widget_set_sensitive(page->keyid_label, FALSE);
271         }
272 }
273
274 static void new_key_clicked(GtkWidget *widget, gpointer user_data)
275 {
276         struct GPGAccountPage *page = (struct GPGAccountPage *) user_data;
277         sgpgme_create_secret_key(page->account, FALSE);
278         prefs_gpg_update_sens(page);
279 }
280
281 static void prefs_gpg_account_create_widget_func(PrefsPage *_page,
282                                                  GtkWindow *window,
283                                                  gpointer data)
284 {
285         struct GPGAccountPage *page = (struct GPGAccountPage *) _page;
286         PrefsAccount *account = (PrefsAccount *) data;
287         GPGAccountConfig *config;
288
289         GtkWidget *vbox;
290         GtkWidget *frame1;
291         GtkWidget *vbox2;
292         GtkWidget *hbox;
293         GSList *key_group = NULL;
294         GtkWidget *key_default;
295         GtkWidget *key_by_from;
296         GtkWidget *key_custom;
297         GtkWidget *keyid_label;
298         GtkWidget *keyid;
299         GtkWidget *image;
300         GtkWidget *new_key_label;
301         GtkWidget *new_key_btn;
302         GtkWidget *new_key_box;
303
304         vbox = gtk_vbox_new(FALSE, VSPACING);
305         gtk_container_set_border_width (GTK_CONTAINER (vbox), VBOX_BORDER);
306         gtk_widget_show(vbox);
307
308         vbox2 = gtkut_get_options_frame(vbox, &frame1, _("Sign key"));
309
310         hbox = gtk_hbox_new (FALSE, 5);
311         gtk_widget_show (hbox);
312         gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
313         gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
314
315         key_default = gtk_radio_button_new_with_label(key_group,
316                         _("Use default GnuPG key"));
317         key_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(key_default));
318         gtk_widget_show(key_default);
319         gtk_box_pack_start(GTK_BOX(hbox), key_default, FALSE, FALSE, 0);
320
321         hbox = gtk_hbox_new (FALSE, 5);
322         gtk_widget_show (hbox);
323         gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
324         gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
325
326         key_by_from = gtk_radio_button_new_with_label(key_group,
327                 _("Select key by your email address"));
328         key_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(key_by_from));
329         gtk_widget_show(key_by_from);
330         gtk_box_pack_start(GTK_BOX(hbox), key_by_from, FALSE, FALSE, 0);
331
332         hbox = gtk_hbox_new (FALSE, 5);
333         gtk_widget_show (hbox);
334         gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
335         gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
336
337         key_custom = gtk_radio_button_new_with_label(key_group,
338                 _("Specify key manually"));
339         key_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(key_custom));
340         gtk_widget_show(key_custom);
341         gtk_box_pack_start(GTK_BOX(hbox), key_custom, FALSE, FALSE, 0);
342
343         hbox = gtk_hbox_new (FALSE, 5);
344         gtk_widget_show (hbox);
345         gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
346         gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
347
348         keyid_label = gtk_label_new(_("User or key ID:"));
349         gtk_widget_show(keyid_label);
350         gtk_label_set_justify(GTK_LABEL(keyid_label), GTK_JUSTIFY_LEFT);
351         gtk_box_pack_start(GTK_BOX(hbox), keyid_label, FALSE, FALSE, 0);
352
353         keyid = gtk_entry_new();
354         gtk_widget_show(keyid);
355         gtk_box_pack_start(GTK_BOX(hbox), keyid, FALSE, FALSE, 0);
356
357         config = prefs_gpg_account_get_config(account);
358         switch (config->sign_key) {
359         case SIGN_KEY_DEFAULT:
360                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(key_default), TRUE);
361                 gtk_widget_set_sensitive(GTK_WIDGET(keyid_label), FALSE);
362                 gtk_widget_set_sensitive(GTK_WIDGET(keyid), FALSE);
363                 break;
364         case SIGN_KEY_BY_FROM:
365                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(key_by_from), TRUE);
366                 gtk_widget_set_sensitive(GTK_WIDGET(keyid_label), FALSE);
367                 gtk_widget_set_sensitive(GTK_WIDGET(keyid), FALSE);
368                 break;
369         case SIGN_KEY_CUSTOM:
370                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(key_custom), TRUE);
371                 gtk_widget_set_sensitive(GTK_WIDGET(keyid_label), TRUE);
372                 gtk_widget_set_sensitive(GTK_WIDGET(keyid), TRUE);
373                 break;
374         }
375
376         hbox = gtk_hbox_new (FALSE, 5);
377         gtk_widget_show (hbox);
378         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
379
380         new_key_box = gtk_hbox_new(FALSE, 6);
381         gtk_widget_show(new_key_box);
382         gtk_box_pack_start(GTK_BOX(hbox), new_key_box, FALSE, FALSE, 0);
383
384         image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING,
385                         GTK_ICON_SIZE_SMALL_TOOLBAR);
386
387         gtk_box_pack_start(GTK_BOX(new_key_box), image, FALSE, FALSE, 0);
388         new_key_label = gtk_label_new(
389                         _("No secret key found."));
390         gtk_box_pack_start(GTK_BOX(new_key_box), new_key_label, FALSE, FALSE, 0);
391
392         new_key_btn = gtk_button_new_with_label(_("Generate a new key pair"));
393         gtk_widget_show(new_key_btn);
394         gtk_box_pack_start(GTK_BOX(hbox), new_key_btn, FALSE, FALSE, 0);
395
396         if (config->sign_key_id != NULL)
397                 gtk_entry_set_text(GTK_ENTRY(keyid), config->sign_key_id);
398
399         g_signal_connect(G_OBJECT(key_custom), "toggled", G_CALLBACK(key_custom_toggled), page);
400         g_signal_connect(G_OBJECT(new_key_btn), "clicked", G_CALLBACK(new_key_clicked), page);
401
402         page->key_default = key_default;
403         page->key_by_from = key_by_from;
404         page->key_custom = key_custom;
405         page->keyid = keyid;
406         page->keyid_label = keyid_label;
407         page->new_key_box = new_key_box;
408
409         page->page.widget = vbox;
410         page->account = account;
411         prefs_gpg_update_sens(page);
412 }
413
414 static void prefs_gpg_account_destroy_widget_func(PrefsPage *_page)
415 {
416         /* nothing to do here */
417 }
418
419 static void prefs_gpg_account_save_func(PrefsPage *_page)
420 {
421         struct GPGAccountPage *page = (struct GPGAccountPage *) _page;
422         GPGAccountConfig *config;
423
424         config = prefs_gpg_account_get_config(page->account);
425
426         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_default)))
427                 config->sign_key = SIGN_KEY_DEFAULT;
428         else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_by_from)))
429                 config->sign_key = SIGN_KEY_BY_FROM;
430         else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom))) {
431                 config->sign_key = SIGN_KEY_CUSTOM;
432                 g_free(config->sign_key_id);
433                 config->sign_key_id = gtk_editable_get_chars(GTK_EDITABLE(page->keyid), 0, -1);
434         }
435
436         prefs_gpg_account_set_config(page->account, config);
437         prefs_gpg_account_free_config(config);
438 }
439
440 GPGConfig *prefs_gpg_get_config(void)
441 {
442         return &prefs_gpg;
443 }
444
445 void prefs_gpg_save_config(void)
446 {
447         PrefFile *pfile;
448         gchar *rcpath;
449
450         debug_print("Saving GPG config\n");
451
452         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
453         pfile = prefs_write_open(rcpath);
454         g_free(rcpath);
455         if (!pfile || (prefs_set_block_label(pfile, "GPG") < 0))
456                 return;
457
458         if (prefs_write_param(param, pfile->fp) < 0) {
459                 g_warning("failed to write GPG configuration to file\n");
460                 prefs_file_close_revert(pfile);
461                 return;
462         }
463         if (fprintf(pfile->fp, "\n") < 0) {
464                 FILE_OP_ERROR(rcpath, "fprintf");
465                 prefs_file_close_revert(pfile);
466         } else
467                 prefs_file_close(pfile);
468 }
469
470 struct GPGAccountConfig *prefs_gpg_account_get_config(PrefsAccount *account)
471 {
472         GPGAccountConfig *config;
473         const gchar *confstr;
474         gchar **strv;
475
476         config = g_new0(GPGAccountConfig, 1);
477         config->sign_key = SIGN_KEY_DEFAULT;
478         config->sign_key_id = NULL;
479
480         confstr = prefs_account_get_privacy_prefs(account, "gpg");
481         if (confstr == NULL)
482                 return config;
483
484         strv = g_strsplit(confstr, ";", 0);
485         if (strv[0] != NULL) {
486                 if (!strcmp(strv[0], "DEFAULT"))
487                         config->sign_key = SIGN_KEY_DEFAULT;
488                 if (!strcmp(strv[0], "BY_FROM"))
489                         config->sign_key = SIGN_KEY_BY_FROM;
490                 if (!strcmp(strv[0], "CUSTOM")) {
491                         if (strv[1] != NULL) {
492                                 config->sign_key = SIGN_KEY_CUSTOM;
493                                 config->sign_key_id = g_strdup(strv[1]);
494                         } else
495                                 config->sign_key = SIGN_KEY_DEFAULT;
496                 }
497         }
498         g_strfreev(strv);
499
500         return config;
501 }
502
503 void prefs_gpg_account_set_config(PrefsAccount *account, GPGAccountConfig *config)
504 {
505         gchar *confstr = NULL;
506
507         switch (config->sign_key) {
508         case SIGN_KEY_DEFAULT:
509                 confstr = g_strdup("DEFAULT");
510                 break;
511         case SIGN_KEY_BY_FROM:
512                 confstr = g_strdup("BY_FROM");
513                 break;
514         case SIGN_KEY_CUSTOM:
515                 confstr = g_strdup_printf("CUSTOM;%s", config->sign_key_id);
516                 break;
517         default:
518                 confstr = g_strdup("");
519                 g_warning("prefs_gpg_account_set_config: bad sign_key val\n");
520         }
521
522         prefs_account_set_privacy_prefs(account, "gpg", confstr);
523
524         g_free(confstr);
525 }
526
527 void prefs_gpg_account_free_config(GPGAccountConfig *config)
528 {
529         g_free(config->sign_key_id);
530         g_free(config);
531 }
532
533 static struct GPGPage gpg_page;
534 static struct GPGAccountPage gpg_account_page;
535
536 void prefs_gpg_enable_agent(gboolean enable)
537 {
538         if (enable) {
539                 if (saved_gpg_agent_info) {
540                         g_setenv("GPG_AGENT_INFO",
541                                  saved_gpg_agent_info, TRUE);
542                         debug_print("set GPG_AGENT_INFO=%s\n", 
543                                 saved_gpg_agent_info);
544                 } else { 
545                         debug_print("Can't enable gpg agent (no GPG_AGENT_INFO)\n");
546                 }
547         } else {
548                 if (saved_gpg_agent_info) {
549                         g_unsetenv("GPG_AGENT_INFO");
550                         debug_print("unset GPG_AGENT_INFO=%s\n", 
551                                 saved_gpg_agent_info);
552                 } else {
553                         debug_print("Can't disable gpg agent (no GPG_AGENT_INFO)\n");
554                 }
555         }
556 }
557
558 void prefs_gpg_init()
559 {
560         static gchar *path[3];
561         gchar *rcpath;
562         const gchar *tmp = NULL;
563
564         prefs_set_default(param);
565         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
566         prefs_read_config(param, "GPG", rcpath, NULL);
567         g_free(rcpath);
568
569         path[0] = _("Plugins");
570         path[1] = _("GPG");
571         path[2] = NULL;
572
573         gpg_page.page.path = path;
574         gpg_page.page.create_widget = prefs_gpg_create_widget_func;
575         gpg_page.page.destroy_widget = prefs_gpg_destroy_widget_func;
576         gpg_page.page.save_page = prefs_gpg_save_func;
577         gpg_page.page.weight = 30.0;
578
579         prefs_gtk_register_page((PrefsPage *) &gpg_page);
580
581         gpg_account_page.page.path = path;
582         gpg_account_page.page.create_widget = prefs_gpg_account_create_widget_func;
583         gpg_account_page.page.destroy_widget = prefs_gpg_account_destroy_widget_func;
584         gpg_account_page.page.save_page = prefs_gpg_account_save_func;
585         gpg_account_page.page.weight = 30.0;
586
587         prefs_account_register_page((PrefsPage *) &gpg_account_page);
588         
589         tmp = g_getenv("GPG_AGENT_INFO");
590         if (tmp)
591                 saved_gpg_agent_info = g_strdup(tmp);
592
593         prefs_gpg_enable_agent(prefs_gpg_get_config()->use_gpg_agent);
594 }
595
596 void prefs_gpg_done()
597 {
598         prefs_gtk_unregister_page((PrefsPage *) &gpg_page);
599         prefs_account_unregister_page((PrefsPage *) &gpg_account_page);
600         prefs_gpg_enable_agent(TRUE);
601 }
602
603 gboolean prefs_gpg_should_skip_encryption_warning(const gchar *systemid)
604 {
605         gchar **systems = NULL;
606         int i = 0;
607         if (prefs_gpg_get_config()->skip_encryption_warning == NULL)
608                 return FALSE;
609         systems = g_strsplit(prefs_gpg_get_config()->skip_encryption_warning,
610                                 ",", -1);
611         while (systems && systems[i]) {
612                 debug_print(" cmp %s %s\n", systems[i], systemid);
613                 if (!strcmp(systems[i],systemid)) {
614                         g_strfreev(systems);
615                         return TRUE;
616                 }
617                 i++;
618         }
619         g_strfreev(systems);
620         return FALSE;
621 }
622
623 void prefs_gpg_add_skip_encryption_warning(const gchar *systemid)
624 {
625         gchar *tmp = NULL;
626         if (prefs_gpg_get_config()->skip_encryption_warning == NULL)
627                 prefs_gpg_get_config()->skip_encryption_warning =
628                         g_strdup_printf("%s,", systemid);
629         else if (!prefs_gpg_should_skip_encryption_warning(systemid)) {
630                 tmp = g_strdup_printf("%s%s,",
631                         prefs_gpg_get_config()->skip_encryption_warning,
632                         systemid);
633                 g_free(prefs_gpg_get_config()->skip_encryption_warning);
634                 prefs_gpg_get_config()->skip_encryption_warning = tmp;
635         }
636         prefs_gpg_save_config();
637 }
638
639 void prefs_gpg_remove_skip_encryption_warning(const gchar *systemid)
640 {
641         gchar **systems = NULL;
642         int i = 0;
643         if (prefs_gpg_get_config()->skip_encryption_warning == NULL)
644                 return;
645
646         if (prefs_gpg_should_skip_encryption_warning(systemid)) {
647                 systems = g_strsplit(prefs_gpg_get_config()->skip_encryption_warning,
648                                 ",", -1);
649                 g_free(prefs_gpg_get_config()->skip_encryption_warning);
650                 prefs_gpg_get_config()->skip_encryption_warning = NULL;
651
652                 while (systems && systems[i]) {
653                         if (!strcmp(systems[i],systemid)) {
654                                 i++;
655                                 continue;
656                         }
657                         prefs_gpg_add_skip_encryption_warning(systems[i]);
658                         i++;
659                 }
660                 
661                 g_strfreev(systems);
662         }
663         prefs_gpg_save_config();
664 }
665
666 gboolean prefs_gpg_auto_check_signatures(void)
667 {
668         return prefs_gpg_get_config()->auto_check_signatures;
669 }