From f1babd48f5259186cd1233288992f942d4b5b0bb Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Fri, 9 Mar 2018 14:02:34 +0100 Subject: Complete rewrite of the master password implementation --- libsylph/masterpassword.c | 159 +++++++++++++++++++++++++++++++++------------- 1 file changed, 115 insertions(+), 44 deletions(-) (limited to 'libsylph/masterpassword.c') diff --git a/libsylph/masterpassword.c b/libsylph/masterpassword.c index ee443aa..4cef644 100644 --- a/libsylph/masterpassword.c +++ b/libsylph/masterpassword.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include "prefs_common.h" #include "ssl.h" #include "utils.h" @@ -29,72 +31,141 @@ gchar *master_password; void set_master_password(const char *password) { - master_password = password; + master_password = password; } gchar *get_master_password(void) { - return master_password; + return master_password; } +void unload_master_password(void) { + #if USE_SSL + OPENSSL_cleanse(master_password, strlen(master_password)); +#endif + g_free(master_password); + master_password = NULL; -gint set_master_password_interactively(guint max_attempts) { +} - if (master_password != NULL) - return 0; /* master_password already set */ +gboolean master_password_active(void) { - master_password = input_set_new_password(max_attempts); +#if USE_SSL + return ((master_password != NULL) && + prefs_common.use_master_password); +#else + return FALSE; +#endif - if (master_password == NULL) - return 1; +} - if (generate_password_hash( - &prefs_common.master_password_hash, - master_password, - NULL) != RC_OK) { - /* should not really happen unless buggy code / library */ - g_free(prefs_common.master_password_hash); - prefs_common.master_password_hash = NULL; - debug_print(_("Could not generate master password hash")); - return 1; - } +gchar *decrypt_with_master_password(gchar *str) { - prefs_common_write_config(); - return 0; +#if USE_SSL + gchar *new_str; + + if ((!str) || (!master_password_active())) + return str; /* do nothing */ + + if (decrypt_data(&new_str, + str, + master_password, + strlen(str)) != RC_OK) { + OPENSSL_cleanse(new_str, strlen(new_str)); + g_free(new_str); + return str; + } + + return new_str; +#else + return str; /* do nothing */ +#endif } -gint check_master_password_interactively(guint max_attempts) { +gchar *encrypt_with_master_password(gchar *str) { + +#if USE_SSL + gchar *new_str; + gint length_encrypted; + + if ((!str) || (!master_password_active())) + return str; /* do nothing */ + + if (encrypt_data(&new_str, + &length_encrypted, + str, + master_password, + strlen(str), + 32, /* TODO: to be set in prefs_common */ + TRUE) != RC_OK) { + OPENSSL_cleanse(new_str, strlen(new_str)); + g_free(new_str); + return str; + } + + return new_str; +#else + return str; /* do nothing */ +#endif - guint cnt; +} - if (max_attempts < 1) - return 1; +#if USE_SSL +gint set_master_password_interactively(guint max_attempts) { - if (prefs_common.master_password_hash != NULL) { - return 1; - } + if (master_password == NULL) + master_password = input_set_new_password(max_attempts); - if (master_password != NULL) { - /* password already cached */ - return check_password(master_password, - prefs_common.master_password_hash); - } + if (master_password == NULL) + return 1; - for (cnt = 0; cnt < max_attempts; ++cnt) { - master_password = input_query_master_password(); - if (check_password(master_password, - prefs_common.master_password_hash) == RC_OK) { - return RC_OK; /* match */ - } - debug_print(_("Wrong master password entered (%d)\n"), cnt); - /* TODO: clear before free? */ - g_free(master_password); - master_password = NULL; - } + if (generate_password_hash( + &prefs_common.master_password_hash, + master_password, + NULL) != RC_OK) { + /* should not really happen unless buggy code / library */ + g_free(prefs_common.master_password_hash); + prefs_common.master_password_hash = NULL; + debug_print(_("Could not generate master password hash")); + return 1; + } - return 1; /* no match */ + prefs_common_write_config(); + return 0; } +gint check_master_password_interactively(guint max_attempts) { + + guint cnt; + + if (max_attempts < 1) + return 1; + + if (prefs_common.master_password_hash != NULL) { + return 1; + } + + if (master_password != NULL) { + /* password already cached */ + return check_password(master_password, + prefs_common.master_password_hash); + } + + for (cnt = 0; cnt < max_attempts; ++cnt) { + master_password = input_query_master_password(); + if (check_password(master_password, + prefs_common.master_password_hash) == RC_OK) { + return RC_OK; /* match */ + } + debug_print(_("Wrong master password entered (%d)\n"), cnt); + OPENSSL_cleanse(master_password, strlen(master_password)); + g_free(master_password); + master_password = NULL; + } + + return 1; /* no match */ + +} #endif /* USE_SSL */ -- cgit v1.3