#include #include #include "alloc.h" #include "buffer.h" #include "byte.h" #include "exit.h" #include "logmsg.h" #include "str.h" #include "stralloc.h" #include "dns.h" #include "spf.h" #define WHO "spfquery" void die(int e, char *s) { buffer_putsflush(buffer_2, s); _exit(e); } void die_nomem() { die(111, "fatal: out of memory\n"); } static stralloc heloin = {0}; static stralloc mfin = {0}; static stralloc spflocal = {0}; static stralloc spfbounce = {0}; int main(int argc, char **argv) { stralloc spfip = {0}; int flag = 0; int r; int verbose = 0; flagip6 = 1; if (argc < 4) logmsg( WHO, 100, USAGE, "spfquery [] [-v(erbose) ]\n"); if (!stralloc_copys(&spfip, argv[1])) die_nomem(); if (!stralloc_0(&spfip)) die_nomem(); r = byte_chr(spfip.s, spfip.len, ':'); if (r < spfip.len) flag = 1; if (!stralloc_copys(&heloin, argv[2])) die_nomem(); if (!stralloc_0(&heloin)) die_nomem(); if (!stralloc_copys(&mfin, argv[3])) die_nomem(); if (!stralloc_0(&mfin)) die_nomem(); if (argc > 4) { if (!byte_diff(argv[4], 2, "-v")) verbose = 1; else { if (!stralloc_copys(&spflocal, argv[4])) die_nomem(); if (spflocal.len && !stralloc_0(&spflocal)) die_nomem(); } } if (argc > 5) { if (!byte_diff(argv[5], 2, "-v")) verbose = 1; } if (!stralloc_copys(&spfexplain, SPF_DEFEXP)) die_nomem(); if (!stralloc_0(&spfexplain)) die_nomem(); DNS_INIT r = spf_query(spfip.s, heloin.s, mfin.s, "localhost", flag); if (r == SPF_NOMEM) die_nomem(); buffer_puts(buffer_1, "result="); switch (r) { case SPF_ME: buffer_puts(buffer_1, "loopback"); break; case SPF_OK: buffer_puts(buffer_1, "pass"); break; case SPF_NONE: buffer_puts(buffer_1, "none"); break; case SPF_UNKNOWN: buffer_puts(buffer_1, "unknown"); break; case SPF_NEUTRAL: buffer_puts(buffer_1, "neutral"); break; case SPF_SOFTFAIL: buffer_puts(buffer_1, "softfail"); break; case SPF_FAIL: buffer_puts(buffer_1, "fail"); break; case SPF_ERROR: buffer_puts(buffer_1, "error"); break; case SPF_SYNTAX: buffer_puts(buffer_1, "IP address syntax error"); break; default: buffer_puts(buffer_1, "undefined"); break; } buffer_putsflush(buffer_1, "\n"); if (r == SPF_SYNTAX) _exit(1); if (verbose) { buffer_puts(buffer_1, "SPF records read: \n"); buffer_put(buffer_1, spfrecord.s, spfrecord.len); } buffer_puts(buffer_1, "SPF information evaluated: "); buffer_put(buffer_1, spfinfo.s, spfinfo.len); buffer_putsflush(buffer_1, "\n"); if (r == SPF_FAIL) { buffer_puts(buffer_1, "SPF results returned: "); if (!spf_parse(&spfbounce, spfexpmsg.s, expdomain.s)) die_nomem(); buffer_put(buffer_1, spfbounce.s, spfbounce.len); buffer_putsflush(buffer_1, "\n"); } _exit(0); }