On Thu, 2011-10-20 at 12:50 -0400, Matthew Barnes wrote: > > I think we could achieve this with multiple calls to > camel_session_authenticate_sync() with a different mechanism name each > time ("kerberos", "ntlm", "login"), and making sure the session logic > knows when to loop and when to bail out if an auth attempt fails. > > It already kinda does that by looking up the CamelServiceAuthType struct > associated with the mechanism name (if one was given) and checking its > 'need_password' flag. If FALSE, it does ONE authentication attempt and > bails on failure (instead of looping). After which you could possibly > call camel_session_authenticate_sync() again with a fallback mechanism > name. > > Problem is when a mechanism name is NOT given, as is the case for most > HTTP-based backends, or when 'need_password' is TRUE, it assumes you'll > *will* need a password to authenticate and prompts if one is not found > in the keyring (which I understand now to be a bad assumption). That's > the part that needs tweaking, for now.
Yeah, the provider could just call camel_session_authenticate_sync() as and when it actually *needs* a password (which looks fairly much to be what imapx *is* doing, so I'm not really sure why it's demanding my password unnecessarily). The issue is the complexity. What happens is that the provider calls out to camel_session_authenticate_sync(), which then calls back to the provider to give it the information it wanted... but it provides it in a *synchronous* method and waits for a result, so we can't just hand off the password with a GAsyncResult to the code which called camel_session_authenticate_sync() in the first place; we have to do nasty things with threads and avoid deadlock while we make our provider's ->authenticate_sync() actually wait for the completion of the function which *called* it. Forget EWS for now; let's just look at it in imapx. This bit in imapx_create_new_connection(), for example: /* XXX As part of the connect operation the CamelIMAPXServer will * have to call camel_session_authenticate_sync(), but it has * no way to pass itself through in that call so the service * knows which CamelIMAPXServer is trying to authenticate. * * IMAPX is the only provider that does multiple connections * like this, so I didn't want to pollute the CamelSession and * CamelService authentication APIs with an extra argument. * Instead we do this little hack so the service knows which * CamelIMAPXServer to act on in its authenticate_sync() method. * * Because we're holding the CAMEL_SERVICE_REC_CONNECT_LOCK * (and our own CON_LOCK for that matter) we should not have * multiple IMAPX connections trying to authenticate at once, * so this should be thread-safe. */ imapx_store->authenticating_server = g_object_ref (conn); success = camel_imapx_server_connect (conn, cancellable, error); g_object_unref (imapx_store->authenticating_server); Then in imapx_reconnect() you call camel_session_authenticate_sync() which ends up calling *back* to imapx's imapx_authenticate_sync() method... which uses that nastily-stashed 'server' object... which was RIGHT THERE in the imapx_reconnect() function. We could have just returned the password to imapx_reconnect() and all would have been well. I'm unlikely to get much done before I disappear to Prague on Saturday, and I'm on baby duty tomorrow because she's unwell and can't go to nursery, but I'll try to put together a patch which sorts this out. Maybe during next week. -- dwmw2 _______________________________________________ evolution-hackers mailing list email@example.com To change your list options or unsubscribe, visit ... http://mail.gnome.org/mailman/listinfo/evolution-hackers