diff options
Diffstat (limited to 'src/spfquery.c')
-rw-r--r-- | src/spfquery.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/spfquery.c b/src/spfquery.c new file mode 100644 index 0000000..8c642ee --- /dev/null +++ b/src/spfquery.c @@ -0,0 +1,98 @@ +#include <string.h> +#include <unistd.h> +#include "buffer.h" +#include "stralloc.h" +#include "alloc.h" +#include "spf.h" +#include "exit.h" +#include "dns.h" +#include "str.h" +#include "byte.h" +#include "logmsg.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 <sender-ip> <sender-helo/ehlo> <envelope-from> [<local rules>] [-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); +} |