From 57944f6147f077ccf4d84b9d2659f4e8645e8858 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Thu, 8 Mar 2018 15:01:45 +0100 Subject: Reastructure master password functionality --- libsylph/Makefile.am | 2 + libsylph/Makefile.in | 7 +++- libsylph/account.c | 49 ++++------------------- libsylph/masterpassword.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++ libsylph/masterpassword.h | 38 ++++++++++++++++++ libsylph/utils.c | 30 ++++++++++++++ libsylph/utils.h | 7 +++- 7 files changed, 189 insertions(+), 44 deletions(-) create mode 100644 libsylph/masterpassword.c create mode 100644 libsylph/masterpassword.h (limited to 'libsylph') diff --git a/libsylph/Makefile.am b/libsylph/Makefile.am index 8f2b76b..40d26a9 100644 --- a/libsylph/Makefile.am +++ b/libsylph/Makefile.am @@ -19,6 +19,7 @@ libsylph_0_la_SOURCES = \ folder.c \ html.c \ imap.c \ + masterpassword.c \ mbox.c \ md5.c \ md5_hmac.c \ @@ -62,6 +63,7 @@ libsylph_0include_HEADERS = \ folder.h \ html.h \ imap.h \ + masterpassword.h \ mbox.h \ md5.h \ md5_hmac.h \ diff --git a/libsylph/Makefile.in b/libsylph/Makefile.in index 6e3c999..ac8fefd 100644 --- a/libsylph/Makefile.in +++ b/libsylph/Makefile.in @@ -129,8 +129,8 @@ libsylph_0_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libsylph_0_la_OBJECTS = account.lo base64.lo codeconv.lo \ customheader.lo displayheader.lo filter.lo folder.lo html.lo \ - imap.lo mbox.lo md5.lo md5_hmac.lo mh.lo news.lo nntp.lo \ - pop.lo prefs.lo prefs_account.lo prefs_common.lo procheader.lo \ + imap.lo masterpassword.lo mbox.lo md5.lo md5_hmac.lo mh.lo news.lo \ + nntp.lo pop.lo prefs.lo prefs_account.lo prefs_common.lo procheader.lo \ procmime.lo procmsg.lo quoted-printable.lo recv.lo session.lo \ smtp.lo socket.lo socks.lo ssl.lo ssl_hostname_validation.lo \ stringtable.lo sylmain.lo unmime.lo utils.lo uuencode.lo \ @@ -402,6 +402,7 @@ libsylph_0_la_SOURCES = \ folder.c \ html.c \ imap.c \ + masterpassword.c \ mbox.c \ md5.c \ md5_hmac.c \ @@ -445,6 +446,7 @@ libsylph_0include_HEADERS = \ folder.h \ html.h \ imap.h \ + masterpassword.h \ mbox.h \ md5.h \ md5_hmac.h \ @@ -579,6 +581,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/folder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/masterpassword.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbox.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_hmac.Plo@am__quote@ diff --git a/libsylph/account.c b/libsylph/account.c index e4cb5cc..7440434 100644 --- a/libsylph/account.c +++ b/libsylph/account.c @@ -37,7 +37,7 @@ #include "utils.h" #include "sylmain.h" #include "prefs_common.h" -#include "ssl.h" +#include "masterpassword.h" PrefsAccount *cur_account; @@ -55,50 +55,17 @@ void account_read_config_all(void) gchar buf[PREFSBUFSIZE]; PrefsAccount *ac_prefs; #if USE_SSL - guint cnt; - gchar *master_password, *master_password_confirm; if (prefs_common.use_master_password) { if (prefs_common.master_password_hash != NULL) { - for (cnt = 0; cnt < 3; ++cnt) { - /* allow 3 attempts to enter the master password */ - master_password = input_query_password(_("Sylpheed"), - _("Master password")); - if (check_password( - master_password, - prefs_common.master_password_hash) == RC_OK) { - break; - } - debug_print(_("Wrong master password entered (%d)\n"), cnt); - g_free(master_password); - master_password = NULL; - } + /* allow 3 attempts to enter the master password */ + if (check_master_password_interactively(3) != 0) { + /* master password does not match the hash */ + g_free(master_password); + master_password = NULL; + } } else { /* No master password set (no master_password_hash) */ - for (cnt = 0; cnt < 3; ++cnt) { - master_password = input_query_password(_("Sylpheed"), - _("Master password")); - master_password_confirm = input_query_password( - _("Sylpheed"), - _("Master password confirmation")); - if (strcmp(master_password, master_password_confirm) == 0) { - /* The passwords match */ - g_free(master_password_confirm); - if (generate_password_hash( - &prefs_common.master_password_hash, - master_password, - NULL) != RC_OK) { - debug_print( - _("Could not generate master password hash")); - g_free(master_password); - continue; - } - prefs_common_write_config(); - break; - } - g_free(master_password); - g_free(master_password_confirm); - master_password = NULL; - } + set_master_password_interactively(3); } /* TODO: Warning if password is NULL */ } else { diff --git a/libsylph/masterpassword.c b/libsylph/masterpassword.c new file mode 100644 index 0000000..ee443aa --- /dev/null +++ b/libsylph/masterpassword.c @@ -0,0 +1,100 @@ +/* + * LibSylph -- E-Mail client library + * Copyright (C) 1999-2018 Hiroyuki Yamamoto + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "prefs_common.h" +#include "ssl.h" +#include "utils.h" + + +gchar *master_password; + +void set_master_password(const char *password) { + master_password = password; +} + +gchar *get_master_password(void) { + return master_password; +} + +#if USE_SSL + +gint set_master_password_interactively(guint max_attempts) { + + if (master_password != NULL) + return 0; /* master_password already set */ + + master_password = input_set_new_password(max_attempts); + + 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; + } + + 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); + /* TODO: clear before free? */ + g_free(master_password); + master_password = NULL; + } + + return 1; /* no match */ + +} + +#endif /* USE_SSL */ diff --git a/libsylph/masterpassword.h b/libsylph/masterpassword.h new file mode 100644 index 0000000..b2798ce --- /dev/null +++ b/libsylph/masterpassword.h @@ -0,0 +1,38 @@ +/* + * LibSylph -- E-Mail client library + * Copyright (C) 1999-2006 Hiroyuki Yamamoto + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __MASTERPASSWORD_H__ +#define __MASTERPASSWORD_H__ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +extern gchar *master_password; +void set_master_password(const char *password); +gchar *get_master_password(void); + +#if USE_SSL + +gint set_master_password_interactively(guint max_attempts); +gint check_master_password_interactively(guint max_attempts); + +#endif /* USE_SSL */ + +#endif /* __MASTERPASSWORD_H__ */ diff --git a/libsylph/utils.c b/libsylph/utils.c index 6ecf328..3bbcbcf 100644 --- a/libsylph/utils.c +++ b/libsylph/utils.c @@ -4598,6 +4598,36 @@ gchar *input_query_password(const gchar *server, const gchar *user) return NULL; } +static QueryMasterPasswordFunc query_master_password_func = NULL; + +void set_input_query_master_password_func(QueryMasterPasswordFunc func) +{ + query_master_password_func = func; +} + +gchar *input_query_master_password(void) +{ + if (query_master_password_func) + return query_master_password_func(); + else + return NULL; +} + +static SetNewPasswordFunc set_new_password_func = NULL; + +void set_input_set_new_password_func(SetNewPasswordFunc func) +{ + set_new_password_func = func; +} + +gchar *input_set_new_password(guint max_attempts) +{ + if (set_new_password_func) + return set_new_password_func(max_attempts); + else + return NULL; +} + /* logging */ static FILE *log_fp = NULL; diff --git a/libsylph/utils.h b/libsylph/utils.h index 9ac65cf..ede55ff 100644 --- a/libsylph/utils.h +++ b/libsylph/utils.h @@ -202,6 +202,8 @@ typedef void (*ProgressFunc) (gint cur, gint total); typedef gchar * (*QueryPasswordFunc) (const gchar *server, const gchar *user); +typedef gchar * (*QueryMasterPasswordFunc) (void); +typedef gchar * (*SetNewPasswordFunc) (guint max_attempts); typedef void (*LogFunc) (const gchar *str); typedef void (*LogFlushFunc) (void); @@ -560,9 +562,12 @@ void progress_show (gint cur, /* user input */ void set_input_query_password_func (QueryPasswordFunc func); - gchar *input_query_password (const gchar *server, const gchar *user); +void set_input_query_master_password_func(QueryMasterPasswordFunc func); +gchar *input_query_master_password(void); +void set_input_set_new_password_func(SetNewPasswordFunc func); +gchar *input_set_new_password(guint max_attempts); /* logging */ void set_log_file (const gchar *filename); -- cgit v1.3