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:
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);