aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--driver.c75
2 files changed, 63 insertions, 13 deletions
diff --git a/NEWS b/NEWS
index baf9e32a..31735e13 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ fetchmail-4.6.8 ():
* Documented fetchmail's actions on ESMTP errors.
* Fix an undead-message hole in POP3 with fetchall on.
* Fix a minor error in generation of fetchmail's trace headers.
+* Better Received-line parsing (avoid some false positives).
There are 247 people on fetchmail-friends and 309 on fetchmail-announce.
diff --git a/driver.c b/driver.c
index efbbec4c..cad5a822 100644
--- a/driver.c
+++ b/driver.c
@@ -231,11 +231,9 @@ static char *parse_received(struct query *ctl, char *bufp)
* which makes nxtaddr() behave correctly.
*/
{
- char *ok = (char *)NULL;
+ char *base, *ok = (char *)NULL;
static char rbuf[HOSTLEN + USERNAMELEN + 4];
- if (outlevel >= O_DEBUG)
- error(0, 0, _("analyzing Received line:\n%s"), bufp);
/*
* Try to extract the real envelope addressee. We look here
* specifically for the mailserver's Received line.
@@ -244,18 +242,40 @@ static char *parse_received(struct query *ctl, char *bufp)
* address in the Received line. Sendmail itself only
* does this when the mail has a single recipient.
*/
- if ((ok = strstr(bufp, "by ")) && isspace(ok[-1]))
- {
- char *sp, *tp;
+ if (outlevel >= O_DEBUG)
+ error(0, 0, _("analyzing Received line:\n%s"), bufp);
- /* extract space-delimited token after "by " */
- for (sp = ok + 3; isspace(*sp); sp++)
+ /* search for whitepace-surrounded "by" followed by xxxx.yyyy */
+ for (base = bufp; ; base = ok + 2)
+ {
+ if (!(ok = strstr(base, "by")))
+ break;
+ else if (!isspace(ok[-1]) || !isspace(ok[2]))
+ {
+ ok = (char *)NULL;
continue;
- tp = rbuf;
- for (; !isspace(*sp); sp++)
- *tp++ = *sp;
- *tp = '\0';
+ }
+ else
+ {
+ char *sp, *tp;
+
+ /* extract space-delimited token after "by" */
+ for (sp = ok + 2; isspace(*sp); sp++)
+ continue;
+ tp = rbuf;
+ for (; !isspace(*sp); sp++)
+ *tp++ = *sp;
+ *tp = '\0';
+ /* look for embedded periods */
+ if (strchr(rbuf, '.'))
+ break;
+ else
+ ok = sp - 1; /* arrange to skip this token */
+ }
+ }
+ if (ok)
+ {
/*
* If it's a DNS name of the mail server, look for the
* recipient name after a following "for". Otherwise
@@ -276,9 +296,38 @@ static char *parse_received(struct query *ctl, char *bufp)
return(NULL);
}
- if ((ok = strstr(sp, "for")) && isspace(ok[3]) && isspace(ok[-1]))
+ /* search for whitepace-surrounded "for" followed by xxxx@yyyy */
+ for (base = ok + 4 + strlen(rbuf); ; base = ok + 2)
+ {
+ if (!(ok = strstr(base, "for")))
+ break;
+ else if (!isspace(ok[-1]) || !isspace(ok[3]))
+ {
+ ok = (char *)NULL;
+ continue;
+ }
+ else
+ {
+ char *sp, *tp;
+
+ /* extract space-delimited token after "for" */
+ for (sp = ok + 3; isspace(*sp); sp++)
+ continue;
+ tp = rbuf;
+ for (; !isspace(*sp); sp++)
+ *tp++ = *sp;
+ *tp = '\0';
+
+ if (strchr(rbuf, '@'))
+ break;
+ else
+ ok = sp - 1; /* arrange to skip this token */
+ }
+ }
+ if (ok)
{
flag want_gt = FALSE;
+ char *sp, *tp;
/* char after "for" could be space or a continuation newline */
for (sp = ok + 4; isspace(*sp); sp++)