Mercurial > dnsbl
diff src/context.cpp @ 421:22027ad2a28f stable-6-0-58
spf code now handles %{d} and %{h} macros; use envelope from value for spf if it is a subdomain of the header from domain
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 19 May 2017 13:44:13 -0700 |
parents | 91f2a127ec69 |
children | c9b7b6dd1206 |
line wrap: on
line diff
--- a/src/context.cpp Wed Apr 26 09:27:01 2017 -0700 +++ b/src/context.cpp Fri May 19 13:44:13 2017 -0700 @@ -1130,31 +1130,62 @@ } +void CONTEXT::replace(char *buf, char *p, const char *what) +{ + // replace 4 chars in buf starting at p with what + char repl[maxlen]; + size_t bn = strlen(buf); + size_t wn = strlen(what); + if ((bn - 4 + wn) < (size_t)maxlen) { + size_t n = p - buf; // leading part length + strncpy(repl, buf, n); // leading part + strcpy(repl+n, what); // replacement + strcpy(repl+n+wn, buf+n+4); // trailing part + strcpy(buf, repl); + } +} + bool CONTEXT::resolve_spf(const char *from, uint32_t ip, mlfiPriv *priv, int level) { // ip is in host order + if ((level == 0) && (priv->mailaddr)) { + const char *f = strchr(priv->mailaddr, '@'); + if (f) { + f++; + size_t efl = strlen(f); // envelope from domain + size_t hfl = strlen(from); // header from domain + if (efl > hfl) { + size_t off = efl - hfl; + if ((f[off-1] == '.') && (strcmp(f+off,from) == 0)) { + // envelope from is a strict child of header from + from = f; // use envelope from rather than header from + } + } + } + } char buf[maxlen]; log(priv->queueid, "looking for %s txt record", from); dns_interface(*priv, from, ns_t_txt, false, NULL, buf, maxlen); if (*buf) { log(priv->queueid, "found txt record %s", buf); // expand some macros here - a very restricted subset of all possible spf macros - // only expand the first one. + // only expand the first instance of each. char *p = strstr(buf, "%{i}"); if (p) { - char repl[maxlen]; char adr[sizeof "255.255.255.255 "]; adr[0] = '\0'; inet_ntop(AF_INET, (const u_char *)&priv->ip, adr, sizeof(adr)); - size_t bn = strlen(buf); - size_t an = strlen(adr); - if ((bn - 4 + an) < (size_t)maxlen) { - size_t n = p - buf; // leading part length - strncpy(repl, buf, n); // leading part - strcpy(repl+n, adr); // replacement - strcpy(repl+n+an, buf+n+4); // trailing part - strcpy(buf, repl); + replace(buf, p, adr); + log(priv->queueid, "have txt record %s", buf); } + p = strstr(buf, "%{h}"); + if (p) { + replace(buf, p, priv->helo); + log(priv->queueid, "have txt record %s", buf); + } + p = strstr(buf, "%{d}"); + if (p) { + replace(buf, p, from); log(priv->queueid, "have txt record %s", buf); } //