diff options
author | Eric S. Raymond <esr@thyrsus.com> | 2002-03-10 19:59:59 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 2002-03-10 19:59:59 +0000 |
commit | a016460027f89e7c81106a0560d1d495f727c182 (patch) | |
tree | 0daf10c7b95f73d7ed3f3330f11f35a00cc96c78 | |
parent | 7c33daaf6fd2bd4342903ad5ce025b5ab6bc89bd (diff) | |
download | fetchmail-a016460027f89e7c81106a0560d1d495f727c182.tar.gz fetchmail-a016460027f89e7c81106a0560d1d495f727c182.tar.bz2 fetchmail-a016460027f89e7c81106a0560d1d495f727c182.zip |
Expose the ESMTP name and password options.
svn path=/trunk/; revision=3596
-rw-r--r-- | design-notes.html | 16 | ||||
-rw-r--r-- | etrn.c | 4 | ||||
-rw-r--r-- | fetchmail.c | 1 | ||||
-rw-r--r-- | fetchmail.h | 2 | ||||
-rw-r--r-- | fetchmail.man | 19 | ||||
-rw-r--r-- | odmr.c | 4 | ||||
-rw-r--r-- | rcfile_l.l | 3 | ||||
-rw-r--r-- | rcfile_y.y | 4 | ||||
-rw-r--r-- | sink.c | 5 | ||||
-rw-r--r-- | smtp.c | 214 | ||||
-rw-r--r-- | smtp.h | 2 |
11 files changed, 148 insertions, 126 deletions
diff --git a/design-notes.html b/design-notes.html index 1b850279..0ff18a89 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: 2001/10/01 03:05:18 $ +<td width="30%" align=right>$Date: 2002/03/10 19:59:57 $ </table> <HR> <H1 ALIGN=CENTER>Design Notes On Fetchmail</H1> @@ -534,13 +534,15 @@ all shaped the design in one way or another.<P> <DD> IMAP IDLE command <DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2449.txt">RFC2449</A> <DD> POP3 Extension Mechanism -<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2683.txt">RFC2683</A> -<DD> IMAP4 Implementation Recommendations -<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2595.html">RFC2595</A> +<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2554.txt">RFC2554</A> +<DD> SMTP Service Extension for Authentication +<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2595.txt">RFC2595</A> <DD> Using TLS with IMAP, POP3 and ACAP -<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2645.html">RFC2645</A> +<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2645.txt">RFC2645</A> <DD>On-Demand Mail Relay: SMTP with Dynamic IP Addresses -<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2821.html">RFC2821</A> +<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2683.txt">RFC2683</A> +<DD> IMAP4 Implementation Recommendations +<DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2821.txt">RFC2821</A> <DD> Simple Mail Transfer Protocol <DT><A HREF="ftp://ftp.isi.edu/in-notes/rfc2822.txt">RFC2822</A> <DD>Internet Message Format @@ -555,7 +557,7 @@ RFC2221 IMAP4 Login Referrals <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/10/01 03:05:18 $ +<td width="30%" align=right>$Date: 2002/03/10 19:59:57 $ </table> <P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com"><esr@snark.thyrsus.com></A></ADDRESS> @@ -40,7 +40,9 @@ static int etrn_getrange(int sock, struct query *ctl, const char *id, char buf [MSGBUFSIZE+1]; struct idlist *qnp; /* pointer to Q names */ - if ((ok = SMTP_ehlo(sock, fetchmailhost, &opts))) + if ((ok = SMTP_ehlo(sock, fetchmailhost, + ctl->server.esmtp_name, ctl->server.esmtp_password, + &opts))) { report(stderr, GT_("%s's SMTP listener does not support ESMTP\n"), ctl->server.pollname); diff --git a/fetchmail.c b/fetchmail.c index d7dbf59c..fa7b4625 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -873,6 +873,7 @@ static int load_params(int argc, char **argv, int optind) def_opts.server.protocol = P_AUTO; def_opts.server.timeout = CLIENT_TIMEOUT; + def_opts.server.esmtp_name = user; def_opts.warnings = WARNING_INTERVAL; def_opts.remotename = user; def_opts.listener = SMTP_MODE; diff --git a/fetchmail.h b/fetchmail.h index 0beccbc3..bacad070 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -220,7 +220,7 @@ struct hostdata /* shared among all user connections to given server */ #endif /* SDPS_ENABLE */ flag checkalias; /* resolve aliases by comparing IPs? */ char *principal; /* Kerberos principal for mail service */ - + char *esmtp_name, *esmtp_password; /* ESMTP AUTH information */ #if defined(linux) || defined(__FreeBSD__) char *interface; diff --git a/fetchmail.man b/fetchmail.man index b03544dc..e68073fd 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -664,7 +664,7 @@ editor like written in Python. .SH USER AUTHENTICATION AND ENCRYPTION -All modes except ETRN require authentication of the client. +All modes except ETRN require authentication of the client to the server. Normal user authentication in .I fetchmail is very much like the authentication mechanism of @@ -821,7 +821,7 @@ by a recognized Certifying Authority. The format for the key files and the certificate files is that required by the underlying SSL libraries (OpenSSL in the general case). .PP -Finally, a word of care about the use of SSL: While above mentioned +A word of care about the use of SSL: While above mentioned setup with self-signed server certificates retrieved over the wires can protect you from a passive eavesdropper it doesn't help against an active attacker. It's clearly an improvement over sending the @@ -830,6 +830,12 @@ attack is trivially possible (in particular with tools such as dsniff, http://www.monkey.org/~dugsong/dsniff/). Use of an ssh tunnel (see below for some examples) is preferable if you care seriously about the security of your mailbox. +.PP +.B fetchmail +also supports authentication to the ESMTP server on the client side +according to RFC 2554. You can specify a name/password pair to be +used with the keywords `esmtpname' and `esmtppassword'; the former +defaults to the username of the calling user. .SH DAEMON MODE The @@ -1305,6 +1311,12 @@ T} principal \& T{ Set Kerberos principal (only useful with imap and kerberos) T} +esmtpname \& T{ +Set name for RFC2554 authentication to the ESMTP server. +T} +esmtppassword \& T{ +Set password for RFC2554 authentication to the ESMTP server. +T} .TE Here are the legal user options: @@ -2193,7 +2205,8 @@ mutt(1), elm(1), mail(1), sendmail(8), popd(8), imapd(8), netrc(5) .SH APPLICABLE STANDARDS .TP 5 SMTP/ESMTP: -RFC 821, RFC2821, RFC 1869, RFC 1652, RFC 1870, RFC1983, RFC 1985 +RFC 821, RFC2821, RFC 1869, RFC 1652, RFC 1870, RFC 1983, RFC 1985, +RFC 2554 .TP 5 mail: RFC 822, RFC2822, RFC 1123, RFC 1892, RFC 1894 @@ -48,7 +48,9 @@ static int odmr_getrange(int sock, struct query *ctl, const char *id, char buf [MSGBUFSIZE+1]; struct idlist *qnp; /* pointer to Q names */ - if ((ok = SMTP_ehlo(sock, fetchmailhost, &opts))) + if ((ok = SMTP_ehlo(sock, fetchmailhost, + ctl->server.esmtp_name, ctl->server.esmtp_password, + &opts))) { report(stderr, GT_("%s's SMTP listener does not support ESMTP\n"), ctl->server.pollname); @@ -98,6 +98,9 @@ timeout { return TIMEOUT;} envelope { return ENVELOPE; } qvirtual { return QVIRTUAL; } principal { return PRINCIPAL; } +esmtpname { return ESMTPNAME; } +esmtppassword { return ESMTPPASSWORD; } + user(name)? {SETSTATE(NAME); return USERNAME; } <INITIAL,NAME>pass(word)? {SETSTATE(NAME); return PASSWORD; } @@ -74,7 +74,7 @@ extern char * yytext; %token DROPSTATUS DROPDELIVERED %token DNS SERVICE PORT UIDL INTERVAL MIMEDECODE IDLE CHECKALIAS %token SSL SSLKEY SSLCERT SSLPROTO SSLCERTCK SSLCERTPATH SSLFINGERPRINT -%token PRINCIPAL +%token PRINCIPAL ESMTPNAME ESMTPPASSWORD %token TRACEPOLLS %% @@ -157,6 +157,8 @@ serv_option : AKA alias_list #endif /* INET6_ENABLE */ } | PRINCIPAL STRING {current.server.principal = xstrdup($2);} + | ESMTPNAME STRING {current.server.esmtp_name = xstrdup($2);} + | ESMTPPASSWORD STRING {current.server.esmtp_password = xstrdup($2);} | PROTOCOL SDPS { #ifdef SDPS_ENABLE current.server.protocol = P_POP3; @@ -154,8 +154,9 @@ int smtp_open(struct query *ctl) /* first, probe for ESMTP */ if (SMTP_ok(ctl->smtp_socket) == SM_OK && - SMTP_ehlo(ctl->smtp_socket, id_me, - &ctl->server.esmtp_options) == SM_OK) + SMTP_ehlo(ctl->smtp_socket, id_me, + ctl->server.esmtp_name, ctl->server.esmtp_password, + &ctl->server.esmtp_options) == SM_OK) break; /* success */ /* @@ -16,8 +16,6 @@ #include "smtp.h" #include "config.h" -static void SMTP_auth(int, char *); - struct opt { const char *name; @@ -37,8 +35,6 @@ static struct opt extensions[] = }; char smtp_response[MSGBUFSIZE]; -char esmtp_auth_username[65]; -char esmtp_auth_password[256]; static char smtp_mode = 'S'; @@ -60,7 +56,110 @@ int SMTP_helo(int sock,const char *host) return ok; } -int SMTP_ehlo(int sock, const char *host, int *opt) +static void SMTP_auth(int sock, char *username, char *password, 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(password, strlen(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", 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", username, 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, username, strlen(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, password, strlen(password)); + SockPrintf(sock, "%s\r\n", b64buf); + SMTP_ok(sock); + } + return; +} + +int SMTP_ehlo(int sock, const char *host, char *name, char *password, int *opt) /* send a "EHLO" message to the SMTP listener, return extension status bits */ { struct opt *hp; @@ -93,7 +192,7 @@ int SMTP_ehlo(int sock, const char *host, int *opt) } 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); + SMTP_auth(sock, name, password, auth_response); return SM_OK; } else if (smtp_response[3] != '-') @@ -227,107 +326,4 @@ 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 */ @@ -23,7 +23,7 @@ void SMTP_setmode(char); int SMTP_helo(int socket,const char *host); -int SMTP_ehlo(int socket,const char *host,int *opt); +int SMTP_ehlo(int socket,const char *host, char *name, char *passwd, int *opt); int SMTP_from(int socket,const char *from,const char *opts); int SMTP_rcpt(int socket,const char *to); int SMTP_data(int socket); |