Skip to content

Instantly share code, notes, and snippets.

@jatrost
Last active July 12, 2020 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jatrost/c25ba8ff8bb374924f1228acc85f7ff1 to your computer and use it in GitHub Desktop.
Save jatrost/c25ba8ff8bb374924f1228acc85f7ff1 to your computer and use it in GitHub Desktop.
Hacky DMARC parse validator using opendmarc's parser. Derived from opendmarc-1.3.2/libopendmarc/tests/test_dmarc_parse.c

dmarc_parse_validator

Running this hacky program

wget https://sourceforge.net/projects/opendmarc/files/latest/download
tar zxvf opendmarc-1.3.2.tar.gz 
cd opendmarc-1.3.2/
./configure && make
cd libopendmarc/
# create compile_dmarc_parse_validator.sh and chmod 755 compile_dmarc_parse_validator.sh
# create dmarc_parse_validator.c
./compile_dmarc_parse_validator.sh

# run it
./tests/dmarc_parse_validator ~/dmarc-records.txt

Example of what is expected:

head -n 3 ~/dmarc-records.txt 
v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com
v=DMARC1; p=reject; rua=mailto:mailauth-reports@google.com
v=DMARC1; p=quarantine; rua=mailto:dmarc-tm@service.alibaba.com
#!/bin/bash
# tests/dmarc_parse_validator.c
gcc -DHAVE_CONFIG_H -I. -I.. -I. -I.. -DCONFIG_BASE=\"/usr/local/etc\" -g -O2 -MT opendmarc_policy.lo -MD -MP -c tests/dmarc_parse_validator.c -fPIC -DPIC -o tests/dmarc_parse_validator.o
gcc -DHAVE_CONFIG_H -I. -I.. -I. -I.. -DCONFIG_BASE=\"/usr/local/etc\" -g -O2 -MT -MD -MP -fPIC -DPIC *.o tests/dmarc_parse_validator.o -o tests/dmarc_parse_validator -lresolv
#include "../opendmarc_internal.h"
#ifndef OPENDMARC_POLICY_C
# define OPENDMARC_POLICY_C
#endif /* ! OPENDMARC_POLICY_C */
#include "../dmarc.h"
int
main(int argc, char **argv)
{
char * line = NULL;
size_t len = 0;
ssize_t read;
FILE *fp;
fp = fopen(argv[1], "r");
if (fp == NULL) {
exit(EXIT_FAILURE);
}
int pass, fails, count;
DMARC_POLICY_T *pctx;
OPENDMARC_STATUS_T status;
pass = fails = count = 0;
while ((read = getline(&line, &len, fp)) != -1) {
count += 1;
pctx = opendmarc_policy_connect_init("1.2.3.4", 0);
if (pctx == NULL){
(void) fprintf(stderr, "opendmarc_policy_connect_init: %s\n", strerror(errno));
return 1;
}
char *pos;
if ((pos=strchr(line, '\n')) != NULL) {
*pos = '\0';
}
printf("TRYING:'%s'\n", line);
fflush(stdout);
status = opendmarc_policy_parse_dmarc(pctx, "abuse.net", line);
printf("%d\t'%s'\n", status, line);
fflush(stdout);
if (status == 0) {
pass += 1;
}
else {
fails += 1;
}
pctx = opendmarc_policy_connect_shutdown(pctx);
}
fclose(fp);
if (line) {
free(line);
}
printf("DMARC Policy Parse: pass=%d, fail=%d\n", pass, fails);
return 0;
}
#!/usr/bin/env python3
'''
opendmarc segfaults on some input.
this allows me to get through as many examples as possible and ignores the segfaults.
obviously not ideal, but good enough for a one time run for some research.
reported the issue here https://github.com/trusteddomainproject/OpenDMARC/issues/62
'''
import sys
import os
for line in open(sys.argv[1], 'r'):
line = line.rstrip('\n\r')
with open('/tmp/test.dat', 'w') as outf:
print(line, file=outf)
os.system('./tests/dmarc_parse_validator /tmp/test.dat >> /tmp/results.txt')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment