diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | driver.c | 6 | ||||
-rw-r--r-- | fetchmail.c | 8 | ||||
-rw-r--r-- | fetchmail.h | 1 | ||||
-rw-r--r-- | pop3.c | 57 |
5 files changed, 46 insertions, 27 deletions
@@ -11,6 +11,7 @@ * Scott Gifford's dotted-quad patch. * Updated Danish translation. * RPM now built with SSL and IPv6 support, reflecting what's in RH 7.3. +* Sunil Shetye's patch to send CAPA during POP3 sessions. fetchmail-5.9.12 (Tue Jun 4 14:57:47 EDT 2002), 21669 lines: @@ -1146,6 +1146,12 @@ is restored.")); close_warning_by_mail(ctl, (struct msgblk *)NULL); } } + else if (err == PS_REPOLL) + { + report(stderr, GT_("Repoll immediately on %s@%s\n"), + ctl->remotename, + ctl->server.truename); + } else report(stderr, GT_("Unknown login or authentication error on %s@%s\n"), ctl->remotename, diff --git a/fetchmail.c b/fetchmail.c index eabc25d4..604dea13 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -1298,7 +1298,9 @@ static int query_host(struct query *ctl) for (i = 0; i < sizeof(autoprobe)/sizeof(autoprobe[0]); i++) { ctl->server.protocol = autoprobe[i]; - st = query_host(ctl); + do { + st = query_host(ctl); + } while (st == PS_REPOLL); if (st == PS_SUCCESS || st == PS_NOMAIL || st == PS_AUTHFAIL || st == PS_LOCKBUSY || st == PS_SMTP || st == PS_MAXFETCH) break; } @@ -1316,7 +1318,9 @@ static int query_host(struct query *ctl) case P_APOP: case P_RPOP: #ifdef POP3_ENABLE - st = doPOP3(ctl); + do { + st = doPOP3(ctl); + } while (st == PS_REPOLL); #else report(stderr, GT_("POP3 support is not configured.\n")); st = PS_PROTOCOL; diff --git a/fetchmail.h b/fetchmail.h index 4d019a34..bf67a280 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -100,6 +100,7 @@ #define PS_REFUSED 25 /* mail refused (internal use) */ #define PS_RETAINED 26 /* message retained (internal use) */ #define PS_TRUNCATED 27 /* headers incomplete (internal use) */ +#define PS_REPOLL 28 /* repoll immediately with changed parameters (internal use) */ /* output noise level */ #define O_SILENT 0 /* mute, max squelch, etc. */ @@ -190,44 +190,51 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting) * latches the server's authentication type, so that in daemon mode * the CAPA check only needs to be done once at start of run. * - * APOP was introduced in RFC 1450, and CAPA not until - * RFC2449. So the < check is an easy way to prevent CAPA from - * being sent to the more primitive POP3 servers dating from - * RFC 1081 and RFC 1225, which seem more likely to choke on - * it. This certainly catches IMAP-2000's POP3 gateway. - * + * If CAPA fails, then force the authentication method to PASSORD + * and repoll immediately. + * * These authentication methods are blessed by RFC1734, * describing the POP3 AUTHentication command. */ - if (ctl->server.authenticate == A_ANY - && strchr(greeting, '<') - && gen_transact(sock, "CAPA") == 0) + if (ctl->server.authenticate == A_ANY) { - char buffer[64]; - - /* determine what authentication methods we have available */ - while ((ok = gen_recv(sock, buffer, sizeof(buffer))) == 0) + ok = gen_transact(sock, "CAPA"); + if (ok == PS_SUCCESS) { - if (DOTLINE(buffer)) - break; + char buffer[64]; + + /* determine what authentication methods we have available */ + while ((ok = gen_recv(sock, buffer, sizeof(buffer))) == 0) + { + if (DOTLINE(buffer)) + break; #ifdef SSL_ENABLE - if (strstr(buffer, "STLS")) - has_ssl = TRUE; + if (strstr(buffer, "STLS")) + has_ssl = TRUE; #endif /* SSL_ENABLE */ #if defined(GSSAPI) - if (strstr(buffer, "GSSAPI")) - has_gssapi = TRUE; + if (strstr(buffer, "GSSAPI")) + has_gssapi = TRUE; #endif /* defined(GSSAPI) */ #if defined(KERBEROS_V4) - if (strstr(buffer, "KERBEROS_V4")) - has_kerberos = TRUE; + if (strstr(buffer, "KERBEROS_V4")) + has_kerberos = TRUE; #endif /* defined(KERBEROS_V4) */ #ifdef OPIE_ENABLE - if (strstr(buffer, "X-OTP")) - has_otp = TRUE; + if (strstr(buffer, "X-OTP")) + has_otp = TRUE; #endif /* OPIE_ENABLE */ - if (strstr(buffer, "CRAM-MD5")) - has_cram = TRUE; + if (strstr(buffer, "CRAM-MD5")) + has_cram = TRUE; + } + } + /* we are in STAGE_GETAUTH! */ + else if (ok == PS_AUTHFAIL) + { + ctl->server.authenticate = A_PASSWORD; + /* repoll immediately */ + ok = PS_REPOLL; + break; } } |