]> Pileus Git - ~andy/fetchmail/commitdiff
Yet another round of fixes.
authorEric S. Raymond <esr@thyrsus.com>
Thu, 17 Jul 2003 15:19:56 +0000 (15:19 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 17 Jul 2003 15:19:56 +0000 (15:19 -0000)
svn path=/trunk/; revision=3819

NEWS
configure.in
pop3.c
socket.c

diff --git a/NEWS b/NEWS
index 38d0944b7968167d00db699ea7cb07b550da624b..0c62a7f463f962134660770da491854a413af1e8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,8 @@
 * Sunil Shetye's configure.in patch to avoid spurious search order messages
   from GCC.
 * Header-reading code now copes better with lines ending in \n only.
+* Elias Israel's patches for POP3 NTLM support and dealing with byte-
+  stuffing failures at socket level.
 
 fetchmail-6.2.2 (Fri Feb 28 21:34:26 EST 2003), 22345 lines:
 
index 6b86ebd042d3f4edd876746cf6d02dbd6fe3d5b3..197a04100fe0fd5e3e7f15b1cf4bd0523cd6c82e 100644 (file)
@@ -601,7 +601,7 @@ then
   then
     ###        ssl.h found under openssl.  Use openssl configuration preferentially
     echo "Enabling OpenSSL support in $with_ssl"
-    CEFLAGS="$CEFLAGS -I$with_ssl/include -I$with_ssl/include/openssl"
+    CEFLAGS="$CEFLAGS -I$with_ssl/include/openssl"
     ###        OpenBSD comes with ssl headers
   elif test -r /usr/include/ssl/ssl.h
   then
@@ -609,7 +609,7 @@ then
     CEFLAGS="$CEFLAGS -I/usr/include/ssl"
   else
     echo "Enabling SSLeay support in $with_ssl"
-    CEFLAGS="$CEFLAGS -I$with_ssl/include"
+    test "$with_ssl" != "/usr" && CEFLAGS="$CEFLAGS -I$with_ssl/include"
   fi
   LDEFLAGS="$LDEFLAGS -L$with_ssl/lib"
   LIBS="$LIBS -lssl -lcrypto"
@@ -668,7 +668,8 @@ x)
     do
       if test -f "$dir/include/hesiod.h"
       then
-        test "$dir" != "/usr" && CEFLAGS="$CEFLAGS -DHESIOD -I$dir/include"
+        CEFLAGS="$CEFLAGS -DHESIOD"
+        test "$dir" != "/usr" && CEFLAGS="$CEFLAGS -I$dir/include"
         LDEFLAGS="$LDEFLAGS -L$dir/lib"
         LIBS="$LIBS -lhesiod"
         with_hesiod=$dir
@@ -678,7 +679,8 @@ x)
     ;;
 *)
     # Path given
-    CEFLAGS="$CEFLAGS -DHESIOD -I$with_hesiod/include"
+    CEFLAGS="$CEFLAGS -DHESIOD"
+    test "$with_hesiod" != "/usr" && CEFLAGS="$CEFLAGS -I$with_hesiod/include"
     LDEFLAGS="$LDEFLAGS -L$with_hesiod/lib"
     LIBS="$LIBS -lhesiod"
     ;;
diff --git a/pop3.c b/pop3.c
index 50673ffe9359d7bdd9b718010cfb3a12a9019e54..1c06c20726e034fb33d21a69c041556c86e295d5 100644 (file)
--- a/pop3.c
+++ b/pop3.c
@@ -54,6 +54,84 @@ static char lastok[POPBUFSIZE+1];
     flag has_ssl = FALSE;
 #endif /* SSL_ENABLE */
 
+#if NTLM_ENABLE
+#include "ntlm.h"
+
+static tSmbNtlmAuthRequest   request;             
+static tSmbNtlmAuthChallenge challenge;
+static tSmbNtlmAuthResponse  response;
+
+/*
+ * NTLM support by Grant Edwards.
+ *
+ * Handle MS-Exchange NTLM authentication method.  This is the same
+ * as the NTLM auth used by Samba for SMB related services. We just
+ * encode the packets in base64 instead of sending them out via a
+ * network interface.
+ * 
+ * Much source (ntlm.h, smb*.c smb*.h) was borrowed from Samba.
+ */
+
+static int do_pop3_ntlm(int sock, struct query *ctl)
+{
+    char msgbuf[2048];
+    int result,len;
+  
+    gen_send(sock, "AUTH MSN");
+
+    if ((result = gen_recv(sock, msgbuf, sizeof msgbuf)))
+       return result;
+  
+    if (msgbuf[0] != '+')
+       return PS_AUTHFAIL;
+  
+    buildSmbNtlmAuthRequest(&request,ctl->remotename,NULL);
+
+    if (outlevel >= O_DEBUG)
+       dumpSmbNtlmAuthRequest(stdout, &request);
+
+    memset(msgbuf,0,sizeof msgbuf);
+    to64frombits (msgbuf, (unsigned char*)&request, SmbLength(&request));
+  
+    if (outlevel >= O_MONITOR)
+       report(stdout, "POP3> %s\n", msgbuf);
+  
+    strcat(msgbuf,"\r\n");
+    SockWrite (sock, msgbuf, strlen (msgbuf));
+
+    if ((gen_recv(sock, msgbuf, sizeof msgbuf)))
+       return result;
+  
+    len = from64tobits ((unsigned char*)&challenge, msgbuf, sizeof(msgbuf));
+    
+    if (outlevel >= O_DEBUG)
+       dumpSmbNtlmAuthChallenge(stdout, &challenge);
+    
+    buildSmbNtlmAuthResponse(&challenge, &response,ctl->remotename,ctl->password);
+  
+    if (outlevel >= O_DEBUG)
+       dumpSmbNtlmAuthResponse(stdout, &response);
+  
+    memset(msgbuf,0,sizeof msgbuf);
+    to64frombits (msgbuf, (unsigned char*)&response, SmbLength(&response));
+
+    if (outlevel >= O_MONITOR)
+       report(stdout, "POP3> %s\n", msgbuf);
+      
+    strcat(msgbuf,"\r\n");
+    SockWrite (sock, msgbuf, strlen (msgbuf));
+  
+    if ((result = gen_recv (sock, msgbuf, sizeof msgbuf)))
+       return result;
+  
+    if (strstr (msgbuf, "OK"))
+       return PS_SUCCESS;
+    else
+       return PS_AUTHFAIL;
+}
+#endif /* NTLM */
+
+
 #define DOTLINE(s)     (s[0] == '.' && (s[1]=='\r'||s[1]=='\n'||s[1]=='\0'))
 
 static int pop3_ok (int sock, char *argbuf)
@@ -205,6 +283,21 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
     if (!(ctl->server.sdps) && MULTIDROP(ctl) && strstr(greeting, "demon."))
         ctl->server.sdps = TRUE;
 #endif /* SDPS_ENABLE */
+#ifdef NTLM_ENABLE
+       /* MSN servers require the use of NTLM (MSN) authentication */
+       if (!strcasecmp(ctl->server.pollname, "pop3.email.msn.com") ||
+           ctl->server.authenticate == A_NTLM)
+       {
+           if (!do_pop3_ntlm(sock, ctl))
+           {
+               return(PS_SUCCESS);
+           }
+           else
+           {
+               return(PS_AUTHFAIL);
+           }
+       }
+#endif
 
     switch (ctl->server.protocol) {
     case P_POP3:
index 47f074ddcb83c0b6075f736283ab96ae113b7157..5f295a0487f50a3fe79fc3b9bf9df88bcbb00eda 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -540,6 +540,7 @@ int SockRead(int sock, char *buf, int len)
 {
     char *newline, *bp = buf;
     int n;
+    int maxavailable = 0;
 #ifdef SSL_ENABLE
     SSL *ssl;
 #endif
@@ -579,6 +580,7 @@ int SockRead(int sock, char *buf, int len)
                        (void)SSL_get_error(ssl, n);
                        return(-1);
                }
+               maxavailable = n;
                if( 0 == n ) {
                        /* SSL_peek says no data...  Does he mean no data
                        or did the connection blow up?  If we got an error
@@ -622,6 +624,7 @@ int SockRead(int sock, char *buf, int len)
            if ((n = fm_peek(sock, bp, len)) <= 0)
 #endif
                return (-1);
+           maxavailable = n;
            if ((newline = memchr(bp, '\n', n)) != NULL)
                n = newline - bp + 1;
 #ifndef __BEOS__
@@ -634,6 +637,44 @@ int SockRead(int sock, char *buf, int len)
     } while 
            (!newline && len);
     *bp = '\0';
+    /* OK, very weird hack coming up here:
+     * When POP and IMAP servers send us a message, they're supposed to
+     * terminate the message with a line containing only a dot. To protect
+     * against lines in the real message that might contain only a dot,
+     * they're supposed to preface any line that starts with a dot with
+     * an additional dot, which will be removed on the client side. That
+     * process, called byte-stuffing (and unstuffing) is really not the
+     * concern of this low-level routine, ordinarily, but there are some
+     * POP servers (and maybe IMAP servers too, who knows) that fail to
+     * do the byte-stuffing, and this routine is the best place to try to
+     * identify and fix that fault.
+     *
+     * Since the DOT line is supposed to come only at the end of a
+     * message, the implication is that right after we see it, the server
+     * is supposed to go back to waiting for the next command. There
+     * isn't supposed to be any more data to read after we see the dot.
+     * THEREFORE, if we see more data to be read after something that
+     * looks like the dot line, then probably the server is failing to
+     * do byte-stuffing. In that case, we'll byte-pack it for them so
+     * that the higher-level routines see things as hunky-dorey.
+     * This is not a perfect test or fix by any means (it has an
+     * obvious race condition, for one thing), but it should at least
+     * reduce the nastiness that ensues when people don't know how
+     * to write POP servers.
+     */
+    if ((maxavailable > (bp-buf)) &&
+           ((((bp-buf) == 3) &&
+             (buf[0] == '.') &&
+             (buf[1] == '\r') &&
+             (buf[2] == '\n')) ||
+            (((bp-buf) == 2) &&
+             (buf[0] == '.') &&
+             (buf[1] == '\n')))) {
+
+       memmove(buf+1, buf, (bp-buf)+1);
+       buf[0] = '.';
+       bp++;
+    }
     return bp - buf;
 }