diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1999-06-08 07:20:17 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1999-06-08 07:20:17 +0000 |
commit | 6f232ed6b5343dea62abdbbd7d38b48858bee373 (patch) | |
tree | 8898d48f48c81a3ded8b0aeb73246af5b22d52e5 | |
parent | 92397efcc624980fdf8467449b69d88d4acc4530 (diff) | |
download | fetchmail-6f232ed6b5343dea62abdbbd7d38b48858bee373.tar.gz fetchmail-6f232ed6b5343dea62abdbbd7d38b48858bee373.tar.bz2 fetchmail-6f232ed6b5343dea62abdbbd7d38b48858bee373.zip |
CRAM-MD5 authentication support a la RFC2195.
svn path=/trunk/; revision=2485
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | design-notes.html | 6 | ||||
-rw-r--r-- | fetchmail-features.html | 6 | ||||
-rw-r--r-- | fetchmail.man | 2 | ||||
-rw-r--r-- | imap.c | 136 |
5 files changed, 146 insertions, 5 deletions
@@ -15,6 +15,7 @@ fetchmail-5.1.0 (): * There is now a documented return code 13 for termination on fetchlimit. * Added qpopper 2.53 warning to the FAQ and fetchmailconf. * Fix fetchmailconf to handle window-manager destroy notifications. +* Todd <tastas@home.com> Sabin's RFC2195 support for AUTH=CRAM-MD5 under IMAP. There are 260 people on fetchmail-friends and 387 on fetchmail-announce. diff --git a/design-notes.html b/design-notes.html index cc193045..356a5b3b 100644 --- a/design-notes.html +++ b/design-notes.html @@ -10,7 +10,7 @@ <table width="100%" cellpadding=0><tr> <td width="30%">Back to <a href="/~esr/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: 1999/05/16 18:24:08 $ +<td width="30%" align=right>$Date: 1999/06/08 07:20:17 $ </table> <HR> <H1 ALIGN=CENTER>Design Notes On Fetchmail</H1> @@ -525,6 +525,8 @@ all shaped the design in one way or another.<P> <DD> IMAP4 Compatibility With IMAP2bis <DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2062.txt">RFC2062</A> <DD> Internet Message Access Protocol - Obsolete Syntax +<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2195.txt">RFC2449</A> +<DD> IMAP/POP AUTHorize Extension for Simple Challenge/Response <DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2449.txt">RFC2449</A> <DD> POP3 Extension Mechanism </DL> @@ -533,7 +535,7 @@ all shaped the design in one way or another.<P> <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: 1999/05/16 18:24:08 $ +<td width="30%" align=right>$Date: 1999/06/08 07:20:17 $ </table> <P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com"><esr@snark.thyrsus.com></A></ADDRESS> diff --git a/fetchmail-features.html b/fetchmail-features.html index ab778a90..b607de57 100644 --- a/fetchmail-features.html +++ b/fetchmail-features.html @@ -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: 1999/04/18 18:32:01 $ +<td width="30%" align=right>$Date: 1999/06/08 07:20:17 $ </table> <HR> @@ -19,6 +19,8 @@ <H2>Since 5.0:</H2> <UL> <LI>Expunge option can now be used to break POP3 retrieval into subsessions. + +<LI>Support for AUTH=CRAM-MD5 under IMAP, a la RFC2195. </UL> <H2>Since 4.0:</H2> @@ -173,7 +175,7 @@ get-mail, gwpop, pimp-1.0, pop-perl5-1.2, popc, popmail-1.6 and upop.<P> <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: 1999/04/18 18:32:01 $ +<td width="30%" align=right>$Date: 1999/06/08 07:20:17 $ </table> <P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com"><esr@snark.thyrsus.com></A></ADDRESS> diff --git a/fetchmail.man b/fetchmail.man index 62dd8df9..3896971c 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -1851,7 +1851,7 @@ IMAP2/IMAP2BIS: RFC 1176, RFC 1732 .TP 5 IMAP4: -RFC 1730, RFC 1731, RFC 1732, RFC 2060, RFC 2061 +RFC 1730, RFC 1731, RFC 1732, RFC 2060, RFC 2061, RFC 2195 .TP 5 ETRN: RFC 1985 @@ -37,6 +37,8 @@ #include <gssapi/gssapi_generic.h> #endif +#include "md5.h" + #if OPIE #include <opie.h> #endif /* OPIE */ @@ -588,6 +590,127 @@ static int do_gssauth(int sock, char *hostname, char *username) } #endif /* GSSAPI */ +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) +{ + int i; + unsigned char ipad[64]; + unsigned char opad[64]; + unsigned char hash_passwd[16]; + + MD5_CTX ctx; + + if (resp_len != 16) + return; + + if (pass_len > sizeof (ipad)) + { + MD5Init (&ctx); + MD5Update (&ctx, password, pass_len); + MD5Final (hash_passwd, &ctx); + password = hash_passwd; pass_len = sizeof (hash_passwd); + } + + memset (ipad, 0, sizeof (ipad)); + memset (opad, 0, sizeof (opad)); + memcpy (ipad, password, pass_len); + memcpy (opad, password, pass_len); + + for (i=0; i<64; i++) { + ipad[i] ^= 0x36; + opad[i] ^= 0x5c; + } + + MD5Init (&ctx); + MD5Update (&ctx, ipad, sizeof (ipad)); + MD5Update (&ctx, challenge, chal_len); + MD5Final (response, &ctx); + + MD5Init (&ctx); + MD5Update (&ctx, opad, sizeof (opad)); + MD5Update (&ctx, response, resp_len); + MD5Final (response, &ctx); +} + + +static int do_cram_md5 (int sock, struct query *ctl) +/* authenticate as per RFC2195 */ +{ + int result; + int len; + unsigned char buf1[1024]; + unsigned char msg_id[768]; + unsigned char response[16]; + unsigned char reply[1024]; + + gen_send (sock, "AUTHENTICATE CRAM-MD5"); + + /* From RFC2195: + * The data encoded in the first ready response contains an + * presumptively arbitrary string of random digits, a timestamp, and the + * fully-qualified primary host name of the server. The syntax of the + * unencoded form must correspond to that of an RFC 822 'msg-id' + * [RFC822] as described in [POP3]. + */ + + if (result = gen_recv (sock, buf1, sizeof (buf1))) { + return result; + } + + len = from64tobits (msg_id, buf1); + if (len < 0) { + report (stderr, _("could not decode BASE64 challenge\n")); + return PS_AUTHFAIL; + } else if (len < sizeof (msg_id)) { + msg_id[len] = 0; + } else { + msg_id[sizeof (msg_id)-1] = 0; + } + if (outlevel >= O_DEBUG) { + report (stdout, "decoded as %s\n", msg_id); + } + + /* The client makes note of the data and then responds with a string + * consisting of the user name, a space, and a 'digest'. The latter is + * computed by applying the keyed MD5 algorithm from [KEYED-MD5] where + * the key is a shared secret and the digested text is the timestamp + * (including angle-brackets). + */ + + hmac_md5 (ctl->password, strlen (ctl->password), + msg_id, strlen (msg_id), + response, sizeof (response)); + + snprintf (reply, sizeof (reply), + "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + ctl->remotename, + response[0], response[1], response[2], response[3], + response[4], response[5], response[6], response[7], + response[8], response[9], response[10], response[11], + response[12], response[13], response[14], response[15]); + + if (outlevel >= O_DEBUG) { + report (stdout, "replying with %s\n", reply); + } + + to64frombits (buf1, reply, strlen (reply)); + if (outlevel >= O_MONITOR) { + report (stdout, "IMAP> %s\n", buf1); + } + SockWrite (sock, buf1, strlen (buf1)); + SockWrite (sock, "\r\n", 2); + + if (result = gen_recv (sock, buf1, sizeof (buf1))) + return result; + + if (strstr (buf1, "OK")) { + return PS_SUCCESS; + } else { + return PS_AUTHFAIL; + } +} + int imap_canonicalize(char *result, char *passwd) /* encode an IMAP password as per RFC1730's quoting conventions */ { @@ -695,6 +818,19 @@ int imap_getauth(int sock, struct query *ctl, char *greeting) } #endif /* KERBEROS_V4 */ + if (strstr (capabilities, "AUTH=CRAM-MD5")) + { + if (outlevel >= O_DEBUG) + report (stdout, _("CRAM-MD5 authentication is supported\n")); + if ((ok = do_cram_md5 (sock, ctl))) + { + if (outlevel >= O_MONITOR) + report (stdout, "IMAP> *\n"); + SockWrite (sock, "*\r\n", 3); + } + return ok; + } + #ifdef __UNUSED__ /* The Cyrus IMAP4rev1 server chokes on this */ /* this handles either AUTH=LOGIN or AUTH-LOGIN */ if ((imap_version >= IMAP4rev1) && (!strstr(capabilities, "LOGIN"))) { |