Skip to content

Instantly share code, notes, and snippets.

@dotysan
Created October 8, 2016 21:11
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 dotysan/0eb0284178f1582bd1e365cef4b3b4ba to your computer and use it in GitHub Desktop.
Save dotysan/0eb0284178f1582bd1e365cef4b3b4ba to your computer and use it in GitHub Desktop.
#! /usr/bin/env bash
#! /bin/bash
set -e
# associative arrays requre bash v4; here's cute way to find it
if [ ${BASH_VERSINFO[0]} -lt 4 ]
# BEWARE! exec in a subshell doesn't. So we must use `for shell in
# $(which -a bash)` instead of `which -a bash |while read shell`.
then for shell in $(which -a bash)
do if [ $("$shell" -c 'echo ${BASH_VERSINFO[0]}') -ge 4 ]
then exec "$shell" "$0" "$@"
fi done fi
declare -A p_none p_quarantine p_reject
#
# sniffing various DMARC policies in the wild
#
main() {
echo ';Collecting DMARC policies...'
while read d
do txt=$(dig +short _dmarc.$d txt |grep '^"v=') # that grep excludes CNAMES
if [ "$txt" == "" ] # retry once (in case we had a temp DNS failure)
then txt=$(dig +short _dmarc.$d txt |grep '^"v=')
fi
if [[ $txt =~ [\ \;\"]p=none ]]
then p_none[$d]="$txt"
elif [[ $txt =~ [\ \;\"]p=quarantine ]]
then p_quarantine[$d]="$txt"
elif [[ $txt =~ [\ \;\"]p=reject ]]
then p_reject[$d]="$txt"
fi
done < <(do_lynx) # process substitution preserves global variables
echo $'\n;PERMISSIVE/GATHERING:'
for d in "${!p_none[@]}"
do printf ";_dmarc.%-25s TXT %s\n" "$d" "${p_none[$d]}"
done |sort
echo $'\n;QUARANTINE:'
for d in "${!p_quarantine[@]}"
do printf ";_dmarc.%-25s TXT %s\n" "$d" "${p_quarantine[$d]}"
done |sort
echo $'\n;REJECT:'
for d in "${!p_reject[@]}"
do printf ";_dmarc.%-25s TXT %s\n" "$d" "${p_reject[$d]}"
done |sort
echo
}
do_lynx() {
lynx -dump https://dmarc.org/who-is-using-dmarc/ |awk '
/^ \* .+ \(.+\)/ {
start=match($0,/\(/)+1
stop=match($0,/\)/)
d=substr($0,start,stop-start)
split(d,a,/, /)
for(d in a) {
print a[d]
}
}
'
}
# dump the list
main
exit
# or look for something spectific
#main |grep -i returnpath.net
#exit
# or generate some stats
main |cut -c40- |tr -d '\\ "' |awk -F ';' '
{
for(i=1;i<=NF;i++)
if($i)
print$i
}
' |sort |uniq -c |sort -n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment