Improve some sieve-related translations
[claws.git] / src / plugins / pgpcore / prefs_gpg.c
blob2dbd5d5051ed3488334227d7ba9164d91776e642
1 /*
2 * Claws Mail -- a GTK based, lightweight, and fast e-mail client
3 * Copyright (C) 2004-2019 the Claws Mail team
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.
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.
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/>.
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #include "claws-features.h"
22 #endif
24 #include <gtk/gtk.h>
25 #include <glib.h>
26 #include <glib/gi18n.h>
28 #include <gtk/filesel.h>
30 #include "defs.h"
31 #include "gtk/gtkutils.h"
32 #include "utils.h"
33 #include "prefs.h"
34 #include "prefs_common.h"
35 #include "prefs_gtk.h"
36 #include "prefs_gpg.h"
37 #include "sgpgme.h"
39 struct GPGConfig prefs_gpg;
41 static PrefParam param[] = {
42 /* Privacy */
43 {"auto_check_signatures", "FALSE",
44 &prefs_gpg.auto_check_signatures, P_BOOL,
45 NULL, NULL, NULL},
46 {"autocompletion", "FALSE",
47 &prefs_gpg.autocompletion, P_BOOL,
48 NULL, NULL, NULL},
49 {"autocompletion_limit", "0",
50 &prefs_gpg.autocompletion_limit, P_INT,
51 NULL, NULL, NULL},
52 {"use_gpg_agent", "TRUE", &prefs_gpg.use_gpg_agent, P_BOOL,
53 NULL, NULL, NULL},
54 {"store_passphrase", "FALSE", &prefs_gpg.store_passphrase, P_BOOL,
55 NULL, NULL, NULL},
56 {"store_passphrase_timeout", "0",
57 &prefs_gpg.store_passphrase_timeout, P_INT,
58 NULL, NULL, NULL},
59 {"passphrase_grab", "FALSE", &prefs_gpg.passphrase_grab, P_BOOL,
60 NULL, NULL, NULL},
61 {"gpg_warning", "TRUE", &prefs_gpg.gpg_warning, P_BOOL,
62 NULL, NULL, NULL},
63 {"gpg_ask_create_key", "TRUE", &prefs_gpg.gpg_ask_create_key, P_BOOL,
64 NULL, NULL, NULL},
65 {"skip_encryption_warning", "", &prefs_gpg.skip_encryption_warning, P_STRING,
66 NULL, NULL, NULL},
67 {"gpg_path", "", &prefs_gpg.gpg_path, P_STRING,
68 NULL, NULL, NULL},
70 {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
73 static gchar *saved_gpg_agent_info = NULL;
74 static void gpg_path_browse_cb(GtkWidget *widget, gpointer data);
76 struct GPGPage
78 PrefsPage page;
80 GtkWidget *checkbtn_auto_check_signatures;
81 GtkWidget *checkbtn_autocompletion;
82 GtkWidget *checkbtn_use_gpg_agent;
83 GtkWidget *checkbtn_store_passphrase;
84 GtkWidget *spinbtn_store_passphrase;
85 GtkWidget *checkbtn_passphrase_grab;
86 GtkWidget *checkbtn_gpg_warning;
87 GtkWidget *gpg_path;
90 struct GPGAccountPage
92 PrefsPage page;
94 GtkWidget *key_default;
95 GtkWidget *key_by_from;
96 GtkWidget *key_custom;
97 GtkWidget *keyid;
98 GtkWidget *keyid_label;
99 GtkWidget *new_key_label;
100 GtkWidget *new_key_btn;
101 GtkWidget *new_key_box;
103 PrefsAccount *account;
106 static struct GPGPage gpg_page;
107 static struct GPGAccountPage gpg_account_page;
108 static struct GPGAccountPage smime_account_page;
110 static void prefs_gpg_create_widget_func(PrefsPage *_page,
111 GtkWindow *window,
112 gpointer data)
114 struct GPGPage *page = (struct GPGPage *) _page;
115 struct GPGConfig *config;
117 GtkWidget *checkbtn_use_gpg_agent;
118 GtkWidget *checkbtn_passphrase_grab;
119 GtkWidget *checkbtn_store_passphrase;
120 GtkWidget *checkbtn_auto_check_signatures;
121 GtkWidget *checkbtn_autocompletion;
122 GtkWidget *checkbtn_gpg_warning;
123 GtkWidget *hbox1, *hbox2;
124 GtkWidget *vbox1, *vbox2;
125 GtkWidget *label_gpg_path;
126 GtkWidget *label_expire1;
127 GtkAdjustment *spinbtn_store_passphrase_adj;
128 GtkWidget *spinbtn_store_passphrase;
129 GtkWidget *label_expire2;
130 GtkWidget *frame_passphrase;
131 GtkWidget *gpg_path, *gpg_path_btn;
133 vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING);
134 gtk_widget_show (vbox1);
135 gtk_container_set_border_width (GTK_CONTAINER (vbox1), VBOX_BORDER);
137 vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
138 gtk_widget_show (vbox2);
139 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
141 PACK_CHECK_BUTTON (vbox2, checkbtn_auto_check_signatures,
142 _("Automatically check signatures"));
144 PACK_CHECK_BUTTON (vbox2, checkbtn_autocompletion,
145 _("Use keyring for address autocompletion"));
147 vbox2 = gtkut_get_options_frame(vbox1, &frame_passphrase, _("Passphrase"));
149 PACK_CHECK_BUTTON (vbox2, checkbtn_use_gpg_agent,
150 _("Use gpg-agent to manage passwords"));
151 if (saved_gpg_agent_info == NULL)
152 gtk_widget_set_sensitive(checkbtn_use_gpg_agent, FALSE);
154 PACK_CHECK_BUTTON (vbox2, checkbtn_store_passphrase,
155 _("Store passphrase in memory"));
157 SET_TOGGLE_SENSITIVITY_REVERSE(checkbtn_use_gpg_agent, checkbtn_store_passphrase);
159 hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 8);
160 gtk_widget_show (hbox1);
161 gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0);
163 SET_TOGGLE_SENSITIVITY_REVERSE(checkbtn_use_gpg_agent, hbox1);
165 label_expire1 = gtk_label_new(_("Expire after"));
166 gtk_widget_show (label_expire1);
167 gtk_box_pack_start (GTK_BOX (hbox1), label_expire1, FALSE, FALSE, 0);
169 spinbtn_store_passphrase_adj =
170 GTK_ADJUSTMENT(gtk_adjustment_new(1, 0, 1440, 1, 10, 0));
171 spinbtn_store_passphrase =
172 gtk_spin_button_new(GTK_ADJUSTMENT
173 (spinbtn_store_passphrase_adj), 1, 0);
174 gtk_widget_show(spinbtn_store_passphrase);
175 gtk_box_pack_start(GTK_BOX(hbox1), spinbtn_store_passphrase, FALSE,
176 FALSE, 0);
177 CLAWS_SET_TIP(spinbtn_store_passphrase,
178 _("Setting to '0' will store the passphrase for the whole session"));
179 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON
180 (spinbtn_store_passphrase), TRUE);
182 label_expire2 = gtk_label_new(_("minutes"));
183 gtk_widget_show(label_expire2);
184 gtk_box_pack_start(GTK_BOX(hbox1), label_expire2, FALSE, FALSE, 0);
185 gtk_label_set_xalign(GTK_LABEL(label_expire2), 0.0);
187 SET_TOGGLE_SENSITIVITY (checkbtn_store_passphrase, label_expire1);
188 SET_TOGGLE_SENSITIVITY (checkbtn_store_passphrase, spinbtn_store_passphrase);
189 SET_TOGGLE_SENSITIVITY (checkbtn_store_passphrase, label_expire2);
191 PACK_CHECK_BUTTON (vbox2, checkbtn_passphrase_grab,
192 _("Grab input while entering a passphrase"));
194 vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
195 gtk_widget_show (vbox2);
196 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, FALSE, 0);
198 PACK_CHECK_BUTTON (vbox2, checkbtn_gpg_warning,
199 _("Display warning on start-up if GnuPG doesn't work"));
201 hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
202 label_gpg_path = gtk_label_new(_("Path to GnuPG executable"));
203 gtk_box_pack_start(GTK_BOX(hbox2), label_gpg_path, FALSE, FALSE, 0);
204 gpg_path = gtk_entry_new();
205 gtk_box_pack_start(GTK_BOX(hbox2), gpg_path, TRUE, TRUE, 0);
206 CLAWS_SET_TIP(gpg_path,
207 _("If left blank the location of the GnuPG executable will be automatically determined."));
208 gpg_path_btn = gtkut_get_browse_file_btn(_("Bro_wse"));
209 gtk_box_pack_start(GTK_BOX(hbox2), gpg_path_btn, FALSE, FALSE, 0);
210 g_signal_connect(G_OBJECT(gpg_path_btn), "clicked",
211 G_CALLBACK(gpg_path_browse_cb), gpg_path);
212 pref_set_entry_from_pref(GTK_ENTRY(gpg_path), prefs_gpg.gpg_path);
214 gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);
215 gtk_widget_show_all(vbox1);
217 config = prefs_gpg_get_config();
219 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_auto_check_signatures), config->auto_check_signatures);
220 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_autocompletion), config->autocompletion);
221 if (!g_getenv("GPG_AGENT_INFO"))
222 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_use_gpg_agent), FALSE);
223 else
224 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_use_gpg_agent), config->use_gpg_agent);
225 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbtn_use_gpg_agent)))
226 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_store_passphrase), config->store_passphrase);
227 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbtn_store_passphrase), (float) config->store_passphrase_timeout);
228 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_passphrase_grab), config->passphrase_grab);
229 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_gpg_warning), config->gpg_warning);
230 gtk_entry_set_text(GTK_ENTRY(gpg_path), config->gpg_path);
232 page->checkbtn_auto_check_signatures = checkbtn_auto_check_signatures;
233 page->checkbtn_autocompletion = checkbtn_autocompletion;
234 page->checkbtn_store_passphrase = checkbtn_store_passphrase;
235 page->spinbtn_store_passphrase = spinbtn_store_passphrase;
236 page->checkbtn_passphrase_grab = checkbtn_passphrase_grab;
237 page->checkbtn_gpg_warning = checkbtn_gpg_warning;
238 page->checkbtn_use_gpg_agent = checkbtn_use_gpg_agent;
239 page->gpg_path = gpg_path;
240 page->page.widget = vbox1;
243 static void gpg_path_browse_cb(GtkWidget* widget, gpointer data)
245 gchar *filename;
246 GtkEntry *dest = GTK_ENTRY(data);
248 filename = filesel_select_file_open(_("Select GnuPG executable"), NULL);
249 if (!filename)
250 return;
252 gtk_entry_set_text(GTK_ENTRY(dest), filename);
253 g_free(filename);
256 static void prefs_gpg_destroy_widget_func(PrefsPage *_page)
260 static void prefs_gpg_save_func(PrefsPage *_page)
262 struct GPGPage *page = (struct GPGPage *) _page;
263 GPGConfig *config = prefs_gpg_get_config();
265 config->auto_check_signatures =
266 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_auto_check_signatures));
267 config->autocompletion =
268 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_autocompletion));
269 config->use_gpg_agent =
270 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_use_gpg_agent));
271 config->store_passphrase =
272 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_store_passphrase));
273 config->store_passphrase_timeout =
274 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(page->spinbtn_store_passphrase));
275 config->passphrase_grab =
276 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_passphrase_grab));
277 config->gpg_warning =
278 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->checkbtn_gpg_warning));
279 g_free(config->gpg_path);
280 config->gpg_path = g_strdup(gtk_entry_get_text(GTK_ENTRY(page->gpg_path)));
281 if (strcmp(config->gpg_path, "") != 0 && access(config->gpg_path, X_OK) != -1) {
282 gpgme_error_t err = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, config->gpg_path, NULL);
283 if (err != GPG_ERR_NO_ERROR)
284 g_warning("failed to set crypto engine configuration: %s", gpgme_strerror(err));
287 prefs_gpg_enable_agent(config->use_gpg_agent);
289 prefs_gpg_save_config();
292 void key_custom_toggled(GtkToggleButton *togglebutton, gpointer user_data)
294 struct GPGAccountPage *page = (struct GPGAccountPage *) user_data;
295 gboolean active;
297 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom));
298 gtk_widget_set_sensitive(GTK_WIDGET(page->keyid_label), active);
299 gtk_widget_set_sensitive(GTK_WIDGET(page->keyid), active);
302 static void prefs_gpg_update_sens(struct GPGAccountPage *page)
304 gboolean active;
305 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom));
306 if (sgpgme_has_secret_key()) {
307 gtk_widget_hide(page->new_key_box);
308 gtk_widget_set_sensitive(page->key_default, TRUE);
309 gtk_widget_set_sensitive(page->key_by_from, TRUE);
310 gtk_widget_set_sensitive(page->key_custom, TRUE);
311 gtk_widget_set_sensitive(page->keyid, active);
312 gtk_widget_set_sensitive(page->keyid_label, active);
313 } else {
314 gtk_widget_show(page->new_key_box);
315 gtk_widget_set_sensitive(page->key_default, FALSE);
316 gtk_widget_set_sensitive(page->key_by_from, FALSE);
317 gtk_widget_set_sensitive(page->key_custom, FALSE);
318 gtk_widget_set_sensitive(page->keyid, FALSE);
319 gtk_widget_set_sensitive(page->keyid_label, FALSE);
323 static void new_key_clicked(GtkWidget *widget, gpointer user_data)
325 struct GPGAccountPage *page = (struct GPGAccountPage *) user_data;
326 sgpgme_create_secret_key(page->account, FALSE);
327 prefs_gpg_update_sens(page);
330 static void prefs_gpg_account_create_widget_func(PrefsPage *_page,
331 GtkWindow *window,
332 gpointer data)
334 struct GPGAccountPage *page = (struct GPGAccountPage *) _page;
335 PrefsAccount *account = (PrefsAccount *) data;
336 GPGAccountConfig *config;
337 SignKeyType sign_key;
339 GtkWidget *vbox;
340 GtkWidget *frame1;
341 GtkWidget *vbox2;
342 GtkWidget *hbox;
343 GSList *key_group = NULL;
344 GtkWidget *key_default;
345 GtkWidget *key_by_from;
346 GtkWidget *key_custom;
347 GtkWidget *keyid_label;
348 GtkWidget *keyid;
349 GtkWidget *image;
350 GtkWidget *new_key_label;
351 GtkWidget *new_key_btn;
352 GtkWidget *new_key_box;
354 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, VSPACING);
355 gtk_container_set_border_width (GTK_CONTAINER (vbox), VBOX_BORDER);
356 gtk_widget_show(vbox);
358 vbox2 = gtkut_get_options_frame(vbox, &frame1, _("Sign key"));
360 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
361 gtk_widget_show (hbox);
362 gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
363 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
365 key_default = gtk_radio_button_new_with_label(key_group,
366 _("Use default GnuPG key"));
367 key_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(key_default));
368 gtk_widget_show(key_default);
369 gtk_box_pack_start(GTK_BOX(hbox), key_default, FALSE, FALSE, 0);
371 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
372 gtk_widget_show (hbox);
373 gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
374 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
376 key_by_from = gtk_radio_button_new_with_label(key_group,
377 _("Select key by your email address"));
378 key_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(key_by_from));
379 gtk_widget_show(key_by_from);
380 gtk_box_pack_start(GTK_BOX(hbox), key_by_from, FALSE, FALSE, 0);
382 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
383 gtk_widget_show (hbox);
384 gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
385 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
387 key_custom = gtk_radio_button_new_with_label(key_group,
388 _("Specify key manually"));
389 key_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(key_custom));
390 gtk_widget_show(key_custom);
391 gtk_box_pack_start(GTK_BOX(hbox), key_custom, FALSE, FALSE, 0);
393 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
394 gtk_widget_show (hbox);
395 gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
396 gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
398 keyid_label = gtk_label_new(_("User or key ID:"));
399 gtk_widget_show(keyid_label);
400 gtk_label_set_justify(GTK_LABEL(keyid_label), GTK_JUSTIFY_LEFT);
401 gtk_box_pack_start(GTK_BOX(hbox), keyid_label, FALSE, FALSE, 0);
403 keyid = gtk_entry_new();
404 gtk_widget_show(keyid);
405 gtk_box_pack_start(GTK_BOX(hbox), keyid, FALSE, FALSE, 0);
407 config = prefs_gpg_account_get_config(account);
409 sign_key =
410 (page == &smime_account_page ? config->smime_sign_key : config->sign_key);
411 switch (sign_key) {
412 case SIGN_KEY_DEFAULT:
413 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(key_default), TRUE);
414 gtk_widget_set_sensitive(GTK_WIDGET(keyid_label), FALSE);
415 gtk_widget_set_sensitive(GTK_WIDGET(keyid), FALSE);
416 break;
417 case SIGN_KEY_BY_FROM:
418 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(key_by_from), TRUE);
419 gtk_widget_set_sensitive(GTK_WIDGET(keyid_label), FALSE);
420 gtk_widget_set_sensitive(GTK_WIDGET(keyid), FALSE);
421 break;
422 case SIGN_KEY_CUSTOM:
423 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(key_custom), TRUE);
424 gtk_widget_set_sensitive(GTK_WIDGET(keyid_label), TRUE);
425 gtk_widget_set_sensitive(GTK_WIDGET(keyid), TRUE);
426 break;
429 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
430 gtk_widget_show (hbox);
431 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
433 new_key_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
434 gtk_widget_show(new_key_box);
435 gtk_box_pack_start(GTK_BOX(hbox), new_key_box, FALSE, FALSE, 0);
437 image = gtk_button_new_from_icon_name("dialog-warning",
438 GTK_ICON_SIZE_SMALL_TOOLBAR);
440 gtk_box_pack_start(GTK_BOX(new_key_box), image, FALSE, FALSE, 0);
441 new_key_label = gtk_label_new(
442 _("No secret key found."));
443 gtk_box_pack_start(GTK_BOX(new_key_box), new_key_label, FALSE, FALSE, 0);
445 new_key_btn = gtk_button_new_with_label(_("Generate a new key pair"));
446 gtk_widget_show(new_key_btn);
447 gtk_box_pack_start(GTK_BOX(hbox), new_key_btn, FALSE, FALSE, 0);
449 if (page == &smime_account_page) {
450 if (config->smime_sign_key_id != NULL)
451 gtk_entry_set_text(GTK_ENTRY(keyid), config->smime_sign_key_id);
452 } else {
453 if (config->sign_key_id != NULL)
454 gtk_entry_set_text(GTK_ENTRY(keyid), config->sign_key_id);
456 g_signal_connect(G_OBJECT(key_custom), "toggled", G_CALLBACK(key_custom_toggled), page);
457 g_signal_connect(G_OBJECT(new_key_btn), "clicked", G_CALLBACK(new_key_clicked), page);
459 page->key_default = key_default;
460 page->key_by_from = key_by_from;
461 page->key_custom = key_custom;
462 page->keyid = keyid;
463 page->keyid_label = keyid_label;
464 page->new_key_box = new_key_box;
466 page->page.widget = vbox;
467 page->account = account;
468 prefs_gpg_update_sens(page);
470 prefs_gpg_account_free_config(config);
473 static void prefs_gpg_account_destroy_widget_func(PrefsPage *_page)
475 /* nothing to do here */
478 static void prefs_gpg_account_save_func(PrefsPage *_page)
480 struct GPGAccountPage *page = (struct GPGAccountPage *) _page;
481 GPGAccountConfig *config;
483 config = prefs_gpg_account_get_config(page->account);
485 if (page == &smime_account_page) {
486 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_default)))
487 config->smime_sign_key = SIGN_KEY_DEFAULT;
488 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_by_from)))
489 config->smime_sign_key = SIGN_KEY_BY_FROM;
490 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom))) {
491 config->smime_sign_key = SIGN_KEY_CUSTOM;
493 g_free(config->smime_sign_key_id);
494 config->smime_sign_key_id = gtk_editable_get_chars(GTK_EDITABLE(page->keyid), 0, -1);
495 } else {
496 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_default)))
497 config->sign_key = SIGN_KEY_DEFAULT;
498 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_by_from)))
499 config->sign_key = SIGN_KEY_BY_FROM;
500 else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->key_custom))) {
501 config->sign_key = SIGN_KEY_CUSTOM;
503 g_free(config->sign_key_id);
504 config->sign_key_id = gtk_editable_get_chars(GTK_EDITABLE(page->keyid), 0, -1);
507 prefs_gpg_account_set_config(page->account, config);
508 prefs_gpg_account_free_config(config);
511 GPGConfig *prefs_gpg_get_config(void)
513 return &prefs_gpg;
516 void prefs_gpg_save_config(void)
518 PrefFile *pfile;
519 gchar *rcpath;
521 debug_print("Saving GPG config\n");
523 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
524 pfile = prefs_write_open(rcpath);
525 g_free(rcpath);
526 if (!pfile || (prefs_set_block_label(pfile, "GPG") < 0))
527 return;
529 if (prefs_write_param(param, pfile->fp) < 0) {
530 g_warning("failed to write GPG configuration to file");
531 prefs_file_close_revert(pfile);
532 return;
534 if (fprintf(pfile->fp, "\n") < 0) {
535 FILE_OP_ERROR(rcpath, "fprintf");
536 prefs_file_close_revert(pfile);
537 } else
538 prefs_file_close(pfile);
541 struct GPGAccountConfig *prefs_gpg_account_get_config(PrefsAccount *account)
543 GPGAccountConfig *config;
544 const gchar *confstr;
545 gchar **strv;
547 config = g_new0(GPGAccountConfig, 1);
548 config->sign_key = SIGN_KEY_DEFAULT;
549 config->sign_key_id = NULL;
550 config->smime_sign_key = SIGN_KEY_DEFAULT;
551 config->smime_sign_key_id = NULL;
553 confstr = prefs_account_get_privacy_prefs(account, "gpg");
554 if (confstr != NULL) {
555 strv = g_strsplit(confstr, ";", 0);
556 if (strv[0] != NULL) {
557 if (!strcmp(strv[0], "DEFAULT"))
558 config->sign_key = SIGN_KEY_DEFAULT;
559 else if (!strcmp(strv[0], "BY_FROM"))
560 config->sign_key = SIGN_KEY_BY_FROM;
561 else if (!strcmp(strv[0], "CUSTOM")) {
562 config->sign_key = SIGN_KEY_CUSTOM;
563 } else {
564 config->sign_key = SIGN_KEY_DEFAULT;
567 if (strv[1] != NULL) {
568 config->sign_key_id = g_strdup(strv[1]);
571 g_strfreev(strv);
574 confstr = prefs_account_get_privacy_prefs(account, "smime");
575 /* If the "smime" section does not yet exist, fall back to
576 * "gpg" section even for smime_ values. This will generally
577 * only happen on first run. */
578 if (confstr == NULL)
579 confstr = prefs_account_get_privacy_prefs(account, "gpg");
580 if (confstr != NULL) {
581 strv = g_strsplit(confstr, ";", 0);
582 if (strv[0] != NULL) {
583 if (!strcmp(strv[0], "DEFAULT"))
584 config->smime_sign_key = SIGN_KEY_DEFAULT;
585 else if (!strcmp(strv[0], "BY_FROM"))
586 config->smime_sign_key = SIGN_KEY_BY_FROM;
587 else if (!strcmp(strv[0], "CUSTOM")) {
588 config->smime_sign_key = SIGN_KEY_CUSTOM;
589 } else {
590 config->smime_sign_key = SIGN_KEY_DEFAULT;
593 if (strv[1] != NULL) {
594 config->smime_sign_key_id = g_strdup(strv[1]);
597 g_strfreev(strv);
600 return config;
603 void prefs_gpg_account_set_config(PrefsAccount *account, GPGAccountConfig *config)
605 gchar *confstr = NULL;
607 switch (config->sign_key) {
608 case SIGN_KEY_DEFAULT:
609 confstr = g_strdup_printf("DEFAULT;%s", config->sign_key_id);
610 break;
611 case SIGN_KEY_BY_FROM:
612 confstr = g_strdup_printf("BY_FROM;%s", config->sign_key_id);
613 break;
614 case SIGN_KEY_CUSTOM:
615 confstr = g_strdup_printf("CUSTOM;%s", config->sign_key_id);
616 break;
617 default:
618 confstr = g_strdup("");
619 g_warning("prefs_gpg_account_set_config: bad sign_key val");
622 prefs_account_set_privacy_prefs(account, "gpg", confstr);
624 g_free(confstr);
625 confstr = NULL;
627 switch (config->smime_sign_key) {
628 case SIGN_KEY_DEFAULT:
629 confstr = g_strdup_printf("DEFAULT;%s", config->smime_sign_key_id);
630 break;
631 case SIGN_KEY_BY_FROM:
632 confstr = g_strdup_printf("BY_FROM;%s", config->smime_sign_key_id);
633 break;
634 case SIGN_KEY_CUSTOM:
635 confstr = g_strdup_printf("CUSTOM;%s", config->smime_sign_key_id);
636 break;
637 default:
638 confstr = g_strdup("");
639 g_warning("prefs_gpg_account_set_config: bad sign_key val");
642 prefs_account_set_privacy_prefs(account, "smime", confstr);
644 g_free(confstr);
647 void prefs_gpg_account_free_config(GPGAccountConfig *config)
649 g_free(config->smime_sign_key_id);
650 g_free(config->sign_key_id);
651 g_free(config);
654 void prefs_gpg_enable_agent(gboolean enable)
656 if (enable) {
657 if (saved_gpg_agent_info) {
658 g_setenv("GPG_AGENT_INFO",
659 saved_gpg_agent_info, TRUE);
660 debug_print("set GPG_AGENT_INFO=%s\n",
661 saved_gpg_agent_info);
662 } else {
663 debug_print("Can't enable gpg agent (no GPG_AGENT_INFO)\n");
665 } else {
666 if (saved_gpg_agent_info) {
667 g_unsetenv("GPG_AGENT_INFO");
668 debug_print("unset GPG_AGENT_INFO=%s\n",
669 saved_gpg_agent_info);
670 } else {
671 debug_print("Can't disable gpg agent (no GPG_AGENT_INFO)\n");
676 void prefs_gpg_init()
678 static gchar *path[3], *spath[3];
679 gchar *rcpath;
680 const gchar *tmp = NULL;
682 prefs_set_default(param);
683 rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
684 prefs_read_config(param, "GPG", rcpath, NULL);
685 g_free(rcpath);
687 path[0] = _("Plugins");
688 path[1] = _("GPG");
689 path[2] = NULL;
691 gpg_page.page.path = path;
692 gpg_page.page.create_widget = prefs_gpg_create_widget_func;
693 gpg_page.page.destroy_widget = prefs_gpg_destroy_widget_func;
694 gpg_page.page.save_page = prefs_gpg_save_func;
695 gpg_page.page.weight = 30.0;
697 prefs_gtk_register_page((PrefsPage *) &gpg_page);
699 gpg_account_page.page.path = path;
700 gpg_account_page.page.create_widget = prefs_gpg_account_create_widget_func;
701 gpg_account_page.page.destroy_widget = prefs_gpg_account_destroy_widget_func;
702 gpg_account_page.page.save_page = prefs_gpg_account_save_func;
703 gpg_account_page.page.weight = 30.0;
705 prefs_account_register_page((PrefsPage *) &gpg_account_page);
707 spath[0] = _("Plugins");
708 spath[1] = _("S/MIME");
709 spath[2] = NULL;
710 smime_account_page.page.path = spath;
711 smime_account_page.page.create_widget = prefs_gpg_account_create_widget_func;
712 smime_account_page.page.destroy_widget = prefs_gpg_account_destroy_widget_func;
713 smime_account_page.page.save_page = prefs_gpg_account_save_func;
714 smime_account_page.page.weight = 30.0;
716 prefs_account_register_page((PrefsPage *) &smime_account_page);
718 tmp = g_getenv("GPG_AGENT_INFO");
719 if (tmp)
720 saved_gpg_agent_info = g_strdup(tmp);
722 prefs_gpg_enable_agent(prefs_gpg_get_config()->use_gpg_agent);
725 void prefs_gpg_done()
727 prefs_gtk_unregister_page((PrefsPage *) &gpg_page);
728 prefs_account_unregister_page((PrefsPage *) &gpg_account_page);
729 prefs_gpg_enable_agent(TRUE);
732 gboolean prefs_gpg_should_skip_encryption_warning(const gchar *systemid)
734 gchar **systems = NULL;
735 int i = 0;
736 if (prefs_gpg_get_config()->skip_encryption_warning == NULL)
737 return FALSE;
738 systems = g_strsplit(prefs_gpg_get_config()->skip_encryption_warning,
739 ",", -1);
740 while (systems && systems[i]) {
741 debug_print(" cmp %s %s\n", systems[i], systemid);
742 if (!strcmp(systems[i],systemid)) {
743 g_strfreev(systems);
744 return TRUE;
746 i++;
748 g_strfreev(systems);
749 return FALSE;
752 void prefs_gpg_add_skip_encryption_warning(const gchar *systemid)
754 gchar *tmp = NULL;
755 if (prefs_gpg_get_config()->skip_encryption_warning == NULL)
756 prefs_gpg_get_config()->skip_encryption_warning =
757 g_strdup_printf("%s,", systemid);
758 else if (!prefs_gpg_should_skip_encryption_warning(systemid)) {
759 tmp = g_strdup_printf("%s%s,",
760 prefs_gpg_get_config()->skip_encryption_warning,
761 systemid);
762 g_free(prefs_gpg_get_config()->skip_encryption_warning);
763 prefs_gpg_get_config()->skip_encryption_warning = tmp;
765 prefs_gpg_save_config();
768 void prefs_gpg_remove_skip_encryption_warning(const gchar *systemid)
770 gchar **systems = NULL;
771 int i = 0;
772 if (prefs_gpg_get_config()->skip_encryption_warning == NULL)
773 return;
775 if (prefs_gpg_should_skip_encryption_warning(systemid)) {
776 systems = g_strsplit(prefs_gpg_get_config()->skip_encryption_warning,
777 ",", -1);
778 g_free(prefs_gpg_get_config()->skip_encryption_warning);
779 prefs_gpg_get_config()->skip_encryption_warning = NULL;
781 while (systems && systems[i]) {
782 if (!strcmp(systems[i],systemid)) {
783 i++;
784 continue;
786 prefs_gpg_add_skip_encryption_warning(systems[i]);
787 i++;
790 g_strfreev(systems);
792 prefs_gpg_save_config();
795 gboolean prefs_gpg_auto_check_signatures(void)
797 return prefs_gpg_get_config()->auto_check_signatures;