aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2003-07-17 15:19:56 +0000
committerEric S. Raymond <esr@thyrsus.com>2003-07-17 15:19:56 +0000
commit736db44524864225b719eda2262cd4b2a940304b (patch)
tree45135b7d62c42e497b90b06bb7d4c09e29997ee7
parent7d1fc7b9e3f5fba4c1f0d09f841a08ca94dd5e8f (diff)
downloadfetchmail-736db44524864225b719eda2262cd4b2a940304b.tar.gz
fetchmail-736db44524864225b719eda2262cd4b2a940304b.tar.bz2
fetchmail-736db44524864225b719eda2262cd4b2a940304b.zip
Yet another round of fixes.
svn path=/trunk/; revision=3819
-rw-r--r--NEWS2
-rw-r--r--configure.in10
-rw-r--r--pop3.c93
-rw-r--r--socket.c41
4 files changed, 142 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 38d0944b..0c62a7f4 100644
--- 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:
diff --git a/configure.in b/configure.in
index 6b86ebd0..197a0410 100644
--- a/configure.in
+++ b/configure.in
@@ -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 50673ffe..1c06c207 100644
--- 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:
diff --git a/socket.c b/socket.c
index 47f074dd..5f295a04 100644
--- 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;
}