]> Pileus Git - ~andy/fetchmail/commitdiff
Initial version of ESMTP AUTH.
authorEric S. Raymond <esr@thyrsus.com>
Sat, 9 Mar 2002 12:33:09 +0000 (12:33 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Sat, 9 Mar 2002 12:33:09 +0000 (12:33 -0000)
svn path=/trunk/; revision=3589

NEWS
cram.c
fetchmail-features.html
fetchmail.h
smtp.c
smtp.h
todo.html

diff --git a/NEWS b/NEWS
index 157ae8650318f863377471c342e2b56309e73651..807baa0cdebbaee916045ad19df6895d8c2de8de 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@
 * Debian fixes merged.
 * Added maildrop (MDA shipped with courier) as fallback after procmail
   and sendmail (thanks to Alexander Lazic <al-fetchmail@none.at>).
+* ESMTP AUTH support from Wojciech Polak <polak@lodz.pdi.net>.
 
 fetchmail-5.9.8 (Thu Feb 14 23:47:31 EST 2002), 21358 lines:
 
diff --git a/cram.c b/cram.c
index d06df7f5fc470e65b57a41eafe17344f2b77dacd..e17b714745a6091e45f8f08720d18aeb37987b3f 100644 (file)
--- a/cram.c
+++ b/cram.c
@@ -17,9 +17,9 @@
 #include  "i18n.h"
 #include "md5.h"
 
-static void hmac_md5 (unsigned char *password,  size_t pass_len,
-                      unsigned char *challenge, size_t chal_len,
-                      unsigned char *response,  size_t resp_len)
+void hmac_md5 (unsigned char *password,  size_t pass_len,
+               unsigned char *challenge, size_t chal_len,
+               unsigned char *response,  size_t resp_len)
 {
     int i;
     unsigned char ipad[64];
index be38896ffbc1cab8e66f83acab94c96383f0c788..8840699059d752244b50ea6e25c57ec7d2420c82 100644 (file)
@@ -10,7 +10,7 @@
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
 <td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 2001/07/25 09:06:23 $
+<td width="30%" align=right>$Date: 2002/03/09 12:33:08 $
 </table>
 <HR>
 
@@ -18,6 +18,8 @@
 
 <H2>Since 5.0:</H2>
 <UL>
+<LI>ESMTP AUTH (RFC 2554) is supported.
+
 <LI>Has the capability of adding trace information to the Received header to
 faciliate mail filtering by mailserver and remote account.
 
@@ -248,7 +250,7 @@ get-mail, gwpop, pimp-1.0, pop-perl5-1.2, popc, popmail-1.6 and upop.
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
 <td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 2001/07/25 09:06:23 $
+<td width="30%" align=right>$Date: 2002/03/09 12:33:08 $
 </table>
 
 <P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com">&lt;esr@snark.thyrsus.com&gt;</A></ADDRESS>
index 943765d93d5b410ac06ee27ff2b33098e377872d..0beccbc340bb238bd1e0cc596fb07284a88928bc 100644 (file)
@@ -567,6 +567,7 @@ int do_otp(int sock, char *command, struct query *ctl);
 struct query *hostalloc(struct query *); 
 int parsecmdline (int, char **, struct runctl *, struct query *);
 char *MD5Digest (unsigned char *);
+void hmac_md5 (unsigned char *, size_t, unsigned char *, size_t, unsigned char *, size_t);
 int POP3_auth_rpa(unsigned char *, unsigned char *, int socket);
 void deal_with_sigchld(void);
 int daemonize(const char *, void (*)(int));
diff --git a/smtp.c b/smtp.c
index 23ada08f5b64b0b4f244f71ee1989f2827fcdce4..ee99bcf7c0e55c2b41e63b54be9fff1bc0ffc64c 100644 (file)
--- a/smtp.c
+++ b/smtp.c
@@ -16,6 +16,8 @@
 #include "smtp.h"
 #include "config.h"
 
+static void SMTP_auth(int, char *);
+
 struct opt
 {
     const char *name;
@@ -27,6 +29,7 @@ static struct opt extensions[] =
     {"8BITMIME",       ESMTP_8BITMIME},
     {"SIZE",           ESMTP_SIZE},
     {"ETRN",           ESMTP_ETRN},
+    {"AUTH ",          ESMTP_AUTH},
 #ifdef ODMR_ENABLE
     {"ATRN",           ESMTP_ATRN},
 #endif /* ODMR_ENABLE */
@@ -34,6 +37,8 @@ static struct opt extensions[] =
 };
 
 char smtp_response[MSGBUFSIZE];
+char esmtp_auth_username[65];
+char esmtp_auth_password[256];
 
 static char smtp_mode = 'S';
 
@@ -59,6 +64,7 @@ int SMTP_ehlo(int sock, const char *host, int *opt)
 /* send a "EHLO" message to the SMTP listener, return extension status bits */
 {
   struct opt *hp;
+  char auth_response[256];
 
   SockPrintf(sock,"%cHLO %s\r\n", (smtp_mode == 'S') ? 'E' : smtp_mode, host);
   if (outlevel >= O_MONITOR)
@@ -80,10 +86,16 @@ int SMTP_ehlo(int sock, const char *host, int *opt)
       if (outlevel >= O_MONITOR)
          report(stdout, "SMTP< %s\n", smtp_response);
       for (hp = extensions; hp->name; hp++)
-         if (!strncasecmp(hp->name, smtp_response+4, strlen(hp->name)))
+         if (!strncasecmp(hp->name, smtp_response+4, strlen(hp->name))) {
              *opt |= hp->value;
-      if ((smtp_response[0] == '1' || smtp_response[0] == '2' || smtp_response[0] == '3') && smtp_response[3] == ' ')
+             if (strncmp(hp->name, "AUTH ", 5) == 0)
+               strncpy(auth_response, smtp_response, sizeof(auth_response));
+         }
+      if ((smtp_response[0] == '1' || smtp_response[0] == '2' || smtp_response[0] == '3') && smtp_response[3] == ' ') {
+         if (*opt & ESMTP_AUTH)
+               SMTP_auth(sock, auth_response);
          return SM_OK;
+      }
       else if (smtp_response[3] != '-')
          return SM_ERROR;
   }
@@ -215,4 +227,107 @@ int SMTP_ok(int sock)
     return SM_UNRECOVERABLE;
 }
 
+static void SMTP_auth(int sock, char *buf)
+/* ESMTP Authentication support for Fetchmail by Wojciech Polak */
+{
+       int c;
+       char *p = 0;
+       char b64buf[512];
+       char tmp[512];
+
+       memset(b64buf, 0, sizeof(b64buf));
+       memset(tmp, 0, sizeof(tmp));
+
+       if (strstr(buf, "CRAM-MD5")) {
+               unsigned char digest[16];
+               static char ascii_digest[33];
+               memset(digest, 0, 16);
+
+               if (outlevel >= O_MONITOR)
+                       report(stdout, "ESMTP CRAM-MD5 Authentication...\n");
+               SockPrintf(sock, "AUTH CRAM-MD5\r\n");
+               SockRead(sock, smtp_response, sizeof(smtp_response) - 1);
+               strncpy(tmp, smtp_response, sizeof(tmp));
+
+               if (strncmp(tmp, "334 ", 4)) { /* Server rejects AUTH */
+                       SockPrintf(sock, "*\r\n");
+                       SockRead(sock, smtp_response, sizeof(smtp_response) - 1);
+                       if (outlevel >= O_MONITOR)
+                               report(stdout, "Server rejected the AUTH command.\n");
+                       return;
+               }
+
+               p = strchr(tmp, ' ');
+               p++;
+               from64tobits(b64buf, p, sizeof(b64buf));
+               if (outlevel >= O_DEBUG)
+                       report(stdout, "Challenge decoded: %s\n", b64buf);
+               hmac_md5(esmtp_auth_password, strlen(esmtp_auth_password),
+                                b64buf, strlen(b64buf), digest, sizeof(digest));
+               for (c = 0; c < 16; c++)
+                       sprintf(ascii_digest + 2 * c, "%02x", digest[c]);
+#ifdef HAVE_SNPRINTF
+               snprintf(tmp, sizeof(tmp),
+#else
+               sprintf(tmp,
+#endif /* HAVE_SNPRINTF */
+               "%s %s", esmtp_auth_username, ascii_digest);
+
+               to64frombits(b64buf, tmp, strlen(tmp));
+               SockPrintf(sock, "%s\r\n", b64buf);
+               SMTP_ok(sock);
+       }
+       else if (strstr(buf, "PLAIN")) {
+               int len;
+               if (outlevel >= O_MONITOR)
+                       report(stdout, "ESMTP PLAIN Authentication...\n");
+#ifdef HAVE_SNPRINTF
+               snprintf(tmp, sizeof(tmp),
+#else
+               sprintf(tmp,
+#endif /* HAVE_SNPRINTF */
+               "^%s^%s", esmtp_auth_username, esmtp_auth_password);
+
+               len = strlen(tmp);
+               for (c = len - 1; c >= 0; c--)
+               {
+                       if (tmp[c] == '^')
+                               tmp[c] = '\0';
+               }
+               to64frombits(b64buf, tmp, len);
+               SockPrintf(sock, "AUTH PLAIN %s\r\n", b64buf);
+               SMTP_ok(sock);
+       }
+       else if (strstr(buf, "LOGIN")) {
+               if (outlevel >= O_MONITOR)
+                       report(stdout, "ESMTP LOGIN Authentication...\n");
+               SockPrintf(sock, "AUTH LOGIN\r\n");
+               SockRead(sock, smtp_response, sizeof(smtp_response) - 1);
+               strncpy(tmp, smtp_response, sizeof(tmp));
+
+               if (strncmp(tmp, "334 ", 4)) { /* Server rejects AUTH */
+                       SockPrintf(sock, "*\r\n");
+                       SockRead(sock, smtp_response, sizeof(smtp_response) - 1);
+                       if (outlevel >= O_MONITOR)
+                               report(stdout, "Server rejected the AUTH command.\n");
+                       return;
+               }
+
+               p = strchr(tmp, ' ');
+               p++;
+               from64tobits(b64buf, p, sizeof(b64buf));
+               to64frombits(b64buf, esmtp_auth_username, strlen(esmtp_auth_username));
+               SockPrintf(sock, "%s\r\n", b64buf);
+               SockRead(sock, smtp_response, sizeof(smtp_response) - 1);
+               strncpy(tmp, smtp_response, sizeof(tmp));
+               p = strchr(tmp, ' ');
+               p++;
+               from64tobits(b64buf, p, sizeof(b64buf));
+               to64frombits(b64buf, esmtp_auth_password, strlen(esmtp_auth_password));
+               SockPrintf(sock, "%s\r\n", b64buf);
+               SMTP_ok(sock);
+       }
+       return;
+}
+
 /* smtp.c ends here */
diff --git a/smtp.h b/smtp.h
index 1dfe70192e6307cf8afa0b3c2ea98491bed959bf..6f375684be9c0ad714bd01f8cdc3b5b41e6177c5 100644 (file)
--- a/smtp.h
+++ b/smtp.h
@@ -19,6 +19,7 @@
 #define ESMTP_SIZE     0x02
 #define ESMTP_ETRN     0x04
 #define ESMTP_ATRN     0x08            /* used with ODMR, RFC 2645 */
+#define ESMTP_AUTH     0x10
 
 void SMTP_setmode(char);
 int SMTP_helo(int socket,const char *host);
index 6f3a09609161af910dc90a6b784a8c69d15afc1f..da6600420610eb5deb7acac6be6abcd64a7f0004 100644 (file)
--- a/todo.html
+++ b/todo.html
@@ -10,7 +10,7 @@
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="/~esr">Eric's Home Page</a>
 <td width="30%" align=center>Up to <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 2001/12/14 03:30:59 $
+<td width="30%" align=right>$Date: 2002/03/09 12:33:09 $
 </table>
 <HR>
 <H1 ALIGN=CENTER>Fetchmail Bugs and To-Do Items</H1>
@@ -36,11 +36,6 @@ command. wait 300 (xx) seconds for a "-ERR" or a "+OK" . If nothing
 comes back, retry at the next poll event and generate no errors. If we
 get an -ERR then log an authentication failure.
 
-<p>SMTP authentication a la RFC 2554 ought to be supported.  The Exim
-reference has a 
-<a href="http://www.exim.org/exim-html-3.10/doc/html/spec_33.html#SEC705">
-whole chapter on this topic</a>.
-
 <p>It has been reported that multidrop name matching fails when the name
 to be matched contains a Latin-1 umlaut.  Dollars to doughnuts this is
 some kind of character sign-extension problem.  Trouble is, it's very
@@ -73,7 +68,7 @@ bug-tracking page for fetchmail</a> lists other bug reports.
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="/~esr">Eric's Home Page</a>
 <td width="30%" align=center>Up to <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 2001/12/14 03:30:59 $
+<td width="30%" align=right>$Date: 2002/03/09 12:33:09 $
 </table>
 
 <P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com">&lt;esr@thyrsus.com&gt;</A></ADDRESS>