Re: [evolution-patches] all components, password serialisation patch



discovered a bug while trying this out, crashed when I hit Send in my
composer w/ SMIME Sign enabled because get_password() in mail-session.c
tried to dereference a NULL service pointer.

attached is the mail-session.c diff as it is after my patch to your
patch.

arguably for the non-service case, we could do away with:

if ((flags & CAMEL_SESSION_PASSWORD_STATIC) != 0)
	eflags = E_PASSWORDS_REMEMBER_NEVER;
else
	eflags = E_PASSWORDS_REMEMBER_SESSION;

and just do:

eflags = E_PASSWORDS_REMEMBER_NEVER;

since we can't actually remember non-service passwords anyway?

Jeff

On Tue, 2004-08-10 at 13:25 +0000, Not Zed wrote:
> 
> this seems to be the only way to fix the password serialisation
> problem across all components.
> 
> its more or less a movement of the mail's password stuff to e-
> password, including making it fully mt-safe, which greatly simplifies
> the mail's calls to it, and could probably simplify the async
> callbacks in other components too.
> 
> it isn't entirely the same as what the mailer had though, since it now
> also guarantees execution order even from (recursive) calls from the
> gui thread, so  i don't know if it hasn't added other problems.
> 
> it will gaurantee you never get more than 1 password dialogue up at a
> time, requests areprocessed in the order they come in, etc etc.
> 
> -- 
> 
> Michael Zucchi <notzed ximian com>
> "born to die, live to work, it's
> all downhill from here"
> Novell's Evolution and Free
> Software Developer
-- 
Jeffrey Stedfast
Evolution Hacker - Novell, Inc.
fejj ximian com  - www.novell.com
Index: mail-session.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-session.c,v
retrieving revision 1.96
diff -u -r1.96 mail-session.c
--- mail-session.c	17 Jun 2004 07:34:50 -0000	1.96
+++ mail-session.c	10 Aug 2004 21:01:00 -0000
@@ -166,260 +166,109 @@
 
 /* ********************************************************************** */
 
-static GtkDialog *password_dialog = NULL;
-static EDList password_list = E_DLIST_INITIALISER(password_list);
-
-struct _pass_msg {
-	struct _mail_msg msg;
-	
-	CamelSession *session;
-	CamelService *service;
-	const char *domain;
-	const char *prompt;
-	const char *item;
-	guint32 flags;
-	CamelException *ex;
-	
-	char *service_url;
-	char *key;
-
-	EAccountService *config_service;
-	GtkWidget *check;
-	GtkWidget *entry;
-	char *result;
-	int ismain;
-};
-
-static void do_get_pass(struct _mail_msg *mm);
-
-static void
-pass_activate (GtkEntry *entry, void *data)
-{
-	if (password_dialog)
-		gtk_dialog_response (password_dialog, GTK_RESPONSE_OK);
-}
-
-static void
-pass_response (GtkDialog *dialog, int button, void *data)
+static char *
+get_password (CamelSession *session, CamelService *service, const char *domain,
+	      const char *prompt, const char *item, guint32 flags, CamelException *ex)
 {
-	struct _pass_msg *m = data;
-	
-	switch (button) {
-	case GTK_RESPONSE_OK:
-	{
-		gboolean cache, remember;
-		
-		m->result = g_strdup (gtk_entry_get_text ((GtkEntry *) m->entry));
-		remember = cache = m->check ? gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m->check)) : FALSE;
-		
-		if (m->service_url) {
-			if (m->config_service) {
-				mail_config_service_set_save_passwd (m->config_service, cache);
+	gboolean remember = FALSE;
+	char *ret = NULL;
+	EAccount *account;
+	guint32 eflags;
+	
+	if (domain == NULL)
+		domain = "Mail";
+	
+	if (service != NULL) {
+		char *url = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
+		
+		if (!strcmp(item, "popb4smtp_uri")) {
+			/* not 100% mt safe, but should be ok */
+			account = mail_config_get_account_by_transport_url (url);
+			g_free(url);
+			if (account)
+				ret = g_strdup(account->source->url);
+		} else {
+			char *key = make_key(service, item);
+			EAccountService *config_service;
+			
+			ret = e_passwords_get_password(domain, key);
+			if (ret == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
+				char *title;
+				
+				if ((account = mail_config_get_account_by_source_url(url)))
+					config_service = account->source;
+				else if ((account = mail_config_get_account_by_transport_url(url)))
+					config_service = account->transport;
+				else
+					config_service = NULL;
+				
+				if (config_service)
+					remember = config_service->save_passwd;
+				
+				if (account)
+					title = g_strdup_printf (_("Enter Password for %s"), account->name);
+				else
+					title = g_strdup (_("Enter Password"));
+				
+				if ((flags & CAMEL_SESSION_PASSWORD_STATIC) != 0)
+					eflags = E_PASSWORDS_REMEMBER_NEVER;
+				else if (config_service == NULL)
+					eflags = E_PASSWORDS_REMEMBER_SESSION;
+				else
+					eflags = E_PASSWORDS_REMEMBER_FOREVER;
+				
+				if (flags & CAMEL_SESSION_PASSWORD_REPROMPT)
+					eflags |= E_PASSWORDS_REPROMPT;
+				
+				if (flags & CAMEL_SESSION_PASSWORD_SECRET)
+					eflags |= E_PASSWORDS_SECRET;
+				
+				ret = e_passwords_ask_password(title, domain, key, prompt, eflags, &remember, NULL);
 				
-				/* set `cache' to TRUE because people don't want to have to
-				   re-enter their passwords for this session even if they told
-				   us not to cache their passwords in the dialog...*sigh* */
-				cache = TRUE;
+				g_free(title);
+				
+				if (ret && config_service)
+					mail_config_service_set_save_passwd(config_service, remember);
 			}
-		} else {
-			/* we can't remember the password if it isn't for an account (pgp?) */
-			remember = FALSE;
-		}
-		
-		if (cache) {
-			/* cache the password for the session */
-			e_passwords_add_password (m->key, m->result);
 			
-			/* should we remember it between sessions? */
-			if (remember)
-				e_passwords_remember_password ("Mail", m->key);
+			g_free(key);
 		}
-		break;
-	}
-	default:
-		camel_exception_set (m->ex, CAMEL_EXCEPTION_USER_CANCEL, _("User canceled operation."));
-		break;
-	}
-
-	gtk_widget_destroy ((GtkWidget *) dialog);
-
-	password_dialog = NULL;
-	e_msgport_reply ((EMsg *)m);
-	
-	if ((m = (struct _pass_msg *) e_dlist_remhead (&password_list)))
-		do_get_pass ((struct _mail_msg *) m);
-}
-
-static void
-request_password (struct _pass_msg *m)
-{
-	EAccount *mca = NULL;
-	GtkWidget *vbox;
-	char *title;
-	
-	/* If we already have a password_dialog up, save this request till later */
-	if (!m->ismain && password_dialog) {
-		e_dlist_addtail (&password_list, (EDListNode *)m);
-		return;
-	}
-	
-	if (m->service_url) {
-		if ((mca = mail_config_get_account_by_source_url (m->service_url)))
-			m->config_service = mca->source;
-		else if ((mca = mail_config_get_account_by_transport_url (m->service_url)))
-			m->config_service = mca->transport;
-	}
-	
-	if (mca)
-		title = g_strdup_printf (_("Enter Password for %s"), mca->name);
-	else
-		title = g_strdup (_("Enter Password"));
-	
-	password_dialog = (GtkDialog *)e_error_new(NULL, "mail:ask-session-password", m->prompt, NULL);
-	gtk_window_set_title (GTK_WINDOW (password_dialog), title);
-	g_free (title);
-
-	vbox = gtk_vbox_new (FALSE, 6);
-	gtk_widget_show (vbox);
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (password_dialog)->vbox), vbox, TRUE, FALSE, 0);
-	gtk_container_set_border_width((GtkContainer *)vbox, 6);
-	
-	m->entry = gtk_entry_new ();
-	gtk_entry_set_visibility ((GtkEntry *) m->entry, !(m->flags & CAMEL_SESSION_PASSWORD_SECRET));
-	g_signal_connect (m->entry, "activate", G_CALLBACK (pass_activate), password_dialog);
-	gtk_box_pack_start (GTK_BOX (vbox), m->entry, TRUE, FALSE, 3);
-	gtk_widget_show (m->entry);
-	gtk_widget_grab_focus (m->entry);
-	
-	if ((m->flags & CAMEL_SESSION_PASSWORD_REPROMPT) && m->result) {
-		gtk_entry_set_text ((GtkEntry *) m->entry, m->result);
-		g_free (m->result);
-		m->result = NULL;
-	}
-
-	/* static password, shouldn't be remembered between sessions,
-	   but will be remembered within the session beyond our control */
-	if ((m->service_url == NULL || m->service != NULL)
-	    && (m->flags & CAMEL_SESSION_PASSWORD_STATIC) == 0) {
-		m->check = gtk_check_button_new_with_mnemonic (m->service_url ? _("_Remember this password")
-							       : _("_Remember this password for the remainder of this session"));
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m->check),
-					      m->config_service ? m->config_service->save_passwd : FALSE);
-		gtk_box_pack_start (GTK_BOX (vbox), m->check, TRUE, FALSE, 3);
-		gtk_widget_show (m->check);
-	}
-	
-	if (m->ismain) {
-		pass_response(password_dialog, gtk_dialog_run (password_dialog), m);
-	} else {
-		g_signal_connect (password_dialog, "response", G_CALLBACK (pass_response), m);
-		gtk_widget_show ((GtkWidget *) password_dialog);
-	}
-}
-
-static void
-do_get_pass(struct _mail_msg *mm)
-{
-	struct _pass_msg *m = (struct _pass_msg *)mm;
-	MailSession *mail_session = MAIL_SESSION (m->session);
-	
-	if (!strcmp (m->item, "popb4smtp_uri")) {
-		char *url = camel_url_to_string (m->service->url, 0);
-		EAccount *account = mail_config_get_account_by_transport_url (url);
 		
 		g_free(url);
-		if (account)
-			m->result = g_strdup(account->source->url);
-	} else if (m->key) {
-		m->result = e_passwords_get_password (m->domain?m->domain:"Mail", m->key);
-		if (m->result == NULL || (m->flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
-			if (mail_session->interactive) {
-				request_password(m);
-				return;
-			}
-		}
-	}
-
-	e_msgport_reply((EMsg *)mm);
-}
-
-static void
-do_free_pass(struct _mail_msg *mm)
-{
-	struct _pass_msg *m = (struct _pass_msg *)mm;
-
-	g_free(m->service_url);
-	g_free(m->key);
-}
-
-static struct _mail_msg_op get_pass_op = {
-	NULL,
-	do_get_pass,
-	NULL,
-	do_free_pass,
-};
-
-static char *
-get_password (CamelSession *session, CamelService *service, const char *domain,
-	      const char *prompt, const char *item, guint32 flags, CamelException *ex)
-{
-	struct _pass_msg *m, *r;
-	EMsgPort *pass_reply;
-	char *ret;
-	
-	/* We setup an async request and send it off, and wait for it to return */
-	/* If we're really in main, we dont of course ...
-	   ... but this shouldn't be allowed because of locking issues */
-	pass_reply = e_msgport_new ();
-	m = mail_msg_new(&get_pass_op, pass_reply, sizeof(struct _pass_msg));
-	m->ismain = pthread_self() == mail_gui_thread;
-	m->session = session;
-	m->prompt = prompt;
-	m->flags = flags;
-	m->service = service;
-	m->domain = domain;
-	m->item = item;
-	m->ex = ex;
-	if (service)
-		m->service_url = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
-	m->key = make_key(service, item);
-
-	if (m->ismain) {
-		do_get_pass((struct _mail_msg *)m);
 	} else {
-		extern EMsgPort *mail_gui_port2;
-		
-		e_msgport_put(mail_gui_port2, (EMsg *)m);
+		ret = e_passwords_get_password (domain, item);
+		if (ret == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
+			if ((flags & CAMEL_SESSION_PASSWORD_STATIC) != 0)
+				eflags = E_PASSWORDS_REMEMBER_NEVER;
+			else
+				eflags = E_PASSWORDS_REMEMBER_SESSION;
+			
+			if (flags & CAMEL_SESSION_PASSWORD_REPROMPT)
+				eflags |= E_PASSWORDS_REPROMPT;
+				
+			if (flags & CAMEL_SESSION_PASSWORD_SECRET)
+				eflags |= E_PASSWORDS_SECRET;
+			
+			ret = e_passwords_ask_password (_("Enter Password"), domain, item, prompt,
+							eflags, &remember, NULL);
+		}
 	}
 	
-	e_msgport_wait(pass_reply);
-	r = (struct _pass_msg *)e_msgport_get(pass_reply);
-	g_assert(m == r);
+	if (ret == NULL)
+		camel_exception_set(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User canceled operation."));
 
-	ret = m->result;
-	mail_msg_free(m);
-	e_msgport_destroy(pass_reply);
-	
 	return ret;
 }
 
 static void
-main_forget_password (CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex)
+forget_password (CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex)
 {
 	char *key = make_key (service, item);
-	
+
 	e_passwords_forget_password (domain?domain:"Mail", key);
-	
 	g_free (key);
 }
 
-static void
-forget_password (CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex)
-{
-	mail_call_main(MAIL_CALL_p_ppppp, (MailMainFunc)main_forget_password,
-		       session, service, domain, item, ex);
-}
-
 /* ********************************************************************** */
 
 static GtkDialog *message_dialog;
@@ -834,21 +683,10 @@
 		struct _user_message_msg *um;
 		
 		d(printf ("Gone non-interactive, checking for outstanding interactive tasks\n"));
+
+		e_passwords_cancel();
 		
-		/* clear out pending password requests */
-		while ((pm = (struct _pass_msg *) e_dlist_remhead (&password_list))) {
-			d(printf ("Flushing password request : %s\n", pm->prompt));
-			e_msgport_reply ((EMsg *) pm);
-		}
-		
-		/* destroy the current */
-		if (password_dialog) {
-			d(printf ("Destroying password dialogue\n"));
-			gtk_widget_destroy ((GtkWidget *) password_dialog);
-			password_dialog =  NULL;
-		}
-		
-		/* same for pending user messages */
+		/* flush/cancel pending user messages */
 		while ((um = (struct _user_message_msg *) e_dlist_remhead (&message_list))) {
 			d(printf ("Flusing message request: %s\n", um->prompt));
 			e_msgport_reply((EMsg *) um);

Attachment: smime.p7s
Description: S/MIME cryptographic signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]