From 7934e12c58af87fce16f1192c920cabbbd36d490 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 28 Nov 1998 19:41:08 +0000 Subject: Avoid false positives in Received parsing. svn path=/trunk/; revision=2224 --- NEWS | 1 + driver.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 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++) -- cgit v1.2.3