]> Pileus Git - ~andy/fetchmail/commitdiff
Before the IDLE patch.
authorEric S. Raymond <esr@thyrsus.com>
Fri, 28 Feb 2003 10:53:49 +0000 (10:53 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Fri, 28 Feb 2003 10:53:49 +0000 (10:53 -0000)
svn path=/trunk/; revision=3792

NEWS
imap.c
indexgen.sh
pop3.c
rcfile_y.y
transact.c

diff --git a/NEWS b/NEWS
index 3f76e34c1b4a66a5a8d2d5f8a781acb1b9667f68..f52f1035c73b79785d388c504c0dd3a433618ced 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,12 @@
 
 (The `lines' figures total .c, .h, .l, and .y files under version control.)
 
+* Sunil Shetye's patch to imprive behavior in empty messages.
+* Conform to RFC2595; reissue capability probes after successful 
+  STARTTLS negotiation.
+* Sunil's patch to make handling of failed STARTTLS more graceful.
+* Sunil's JF2 fix patch for .fetchmailrc security fix.
+
 fetchmail-6.2.1 (Tue Jan 14 08:17:19 EST 2003), 22219 lines:
 
 * Updated German, Turkish, Spanish, and Danish translation files.
diff --git a/imap.c b/imap.c
index 3ea5c27d190069d1c3147653f0a644a884aea561..9d4a506d973cd2b472376b10a068136235a6c239 100644 (file)
--- a/imap.c
+++ b/imap.c
@@ -248,13 +248,10 @@ static int imap_canonicalize(char *result, char *raw, int maxlen)
     return(i);
 }
 
-static int imap_getauth(int sock, struct query *ctl, char *greeting)
-/* apply for connection authorization */
+static void capa_probe(int sock, struct query *ctl)
+/* set capability variables from a CAPA probe */
 {
-    int ok = 0;
-#ifdef SSL_ENABLE
-    flag did_stls = FALSE;
-#endif /* SSL_ENABLE */
+    int        ok;
 
     /* probe to see if we're running IMAP4 and can use RFC822.PEEK */
     capabilities[0] = '\0';
@@ -287,19 +284,6 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting)
        if (outlevel >= O_DEBUG)
            report(stdout, GT_("Protocol identified as IMAP2 or IMAP2BIS\n"));
     }
-    else
-       return(ok);
-
-    peek_capable = (imap_version >= IMAP4);
-
-    /* 
-     * Assumption: expunges are cheap, so we want to do them
-     * after every message unless user said otherwise.
-     */
-    if (NUM_SPECIFIED(ctl->expunge))
-       expunge_period = NUM_VALUE_OUT(ctl->expunge);
-    else
-       expunge_period = 1;
 
     /* 
      * Handle idling.  We depend on coming through here on startup
@@ -311,6 +295,17 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting)
        if (outlevel >= O_VERBOSE)
            report(stdout, GT_("will idle after poll\n"));
     }
+}
+
+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 */
+
+    capa_probe(sock, ctl);
 
     /* 
      * If either (a) we saw a PREAUTH token in the greeting, or
@@ -321,7 +316,6 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting)
         preauth = FALSE;  /* reset for the next session */
         return(PS_SUCCESS);
     }
-
     /*
      * Time to authenticate the user.
      * Try the protocol variants that don't require passwords first.
@@ -369,12 +363,13 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting)
            char *realhost;
 
            realhost = ctl->server.via ? ctl->server.via : ctl->server.pollname;
-           gen_transact(sock, "STARTTLS");
+           ok = gen_transact(sock, "STARTTLS");
 
            /* We use "tls1" instead of ctl->sslproto, as we want STARTTLS,
             * not other SSL protocols
             */
-           if (SSLOpen(sock,ctl->sslcert,ctl->sslkey,"tls1",ctl->sslcertck, ctl->sslcertpath,ctl->sslfingerprint,realhost,ctl->server.pollname) == -1)
+           if (ok == PS_SUCCESS &&
+              SSLOpen(sock,ctl->sslcert,ctl->sslkey,"tls1",ctl->sslcertck, ctl->sslcertpath,ctl->sslfingerprint,realhost,ctl->server.pollname) == -1)
            {
               if (!ctl->sslproto && !ctl->wehaveauthed)
               {
@@ -387,9 +382,32 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting)
                return(PS_AUTHFAIL);
            }
           did_stls = TRUE;
+
+          /*
+           * RFC 2595 says this:
+           *
+           * "Once TLS has been started, the client MUST discard cached
+           * information about server capabilities and SHOULD re-issue the
+           * CAPABILITY command.  This is necessary to protect against
+           * man-in-the-middle attacks which alter the capabilities list prior
+           * to STARTTLS.  The server MAY advertise different capabilities
+           * after STARTTLS."
+           */
+          capa_probe(sock, ctl);
     }
 #endif /* SSL_ENABLE */
 
+    peek_capable = (imap_version >= IMAP4);
+
+    /* 
+     * Assumption: expunges are cheap, so we want to do them
+     * after every message unless user said otherwise.
+     */
+    if (NUM_SPECIFIED(ctl->expunge))
+       expunge_period = NUM_VALUE_OUT(ctl->expunge);
+    else
+       expunge_period = 1;
+
     /*
      * No such luck.  OK, now try the variants that mask your password
      * in a challenge-response.
index 7917b50185d0628a8fec6fb332d874a1b521dd29..0843952c98f56e402a77c39b53b39a54d8b37357 100755 (executable)
@@ -278,7 +278,7 @@ as a technical effort.  I ran it as a test of some theories about why the
 Linux development model works.</p>
 
 <p>I wrote a paper, <a
-href="http://www.tuxedo.org/~esr/writings/cathedral-bazaar/">The
+href="http://www.catb.org/~esr/writings/cathedral-bazaar/">The
 Cathedral And The Bazaar</a>, about these theories and the project.
 I developed the line of analysis it suggested in two later essays.
 These papers became quite popular and (to my continuing astonishment) may
diff --git a/pop3.c b/pop3.c
index a2f7d5f09132007a3dcebe2fdc95a9453125bbef..123e1b81ef03ca256deb4b7fdd29a86650a1604f 100644 (file)
--- a/pop3.c
+++ b/pop3.c
@@ -39,6 +39,21 @@ char *sdps_envto;
 static char lastok[POPBUFSIZE+1];
 #endif /* OPIE_ENABLE */
 
+/* these variables are shared between the CAPA probe and the authenticator */
+#if defined(GSSAPI)
+    flag has_gssapi = FALSE;
+#endif /* defined(GSSAPI) */
+#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
+    flag has_kerberos = FALSE;
+#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
+    flag has_cram = FALSE;
+#ifdef OPIE_ENABLE
+    flag has_otp = FALSE;
+#endif /* OPIE_ENABLE */
+#ifdef SSL_ENABLE
+    flag has_ssl = FALSE;
+#endif /* SSL_ENABLE */
+
 #define DOTLINE(s)     (s[0] == '.' && (s[1]=='\r'||s[1]=='\n'||s[1]=='\0'))
 
 static int pop3_ok (int sock, char *argbuf)
@@ -124,6 +139,46 @@ static int pop3_ok (int sock, char *argbuf)
     return(ok);
 }
 
+
+
+static int capa_probe(sock)
+/* probe the capabilities of the remote server */
+{
+    int        ok;
+
+    ok = gen_transact(sock, "CAPA");
+    if (ok == PS_SUCCESS)
+    {
+       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;
+#endif /* SSL_ENABLE */
+#if defined(GSSAPI)
+           if (strstr(buffer, "GSSAPI"))
+               has_gssapi = TRUE;
+#endif /* defined(GSSAPI) */
+#if defined(KERBEROS_V4)
+           if (strstr(buffer, "KERBEROS_V4"))
+               has_kerberos = TRUE;
+#endif /* defined(KERBEROS_V4)  */
+#ifdef OPIE_ENABLE
+           if (strstr(buffer, "X-OTP"))
+               has_otp = TRUE;
+#endif /* OPIE_ENABLE */
+           if (strstr(buffer, "CRAM-MD5"))
+               has_cram = TRUE;
+       }
+    }
+    return(ok);
+}
+
 static int pop3_getauth(int sock, struct query *ctl, char *greeting)
 /* apply for connection authorization */
 {
@@ -133,18 +188,7 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
 #if OPIE_ENABLE
     char *challenge;
 #endif /* OPIE_ENABLE */
-#if defined(GSSAPI)
-    flag has_gssapi = FALSE;
-#endif /* defined(GSSAPI) */
-#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
-    flag has_kerberos = FALSE;
-#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
-    flag has_cram = FALSE;
-#ifdef OPIE_ENABLE
-    flag has_otp = FALSE;
-#endif /* OPIE_ENABLE */
 #ifdef SSL_ENABLE
-    flag has_ssl = FALSE;
     flag did_stls = FALSE;
 #endif /* SSL_ENABLE */
 
@@ -201,50 +245,21 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
         */
        if (ctl->server.authenticate == A_ANY)
        {
-           ok = gen_transact(sock, "CAPA");
-           if (ok == PS_SUCCESS)
-           {
-               char buffer[64];
-
-               /* determine what authentication methods we have available */
-               while ((ok = gen_recv(sock, buffer, sizeof(buffer))) == 0)
+           if (capa_probe(sock) != PS_SUCCESS)
+           /* we are in STAGE_GETAUTH! */
+               if (ok == PS_AUTHFAIL ||
+                   /* Some servers directly close the socket. However, if we
+                    * have already authenticated before, then a previous CAPA
+                    * must have succeeded. In that case, treat this as a
+                    * genuine socket error and do not change the auth method.
+                    */
+                   (ok == PS_SOCKET && !ctl->wehaveauthed))
                {
-                   if (DOTLINE(buffer))
-                       break;
-#ifdef SSL_ENABLE
-                   if (strstr(buffer, "STLS"))
-                       has_ssl = TRUE;
-#endif /* SSL_ENABLE */
-#if defined(GSSAPI)
-                   if (strstr(buffer, "GSSAPI"))
-                       has_gssapi = TRUE;
-#endif /* defined(GSSAPI) */
-#if defined(KERBEROS_V4)
-                   if (strstr(buffer, "KERBEROS_V4"))
-                       has_kerberos = TRUE;
-#endif /* defined(KERBEROS_V4)  */
-#ifdef OPIE_ENABLE
-                   if (strstr(buffer, "X-OTP"))
-                       has_otp = TRUE;
-#endif /* OPIE_ENABLE */
-                   if (strstr(buffer, "CRAM-MD5"))
-                       has_cram = TRUE;
+                   ctl->server.authenticate = A_PASSWORD;
+                   /* repoll immediately */
+                   ok = PS_REPOLL;
+                   break;
                }
-           }
-           /* we are in STAGE_GETAUTH! */
-           else if (ok == PS_AUTHFAIL ||
-               /* Some servers directly close the socket. However, if we
-                * have already authenticated before, then a previous CAPA
-                * must have succeeded. In that case, treat this as a
-                * genuine socket error and do not change the auth method.
-                */
-               (ok == PS_SOCKET && !ctl->wehaveauthed))
-           {
-               ctl->server.authenticate = A_PASSWORD;
-               /* repoll immediately */
-               ok = PS_REPOLL;
-               break;
-           }
        }
 
 #ifdef SSL_ENABLE
@@ -255,12 +270,13 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
            char *realhost;
 
           realhost = ctl->server.via ? ctl->server.via : ctl->server.pollname;
-           gen_transact(sock, "STLS");
+           ok = gen_transact(sock, "STLS");
 
            /* 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 (ok == PS_SUCCESS &&
+              SSLOpen(sock,ctl->sslcert,ctl->sslkey,"tls1",ctl->sslcertck, ctl->sslcertpath,ctl->sslfingerprint,realhost,ctl->server.pollname) == -1)
           {
               if (!ctl->sslproto && !ctl->wehaveauthed)
               {
@@ -273,6 +289,18 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
                return(PS_AUTHFAIL);
            }
           did_stls = TRUE;
+
+          /*
+           * RFC 2595 says this:
+           *
+           * "Once TLS has been started, the client MUST discard cached
+           * information about server capabilities and SHOULD re-issue the
+           * CAPABILITY command.  This is necessary to protect against
+           * man-in-the-middle attacks which alter the capabilities list prior
+           * to STARTTLS.  The server MAY advertise different capabilities
+           * after STARTTLS."
+           */
+          capa_probe(sock);
        }
 #endif /* SSL_ENABLE */
 
index 3dac325bbb3ebe2dfcec672806201654a3175a92..bd5faa6dc117a585209e5c0b41c54c94972c3d9c 100644 (file)
@@ -428,14 +428,14 @@ int prc_filecheck(const char *pathname, const flag securecheck)
 
     if (!securecheck)  return PS_SUCCESS;
 
-    if ((statbuf.st_mode & S_IFLNK) == S_IFLNK)
+    if (!S_ISREG(statbuf.st_mode))
     {
-       fprintf(stderr, GT_("File %s must not be a symbolic link.\n"), pathname);
+       fprintf(stderr, GT_("File %s must be a regular file.\n"), pathname);
        return(PS_IOERR);
     }
 
 #ifndef __BEOS__
-    if (statbuf.st_mode & ~(S_IFREG | S_IREAD | S_IWRITE | S_IEXEC | S_IXGRP))
+    if (statbuf.st_mode & (S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_IXOTH))
     {
        fprintf(stderr, GT_("File %s must have no more than -rwx--x--- (0710) permissions.\n"), 
                pathname);
index f419828e34ab5c26b3a8819b8d8d14a1dd90e039..6fbe1879e9f613e2f7ff3ed0d610479bc087c3a5 100644 (file)
@@ -864,18 +864,6 @@ int readheaders(int sock,
        }
     }
 
-    /*
-     * We want to detect this early in case there are so few headers that the
-     * dispatch logic barfs.
-     */
-    if (!headers_ok)
-    {
-       if (outlevel > O_SILENT)
-           report(stdout,
-                  GT_("message delimiter found while scanning headers\n"));
-       return(PS_TRUNCATED);
-    }
-
     /*
      * Hack time.  If the first line of the message was blank, with no headers
      * (this happens occasionally due to bad gatewaying software) cons up
@@ -1255,7 +1243,15 @@ int readheaders(int sock,
     *cp++ = '\0';
     stuffline(ctl, buf);
 
-    return(headers_ok ? PS_SUCCESS : PS_TRUNCATED);
+    if (!headers_ok)
+    {
+       if (outlevel > O_SILENT)
+           report(stdout,
+                  GT_("message delimiter found while scanning headers\n"));
+       return(PS_TRUNCATED);
+    }
+
+    return(PS_SUCCESS);
 }
 
 int readbody(int sock, struct query *ctl, flag forward, int len)