diff options
| -rw-r--r-- | libsylph/masterpassword.c | 23 | ||||
| -rw-r--r-- | libsylph/prefs_account.c | 2 | ||||
| -rw-r--r-- | libsylph/prefs_common.c | 3 | ||||
| -rw-r--r-- | libsylph/prefs_common.h | 3 | ||||
| -rw-r--r-- | src/main.c | 7 | ||||
| -rw-r--r-- | src/prefs_common_dialog.c | 15 | ||||
| -rw-r--r-- | src/prefs_ui.c | 19 |
7 files changed, 67 insertions, 5 deletions
diff --git a/libsylph/masterpassword.c b/libsylph/masterpassword.c index 950b79a..8174def 100644 --- a/libsylph/masterpassword.c +++ b/libsylph/masterpassword.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "prefs_common.h" | 26 | #include "prefs_common.h" |
| 27 | #include "ssl.h" | 27 | #include "ssl.h" |
| 28 | #include "utils.h" | 28 | #include "utils.h" |
| 29 | #include "masterpassword.h" | ||
| 29 | 30 | ||
| 30 | 31 | ||
| 31 | gchar *master_password; | 32 | gchar *master_password; |
| @@ -84,9 +85,18 @@ gchar *decrypt_with_master_password(const gchar *str) { | |||
| 84 | gchar *new_str; | 85 | gchar *new_str; |
| 85 | gint str_prefix; | 86 | gint str_prefix; |
| 86 | 87 | ||
| 87 | if ((!str) || (!master_password_active())) | 88 | if ((!str) || (!prefs_common.use_master_password)) |
| 88 | return g_strdup(str); | 89 | return g_strdup(str); |
| 89 | 90 | ||
| 91 | if (master_password == NULL) { | ||
| 92 | /* we have empty or auto unloaded master password */ | ||
| 93 | if ((!prefs_common.auto_unload_master_password) || | ||
| 94 | (check_master_password_interactively(3) != RC_OK)) { | ||
| 95 | return g_strdup(str); | ||
| 96 | } | ||
| 97 | debug_print("Reloaded master password\n"); | ||
| 98 | } | ||
| 99 | |||
| 90 | str_prefix = mpes_string_prefix(str); | 100 | str_prefix = mpes_string_prefix(str); |
| 91 | if (!str_prefix) | 101 | if (!str_prefix) |
| 92 | return g_strdup(str); | 102 | return g_strdup(str); |
| @@ -113,9 +123,18 @@ gchar *encrypt_with_master_password(const gchar *str) { | |||
| 113 | gchar *new_str, *mpes1_str; | 123 | gchar *new_str, *mpes1_str; |
| 114 | gint length_encrypted; | 124 | gint length_encrypted; |
| 115 | 125 | ||
| 116 | if ((!str) || (!master_password_active())) | 126 | if ((!str) || (!prefs_common.use_master_password)) |
| 117 | return g_strdup(str); | 127 | return g_strdup(str); |
| 118 | 128 | ||
| 129 | if (master_password == NULL) { | ||
| 130 | /* we have empty or auto unloaded master password */ | ||
| 131 | if ((!prefs_common.auto_unload_master_password) || | ||
| 132 | (check_master_password_interactively(3) != RC_OK)) { | ||
| 133 | return g_strdup(str); | ||
| 134 | } | ||
| 135 | debug_print("Reloaded master password\n"); | ||
| 136 | } | ||
| 137 | |||
| 119 | if (encrypt_data(&new_str, | 138 | if (encrypt_data(&new_str, |
| 120 | &length_encrypted, | 139 | &length_encrypted, |
| 121 | str, | 140 | str, |
diff --git a/libsylph/prefs_account.c b/libsylph/prefs_account.c index fc4d8f1..54cbc89 100644 --- a/libsylph/prefs_account.c +++ b/libsylph/prefs_account.c | |||
| @@ -239,6 +239,7 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label) | |||
| 239 | label); | 239 | label); |
| 240 | tmp_str = ac_prefs->passwd; | 240 | tmp_str = ac_prefs->passwd; |
| 241 | ac_prefs->passwd = encrypt_with_master_password(ac_prefs->passwd); | 241 | ac_prefs->passwd = encrypt_with_master_password(ac_prefs->passwd); |
| 242 | cleanse_buffer(tmp_str, strlen(tmp_str)); | ||
| 242 | g_free(tmp_str); | 243 | g_free(tmp_str); |
| 243 | } | 244 | } |
| 244 | 245 | ||
| @@ -251,6 +252,7 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label) | |||
| 251 | tmp_str = ac_prefs->smtp_passwd; | 252 | tmp_str = ac_prefs->smtp_passwd; |
| 252 | ac_prefs->smtp_passwd = encrypt_with_master_password( | 253 | ac_prefs->smtp_passwd = encrypt_with_master_password( |
| 253 | ac_prefs->smtp_passwd); | 254 | ac_prefs->smtp_passwd); |
| 255 | cleanse_buffer(tmp_str, strlen(tmp_str)); | ||
| 254 | g_free(tmp_str); | 256 | g_free(tmp_str); |
| 255 | } | 257 | } |
| 256 | 258 | ||
diff --git a/libsylph/prefs_common.c b/libsylph/prefs_common.c index dda4a0f..192964e 100644 --- a/libsylph/prefs_common.c +++ b/libsylph/prefs_common.c | |||
| @@ -425,6 +425,9 @@ static PrefParam param[] = { | |||
| 425 | P_STRING}, | 425 | P_STRING}, |
| 426 | {"encrypted_password_min_length", "32", | 426 | {"encrypted_password_min_length", "32", |
| 427 | &prefs_common.encrypted_password_min_length, P_INT}, | 427 | &prefs_common.encrypted_password_min_length, P_INT}, |
| 428 | {"auto_unload_master_password", "FALSE", | ||
| 429 | &prefs_common.auto_unload_master_password, | ||
| 430 | P_BOOL}, | ||
| 428 | 431 | ||
| 429 | /* Interface */ | 432 | /* Interface */ |
| 430 | {"separate_folder", "FALSE", &prefs_common.sep_folder, P_BOOL}, | 433 | {"separate_folder", "FALSE", &prefs_common.sep_folder, P_BOOL}, |
diff --git a/libsylph/prefs_common.h b/libsylph/prefs_common.h index 92333aa..6f9c364 100644 --- a/libsylph/prefs_common.h +++ b/libsylph/prefs_common.h | |||
| @@ -252,7 +252,8 @@ struct _PrefsCommon | |||
| 252 | /* Master password */ | 252 | /* Master password */ |
| 253 | gboolean use_master_password; | 253 | gboolean use_master_password; |
| 254 | gchar *master_password_hash; | 254 | gchar *master_password_hash; |
| 255 | guint encrypted_password_min_length; | 255 | guint encrypted_password_min_length; |
| 256 | gboolean auto_unload_master_password; | ||
| 256 | 257 | ||
| 257 | /* Interface */ | 258 | /* Interface */ |
| 258 | gboolean sep_folder; | 259 | gboolean sep_folder; |
| @@ -412,6 +412,13 @@ int main(int argc, char *argv[]) | |||
| 412 | 412 | ||
| 413 | remote_command_exec(); | 413 | remote_command_exec(); |
| 414 | 414 | ||
| 415 | #if USE_SSL | ||
| 416 | if (prefs_common.auto_unload_master_password && master_password_active()) { | ||
| 417 | debug_print("Auto unloading master password\n"); | ||
| 418 | unload_master_password(); | ||
| 419 | } | ||
| 420 | #endif | ||
| 421 | |||
| 415 | #if USE_UPDATE_CHECK | 422 | #if USE_UPDATE_CHECK |
| 416 | if (prefs_common.auto_update_check) | 423 | if (prefs_common.auto_update_check) |
| 417 | update_check(FALSE); | 424 | update_check(FALSE); |
diff --git a/src/prefs_common_dialog.c b/src/prefs_common_dialog.c index 41fdb24..119a056 100644 --- a/src/prefs_common_dialog.c +++ b/src/prefs_common_dialog.c | |||
| @@ -219,6 +219,7 @@ static struct Privacy { | |||
| 219 | #if USE_SSL | 219 | #if USE_SSL |
| 220 | static struct MasterPassword { | 220 | static struct MasterPassword { |
| 221 | GtkWidget *checkbtn_use_master_password; | 221 | GtkWidget *checkbtn_use_master_password; |
| 222 | GtkWidget *checkbtn_auto_unload_master_password; | ||
| 222 | GtkWidget *spinbtn_encrypted_password_min_length; | 223 | GtkWidget *spinbtn_encrypted_password_min_length; |
| 223 | } master_password; | 224 | } master_password; |
| 224 | #endif | 225 | #endif |
| @@ -573,6 +574,9 @@ static PrefsUIData ui_data[] = { | |||
| 573 | #if USE_SSL | 574 | #if USE_SSL |
| 574 | {"use_master_password", &master_password.checkbtn_use_master_password, | 575 | {"use_master_password", &master_password.checkbtn_use_master_password, |
| 575 | prefs_set_data_from_toggle, prefs_set_toggle}, | 576 | prefs_set_data_from_toggle, prefs_set_toggle}, |
| 577 | {"auto_unload_master_password", | ||
| 578 | &master_password.checkbtn_auto_unload_master_password, | ||
| 579 | prefs_set_data_from_toggle, prefs_set_toggle}, | ||
| 576 | {"encrypted_password_min_length", | 580 | {"encrypted_password_min_length", |
| 577 | &master_password.spinbtn_encrypted_password_min_length, | 581 | &master_password.spinbtn_encrypted_password_min_length, |
| 578 | prefs_set_data_from_spinbtn, | 582 | prefs_set_data_from_spinbtn, |
| @@ -2681,6 +2685,7 @@ static void prefs_master_password_create(void) | |||
| 2681 | GtkWidget *hbox_spc; | 2685 | GtkWidget *hbox_spc; |
| 2682 | GtkWidget *label; | 2686 | GtkWidget *label; |
| 2683 | GtkWidget *checkbtn_use_master_password; | 2687 | GtkWidget *checkbtn_use_master_password; |
| 2688 | GtkWidget *checkbtn_auto_unload_master_password; | ||
| 2684 | GtkWidget *spinbtn_encrypted_password_min_length; | 2689 | GtkWidget *spinbtn_encrypted_password_min_length; |
| 2685 | GtkObject *spinbtn_encrypted_password_min_length_adj; | 2690 | GtkObject *spinbtn_encrypted_password_min_length_adj; |
| 2686 | 2691 | ||
| @@ -2706,6 +2711,11 @@ static void prefs_master_password_create(void) | |||
| 2706 | FALSE, | 2711 | FALSE, |
| 2707 | 0); | 2712 | 0); |
| 2708 | 2713 | ||
| 2714 | PACK_CHECK_BUTTON (vbox_master_password_suboptions, | ||
| 2715 | checkbtn_auto_unload_master_password, | ||
| 2716 | _("Automatically unload master password " | ||
| 2717 | "after session initialization")); | ||
| 2718 | |||
| 2709 | hbox1 = gtk_hbox_new (FALSE, 8); | 2719 | hbox1 = gtk_hbox_new (FALSE, 8); |
| 2710 | gtk_widget_show (hbox1); | 2720 | gtk_widget_show (hbox1); |
| 2711 | gtk_box_pack_start (GTK_BOX (vbox_master_password_suboptions), | 2721 | gtk_box_pack_start (GTK_BOX (vbox_master_password_suboptions), |
| @@ -2740,10 +2750,13 @@ static void prefs_master_password_create(void) | |||
| 2740 | 64, | 2750 | 64, |
| 2741 | -1); | 2751 | -1); |
| 2742 | 2752 | ||
| 2743 | SET_TOGGLE_SENSITIVITY (checkbtn_use_master_password, hbox1); | 2753 | SET_TOGGLE_SENSITIVITY (checkbtn_use_master_password, |
| 2754 | vbox_master_password_suboptions); | ||
| 2744 | 2755 | ||
| 2745 | master_password.checkbtn_use_master_password | 2756 | master_password.checkbtn_use_master_password |
| 2746 | = checkbtn_use_master_password; | 2757 | = checkbtn_use_master_password; |
| 2758 | master_password.checkbtn_auto_unload_master_password | ||
| 2759 | = checkbtn_auto_unload_master_password; | ||
| 2747 | master_password.spinbtn_encrypted_password_min_length | 2760 | master_password.spinbtn_encrypted_password_min_length |
| 2748 | = spinbtn_encrypted_password_min_length; | 2761 | = spinbtn_encrypted_password_min_length; |
| 2749 | } | 2762 | } |
diff --git a/src/prefs_ui.c b/src/prefs_ui.c index 5539f4a..051a058 100644 --- a/src/prefs_ui.c +++ b/src/prefs_ui.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <errno.h> | 31 | #include <errno.h> |
| 32 | 32 | ||
| 33 | #include "prefs.h" | 33 | #include "prefs.h" |
| 34 | #include "prefs_common.h" | ||
| 34 | #include "prefs_ui.h" | 35 | #include "prefs_ui.h" |
| 35 | #include "menu.h" | 36 | #include "menu.h" |
| 36 | #include "codeconv.h" | 37 | #include "codeconv.h" |
| @@ -276,9 +277,25 @@ void prefs_set_data_from_epass_entry(PrefParam *pparam) | |||
| 276 | gchar **str; | 277 | gchar **str; |
| 277 | const gchar *entry_str; | 278 | const gchar *entry_str; |
| 278 | 279 | ||
| 279 | if (!master_password_active()) { | 280 | /* This is where decrypted passwords are encrypted and stored again */ |
| 281 | |||
| 282 | /* TODO: A potential exploit is disabling master password and then forcing | ||
| 283 | * Sylpheed to store the password | ||
| 284 | */ | ||
| 285 | |||
| 286 | /* master_password == NULL for any of the following reasons: | ||
| 287 | * - use_master_password is not enabled (we just save without encrypting) | ||
| 288 | * - master_password is auto unloaded (let the encrypt function handle it) | ||
| 289 | * - undefined reason (refure to store the password) | ||
| 290 | */ | ||
| 291 | if (!prefs_common.use_master_password) { | ||
| 280 | prefs_set_data_from_entry(pparam); | 292 | prefs_set_data_from_entry(pparam); |
| 281 | return; | 293 | return; |
| 294 | } else if ((master_password == NULL) && | ||
| 295 | (!prefs_common.auto_unload_master_password)) { | ||
| 296 | debug_print("Master password enabled, but not loaded for no " | ||
| 297 | "apparent reason. Not storing\n"); | ||
| 298 | return; | ||
| 282 | } | 299 | } |
| 283 | 300 | ||
| 284 | ui_data = (PrefsUIData *)pparam->ui_data; | 301 | ui_data = (PrefsUIData *)pparam->ui_data; |
