aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2002-03-10 19:59:59 +0000
committerEric S. Raymond <esr@thyrsus.com>2002-03-10 19:59:59 +0000
commita016460027f89e7c81106a0560d1d495f727c182 (patch)
tree0daf10c7b95f73d7ed3f3330f11f35a00cc96c78
parent7c33daaf6fd2bd4342903ad5ce025b5ab6bc89bd (diff)
downloadfetchmail-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.html16
-rw-r--r--etrn.c4
-rw-r--r--fetchmail.c1
-rw-r--r--fetchmail.h2
-rw-r--r--fetchmail.man19
-rw-r--r--odmr.c4
-rw-r--r--rcfile_l.l3
-rw-r--r--rcfile_y.y4
-rw-r--r--sink.c5
-rw-r--r--smtp.c214
-rw-r--r--smtp.h2
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">&lt;esr@snark.thyrsus.com&gt;</A></ADDRESS>
diff --git a/etrn.c b/etrn.c
index 00455faf..7f5e882d 100644
--- a/etrn.c
+++ b/etrn.c
@@ -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
diff --git a/odmr.c b/odmr.c
index 1f13c1b3..0c4db033 100644
--- a/odmr.c
+++ b/odmr.c
@@ -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);
diff --git a/rcfile_l.l b/rcfile_l.l
index 39574586..bf7a663f 100644
--- a/rcfile_l.l
+++ b/rcfile_l.l
@@ -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; }
diff --git a/rcfile_y.y b/rcfile_y.y
index 7701d2c4..a85a7fa0 100644
--- a/rcfile_y.y
+++ b/rcfile_y.y
@@ -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;
diff --git a/sink.c b/sink.c
index ebd674b9..bd1d9243 100644
--- a/sink.c
+++ b/sink.c
@@ -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 */
/*
diff --git a/smtp.c b/smtp.c
index ee99bcf7..68908412 100644
--- a/smtp.c
+++ b/smtp.c
@@ -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 */
diff --git a/smtp.h b/smtp.h
index 6f375684..8d27049b 100644
--- a/smtp.h
+++ b/smtp.h
@@ -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);