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/>.
21 #include "claws-features.h"
26 #include <glib/gi18n.h>
28 #include <gtk/filesel.h>
31 #include "gtk/gtkutils.h"
34 #include "prefs_common.h"
35 #include "prefs_gtk.h"
36 #include "prefs_gpg.h"
39 struct GPGConfig prefs_gpg
;
41 static PrefParam param
[] = {
43 {"auto_check_signatures", "FALSE",
44 &prefs_gpg
.auto_check_signatures
, P_BOOL
,
46 {"autocompletion", "FALSE",
47 &prefs_gpg
.autocompletion
, P_BOOL
,
49 {"autocompletion_limit", "0",
50 &prefs_gpg
.autocompletion_limit
, P_INT
,
52 {"use_gpg_agent", "TRUE", &prefs_gpg
.use_gpg_agent
, P_BOOL
,
54 {"store_passphrase", "FALSE", &prefs_gpg
.store_passphrase
, P_BOOL
,
56 {"store_passphrase_timeout", "0",
57 &prefs_gpg
.store_passphrase_timeout
, P_INT
,
59 {"passphrase_grab", "FALSE", &prefs_gpg
.passphrase_grab
, P_BOOL
,
61 {"gpg_warning", "TRUE", &prefs_gpg
.gpg_warning
, P_BOOL
,
63 {"gpg_ask_create_key", "TRUE", &prefs_gpg
.gpg_ask_create_key
, P_BOOL
,
65 {"skip_encryption_warning", "", &prefs_gpg
.skip_encryption_warning
, P_STRING
,
67 {"gpg_path", "", &prefs_gpg
.gpg_path
, P_STRING
,
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
);
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
;
94 GtkWidget
*key_default
;
95 GtkWidget
*key_by_from
;
96 GtkWidget
*key_custom
;
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
,
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
,
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
);
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
)
246 GtkEntry
*dest
= GTK_ENTRY(data
);
248 filename
= filesel_select_file_open(_("Select GnuPG executable"), NULL
);
252 gtk_entry_set_text(GTK_ENTRY(dest
), 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
;
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
)
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
);
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
,
334 struct GPGAccountPage
*page
= (struct GPGAccountPage
*) _page
;
335 PrefsAccount
*account
= (PrefsAccount
*) data
;
336 GPGAccountConfig
*config
;
337 SignKeyType sign_key
;
343 GSList
*key_group
= NULL
;
344 GtkWidget
*key_default
;
345 GtkWidget
*key_by_from
;
346 GtkWidget
*key_custom
;
347 GtkWidget
*keyid_label
;
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
);
410 (page
== &smime_account_page
? config
->smime_sign_key
: config
->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
);
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
);
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
);
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
);
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
;
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);
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)
516 void prefs_gpg_save_config(void)
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
);
526 if (!pfile
|| (prefs_set_block_label(pfile
, "GPG") < 0))
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
);
534 if (fprintf(pfile
->fp
, "\n") < 0) {
535 FILE_OP_ERROR(rcpath
, "fprintf");
536 prefs_file_close_revert(pfile
);
538 prefs_file_close(pfile
);
541 struct GPGAccountConfig
*prefs_gpg_account_get_config(PrefsAccount
*account
)
543 GPGAccountConfig
*config
;
544 const gchar
*confstr
;
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
;
564 config
->sign_key
= SIGN_KEY_DEFAULT
;
567 if (strv
[1] != NULL
) {
568 config
->sign_key_id
= g_strdup(strv
[1]);
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. */
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
;
590 config
->smime_sign_key
= SIGN_KEY_DEFAULT
;
593 if (strv
[1] != NULL
) {
594 config
->smime_sign_key_id
= g_strdup(strv
[1]);
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
);
611 case SIGN_KEY_BY_FROM
:
612 confstr
= g_strdup_printf("BY_FROM;%s", config
->sign_key_id
);
614 case SIGN_KEY_CUSTOM
:
615 confstr
= g_strdup_printf("CUSTOM;%s", config
->sign_key_id
);
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
);
627 switch (config
->smime_sign_key
) {
628 case SIGN_KEY_DEFAULT
:
629 confstr
= g_strdup_printf("DEFAULT;%s", config
->smime_sign_key_id
);
631 case SIGN_KEY_BY_FROM
:
632 confstr
= g_strdup_printf("BY_FROM;%s", config
->smime_sign_key_id
);
634 case SIGN_KEY_CUSTOM
:
635 confstr
= g_strdup_printf("CUSTOM;%s", config
->smime_sign_key_id
);
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
);
647 void prefs_gpg_account_free_config(GPGAccountConfig
*config
)
649 g_free(config
->smime_sign_key_id
);
650 g_free(config
->sign_key_id
);
654 void prefs_gpg_enable_agent(gboolean 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
);
663 debug_print("Can't enable gpg agent (no GPG_AGENT_INFO)\n");
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
);
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];
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
);
687 path
[0] = _("Plugins");
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");
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");
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
;
736 if (prefs_gpg_get_config()->skip_encryption_warning
== NULL
)
738 systems
= g_strsplit(prefs_gpg_get_config()->skip_encryption_warning
,
740 while (systems
&& systems
[i
]) {
741 debug_print(" cmp %s %s\n", systems
[i
], systemid
);
742 if (!strcmp(systems
[i
],systemid
)) {
752 void prefs_gpg_add_skip_encryption_warning(const gchar
*systemid
)
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
,
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
;
772 if (prefs_gpg_get_config()->skip_encryption_warning
== NULL
)
775 if (prefs_gpg_should_skip_encryption_warning(systemid
)) {
776 systems
= g_strsplit(prefs_gpg_get_config()->skip_encryption_warning
,
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
)) {
786 prefs_gpg_add_skip_encryption_warning(systems
[i
]);
792 prefs_gpg_save_config();
795 gboolean
prefs_gpg_auto_check_signatures(void)
797 return prefs_gpg_get_config()->auto_check_signatures
;