talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit caa44e52c9f535bd0f2ebe5214fb601c63373bcc
parent 2a6f8d16b275c63c5daa373d58d5ae867f1f6ba2
Author: Andrej Kacian <ticho@claws-mail.org>
Date:   Sun, 28 Feb 2016 23:42:56 +0100

Make accounts use new password store for their passwords.

Diffstat:
Msrc/common/ssl.c | 6+++++-
Msrc/common/ssl.h | 2+-
Msrc/imap.c | 5+++--
Msrc/main.c | 3+++
Msrc/news.c | 7+++----
Msrc/password.c | 46++--------------------------------------------
Msrc/prefs_account.c | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Msrc/prefs_gtk.c | 23++++-------------------
Msrc/send_message.c | 8+++++---
Msrc/wizard.c | 35+++++++++++++++++++++++++----------
10 files changed, 136 insertions(+), 96 deletions(-)

diff --git a/src/common/ssl.c b/src/common/ssl.c @@ -83,8 +83,10 @@ static int gnutls_cert_cb(gnutls_session_t session, hookdata.is_smtp = sockinfo->is_smtp; hooks_invoke(SSLCERT_GET_CLIENT_CERT_HOOKLIST, &hookdata); - if (hookdata.cert_path == NULL) + if (hookdata.cert_path == NULL) { + g_free(hookdata.password); return 0; + } sockinfo->client_crt = ssl_certificate_get_x509_from_pem_file(hookdata.cert_path); sockinfo->client_key = ssl_certificate_get_pkey_from_pem_file(hookdata.cert_path); @@ -106,8 +108,10 @@ static int gnutls_cert_cb(gnutls_session_t session, st->cert.x509 = &(sockinfo->client_crt); st->key.x509 = sockinfo->client_key; st->deinit_all = 0; + g_free(hookdata.password); return 0; } + g_free(hookdata.password); return 0; } diff --git a/src/common/ssl.h b/src/common/ssl.h @@ -47,7 +47,7 @@ struct _SSLClientCertHookData { const void *account; const gchar *cert_path; - const gchar *password; + gchar *password; gboolean is_smtp; }; diff --git a/src/imap.c b/src/imap.c @@ -71,7 +71,7 @@ #include "account.h" #include "tags.h" #include "main.h" -#include "password.h" +#include "passwordstore.h" typedef struct _IMAPFolder IMAPFolder; typedef struct _IMAPSession IMAPSession; @@ -1288,7 +1288,8 @@ static gint imap_session_authenticate(IMAPSession *session, Xstrdup_a(acc_pass, pass, {g_free(pass); return MAILIMAP_NO_ERROR;}); g_free(pass); } else { - acc_pass = password_decrypt(account->passwd, NULL); + acc_pass = passwd_store_get(PWS_ACCOUNT, account->account_name, + PWS_ACCOUNT_RECV); } try_again: pass = acc_pass; diff --git a/src/main.c b/src/main.c @@ -126,6 +126,7 @@ #include "quicksearch.h" #include "advsearch.h" #include "avatars.h" +#include "passwordstore.h" #ifdef HAVE_LIBETPAN #include "imap-thread.h" @@ -1301,6 +1302,7 @@ int main(int argc, char *argv[]) gtk_cmclist_freeze(GTK_CMCLIST(mainwin->folderview->ctree)); folder_item_update_freeze(); + passwd_store_read_config(); prefs_account_init(); account_read_config_all(); @@ -1644,6 +1646,7 @@ static void exit_claws(MainWindow *mainwin) prefs_common_write_config(); account_write_config_all(); + passwd_store_write_config(); #ifndef USE_ALT_ADDRBOOK addressbook_export_to_file(); #endif diff --git a/src/news.c b/src/news.c @@ -48,7 +48,7 @@ #include "statusbar.h" #include "codeconv.h" #include "utils.h" -#include "password.h" +#include "passwordstore.h" #include "prefs_common.h" #include "prefs_account.h" #include "inputdialog.h" @@ -405,9 +405,8 @@ static Session *news_session_new_for_folder(Folder *folder) userid = ac->userid; if (password_get(userid, ac->nntp_server, "nntp", port, &passwd)) { /* NOP */; - } else if (ac->passwd && ac->passwd[0]) - passwd = password_decrypt(ac->passwd, NULL); - else + } else if ((passwd = passwd_store_get(PWS_ACCOUNT, ac->account_name, + PWS_ACCOUNT_RECV)) == NULL) passwd = input_dialog_query_password_keep(ac->nntp_server, userid, &(ac->session_passwd)); diff --git a/src/password.c b/src/password.c @@ -45,6 +45,7 @@ #include "alertpanel.h" #include "inputdialog.h" #include "password.h" +#include "passwordstore.h" #include "prefs_common.h" #ifndef PASSWORD_CRYPTO_OLD @@ -139,10 +140,6 @@ void master_password_forget() void master_password_change(const gchar *oldp, const gchar *newp) { - gchar *pwd, *newpwd; - GList *cur; - PrefsAccount *acc; - if (oldp == NULL) { /* If oldp is NULL, make sure the user has to enter the * current master password before being able to change it. */ @@ -173,46 +170,7 @@ void master_password_change(const gchar *oldp, const gchar *newp) newp = PASSCRYPT_KEY; debug_print("Reencrypting all account passwords...\n"); - for (cur = account_get_list(); cur != NULL; cur = cur->next) { - acc = (PrefsAccount *)cur->data; - debug_print("account %s\n", acc->account_name); - - /* Password for receiving */ - if (acc->passwd != NULL && strlen(acc->passwd) > 0) { - pwd = password_decrypt(acc->passwd, oldp); - if (pwd == NULL) { - debug_print("failed to decrypt recv password with old master password\n"); - } else { - newpwd = password_encrypt(pwd, newp); - memset(pwd, 0, strlen(pwd)); - g_free(pwd); - if (newpwd == NULL) { - debug_print("failed to encrypt recv password with new master password\n"); - } else { - g_free(acc->passwd); - acc->passwd = newpwd; - } - } - } - - /* Password for sending */ - if (acc->smtp_passwd != NULL && strlen(acc->smtp_passwd) > 0) { - pwd = password_decrypt(acc->smtp_passwd, oldp); - if (pwd == NULL) { - debug_print("failed to decrypt smtp password with old master password\n"); - } else { - newpwd = password_encrypt(pwd, newp); - memset(pwd, 0, strlen(pwd)); - g_free(pwd); - if (newpwd == NULL) { - debug_print("failed to encrypt smtp password with new master password\n"); - } else { - g_free(acc->smtp_passwd); - acc->smtp_passwd = newpwd; - } - } - } - } + passwd_store_reencrypt_all(oldp, newp); /* Now reencrypt all plugins passwords fields * FIXME: Unloaded plugins won't be able to update their stored passwords diff --git a/src/prefs_account.c b/src/prefs_account.c @@ -63,6 +63,7 @@ #include "privacy.h" #include "inputdialog.h" #include "ssl_certificate.h" +#include "passwordstore.h" static gboolean cancelled; static gboolean new_account; @@ -432,7 +433,7 @@ static PrefParam basic_param[] = { &basic_page.uid_entry, prefs_set_data_from_entry, prefs_set_entry}, {"password", NULL, &tmp_ac_prefs.passwd, P_PASSWORD, - &basic_page.pass_entry, prefs_set_data_from_entry, prefs_set_entry}, + NULL, NULL, NULL}, {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL} }; @@ -536,7 +537,7 @@ static PrefParam send_param[] = { {"smtp_user_id", NULL, &tmp_ac_prefs.smtp_userid, P_STRING, &send_page.smtp_uid_entry, prefs_set_data_from_entry, prefs_set_entry}, {"smtp_password", NULL, &tmp_ac_prefs.smtp_passwd, P_PASSWORD, - &send_page.smtp_pass_entry, prefs_set_data_from_entry, prefs_set_entry}, + NULL, NULL, NULL}, {"pop_before_smtp", "FALSE", &tmp_ac_prefs.pop_before_smtp, P_BOOL, &send_page.pop_bfr_smtp_checkbtn, @@ -740,13 +741,13 @@ static PrefParam ssl_param[] = { &ssl_page.entry_in_cert_file, prefs_set_data_from_entry, prefs_set_entry}, {"in_ssl_client_cert_pass", "", &tmp_ac_prefs.in_ssl_client_cert_pass, P_PASSWORD, - &ssl_page.entry_in_cert_pass, prefs_set_data_from_entry, prefs_set_entry}, + NULL, NULL, NULL}, {"out_ssl_client_cert_file", "", &tmp_ac_prefs.out_ssl_client_cert_file, P_STRING, &ssl_page.entry_out_cert_file, prefs_set_data_from_entry, prefs_set_entry}, {"out_ssl_client_cert_pass", "", &tmp_ac_prefs.out_ssl_client_cert_pass, P_PASSWORD, - &ssl_page.entry_out_cert_pass, prefs_set_data_from_entry, prefs_set_entry}, + NULL, NULL, NULL}, #else {"ssl_pop", "0", &tmp_ac_prefs.ssl_pop, P_ENUM, NULL, NULL, NULL}, @@ -1018,6 +1019,7 @@ static void basic_create_widget_func(PrefsPage * _page, GtkWidget *auto_configure_lbl; GtkListStore *menu; GtkTreeIter iter; + gchar *buf; struct BasicProtocol *protocol_optmenu; gint i; @@ -1332,7 +1334,6 @@ static void basic_create_widget_func(PrefsPage * _page, if (new_account) { PrefsAccount *def_ac; - gchar *buf; prefs_set_dialog_to_default(basic_param); buf = g_strdup_printf(_("Account%d"), ac_prefs->account_id); @@ -1359,9 +1360,16 @@ static void basic_create_widget_func(PrefsPage * _page, g_free(id); } } - } else + } else { prefs_set_dialog(basic_param); + /* Passwords are handled outside of PrefParams. */ + buf = passwd_store_get(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_RECV); + gtk_entry_set_text(GTK_ENTRY(page->pass_entry), buf); + g_free(buf); + } + page->vbox = vbox1; page->page.widget = vbox1; @@ -1712,6 +1720,7 @@ static void send_create_widget_func(PrefsPage * _page, GtkWidget *pop_bfr_smtp_tm_spinbtn; GtkWidget *pop_auth_timeout_lbl; GtkWidget *pop_auth_minutes_lbl; + gchar *buf; vbox1 = gtk_vbox_new (FALSE, VSPACING); gtk_widget_show (vbox1); @@ -1888,9 +1897,16 @@ static void send_create_widget_func(PrefsPage * _page, if (new_account) { prefs_set_dialog_to_default(send_param); - } else + } else { prefs_set_dialog(send_param); + /* Passwords are handled outside of PrefParams. */ + buf = passwd_store_get(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_SEND); + gtk_entry_set_text(GTK_ENTRY(page->smtp_pass_entry), buf); + g_free(buf); + } + pop_bfr_smtp_tm_set_sens (NULL, NULL); page->vbox = vbox1; @@ -2428,6 +2444,7 @@ static void ssl_create_widget_func(PrefsPage * _page, GtkWidget *hbox; GtkWidget *hbox_spc; GtkWidget *label; + gchar *buf; vbox1 = gtk_vbox_new (FALSE, VSPACING); gtk_widget_show (vbox1); @@ -2608,9 +2625,20 @@ static void ssl_create_widget_func(PrefsPage * _page, if (new_account) { prefs_set_dialog_to_default(ssl_param); - } else + } else { prefs_set_dialog(ssl_param); + /* Passwords are handled outside of PrefParams. */ + buf = passwd_store_get(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_RECV_CERT); + gtk_entry_set_text(GTK_ENTRY(page->entry_in_cert_pass), buf); + g_free(buf); + buf = passwd_store_get(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_SEND_CERT); + gtk_entry_set_text(GTK_ENTRY(page->entry_out_cert_pass), buf); + g_free(buf); + } + page->vbox = vbox1; page->page.widget = vbox1; @@ -2944,6 +2972,12 @@ static gint prefs_basic_apply(void) tmp_ac_prefs.account_name ? tmp_ac_prefs.account_name : "(null)"); prefs_set_data_from_dialog(basic_param); + + /* Passwords are stored outside of PrefParams. */ + passwd_store_set(PWS_ACCOUNT, tmp_ac_prefs.account_name, + PWS_ACCOUNT_RECV, + gtk_entry_get_text(GTK_ENTRY(basic_page.pass_entry)), + FALSE); if (protocol == A_IMAP4 || protocol == A_NNTP) { new_id = g_strdup_printf("#%s/%s", @@ -2967,6 +3001,13 @@ static gint prefs_receive_apply(void) static gint prefs_send_apply(void) { prefs_set_data_from_dialog(send_param); + + /* Passwords are stored outside of PrefParams. */ + passwd_store_set(PWS_ACCOUNT, tmp_ac_prefs.account_name, + PWS_ACCOUNT_SEND, + gtk_entry_get_text(GTK_ENTRY(send_page.smtp_pass_entry)), + FALSE); + return 0; } @@ -2992,6 +3033,17 @@ static gint prefs_privacy_apply(void) static gint prefs_ssl_apply(void) { prefs_set_data_from_dialog(ssl_param); + + /* Passwords are stored outside of PrefParams. */ + passwd_store_set(PWS_ACCOUNT, tmp_ac_prefs.account_name, + PWS_ACCOUNT_RECV_CERT, + gtk_entry_get_text(GTK_ENTRY(ssl_page.entry_in_cert_pass)), + FALSE); + passwd_store_set(PWS_ACCOUNT, tmp_ac_prefs.account_name, + PWS_ACCOUNT_SEND_CERT, + gtk_entry_get_text(GTK_ENTRY(ssl_page.entry_out_cert_pass)), + FALSE); + return 0; } #endif @@ -3359,6 +3411,7 @@ static gboolean sslcert_get_client_cert_hook(gpointer source, gpointer data) { SSLClientCertHookData *hookdata = (SSLClientCertHookData *)source; PrefsAccount *account = (PrefsAccount *)hookdata->account; + gchar *pwd_id; hookdata->cert_path = NULL; hookdata->password = NULL; @@ -3371,14 +3424,15 @@ static gboolean sslcert_get_client_cert_hook(gpointer source, gpointer data) if (hookdata->is_smtp) { if (account->out_ssl_client_cert_file && *account->out_ssl_client_cert_file) hookdata->cert_path = account->out_ssl_client_cert_file; - if (account->out_ssl_client_cert_pass && *account->out_ssl_client_cert_pass) - hookdata->password = account->out_ssl_client_cert_pass; + pwd_id = PWS_ACCOUNT_SEND_CERT; } else { if (account->in_ssl_client_cert_file && *account->in_ssl_client_cert_file) hookdata->cert_path = account->in_ssl_client_cert_file; - if (account->in_ssl_client_cert_pass && *account->in_ssl_client_cert_pass) - hookdata->password = account->in_ssl_client_cert_pass; + pwd_id = PWS_ACCOUNT_RECV_CERT; } + + hookdata->password = passwd_store_get(PWS_ACCOUNT, + account->account_name, pwd_id); return TRUE; } @@ -3544,6 +3598,25 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label) privacy_prefs = NULL; } + if (ac_prefs->passwd != NULL && strlen(ac_prefs->passwd) > 1) { + passwd_store_set(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_RECV, ac_prefs->passwd, TRUE); + } + if (ac_prefs->smtp_passwd != NULL && strlen(ac_prefs->smtp_passwd) > 1) { + passwd_store_set(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_SEND, ac_prefs->smtp_passwd, TRUE); + } + if (ac_prefs->in_ssl_client_cert_pass != NULL + && strlen(ac_prefs->in_ssl_client_cert_pass) > 1) { + passwd_store_set(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_RECV_CERT, ac_prefs->in_ssl_client_cert_pass, TRUE); + } + if (ac_prefs->out_ssl_client_cert_pass != NULL + && strlen(ac_prefs->out_ssl_client_cert_pass) > 1) { + passwd_store_set(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_SEND_CERT, ac_prefs->out_ssl_client_cert_pass, TRUE); + } + ac_prefs->receive_in_progress = FALSE; prefs_custom_header_read_config(ac_prefs); diff --git a/src/prefs_gtk.c b/src/prefs_gtk.c @@ -324,7 +324,6 @@ gint prefs_write_param(PrefParam *param, FILE *fp) for (i = 0; param[i].name != NULL; i++) { switch (param[i].type) { case P_STRING: - case P_PASSWORD: { gchar *tmp = NULL; @@ -346,6 +345,8 @@ gint prefs_write_param(PrefParam *param, FILE *fp) g_free(tmp); break; } + case P_PASSWORD: + break; case P_INT: g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name, *((gint *)param[i].data)); @@ -630,17 +631,14 @@ void prefs_set_data_from_entry(PrefParam *pparam) g_free(*str); *str = entry_str[0] ? g_strdup(entry_str) : NULL; break; + case P_PASSWORD: + break; case P_USHORT: *((gushort *)pparam->data) = atoi(entry_str); break; case P_INT: *((gint *)pparam->data) = atoi(entry_str); break; - case P_PASSWORD: - str = (gchar **)pparam->data; - g_free(*str); - *str = password_encrypt(entry_str, NULL); - break; default: g_warning("Invalid PrefType for GtkEntry widget: %d", pparam->type); @@ -668,7 +666,6 @@ void prefs_set_escaped_data_from_entry(PrefParam *pparam) void prefs_set_entry(PrefParam *pparam) { gchar **str; - char *decrypted_pass = NULL; cm_return_if_fail(*pparam->widget != NULL); switch (pparam->type) { @@ -685,16 +682,6 @@ void prefs_set_entry(PrefParam *pparam) gtk_entry_set_text(GTK_ENTRY(*pparam->widget), itos(*((gushort *)pparam->data))); break; - case P_PASSWORD: - str = (gchar **)pparam->data; - decrypted_pass = password_decrypt(*str, NULL); - gtk_entry_set_text(GTK_ENTRY(*pparam->widget), - (decrypted_pass != NULL ? decrypted_pass : "")); - if (decrypted_pass != NULL) { - memset(decrypted_pass, 0, strlen(decrypted_pass)); - } - g_free(decrypted_pass); - break; default: g_warning("Invalid PrefType for GtkEntry widget: %d", pparam->type); @@ -729,7 +716,6 @@ void prefs_set_data_from_text(PrefParam *pparam) switch (pparam->type) { case P_STRING: - case P_PASSWORD: str = (gchar **)pparam->data; g_free(*str); if (GTK_IS_EDITABLE(*pparam->widget)) { /* need? */ @@ -802,7 +788,6 @@ void prefs_set_text(PrefParam *pparam) switch (pparam->type) { case P_STRING: - case P_PASSWORD: str = (gchar **)pparam->data; if (*str) { bufp = buf = alloca(strlen(*str) + 1); diff --git a/src/send_message.c b/src/send_message.c @@ -54,7 +54,7 @@ #include "gtkutils.h" #include "inc.h" #include "log.h" -#include "password.h" +#include "passwordstore.h" typedef struct _SendProgressDialog SendProgressDialog; @@ -306,7 +306,8 @@ gint send_message_smtp_full(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp, g /* NOP */; } else if (ac_prefs->smtp_passwd) smtp_session->pass = - password_decrypt(ac_prefs->smtp_passwd, NULL); + passwd_store_get(PWS_ACCOUNT, ac_prefs->account_name, + PWS_ACCOUNT_SEND); else { smtp_session->pass = input_dialog_query_password_keep @@ -325,7 +326,8 @@ gint send_message_smtp_full(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp, g &(smtp_session->pass))) { /* NOP */; } else if (ac_prefs->passwd) - smtp_session->pass = password_decrypt(ac_prefs->passwd, NULL); + smtp_session->pass = passwd_store_get(PWS_ACCOUNT, + ac_prefs->account_name, PWS_ACCOUNT_RECV); else { smtp_session->pass = input_dialog_query_password_keep diff --git a/src/wizard.c b/src/wizard.c @@ -50,7 +50,7 @@ #endif #include "prefs_common.h" #include "combobox.h" -#include "password.h" +#include "passwordstore.h" typedef enum { @@ -757,13 +757,20 @@ static gboolean wizard_write_config(WizardWindow *wizard) prefs_account->userid = g_strdup( gtk_entry_get_text(GTK_ENTRY(wizard->recv_username))); - prefs_account->passwd = password_encrypt( - gtk_entry_get_text(GTK_ENTRY(wizard->recv_password)), NULL); - prefs_account->smtp_userid = g_strdup( gtk_entry_get_text(GTK_ENTRY(wizard->smtp_username))); - prefs_account->smtp_passwd = password_encrypt( - gtk_entry_get_text(GTK_ENTRY(wizard->smtp_password)), NULL); + + passwd_store_set(PWS_ACCOUNT, + prefs_account->account_name, + PWS_ACCOUNT_RECV, + gtk_entry_get_text(GTK_ENTRY(wizard->recv_password)), + FALSE); + passwd_store_set(PWS_ACCOUNT, + prefs_account->account_name, + PWS_ACCOUNT_SEND, + gtk_entry_get_text(GTK_ENTRY(wizard->smtp_password)), + FALSE); + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wizard->smtp_auth))) { prefs_account->use_smtp_auth = TRUE; } @@ -794,13 +801,21 @@ static gboolean wizard_write_config(WizardWindow *wizard) prefs_account->out_ssl_client_cert_file = g_strdup( gtk_entry_get_text(GTK_ENTRY(wizard->smtp_ssl_cert_file))); - prefs_account->out_ssl_client_cert_pass = g_strdup( - gtk_entry_get_text(GTK_ENTRY(wizard->smtp_ssl_cert_pass))); prefs_account->in_ssl_client_cert_file = g_strdup( gtk_entry_get_text(GTK_ENTRY(wizard->recv_ssl_cert_file))); - prefs_account->in_ssl_client_cert_pass = g_strdup( - gtk_entry_get_text(GTK_ENTRY(wizard->recv_ssl_cert_pass))); + + passwd_store_set(PWS_ACCOUNT, + prefs_account->account_name, + PWS_ACCOUNT_SEND_CERT, + gtk_entry_get_text(GTK_ENTRY(wizard->smtp_ssl_cert_pass)), + FALSE); + passwd_store_set(PWS_ACCOUNT, + prefs_account->account_name, + PWS_ACCOUNT_RECV_CERT, + gtk_entry_get_text(GTK_ENTRY(wizard->recv_ssl_cert_pass)), + FALSE); #endif + if (prefs_account->protocol == A_IMAP4) { gchar *directory = gtk_editable_get_chars( GTK_EDITABLE(wizard->recv_imap_subdir), 0, -1);