From 7c69d2523a8b4760065b1596c1837292e9dfff53 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 1 Dec 2000 20:25:10 +0000 Subject: Writes out passwords (to .gnome_private) in our patented proprietary "Best * session.c (mail_session_remember_password): Writes out passwords (to .gnome_private) in our patented proprietary "Best Awesome Super Encryption 64" ("BASE64") format which could not possibly ever be cracked by even the most cryptographically knowledgeable five-year-olds. (mail_session_init): Load remembered passwords at startup. (mail_session_forget_passwords): Erase them from disk as well as memory. * mail-config.c: Add "remember_password" field to MailConfigService. (mail_config_write_on_exit): Call mail_session_remember_password for services with "remember_password" set. * mail-config-gui.c: Add "remember password" checkbox to the dialogs, and make it appear and disappear as appropriate. svn path=/trunk/; revision=6760 --- mail/ChangeLog | 22 ++++++++++++++++ mail/mail-config-gui.c | 32 ++++++++++++++++++++--- mail/mail-config.c | 17 ++++++++++++ mail/mail-config.h | 1 + mail/mail-session.h | 1 + mail/session.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 136 insertions(+), 8 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index 51bbdbf099..172bdd6ca4 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,25 @@ +2000-12-01 Dan Winship + + * session.c (mail_session_remember_password): Writes out passwords + (to .gnome_private) in our patented proprietary "Best Awesome + Super Encryption 64" ("BASE64") format which could not possibly + ever be cracked by even the most cryptographically knowledgeable + five-year-olds. + (mail_session_init): Load remembered passwords at startup. + (mail_session_forget_passwords): Erase them from disk as well as + memory. + + * mail-config.c: Add "remember_password" field to + MailConfigService. + (mail_config_write_on_exit): Call mail_session_remember_password + for services with "remember_password" set. + * mail-config-gui.c: Add "remember password" checkbox to the + dialogs, and make it appear and disappear as appropriate. + + * component-factory.c (mail_load_storages): Unref the store + regardless of whether or not we're using it, so we don't leak + references to non-storage stores. + 2000-12-01 Jeffrey Stedfast * message-list.c (e_mail_address_new): Perform better diff --git a/mail/mail-config-gui.c b/mail/mail-config-gui.c index 90e11083f0..513a1bcd5e 100644 --- a/mail/mail-config-gui.c +++ b/mail/mail-config-gui.c @@ -83,6 +83,7 @@ typedef struct GtkWidget *auth_html; GtkWidget *auth_detect; GtkWidget *keep_on_server; + GtkWidget *remember_password; gint pnum; } MailDialogServicePageItem; @@ -708,6 +709,9 @@ service_page_set_url (MailDialogServicePage *page, MailConfigService *service) if (spitem->keep_on_server) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (spitem->keep_on_server), service->keep_on_server); + if (spitem->remember_password) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (spitem->remember_password), service->remember_password); + camel_exception_free (ex); camel_url_free (url); } @@ -721,6 +725,10 @@ service_page_item_auth_activate (GtkWidget *menuitem, authtype = gtk_object_get_data (GTK_OBJECT (menuitem), "authtype"); put_html (GTK_HTML (spitem->auth_html), _(authtype->description)); + if (authtype->need_password) + gtk_widget_show (spitem->remember_password); + else + gtk_widget_hide (spitem->remember_password); } static void @@ -780,7 +788,15 @@ service_page_extract (MailDialogServicePage *page) if (spitem->keep_on_server) { source->keep_on_server = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON (spitem->keep_on_server)); - } + } else + source->keep_on_server = FALSE; + + if (spitem->remember_password && + GTK_WIDGET_VISIBLE (spitem->remember_password)) { + source->remember_password = gtk_toggle_button_get_active ( + GTK_TOGGLE_BUTTON (spitem->remember_password)); + } else + source->remember_password = FALSE; return source; } @@ -890,7 +906,7 @@ service_page_item_new (MailDialogServicePage *page, MailService *mcs) description->parent->parent, TRUE, TRUE, 0); - table = gtk_table_new (6, 3, FALSE); + table = gtk_table_new (7, 3, FALSE); gtk_table_set_row_spacings (GTK_TABLE (table), 2); gtk_table_set_col_spacings (GTK_TABLE (table), 10); gtk_container_set_border_width (GTK_CONTAINER (table), 8); @@ -948,17 +964,25 @@ service_page_item_new (MailDialogServicePage *page, MailService *mcs) GTK_SIGNAL_FUNC (service_page_detect), page); + item->remember_password = gtk_check_button_new_with_label ( + _("Remember this password")); + gtk_signal_connect (GTK_OBJECT (item->keep_on_server), "toggled", + GTK_SIGNAL_FUNC (service_page_item_changed), + page); + gtk_table_attach (GTK_TABLE (table), item->remember_password, + 1, 3, row + 1, row + 2, GTK_FILL, 0, 0, 0); + item->auth_html = html_new (TRUE); gtk_table_attach (GTK_TABLE (table), item->auth_html->parent->parent, - 0, 3, row + 1, row + 2, + 0, 3, row + 2, row + 3, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); /* this is done async */ url = camel_url_to_string (mcs->service->url, FALSE); config_do_query_authtypes (page, url, item); g_free (url); - row += 2; + row += 3; } if ((mcs->provider->flags & CAMEL_PROVIDER_IS_REMOTE) && diff --git a/mail/mail-config.c b/mail/mail-config.c index 2bbd9194f3..18927b4aa3 100644 --- a/mail/mail-config.c +++ b/mail/mail-config.c @@ -107,6 +107,7 @@ service_copy (MailConfigService *source) newsource = g_new0 (MailConfigService, 1); newsource->url = g_strdup (source->url); newsource->keep_on_server = source->keep_on_server; + newsource->remember_password = source->remember_password; return newsource; } @@ -232,6 +233,9 @@ config_read (void) path = g_strdup_printf ("keep_on_server_%d", i); s->keep_on_server = gnome_config_get_bool (path); g_free (path); + path = g_strdup_printf ("remember_password_%d", i); + s->remember_password = gnome_config_get_bool (path); + g_free (path); config->sources = g_slist_append (config->sources, s); } @@ -351,6 +355,9 @@ mail_config_write (void) path = g_strdup_printf ("keep_on_server_%d", i); gnome_config_set_bool (path, s->keep_on_server); g_free (path); + path = g_strdup_printf ("remember_password_%d", i); + gnome_config_set_bool (path, s->remember_password); + g_free (path); } gnome_config_pop_prefix (); @@ -398,6 +405,8 @@ void mail_config_write_on_exit (void) { gchar *str; + GSList *sources; + MailConfigService *s; /* Show Messages Threaded */ str = g_strdup_printf ("=%s/config/Mail=/Display/thread_list", @@ -411,6 +420,14 @@ mail_config_write_on_exit (void) gnome_config_set_int (str, config->paned_size); g_free (str); + /* Passwords */ + gnome_config_private_clean_section ("/Evolution/Passwords"); + for (sources = config->sources; sources; sources = sources->next) { + s = sources->data; + if (s->remember_password) + mail_session_remember_password (s->url); + } + gnome_config_sync (); } diff --git a/mail/mail-config.h b/mail/mail-config.h index e11ce1a67f..bbf7176acb 100644 --- a/mail/mail-config.h +++ b/mail/mail-config.h @@ -38,6 +38,7 @@ typedef struct { gchar *url; gboolean keep_on_server; + gboolean remember_password; } MailConfigService; /* Identities */ diff --git a/mail/mail-session.h b/mail/mail-session.h index da0ca15ff3..3df9516156 100644 --- a/mail/mail-session.h +++ b/mail/mail-session.h @@ -37,6 +37,7 @@ char *mail_session_request_dialog (const char *prompt, gboolean secret, const char *key, gboolean async); void mail_session_forget_passwords (BonoboUIComponent *uih, void *user_data, const char *path); +void mail_session_remember_password (const char *url); extern CamelSession *session; diff --git a/mail/session.c b/mail/session.c index 6bcfc96404..aa98c20908 100644 --- a/mail/session.c +++ b/mail/session.c @@ -64,9 +64,6 @@ auth_callback (CamelAuthCallbackMode mode, char *data, gboolean secret, { char *key, *ans, *url; - if (!passwords) - passwords = g_hash_table_new (g_str_hash, g_str_equal); - url = camel_url_to_string (service->url, FALSE); key = g_strdup_printf ("%s:%s", url, item); g_free (url); @@ -102,6 +99,58 @@ auth_callback (CamelAuthCallbackMode mode, char *data, gboolean secret, return ans; } +static char * +decode_base64 (char *base64) +{ + char *plain, *pad = "=="; + int len, out, state, save; + + len = strlen (base64); + plain = g_malloc0 (len); + state = save = 0; + out = base64_decode_step (base64, len, plain, &state, &save); + if (len % 4) { + base64_decode_step (pad, 4 - len % 4, plain + out, + &state, &save); + } + + return plain; +} + +static void +maybe_remember_password (gpointer key, gpointer password, gpointer url) +{ + char *path, *key64, *pass64; + int len, state, save; + + len = strlen (url); + if (strncmp (key, url, len) != 0) + return; + + len = strlen (key); + key64 = g_malloc0 ((len + 2) * 4 / 3 + 1); + state = save = 0; + base64_encode_close (key, len, FALSE, key64, &state, &save); + path = g_strdup_printf ("/Evolution/Passwords/%s", key64); + g_free (key64); + + len = strlen (password); + pass64 = g_malloc0 ((len + 2) * 4 / 3 + 1); + state = save = 0; + base64_encode_close (password, len, FALSE, pass64, &state, &save); + + gnome_config_private_set_string (path, pass64); + g_free (path); + g_free (pass64); +} + +void +mail_session_remember_password (const char *url) +{ + g_hash_table_foreach (passwords, maybe_remember_password, url); +} + + /* ******************** */ typedef struct _timeout_data_s { @@ -190,13 +239,25 @@ remove_callback (guint handle) void mail_session_init (void) { - char *camel_dir; + char *camel_dir, *key, *value; + void *iter; camel_init (); camel_dir = g_strdup_printf ("%s/mail", evolution_dir); session = camel_session_new (camel_dir, auth_callback, register_callback, remove_callback); g_free (camel_dir); + + passwords = g_hash_table_new (g_str_hash, g_str_equal); + iter = gnome_config_private_init_iterator ("/Evolution/Passwords"); + if (iter) { + while (gnome_config_iterator_next (iter, &key, &value)) { + g_hash_table_insert (passwords, decode_base64 (key), + decode_base64 (value)); + g_free (key); + g_free (value); + } + } } static gboolean @@ -213,4 +274,6 @@ mail_session_forget_passwords (BonoboUIComponent *uih, void *user_data, const char *path) { g_hash_table_foreach_remove (passwords, free_entry, NULL); + gnome_config_private_clean_section ("/Evolution/Passwords"); + gnome_config_sync (); } -- cgit v1.2.3