summaryrefslogtreecommitdiff
path: root/src/spf.c
diff options
context:
space:
mode:
authorJannis Hoffmann <jannis@fehcom.de>2024-07-03 15:52:39 +0200
committerJannis Hoffmann <jannis@fehcom.de>2024-07-03 15:52:39 +0200
commita6a7d6ce079cabdaf2fa502b2e2cf15e5428ac6f (patch)
treeb88cc7a8457658d67e0321718556ac807f6bccf3 /src/spf.c
parent00be7622c428f279872f84569f098ce16150f8a8 (diff)
format files
Diffstat (limited to 'src/spf.c')
-rw-r--r--src/spf.c551
1 files changed, 310 insertions, 241 deletions
diff --git a/src/spf.c b/src/spf.c
index 2b61ba1..a4d31d3 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -1,34 +1,36 @@
-#include "stralloc.h"
+#include "spf.h"
+
#include "alloc.h"
+#include "byte.h"
+#include "case.h"
+#include "fmt.h"
#include "ip.h"
+#include "scan.h"
+#include "str.h"
+#include "stralloc.h"
+
+#include "dns.h"
#include "ipalloc.h"
#include "ipme.h"
-#include "str.h"
-#include "fmt.h"
-#include "scan.h"
-#include "byte.h"
#include "now.h"
-#include "dns.h"
-#include "case.h"
-#include "spf.h"
/* long lived SPF variables (output) */
-stralloc spfinfo = {0}; /* SPF results - see spf.h */
-stralloc spfrecord = {0}; /* Used for diagnostics */
+stralloc spfinfo = {0}; /* SPF results - see spf.h */
+stralloc spfrecord = {0}; /* Used for diagnostics */
/* s/qmail control SPF variables (input) */
-stralloc spflocalrules; /* Local rules provided here */
-stralloc spfexplain; /* Default SPF_EXPMSG in spf.h */
+stralloc spflocalrules; /* Local rules provided here */
+stralloc spfexplain; /* Default SPF_EXPMSG in spf.h */
-stralloc spfmf = {0}; /* aka envelopefrom = clientid */
-stralloc spfhelo = {0}; /* helo or domain part for spfmf */
-stralloc dnsname = {0}; /* FQDN of client host in DNS */
-stralloc spflocal = {0}; /* Receiving host */
+stralloc spfmf = {0}; /* aka envelopefrom = clientid */
+stralloc spfhelo = {0}; /* helo or domain part for spfmf */
+stralloc dnsname = {0}; /* FQDN of client host in DNS */
+stralloc spflocal = {0}; /* Receiving host */
-stralloc spfexpmsg = {0}; /* additional explanation given as 5xx SMTP response */
-stralloc expdomain = {0}; /* the domain, for which explanation is given */
+stralloc spfexpmsg = {0}; /* additional explanation given as 5xx SMTP response */
+stralloc expdomain = {0}; /* the domain, for which explanation is given */
int flagip6;
stralloc domain = {0};
@@ -55,75 +57,81 @@ Exists+Expand: exists.com TXT "v=spf1 exists:%{ir}.%{l1r+-}._spf.%{d} -all"
*/
-int spf_query(const char *remoteip,const char *helo,const char *mf,const char *local,const int flagip)
+int spf_query(
+ const char *remoteip, const char *helo, const char *mf, const char *local, const int flagip)
{
int at;
int r = SPF_INIT;
flagip6 = flagip;
- if (!stralloc_copys(&spfinfo," ")) return SPF_NOMEM;
-
+ if (!stralloc_copys(&spfinfo, " ")) return SPF_NOMEM;
+
switch (flagip6) {
- case -1: if (!spf_info("MLocal=",remoteip)) return SPF_NOMEM;
- if (!spf_info("R:","+")) return SPF_NOMEM;
- break;
- case 0: if (!ip4_scan(remoteip,ip4remote)) return SPF_SYNTAX;
- if (ipme_is4(ip4remote) == 1) {
- if (!spf_info("MLocal=",remoteip)) return SPF_NOMEM;
- if (!spf_info("R:","+")) return SPF_NOMEM;
- return SPF_ME;
- } break;
- case 1: if (!ip6_scan(remoteip,ip6remote)) return SPF_SYNTAX;
- if (ipme_is6(ip6remote) == 1) {
- if (!spf_info("MLocal=",remoteip)) return SPF_NOMEM;
- if (!spf_info("R:","+")) return SPF_NOMEM;
- return SPF_ME;
- } break;
+ case -1:
+ if (!spf_info("MLocal=", remoteip)) return SPF_NOMEM;
+ if (!spf_info("R:", "+")) return SPF_NOMEM;
+ break;
+ case 0:
+ if (!ip4_scan(remoteip, ip4remote)) return SPF_SYNTAX;
+ if (ipme_is4(ip4remote) == 1) {
+ if (!spf_info("MLocal=", remoteip)) return SPF_NOMEM;
+ if (!spf_info("R:", "+")) return SPF_NOMEM;
+ return SPF_ME;
+ }
+ break;
+ case 1:
+ if (!ip6_scan(remoteip, ip6remote)) return SPF_SYNTAX;
+ if (ipme_is6(ip6remote) == 1) {
+ if (!spf_info("MLocal=", remoteip)) return SPF_NOMEM;
+ if (!spf_info("R:", "+")) return SPF_NOMEM;
+ return SPF_ME;
+ }
+ break;
}
if (helo && str_len(helo)) {
- if (!stralloc_copys(&spfhelo,helo)) return SPF_NOMEM;
+ if (!stralloc_copys(&spfhelo, helo)) return SPF_NOMEM;
} else {
- if (!stralloc_copys(&spfhelo,"unknown")) return SPF_NOMEM;
+ if (!stralloc_copys(&spfhelo, "unknown")) return SPF_NOMEM;
}
if (!stralloc_0(&spfhelo)) return SPF_NOMEM;
if (mf && str_len(mf)) {
- if (!stralloc_copys(&spfmf,mf)) return SPF_NOMEM;
+ if (!stralloc_copys(&spfmf, mf)) return SPF_NOMEM;
if (!stralloc_0(&spfmf)) return SPF_NOMEM;
- at = str_rchr(spfmf.s,'@');
+ at = str_rchr(spfmf.s, '@');
if (spfmf.s[at] == '@') {
- if (!stralloc_copys(&domain,spfmf.s + at + 1)) return SPF_NOMEM;
+ if (!stralloc_copys(&domain, spfmf.s + at + 1)) return SPF_NOMEM;
} else {
-// if (!stralloc_0(&spfhelo)) return SPF_NOMEM;
- if (!stralloc_copys(&domain,&spfhelo)) return SPF_NOMEM;
+ // if (!stralloc_0(&spfhelo)) return SPF_NOMEM;
+ if (!stralloc_copys(&domain, &spfhelo)) return SPF_NOMEM;
}
- if (!stralloc_copy(&identity,&domain)) return SPF_NOMEM;
+ if (!stralloc_copy(&identity, &domain)) return SPF_NOMEM;
}
if (!stralloc_0(&identity)) return SPF_NOMEM;
if (local && str_len(local)) {
- if (!stralloc_copys(&spflocal,local)) return SPF_NOMEM;
+ if (!stralloc_copys(&spflocal, local)) return SPF_NOMEM;
} else {
- if (!stralloc_copys(&spflocal,"localhost")) return SPF_NOMEM;
+ if (!stralloc_copys(&spflocal, "localhost")) return SPF_NOMEM;
}
if (!stralloc_0(&spflocal)) return SPF_NOMEM;
- if (!spf_info("S=",remoteip)) return SPF_NOMEM;
- if (!spf_info("O=",spfmf.s)) return SPF_NOMEM;
- if (!spf_info("C=",identity.s)) return SPF_NOMEM;
- if (!spf_info("H=",spfhelo.s)) return SPF_NOMEM;
+ if (!spf_info("S=", remoteip)) return SPF_NOMEM;
+ if (!spf_info("O=", spfmf.s)) return SPF_NOMEM;
+ if (!spf_info("C=", identity.s)) return SPF_NOMEM;
+ if (!spf_info("H=", spfhelo.s)) return SPF_NOMEM;
- if (!stralloc_copy(&spfexpmsg,&spfexplain)) return SPF_NOMEM;
- if (!stralloc_0(&spfexpmsg)) return SPF_NOMEM;
+ if (!stralloc_copy(&spfexpmsg, &spfexplain)) return SPF_NOMEM;
+ if (!stralloc_0(&spfexpmsg)) return SPF_NOMEM;
recursion = 0;
dnsname.len = 0;
if (r == SPF_INIT) r = spf_lookup(&domain);
if (r == SPF_LOOP) {
- if (!spf_info("P=","Maximum nesting level exceeded; possible loop")) return SPF_NOMEM;
- if (!spf_info("R:","e")) return SPF_NOMEM;
+ if (!spf_info("P=", "Maximum nesting level exceeded; possible loop")) return SPF_NOMEM;
+ if (!spf_info("R:", "e")) return SPF_NOMEM;
}
if (r < 0) r = SPF_UNKNOWN; /* return 2main */
@@ -136,14 +144,14 @@ static struct spf_aliases {
char *alias;
int defrc;
} spf_aliases[] = {
- { "allow", SPF_OK }
-, { "pass", SPF_OK }
-, { "deny", SPF_FAIL }
-, { "softdeny",SPF_SOFTFAIL }
-, { "fail", SPF_FAIL }
-, { "softfail",SPF_SOFTFAIL }
-, { "unknown", SPF_NEUTRAL }
-, { 0, SPF_UNKNOWN }
+ { "allow", SPF_OK},
+ { "pass", SPF_OK},
+ { "deny", SPF_FAIL},
+ {"softdeny", SPF_SOFTFAIL},
+ { "fail", SPF_FAIL},
+ {"softfail", SPF_SOFTFAIL},
+ { "unknown", SPF_NEUTRAL},
+ { 0, SPF_UNKNOWN}
};
/**
@@ -155,7 +163,7 @@ static struct spf_aliases {
@return int r = SPF return code
*/
-int spf_lookup(stralloc *domain)
+int spf_lookup(stralloc *domain)
{
stralloc spfdata = {0};
stralloc sa = {0};
@@ -164,7 +172,7 @@ int spf_lookup(stralloc *domain)
int local_pos = -1;
int localrules = 0;
int q = -1;
- int i, r;
+ int i, r;
int begin, pos;
int spfrc;
int done;
@@ -172,64 +180,64 @@ int spf_lookup(stralloc *domain)
/* Fallthrough result */
- REDIRECT:
- if (++recursion > LOOKUP_LIMIT) return SPF_EXHAUST;
+REDIRECT:
+ if (++recursion > LOOKUP_LIMIT) return SPF_EXHAUST;
- if (!stralloc_copys(&expdomain,domain->s)) return SPF_NOMEM; // *FIXME */
+ if (!stralloc_copys(&expdomain, domain->s)) return SPF_NOMEM; // *FIXME */
- if (!stralloc_copys(&spfdata,"")) return SPF_NOMEM;
- r = spf_records(&spfdata,domain);
+ if (!stralloc_copys(&spfdata, "")) return SPF_NOMEM;
+ r = spf_records(&spfdata, domain);
if (!stralloc_0(domain)) return SPF_NOMEM;
- if (first) if (!stralloc_copys(&spfrecord,"")) return SPF_NOMEM;
- if (!stralloc_cats(&spfrecord,"(")) return SPF_NOMEM;
- if (!stralloc_cat(&spfrecord,domain)) return SPF_NOMEM;
- if (!stralloc_cats(&spfrecord,")")) return SPF_NOMEM;
- if (!stralloc_cats(&spfrecord," => ")) return SPF_NOMEM;
- if (!stralloc_cat(&spfrecord,&spfdata)) return SPF_NOMEM;
- if (!stralloc_cats(&spfrecord,"\n")) return SPF_NOMEM;
+ if (first)
+ if (!stralloc_copys(&spfrecord, "")) return SPF_NOMEM;
+ if (!stralloc_cats(&spfrecord, "(")) return SPF_NOMEM;
+ if (!stralloc_cat(&spfrecord, domain)) return SPF_NOMEM;
+ if (!stralloc_cats(&spfrecord, ")")) return SPF_NOMEM;
+ if (!stralloc_cats(&spfrecord, " => ")) return SPF_NOMEM;
+ if (!stralloc_cat(&spfrecord, &spfdata)) return SPF_NOMEM;
+ if (!stralloc_cats(&spfrecord, "\n")) return SPF_NOMEM;
if (!stralloc_0(&spfrecord)) return SPF_NOMEM;
/* In spite of none-existing SPF data, use local rules as substitude */
- if (r == SPF_NONE) { /* No SPF records published */
- if (!first) {
- return r;
+ if (r == SPF_NONE) { /* No SPF records published */
+ if (!first) {
+ return r;
} else {
spfdata.len = 0;
}
- if (localrules) { /* append local ruleset */
+ if (localrules) { /* append local ruleset */
local_pos = spfdata.len;
- if (!stralloc_cats(&spfdata,spflocalrules.s)) return SPF_NOMEM;
+ if (!stralloc_cats(&spfdata, spflocalrules.s)) return SPF_NOMEM;
}
if (!stralloc_0(&spfdata)) return SPF_NOMEM;
- if (!stralloc_copys(&expdomain,"")) return SPF_NOMEM;
-
- } else if (r == SPF_OK) { /* SPF records published */
+ if (!stralloc_copys(&expdomain, "")) return SPF_NOMEM;
+
+ } else if (r == SPF_OK) { /* SPF records published */
if (!stralloc_0(&spfdata)) return SPF_NOMEM;
r = SPF_NEUTRAL;
if (first && localrules) { /* try to add local rules before failure of all mechs */
pos = 0;
- p = (char *) 0;
+ p = (char *)0;
while (pos < spfdata.len) {
- NXTOK(begin,pos,&spfdata);
+ NXTOK(begin, pos, &spfdata);
if (!spfdata.s[begin]) continue;
- if (p && spfdata.s[begin] != *p) p = (char *) 0;
- if (!p && (spfdata.s[begin] == '-' ||
- spfdata.s[begin] == '~' ||
- spfdata.s[begin] == '?')) p = &spfdata.s[begin];
+ if (p && spfdata.s[begin] != *p) p = (char *)0;
+ if (!p && (spfdata.s[begin] == '-' || spfdata.s[begin] == '~' || spfdata.s[begin] == '?'))
+ p = &spfdata.s[begin];
- if (p && p > spfdata.s && case_equals(spfdata.s + begin + 1,"all")) {
+ if (p && p > spfdata.s && case_equals(spfdata.s + begin + 1, "all")) {
/* ok, we can insert the local rules at p */
local_pos = p - spfdata.s;
- if (!stralloc_readyplus(&spfdata,spflocalrules.len)) return 0;
+ if (!stralloc_readyplus(&spfdata, spflocalrules.len)) return 0;
p = spfdata.s + local_pos;
- byte_copyr(p + spflocalrules.len,spfdata.len - local_pos,p);
- byte_copy(p,spflocalrules.len,spflocalrules.s);
+ byte_copyr(p + spflocalrules.len, spfdata.len - local_pos, p);
+ byte_copy(p, spflocalrules.len, spflocalrules.s);
spfdata.len += spflocalrules.len;
pos += spflocalrules.len;
@@ -241,8 +249,8 @@ int spf_lookup(stralloc *domain)
for (i = 0; i < pos; i++)
if (!spfdata.s[i]) spfdata.s[i] = ' ';
}
-
- } else { /* Any other SPF return code */
+
+ } else { /* Any other SPF return code */
return r;
}
@@ -251,15 +259,15 @@ int spf_lookup(stralloc *domain)
pos = 0;
done = 0;
while (pos < spfdata.len) {
- NXTOK(begin,pos,&spfdata);
+ NXTOK(begin, pos, &spfdata);
if (!spfdata.s[begin]) continue;
- if (!done && localrules) { /* in local ruleset? */
+ if (!done && localrules) { /* in local ruleset? */
if (local_pos >= 0 && begin >= local_pos) {
if (begin < (local_pos + spflocalrules.len)) {
- if (!stralloc_copys(&expdomain,"")) return SPF_NOMEM;
+ if (!stralloc_copys(&expdomain, "")) return SPF_NOMEM;
} else {
- if (!stralloc_copy(&expdomain,domain)) return SPF_NOMEM;
+ if (!stralloc_copy(&expdomain, domain)) return SPF_NOMEM;
}
}
}
@@ -270,88 +278,116 @@ int spf_lookup(stralloc *domain)
if (*p == '=') {
*p++ = 0;
- if (case_equals(spfdata.s + begin,"redirect")) { /* modifiers are simply handled here */
+ if (case_equals(spfdata.s + begin, "redirect")) { /* modifiers are simply handled here */
if (done) continue;
-
-// if (!stralloc_0(domain)) return SPF_NOMEM;
- if (!spf_parse(&sa,p,domain->s)) return SPF_NOMEM;
- if (!stralloc_copy(domain,&sa)) return SPF_NOMEM;
- if (!spf_info("D=",p)) return SPF_NOMEM;
+
+ // if (!stralloc_0(domain)) return SPF_NOMEM;
+ if (!spf_parse(&sa, p, domain->s)) return SPF_NOMEM;
+ if (!stralloc_copy(domain, &sa)) return SPF_NOMEM;
+ if (!spf_info("D=", p)) return SPF_NOMEM;
r = SPF_UNKNOWN;
goto REDIRECT;
- } else if (case_equals(spfdata.s + begin,"default")) { /* we don't need those anymore */
- if (done) continue;
+ } else if (case_equals(spfdata.s + begin, "default")) { /* we don't need those anymore */
+ if (done) continue;
- for (da = spf_aliases; da->alias; ++da)
- if (case_equals(da->alias,p)) break;
+ for (da = spf_aliases; da->alias; ++da)
+ if (case_equals(da->alias, p)) break;
- r = da->defrc;
- } else if (case_equals(spfdata.s + begin,"exp")) { /* exp= only on top level */
+ r = da->defrc;
+ } else if (case_equals(spfdata.s + begin, "exp")) { /* exp= only on top level */
stralloc out = {0};
if (!first) continue;
- if (!stralloc_copys(&sa,p)) return SPF_NOMEM;
-
- switch (dns_txt(&out,&sa)) {
+ if (!stralloc_copys(&sa, p)) return SPF_NOMEM;
+
+ switch (dns_txt(&out, &sa)) {
case -1: return SPF_NOMEM;
- case 0: continue; /* nobody @home */
+ case 0: continue; /* nobody @home */
}
- if (!stralloc_copys(&spfexpmsg,out.s)) return SPF_NOMEM;
- if (!stralloc_append(&spfexpmsg,"\n")) return SPF_NOMEM;
+ if (!stralloc_copys(&spfexpmsg, out.s)) return SPF_NOMEM;
+ if (!stralloc_append(&spfexpmsg, "\n")) return SPF_NOMEM;
if (!stralloc_0(&spfexpmsg)) return SPF_NOMEM;
}
- } else if (!done) { /* and unknown modifiers are ignored */
- if (!stralloc_copys(&sa,spfdata.s + begin)) return SPF_NOMEM;
+ } else if (!done) { /* and unknown modifiers are ignored */
+ if (!stralloc_copys(&sa, spfdata.s + begin)) return SPF_NOMEM;
if (!stralloc_0(&sa)) return SPF_NOMEM;
-
+
switch (spfdata.s[begin]) {
- case '-': begin++; spfrc = SPF_FAIL; break;
- case '~': begin++; spfrc = SPF_SOFTFAIL; break;
- case '+': begin++; spfrc = SPF_OK; break;
- case '?': begin++; spfrc = SPF_NEUTRAL; break;
- default: spfrc = SPF_OK;
+ case '-':
+ begin++;
+ spfrc = SPF_FAIL;
+ break;
+ case '~':
+ begin++;
+ spfrc = SPF_SOFTFAIL;
+ break;
+ case '+':
+ begin++;
+ spfrc = SPF_OK;
+ break;
+ case '?':
+ begin++;
+ spfrc = SPF_NEUTRAL;
+ break;
+ default: spfrc = SPF_OK;
}
if (*p == '/') {
*p++ = 0;
- q = spf_mechanism(spfdata.s + begin,0,p,domain->s);
+ q = spf_mechanism(spfdata.s + begin, 0, p, domain->s);
} else {
if (*p) *p++ = 0;
- i = str_chr(p,'/');
+ i = str_chr(p, '/');
if (p[i] == '/') {
p[i++] = 0;
- q = spf_mechanism(spfdata.s + begin,p,p + i,domain->s);
+ q = spf_mechanism(spfdata.s + begin, p, p + i, domain->s);
} else if (i > 0) {
- q = spf_mechanism(spfdata.s + begin,p,0,domain->s);
+ q = spf_mechanism(spfdata.s + begin, p, 0, domain->s);
} else {
- q = spf_mechanism(spfdata.s + begin,0,0,domain->s);
+ q = spf_mechanism(spfdata.s + begin, 0, 0, domain->s);
}
}
if (q == SPF_OK) q = spfrc;
switch (q) {
- case SPF_OK: if (!spf_info("R:","+")) return SPF_NOMEM; break;
- case SPF_NEUTRAL: if (!spf_info("R:","?")) return SPF_NOMEM; break;
- case SPF_SYNTAX: if (!spf_info("P=","Unknown parse error")) return SPF_NOMEM;
- if (!spf_info("R:","e")) return SPF_NOMEM; break;
- case SPF_SOFTFAIL: if (!spf_info("R:","~")) return SPF_NOMEM; break;
- case SPF_FAIL: if (!spf_info("R:","-")) return SPF_NOMEM; break;
- case SPF_EXT: if (!spf_info("P=","Unknown SPF mechanism")) return SPF_NOMEM; break;
- case SPF_ERROR: if (localrules) if (local_pos >= 0 && begin >= local_pos) break;
- if (!spf_info("R:","o")) return SPF_NOMEM; q = SPF_NONE; break;
- case SPF_NONE: continue;
+ case SPF_OK:
+ if (!spf_info("R:", "+")) return SPF_NOMEM;
+ break;
+ case SPF_NEUTRAL:
+ if (!spf_info("R:", "?")) return SPF_NOMEM;
+ break;
+ case SPF_SYNTAX:
+ if (!spf_info("P=", "Unknown parse error")) return SPF_NOMEM;
+ if (!spf_info("R:", "e")) return SPF_NOMEM;
+ break;
+ case SPF_SOFTFAIL:
+ if (!spf_info("R:", "~")) return SPF_NOMEM;
+ break;
+ case SPF_FAIL:
+ if (!spf_info("R:", "-")) return SPF_NOMEM;
+ break;
+ case SPF_EXT:
+ if (!spf_info("P=", "Unknown SPF mechanism")) return SPF_NOMEM;
+ break;
+ case SPF_ERROR:
+ if (localrules)
+ if (local_pos >= 0 && begin >= local_pos) break;
+ if (!spf_info("R:", "o")) return SPF_NOMEM;
+ q = SPF_NONE;
+ break;
+ case SPF_NONE: continue;
}
r = q;
- done = 1; /* we're done, no more mechanisms */
+ done = 1; /* we're done, no more mechanisms */
}
}
/* we fell through, no local rule applied */
if (!done)
- if (!stralloc_copy(&expdomain,domain)) return SPF_NOMEM;
+ if (!stralloc_copy(&expdomain, domain)) return SPF_NOMEM;
return r;
}
@@ -360,23 +396,23 @@ int spf_lookup(stralloc *domain)
static struct mechanisms {
char *mechanism;
- int (*func)(char *spfspec,char *prefix);
+ int (*func)(char *spfspec, char *prefix);
unsigned int use_spfspec : 1;
- unsigned int use_prefix : 1;
- unsigned int expands : 1;
- unsigned int filldomain : 1;
- int defresult : 4;
+ unsigned int use_prefix : 1;
+ unsigned int expands : 1;
+ unsigned int filldomain : 1;
+ int defresult : 4;
} mechanisms[] = {
- { "all", 0, 0,0,0,0,SPF_OK }
-, { "include", spf_include,1,0,1,0,0 }
-, { "a", spf_a, 1,1,1,1,0 }
-, { "mx", spf_mx, 1,1,1,1,0 }
-, { "ptr", spf_ptr, 1,0,1,1,0 }
-, { "ip4", spf_ip4, 1,1,0,0,0 }
-, { "ip6", spf_ip6, 1,1,0,0,0 }
-, { "exists", spf_exists, 1,0,1,0,0 }
-, { "extension",0, 1,1,0,0,SPF_EXT }
-, { 0, 0, 1,1,0,0,SPF_EXT }
+ { "all", 0, 0, 0, 0, 0, SPF_OK},
+ { "include", spf_include, 1, 0, 1, 0, 0},
+ { "a", spf_a, 1, 1, 1, 1, 0},
+ { "mx", spf_mx, 1, 1, 1, 1, 0},
+ { "ptr", spf_ptr, 1, 0, 1, 1, 0},
+ { "ip4", spf_ip4, 1, 1, 0, 0, 0},
+ { "ip6", spf_ip6, 1, 1, 0, 0, 0},
+ { "exists", spf_exists, 1, 0, 1, 0, 0},
+ {"extension", 0, 1, 1, 0, 0, SPF_EXT},
+ { 0, 0, 1, 1, 0, 0, SPF_EXT}
};
/**
@@ -388,7 +424,7 @@ static struct mechanisms {
@return int r
*/
-int spf_mechanism(char *mechanism,char *spfspec,char *prefix,char *domain)
+int spf_mechanism(char *mechanism, char *spfspec, char *prefix, char *domain)
{
struct mechanisms *mech;
stralloc sa = {0};
@@ -396,28 +432,28 @@ int spf_mechanism(char *mechanism,char *spfspec,char *prefix,char *domain)
int pos;
for (mech = mechanisms; mech->mechanism; mech++)
- if (case_equals(mech->mechanism,mechanism)) break;
+ if (case_equals(mech->mechanism, mechanism)) break;
if (mech->use_spfspec && !spfspec && mech->filldomain) spfspec = domain;
if (!mech->use_spfspec != !spfspec) return SPF_SYNTAX;
if (mech->use_prefix && !get_prefix(prefix)) return SPF_SYNTAX;
if (!mech->func) return mech->defresult;
- if (!stralloc_readyplus(&sa,1)) return SPF_NOMEM;
+ if (!stralloc_readyplus(&sa, 1)) return SPF_NOMEM;
- if (mech->expands && case_diffs(spfspec,domain)) {
- if (!spf_parse(&sa,spfspec,domain)) return SPF_NOMEM;
+ if (mech->expands && case_diffs(spfspec, domain)) {
+ if (!spf_parse(&sa, spfspec, domain)) return SPF_NOMEM;
for (pos = 0; (sa.len - pos) > 255;) {
- pos += byte_chr(sa.s + pos,sa.len - pos,'.');
+ pos += byte_chr(sa.s + pos, sa.len - pos, '.');
if (pos < sa.len) pos++;
}
sa.len -= pos;
- if (pos > 0) byte_copy(sa.s,sa.len,sa.s + pos);
+ if (pos > 0) byte_copy(sa.s, sa.len, sa.s + pos);
if (!stralloc_0(&sa)) return SPF_NOMEM;
spfspec = sa.s;
}
- r = mech->func(spfspec,prefix);
+ r = mech->func(spfspec, prefix);
return r;
}
@@ -428,12 +464,12 @@ int spf_mechanism(char *mechanism,char *spfspec,char *prefix,char *domain)
@return int r = 1 ok; 0 failure
*/
-int spf_include(char *spfspec,char *prefix)
+int spf_include(char *spfspec, char *prefix)
{
stralloc sa = {0};
int r;
- if (!stralloc_copys(&sa,spfspec)) return SPF_NOMEM;
+ if (!stralloc_copys(&sa, spfspec)) return SPF_NOMEM;
r = spf_lookup(&sa);
switch (r) {
@@ -444,8 +480,8 @@ int spf_include(char *spfspec,char *prefix)
case SPF_FAIL: r = SPF_NONE; break;
}
if (!stralloc_0(&sa)) return SPF_NOMEM;
- if (!spf_info("I=",sa.s)) return SPF_NOMEM;
-
+ if (!spf_info("I=", sa.s)) return SPF_NOMEM;
+
return r;
}
@@ -458,34 +494,39 @@ int spf_include(char *spfspec,char *prefix)
@return int r = 1 ok; 0 failure
*/
-int spf_parse(stralloc *sa,char *spfspec,char *domain)
+int spf_parse(stralloc *sa, char *spfspec, char *domain)
{
char *p;
int pos;
char append;
- if (!stralloc_readyplus(sa,3)) return 0;
- if (!stralloc_copys(sa,"")) return 0;
+ if (!stralloc_readyplus(sa, 3)) return 0;
+ if (!stralloc_copys(sa, "")) return 0;
for (p = spfspec; *p; ++p) {
append = *p;
- if (byte_equal(p,1,"%")) {
+ if (byte_equal(p, 1, "%")) {
p++;
switch (*p) {
case '%': break;
case '_': append = ' '; break;
- case '-': if (!stralloc_cats(sa,"%20")) return 0; continue;
+ case '-':
+ if (!stralloc_cats(sa, "%20")) return 0;
+ continue;
case '{':
- pos = str_chr(p,'}');
- if (p[pos] != '}') { p--; break; }
- p[pos] = '\0';
- if (!spf_macros(sa,p + 1,domain)) return 0;
+ pos = str_chr(p, '}');
+ if (p[pos] != '}') {
+ p--;
+ break;
+ }
+ p[pos] = '\0';
+ if (!spf_macros(sa, p + 1, domain)) return 0;
p += pos;
continue;
default: p--;
}
}
- if (!stralloc_append(sa,&append)) return 0;
+ if (!stralloc_append(sa, &append)) return 0;
}
return 1;
@@ -499,7 +540,7 @@ int spf_parse(stralloc *sa,char *spfspec,char *domain)
@return int r = 1 ok; 0 failure
*/
-int spf_macros(stralloc *expand,char *macro,char *domain)
+int spf_macros(stralloc *expand, char *macro, char *domain)
{
static const char hextab[] = "0123456789abcdef";
stralloc sa = {0};
@@ -509,139 +550,167 @@ int spf_macros(stralloc *expand,char *macro,char *domain)
unsigned long u;
char ch = {0};
char ascii;
- int pos, i, n;
- int start = expand->len;
+ int pos, i, n;
+ int start = expand->len;
/* URL encoding - hidden in RFC 7208 Sec. 7.3 */
- if (*macro == 'x') { urlencode = -1; ++macro; } else urlencode = 0;
+ if (*macro == 'x') {
+ urlencode = -1;
+ ++macro;
+ } else
+ urlencode = 0;
ch = *macro;
- if (!ch) { return 1; }
- if (ch >= 'A' && ch <= 'Z') { ch += 32; urlencode = 1; }
+ if (!ch) {
+ return 1;
+ }
+ if (ch >= 'A' && ch <= 'Z') {
+ ch += 32;
+ urlencode = 1;
+ }
if (urlencode == -1) ch -= 32;
/* No. digits determine number of printed labels */
-
+
i = 0;
while (*macro) {
i++;
if (*macro == '}') break;
if (*macro >= '0' && *macro <= '9') {
- scan_ulong(macro,&u); ndigits = u;
- } else if (i > 1 && *macro == 'r') { reverse = 1; break; } /* Reverse representation */
+ scan_ulong(macro, &u);
+ ndigits = u;
+ } else if (i > 1 && *macro == 'r') {
+ reverse = 1;
+ break;
+ } /* Reverse representation */
macro++;
}
- switch (ch) { /* see RFC7208 sec. 7.2 */
- case 's': case 'S':
- if (!stralloc_readyplus(&sa,spfmf.len)) return 0;
- if (!stralloc_copys(&sa,spfmf.s)) return 0;
+ switch (ch) { /* see RFC7208 sec. 7.2 */
+ case 's':
+ case 'S':
+ if (!stralloc_readyplus(&sa, spfmf.len)) return 0;
+ if (!stralloc_copys(&sa, spfmf.s)) return 0;
break;
- case 'l': case 'L':
- i = byte_rchr(spfmf.s,spfmf.len,'@');
+ case 'l':
+ case 'L':
+ i = byte_rchr(spfmf.s, spfmf.len, '@');
if (i < spfmf.len) {
- if (!stralloc_copyb(&sa,spfmf.s,i)) return 0;
+ if (!stralloc_copyb(&sa, spfmf.s, i)) return 0;
} else {
- if (!stralloc_copys(&sa,"postmaster")) return 0;
+ if (!stralloc_copys(&sa, "postmaster")) return 0;
}
break;
- case 'o': case 'O':
- i = byte_rchr(spfmf.s,spfmf.len,'@') + 1;
+ case 'o':
+ case 'O':
+ i = byte_rchr(spfmf.s, spfmf.len, '@') + 1;
if (i > spfmf.len) break;
- if (!stralloc_copys(&sa,spfmf.s + i)) return 0;
+ if (!stralloc_copys(&sa, spfmf.s + i)) return 0;
break;
- case 'd': case 'D':
- if (!stralloc_copys(&sa,domain)) return 0; /* the hack for 'Z'; Russions everywhere ;-) */
+ case 'd':
+ case 'D':
+ if (!stralloc_copys(&sa, domain)) return 0; /* the hack for 'Z'; Russions everywhere ;-) */
break;
- case 'i': case 'c': case 'I': case 'C':
- if (!stralloc_ready(&sa,IPFMT)) return 0;
+ case 'i':
+ case 'c':
+ case 'I':
+ case 'C':
+ if (!stralloc_ready(&sa, IPFMT)) return 0;
if (flagip6) {
- sa.len = ip6_fmt(sa.s,ip6remote);
+ sa.len = ip6_fmt(sa.s, ip6remote);
} else {
- sa.len = ip4_fmt(sa.s,ip4remote);
+ sa.len = ip4_fmt(sa.s, ip4remote);
}
break;
- case 'p': case 'P':
- if (!dnsname.len) spf_ptr(domain,0);
+ case 'p':
+ case 'P':
+ if (!dnsname.len) spf_ptr(domain, 0);
if (dnsname.len) {
- if (!stralloc_copys(&sa,dnsname.s)) return 0;
+ if (!stralloc_copys(&sa, dnsname.s)) return 0;
} else {
- if (!stralloc_copys(&sa,"unknown")) return 0;
+ if (!stralloc_copys(&sa, "unknown")) return 0;
}
break;
- case 'h': case 'H':
- if (!stralloc_copys(&sa,spfhelo.s)) return 0; /* FIXME: FQDN? */
+ case 'h':
+ case 'H':
+ if (!stralloc_copys(&sa, spfhelo.s)) return 0; /* FIXME: FQDN? */
break;
- case 't': case 'T':
- if (!stralloc_ready(&sa,FMT_ULONG)) return 0;
- sa.len = fmt_ulong(sa.s,(unsigned long)now());
+ case 't':
+ case 'T':
+ if (!stralloc_ready(&sa, FMT_ULONG)) return 0;
+ sa.len = fmt_ulong(sa.s, (unsigned long)now());
break;
- case 'v': case 'V':
+ case 'v':
+ case 'V':
if (flagip6) {
- if (!stralloc_copys(&sa,"ip6")) return 0;
+ if (!stralloc_copys(&sa, "ip6")) return 0;
} else {
- if (!stralloc_copys(&sa,"in-addr")) return 0;
+ if (!stralloc_copys(&sa, "in-addr")) return 0;
}
break;
- case 'r': case 'R':
- if (!stralloc_copy(&sa,&spflocal)) return 0;
+ case 'r':
+ case 'R':
+ if (!stralloc_copy(&sa, &spflocal)) return 0;
break;
default: break;
}
- if (!stralloc_0(&sa)) return 0; // XXX
+ if (!stralloc_0(&sa)) return 0; // XXX
if (reverse) {
n = 0;
for (i = 1; i <= sa.len; i++) {
if ((ndigits == -1) || (n < ndigits)) {
- if (!byte_diff(sa.s + sa.len - i - 1,1,".") || (i == sa.len)) {
+ if (!byte_diff(sa.s + sa.len - i - 1, 1, ".") || (i == sa.len)) {
n++;
- if (!stralloc_cats(expand,sa.s + sa.len - i)) return 0;
+ if (!stralloc_cats(expand, sa.s + sa.len - i)) return 0;
if (i < sa.len) {
sa.s[sa.len - i - 1] = 0;
- if (!stralloc_cats(expand,".")) return 0;
- }
+ if (!stralloc_cats(expand, ".")) return 0;
+ }
}
- }
+ }
}
} else if (ndigits != -1) {
n = pos = 0;
for (i = 1; i <= sa.len; i++) {
if (n < ndigits) {
- if (!byte_diff(sa.s + i,1,".")) { n++; pos = i; }
+ if (!byte_diff(sa.s + i, 1, ".")) {
+ n++;
+ pos = i;
+ }
}
}
- if (!stralloc_catb(expand,sa.s,pos)) return 0;
- } else
- if (!stralloc_cats(expand,sa.s)) return 0;
+ if (!stralloc_catb(expand, sa.s, pos)) return 0;
+ } else if (!stralloc_cats(expand, sa.s))
+ return 0;
if (urlencode) {
- stralloc_copyb(&sa,expand->s + start,expand->len - start);
+ stralloc_copyb(&sa, expand->s + start, expand->len - start);
expand->len = start;
for (i = 0; i < sa.len; ++i) {
ch = sa.s[i];
if (urlchr_table[(unsigned char)ch]) {
- if (!stralloc_readyplus(expand,3)) return 0;
- if (!stralloc_append(expand,"%")) return 0;
+ if (!stralloc_readyplus(expand, 3)) return 0;
+ if (!stralloc_append(expand, "%")) return 0;
ascii = hextab[(unsigned char)ch >> 4];
- if (!stralloc_append(expand,&ascii)) return 0;
+ if (!stralloc_append(expand, &ascii)) return 0;
ascii = hextab[(unsigned char)ch & 0x0f];
- if (!stralloc_append(expand,&ascii)) return 0;
+ if (!stralloc_append(expand, &ascii)) return 0;
} else {
- if (!stralloc_append(expand,&ch)) return 0;
+ if (!stralloc_append(expand, &ch)) return 0;
}
}
- }
+ }
return 1;
}
-int spf_info(char *s,const char *t)
+int spf_info(char *s, const char *t)
{
- if (!stralloc_cats(&spfinfo,s)) return 0;
- if (!stralloc_cats(&spfinfo,t)) return 0;
- if (!stralloc_cats(&spfinfo," ")) return 0;
+ if (!stralloc_cats(&spfinfo, s)) return 0;
+ if (!stralloc_cats(&spfinfo, t)) return 0;
+ if (!stralloc_cats(&spfinfo, " ")) return 0;
return 1;
}