From b53d36176029927e5c4b9394f50140cebf21d19f Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 28 Nov 2002 10:32:38 +0000 Subject: Sunil's patch for the STARTTLS problem. svn path=/trunk/; revision=3772 --- NEWS | 2 ++ fetchmail.c | 6 +++++- imap.c | 22 +++++++++++++++++++++- pop3.c | 26 ++++++++++++++++++++++++-- socket.c | 2 ++ 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index a81298ac..de8f8989 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ * Be case-insensitive when looking for IMAP responses. * Fix logout-after-idle-delivery bug (Sunil Shetye). * Sunil Shetye's patch to bulletproof end-of-header detection. +* Sunil's fix for the STARTTLS problem -- repoll if TLS nabdshake + fails. The attenmpt to set up STARTTLS can be suppressed with 'sslproto ""'. fetchmail-6.1.2 (Thu Oct 31 11:41:02 EST 2002), 22135 lines: diff --git a/fetchmail.c b/fetchmail.c index b59209d5..debb8853 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -1356,7 +1356,9 @@ static int query_host(struct query *ctl) break; case P_IMAP: #ifdef IMAP_ENABLE - st = doIMAP(ctl); + do { + st = doIMAP(ctl); + } while (st == PS_REPOLL); #else report(stderr, GT_("IMAP support is not configured.\n")); st = PS_PROTOCOL; @@ -1537,6 +1539,8 @@ static void dump_params (struct runctl *runp, #ifdef SSL_ENABLE if (ctl->use_ssl) printf(GT_(" SSL encrypted sessions enabled.\n")); + if (ctl->sslproto) + printf(GT_(" SSL protocol: %s.\n"), ctl->sslproto); if (ctl->sslcertck) { printf(GT_(" SSL server certificate checking enabled.\n")); if (ctl->sslcertpath != NULL) diff --git a/imap.c b/imap.c index d7eb0fa3..732141d8 100644 --- a/imap.c +++ b/imap.c @@ -252,6 +252,9 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting) /* apply for connection authorization */ { int ok = 0; +#ifdef SSL_ENABLE + flag did_stls = FALSE; +#endif /* SSL_ENABLE */ /* probe to see if we're running IMAP4 and can use RFC822.PEEK */ capabilities[0] = '\0'; @@ -359,7 +362,7 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting) #endif /* KERBEROS_V4 */ #ifdef SSL_ENABLE - if ((ctl->server.authenticate == A_ANY) + if ((!ctl->sslproto || !strcmp(ctl->sslproto,"tls1")) && !ctl->use_ssl && strstr(capabilities, "STARTTLS")) { @@ -373,10 +376,17 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting) */ if (SSLOpen(sock,ctl->sslcert,ctl->sslkey,"tls1",ctl->sslcertck, ctl->sslcertpath,ctl->sslfingerprint,realhost,ctl->server.pollname) == -1) { + if (!ctl->sslproto && !ctl->wehaveauthed) + { + ctl->sslproto = xstrdup(""); + /* repoll immediately */ + return(PS_REPOLL); + } report(stderr, GT_("SSL connection failed.\n")); return(PS_AUTHFAIL); } + did_stls = TRUE; } #endif /* SSL_ENABLE */ @@ -471,6 +481,16 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting) strcpy(shroud, password); ok = gen_transact(sock, "LOGIN \"%s\" \"%s\"", remotename, password); shroud[0] = '\0'; +#ifdef SSL_ENABLE + /* this is for servers which claim to support TLS, but actually + * don't! */ + if (did_stls && ok == PS_SOCKET && !ctl->sslproto && !ctl->wehaveauthed) + { + ctl->sslproto = xstrdup(""); + /* repoll immediately */ + ok = PS_REPOLL; + } +#endif if (ok) { /* SASL cancellation of authentication */ diff --git a/pop3.c b/pop3.c index 573a8cd0..7082d94f 100644 --- a/pop3.c +++ b/pop3.c @@ -145,6 +145,7 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting) #endif /* OPIE_ENABLE */ #ifdef SSL_ENABLE flag has_ssl = FALSE; + flag did_stls = FALSE; #endif /* SSL_ENABLE */ #ifdef SDPS_ENABLE @@ -249,18 +250,29 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting) #ifdef SSL_ENABLE if (has_ssl && !ctl->use_ssl - && (ctl->server.authenticate == A_ANY)) + && (!ctl->sslproto || !strcmp(ctl->sslproto,"tls1"))) { char *realhost; realhost = ctl->server.via ? ctl->server.via : ctl->server.pollname; gen_transact(sock, "STLS"); - if (SSLOpen(sock,ctl->sslcert,ctl->sslkey,ctl->sslproto,ctl->sslcertck, ctl->sslcertpath,ctl->sslfingerprint,realhost,ctl->server.pollname) == -1) + + /* We use "tls1" instead of ctl->sslproto, as we want STLS, + * not other SSL protocols + */ + if (SSLOpen(sock,ctl->sslcert,ctl->sslkey,"tls1",ctl->sslcertck, ctl->sslcertpath,ctl->sslfingerprint,realhost,ctl->server.pollname) == -1) { + if (!ctl->sslproto && !ctl->wehaveauthed) + { + ctl->sslproto = xstrdup(""); + /* repoll immediately */ + return(PS_REPOLL); + } report(stderr, GT_("SSL connection failed.\n")); return(PS_AUTHFAIL); } + did_stls = TRUE; } #endif /* SSL_ENABLE */ @@ -350,6 +362,16 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting) strcpy(shroud, ctl->password); ok = gen_transact(sock, "PASS %s", ctl->password); shroud[0] = '\0'; +#ifdef SSL_ENABLE + /* this is for servers which claim to support TLS, but actually + * don't! */ + if (did_stls && ok == PS_SOCKET && !ctl->sslproto && !ctl->wehaveauthed) + { + ctl->sslproto = xstrdup(""); + /* repoll immediately */ + ok = PS_REPOLL; + } +#endif break; case P_APOP: diff --git a/socket.c b/socket.c index f1bea9f6..bef0deea 100644 --- a/socket.c +++ b/socket.c @@ -876,6 +876,8 @@ int SSLOpen(int sock, char *mycert, char *mykey, char *myproto, int certck, char _ctx = SSL_CTX_new(SSLv3_client_method()); } else if(!strcmp("tls1",myproto)) { _ctx = SSL_CTX_new(TLSv1_client_method()); + } else if (!strcmp("ssl23",myproto)) { + myproto = NULL; } else { fprintf(stderr,GT_("Invalid SSL protocol '%s' specified, using default (SSLv23).\n"), myproto); myproto = NULL; -- cgit v1.2.3