-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspf_dump.rb
86 lines (82 loc) · 1.99 KB
/
spf_dump.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#/usr/local/bin/ruby19
# https://github.com/nullstream/spf_dump
require "pp"
require 'ipaddr'
# IPAddr.new('192.168.0.1/24').to_range.each { |i| puts i};
class SPF
def initialize( debug = false )
@debug = debug
end
def log( str )
puts str if @debug
end
def dig( domain, type )
log "*** dig #{domain} #{type} +short"
`dig #{domain} #{type} +short`.gsub( /\"/, '' )
end
def handle_a( ip )
log "* handle a for #{ip}"
dig( ip, 'a' ).split.map do | token |
token
end
end
def handle_mx( ip )
log "* handle mx for #{ip}"
dig( ip, 'mx' ).split(/\n/).map do | token |
handle_a( ( token.split() )[ 1 ] )
end.flatten
end
def parse( domain )
ranges = []
record = dig( domain, 'txt' ).downcase
record.split.each do | token |
log "* found token #{token}"
token = token.split(/:|=/)
if token.length == 2
case token.first
when 'ip4'
log "* scan ip4 #{token[1]}"
ranges.push( token[1] )
when 'a'
log "* scan a #{token[1]}"
ranges.concat( handle_a( token[ 1 ] ) )
when 'mx'
log "* scan mx #{token[1]}"
ranges.concat( handle_mx( token[ 1 ] ) )
when 'include', 'redirect'
log "* scan include or redirect #{token[1]}"
ranges.concat( parse( token[ 1 ] ) )
else
log "* scan unknown #{token}"
end
else
log "* ELSE #{token.first}"
case token.first
when 'a', '?all', 'ptr'
log "* scan ?all for #{domain}"
ranges.concat( handle_a( domain ) )
when 'mx', '+mx'
log "* scan +mx for #{domain}"
ranges.concat( handle_mx( domain ) )
else
alt = token.first.split( /=/ )
case alt.first
when 'redirect'
log "* redirect for #{alt.last}"
ranges.concat( parse( alt.last ) )
else
log "** alt: " + token.first
end
end
end
end
log "----------#{domain}-------------"
# pp ranges
ranges
end
end
spf = SPF.new( false )
puts spf.parse( ARGV.first ).uniq
#spf.parse( ARGV.first ).uniq.each do | ip |
# IPAddr.new( ip ).to_range.each { |i| puts i };
#end