diff options
-rw-r--r-- | camel/ChangeLog | 7 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 206 |
2 files changed, 108 insertions, 105 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 7adf2060d6..1c3d1a031c 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,10 @@ +2000-08-12 Dan Winship <danw@helixcode.com> + + * providers/pop3/camel-pop3-store.c (pop3_try_authenticate): New + function to do one round of attempted authentication. + (pop3_connect): Move a bunch of code out into + pop3_try_authenticate and fix some bugs in the edge cases. + 2000-08-12 Jeffrey Stedfast <fejj@helixcode.com> * providers/imap/camel-imap-store.c (query_auth_types): No longer diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c index 3cab99e0dd..78d7d106e5 100644 --- a/camel/providers/pop3/camel-pop3-store.c +++ b/camel/providers/pop3/camel-pop3-store.c @@ -397,15 +397,91 @@ camel_pop3_store_expunge (CamelPop3Store *store, CamelException *ex) pop3_disconnect (CAMEL_SERVICE (store), ex); } + static gboolean -pop3_connect (CamelService *service, CamelException *ex) +pop3_try_authenticate (CamelService *service, gboolean kpop, + const char *errmsg, CamelException *ex) { - CamelPop3Store *store = CAMEL_POP3_STORE (service); + CamelPop3Store *store = (CamelPop3Store *)service; int status; - char *msg, *errbuf = NULL; - gboolean authenticated = FALSE; - gboolean auth_supported = TRUE; - gboolean kpop = FALSE; + char *msg; + + /* The KPOP code will have set the password to be the username + * in connect_to_server. Password and APOP are the only other + * cases, and they both need a password. So if there's no + * password stored, query for it. + */ + if (!service->url->passwd) { + char *prompt; + + prompt = g_strdup_printf ("%sPlease enter the POP3 password " + "for %s@%s", errmsg ? errmsg : "", + service->url->user, + service->url->host); + service->url->passwd = camel_session_query_authenticator ( + camel_service_get_session (service), + CAMEL_AUTHENTICATOR_ASK, prompt, TRUE, + service, "password", ex); + g_free (prompt); + if (!service->url->passwd) + return FALSE; + } + + if (!service->url->authmech || kpop) { + status = camel_pop3_command (store, &msg, "USER %s", + service->url->user); + if (status != CAMEL_POP3_OK) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, + "Unable to connect to POP " + "server.\nError sending " + "username: %s", + msg ? msg : "(Unknown)"); + g_free (msg); + return FALSE; + } + g_free (msg); + + status = camel_pop3_command (store, &msg, "PASS %s", + service->url->passwd); + } else if (!strcmp (service->url->authmech, "+APOP") + && store->apop_timestamp) { + char *secret, md5asc[33], *d; + unsigned char md5sum[16], *s; + + secret = g_strdup_printf ("%s%s", store->apop_timestamp, + service->url->passwd); + md5_get_digest (secret, strlen (secret), md5sum); + g_free (secret); + + for (s = md5sum, d = md5asc; d < md5asc + 32; s++, d += 2) + sprintf (d, "%.2x", *s); + + status = camel_pop3_command (store, &msg, "APOP %s %s", + service->url->user, md5asc); + } else { + camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, + "Unable to connect to POP server.\n" + "No support for requested authentication " + "mechanism."); + return FALSE; + } + + if (status != CAMEL_POP3_OK) { + camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, + "Unable to connect to POP server.\n" + "Error sending password: %s", + msg ? msg : "(Unknown)"); + } + + g_free (msg); + return camel_exception_is_set (ex); +} + +static gboolean +pop3_connect (CamelService *service, CamelException *ex) +{ + char *errbuf = NULL; + gboolean tryagain, kpop = FALSE; #ifdef HAVE_KRB4 kpop = (service->url->authmech && @@ -419,112 +495,32 @@ pop3_connect (CamelService *service, CamelException *ex) if (!connect_to_server (service, TRUE, ex)) return FALSE; - while (auth_supported && !authenticated) { - if (errbuf) { - /* We need to un-cache the password before prompting again */ - camel_session_query_authenticator (camel_service_get_session (service), - CAMEL_AUTHENTICATOR_TELL, NULL, - TRUE, service, "password", ex); + camel_exception_clear (ex); + do { + if (camel_exception_is_set (ex)) { + errbuf = g_strdup_printf ( + "%s\n\n", + camel_exception_get_description (ex)); + + /* Uncache the password before prompting again. */ + camel_session_query_authenticator ( + camel_service_get_session (service), + CAMEL_AUTHENTICATOR_TELL, NULL, TRUE, service, + "password", ex); g_free (service->url->passwd); service->url->passwd = NULL; } - - /* The KPOP code will have set the password to be the username - * in connect_to_server. Password and APOP are the only other - * cases, and they both need a password. - */ - if (!service->url->passwd) { - char *prompt; - - prompt = g_strdup_printf ("%sPlease enter the POP3 password for %s@%s", - errbuf ? errbuf : "", - service->url->user, - service->url->host); - g_free (errbuf); - errbuf = NULL; - service->url->passwd = camel_session_query_authenticator ( - camel_service_get_session (service), - CAMEL_AUTHENTICATOR_ASK, prompt, TRUE, - service, "password", ex); - - g_free (prompt); - if (!service->url->passwd) { - pop3_disconnect (service, ex); - return FALSE; - } - } - - if (!service->url->authmech || kpop) { - status = camel_pop3_command (store, &msg, "USER %s", service->url->user); - if (status != CAMEL_POP3_OK) { - if (kpop) - goto lose; - errbuf = g_strdup_printf ("Unable to connect to POP server.\n" - "Error sending username: %s\n\n", - msg ? msg : "(Unknown)"); + tryagain = pop3_try_authenticate (service, kpop, errbuf, ex); + g_free (errbuf); + } while (tryagain); - g_free (msg); - continue; - } - g_free (msg); - - status = camel_pop3_command (store, &msg, "PASS %s", service->url->passwd); - } else if (!strcmp (service->url->authmech, "+APOP") - && store->apop_timestamp) { - char *secret, md5asc[33], *d; - unsigned char md5sum[16], *s; - - secret = g_strdup_printf ("%s%s", store->apop_timestamp, service->url->passwd); - md5_get_digest (secret, strlen (secret), md5sum); - g_free (secret); - - for (s = md5sum, d = md5asc; d < md5asc + 32; s++, d += 2) - sprintf (d, "%.2x", *s); - - status = camel_pop3_command (store, &msg, "APOP %s %s", service->url->user, md5asc); - } else { - camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - "No support for requested authentication mechanism."); - - auth_supported = FALSE; - goto lose; - } - - if (status != CAMEL_POP3_OK) { - errbuf = g_strdup_printf ("Unable to connect to POP server.\n" - "Error sending password: %s\n\n", - msg ? msg : "(Unknown)"); - - g_free (msg); - continue; - } - - g_free (msg); - authenticated = TRUE; - } - - g_free (errbuf); - - service_class->connect (service, ex); - return TRUE; - - lose: - /* Uncache the password. */ - camel_session_query_authenticator (camel_service_get_session (service), - CAMEL_AUTHENTICATOR_TELL, NULL, - TRUE, service, "password", ex); - - if (auth_supported && !authenticated) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, - "Unable to authenticate to POP server: %s", - msg ? msg : "(Unknown)"); + if (camel_exception_is_set (ex)) { + pop3_disconnect (service, NULL); + return FALSE; } - g_free (errbuf); - - pop3_disconnect (service, ex); - return FALSE; + return service_class->connect (service, ex); } static gboolean |