postscreen spf generator. dependencies: python3 instead of python2. cdb -> lmdb for aliases
parent
3049e878a0
commit
b0ba5834ce
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env ruby
|
||||
require 'shellwords'
|
||||
require 'ipaddress'
|
||||
require 'resolv'
|
||||
|
||||
class R
|
||||
def initialize opts=nil
|
||||
@resolv = Resolv::DNS.new opts
|
||||
end
|
||||
IN = Resolv::DNS::Resource::IN
|
||||
|
||||
def a( q) @resolv.getresources( q, IN::A) end
|
||||
def aaaa( q) @resolv.getresources( q, IN::AAAA) end
|
||||
def txt( q) @resolv.getresources( q, IN::TXT) end
|
||||
def mx( q) @resolv.getresources( q, IN::MX) end
|
||||
|
||||
def ip q
|
||||
a(q) + aaaa(q)
|
||||
end
|
||||
end
|
||||
|
||||
$resolv = R.new
|
||||
|
||||
def bb d
|
||||
$resolv.txt( d).map do |l|
|
||||
v, *as = l.data.split( ' ')
|
||||
if "v=spf1" == v
|
||||
as.map do |a|
|
||||
case a
|
||||
when /\Aa:(.*)\z/
|
||||
$resolv.ip( $1).map( &:address)
|
||||
when "mx"
|
||||
$resolv.mx( d).map do |l|
|
||||
$resolv.ip( l.exchange.to_s).map( &:address)
|
||||
end
|
||||
when /\Aip[46]:(.*)\z/ then $1
|
||||
when /\A(?:redirect=|include:)(.*)\z/ then bb $1
|
||||
when /\A[-~+]all/ then nil
|
||||
else nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ARGV.
|
||||
flat_map do |d|
|
||||
bb( d).
|
||||
flatten.
|
||||
compact.
|
||||
uniq.
|
||||
map {|x| IPAddress.parse( x).first.to_string rescue ArgumentError }.
|
||||
select {|x| String === x }.
|
||||
uniq.
|
||||
map {|x| [x, d]}
|
||||
end.
|
||||
group_by {|(x,d)| x }.
|
||||
each {|x,xs| xs.map! &:last }.
|
||||
sort_by {|x,ds| x = IPAddress.parse x; [x.class.name, x] }.
|
||||
each do |(x,ds)|
|
||||
puts "#{x} permit # #{ds.uniq.sort.join ' '}"
|
||||
end
|
Loading…
Reference in New Issue