From 46275eef3de4e025b5657e67e142fc58125779be Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Fri, 13 Apr 2018 15:24:01 +0200 Subject: Add support for auto-unloading av the master password --- libsylph/masterpassword.c | 23 +++++++++++++++++++++-- libsylph/prefs_account.c | 2 ++ libsylph/prefs_common.c | 3 +++ libsylph/prefs_common.h | 3 ++- src/main.c | 7 +++++++ src/prefs_common_dialog.c | 15 ++++++++++++++- 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 @@ #include "prefs_common.h" #include "ssl.h" #include "utils.h" +#include "masterpassword.h" gchar *master_password; @@ -84,9 +85,18 @@ gchar *decrypt_with_master_password(const gchar *str) { gchar *new_str; gint str_prefix; - if ((!str) || (!master_password_active())) + if ((!str) || (!prefs_common.use_master_password)) return g_strdup(str); + if (master_password == NULL) { + /* we have empty or auto unloaded master password */ + if ((!prefs_common.auto_unload_master_password) || + (check_master_password_interactively(3) != RC_OK)) { + return g_strdup(str); + } + debug_print("Reloaded master password\n"); + } + str_prefix = mpes_string_prefix(str); if (!str_prefix) return g_strdup(str); @@ -113,9 +123,18 @@ gchar *encrypt_with_master_password(const gchar *str) { gchar *new_str, *mpes1_str; gint length_encrypted; - if ((!str) || (!master_password_active())) + if ((!str) || (!prefs_common.use_master_password)) return g_strdup(str); + if (master_password == NULL) { + /* we have empty or auto unloaded master password */ + if ((!prefs_common.auto_unload_master_password) || + (check_master_password_interactively(3) != RC_OK)) { + return g_strdup(str); + } + debug_print("Reloaded master password\n"); + } + if (encrypt_data(&new_str, &length_encrypted, 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) label); tmp_str = ac_prefs->passwd; ac_prefs->passwd = encrypt_with_master_password(ac_prefs->passwd); + cleanse_buffer(tmp_str, strlen(tmp_str)); g_free(tmp_str); } @@ -251,6 +252,7 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label) tmp_str = ac_prefs->smtp_passwd; ac_prefs->smtp_passwd = encrypt_with_master_password( ac_prefs->smtp_passwd); + cleanse_buffer(tmp_str, strlen(tmp_str)); g_free(tmp_str); } 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[] = { P_STRING}, {"encrypted_password_min_length", "32", &prefs_common.encrypted_password_min_length, P_INT}, + {"auto_unload_master_password", "FALSE", + &prefs_common.auto_unload_master_password, + P_BOOL}, /* Interface */ {"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 /* Master password */ gboolean use_master_password; gchar *master_password_hash; - guint encrypted_password_min_length; + guint encrypted_password_min_length; + gboolean auto_unload_master_password; /* Interface */ gboolean sep_folder; diff --git a/src/main.c b/src/main.c index c6bd812..3c87c70 100644 --- a/src/main.c +++ b/src/main.c @@ -412,6 +412,13 @@ int main(int argc, char *argv[]) remote_command_exec(); +#if USE_SSL + if (prefs_common.auto_unload_master_password && master_password_active()) { + debug_print("Auto unloading master password\n"); + unload_master_password(); + } +#endif + #if USE_UPDATE_CHECK if (prefs_common.auto_update_check) 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 { #if USE_SSL static struct MasterPassword { GtkWidget *checkbtn_use_master_password; + GtkWidget *checkbtn_auto_unload_master_password; GtkWidget *spinbtn_encrypted_password_min_length; } master_password; #endif @@ -573,6 +574,9 @@ static PrefsUIData ui_data[] = { #if USE_SSL {"use_master_password", &master_password.checkbtn_use_master_password, prefs_set_data_from_toggle, prefs_set_toggle}, + {"auto_unload_master_password", + &master_password.checkbtn_auto_unload_master_password, + prefs_set_data_from_toggle, prefs_set_toggle}, {"encrypted_password_min_length", &master_password.spinbtn_encrypted_password_min_length, prefs_set_data_from_spinbtn, @@ -2681,6 +2685,7 @@ static void prefs_master_password_create(void) GtkWidget *hbox_spc; GtkWidget *label; GtkWidget *checkbtn_use_master_password; + GtkWidget *checkbtn_auto_unload_master_password; GtkWidget *spinbtn_encrypted_password_min_length; GtkObject *spinbtn_encrypted_password_min_length_adj; @@ -2706,6 +2711,11 @@ static void prefs_master_password_create(void) FALSE, 0); + PACK_CHECK_BUTTON (vbox_master_password_suboptions, + checkbtn_auto_unload_master_password, + _("Automatically unload master password " + "after session initialization")); + hbox1 = gtk_hbox_new (FALSE, 8); gtk_widget_show (hbox1); gtk_box_pack_start (GTK_BOX (vbox_master_password_suboptions), @@ -2740,10 +2750,13 @@ static void prefs_master_password_create(void) 64, -1); - SET_TOGGLE_SENSITIVITY (checkbtn_use_master_password, hbox1); + SET_TOGGLE_SENSITIVITY (checkbtn_use_master_password, + vbox_master_password_suboptions); master_password.checkbtn_use_master_password = checkbtn_use_master_password; + master_password.checkbtn_auto_unload_master_password + = checkbtn_auto_unload_master_password; master_password.spinbtn_encrypted_password_min_length = spinbtn_encrypted_password_min_length; } 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 @@ #include #include "prefs.h" +#include "prefs_common.h" #include "prefs_ui.h" #include "menu.h" #include "codeconv.h" @@ -276,9 +277,25 @@ void prefs_set_data_from_epass_entry(PrefParam *pparam) gchar **str; const gchar *entry_str; - if (!master_password_active()) { + /* This is where decrypted passwords are encrypted and stored again */ + + /* TODO: A potential exploit is disabling master password and then forcing + * Sylpheed to store the password + */ + + /* master_password == NULL for any of the following reasons: + * - use_master_password is not enabled (we just save without encrypting) + * - master_password is auto unloaded (let the encrypt function handle it) + * - undefined reason (refure to store the password) + */ + if (!prefs_common.use_master_password) { prefs_set_data_from_entry(pparam); return; + } else if ((master_password == NULL) && + (!prefs_common.auto_unload_master_password)) { + debug_print("Master password enabled, but not loaded for no " + "apparent reason. Not storing\n"); + return; } ui_data = (PrefsUIData *)pparam->ui_data; -- cgit v1.3