dnsbl-client 1.0.7 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39cc1894f213c35792030a3167985e31e77ad89e5fe112d7960c30d240f5974e
4
- data.tar.gz: e738c293677b6dc2b163a4983f4762c29c0d06cfe7cc29ce5be87a9bb5327e1f
3
+ metadata.gz: 2627a94892578f667a8a2b0e55bb74352eccc688caa036037f3252a695079434
4
+ data.tar.gz: 8908b619c28fce048d42090af6fcb775df6e7617bad764c33fbba304f3aab418
5
5
  SHA512:
6
- metadata.gz: 7e1a0af6659598d81dbdb1636449e39178f936d2800144c2c111c5975f1cdedcc7e893f909c193ac3e074ff2f41aa7a44abaaa4ffd376f8feba628f7e9030eca
7
- data.tar.gz: 3fbbf8301c066eabb6c0cd6edd5078b77823efca3051f9bc71d0286b3dee02281757f3adcb72446ac6848c37f487c3ff8d25ac0706d97bb9c529625f2d84b96c
6
+ metadata.gz: 832f66d7c6a57a509d15a4655f9fcae795dd6713a01c4a1bd4093dc121870eb637ea36eb5789c8c17bd75ccac71060d0dec048cd1dfd9e9200eac8ca3ce7f0cb
7
+ data.tar.gz: 78e2c95ee4185e45a2c61d1c5ace689cc6fcab3a3bbd0d6a522490c2369c17e6247f0cd46d64f19aca9a9b51d7091b72922d9542f5afdbc01318433d8104e36c
data/bin/dnsbl-client CHANGED
@@ -1,30 +1,32 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'dnsbl/client'
3
5
 
4
6
  c = DNSBL::Client.new
5
7
  c.first_only = true
6
8
 
7
- if ARGV.length > 0
8
- c.lookup(ARGV).each do |res|
9
- sep = ""
10
- res.members.each do |member|
11
- print sep
12
- print res[member]
13
- sep = "\t"
14
- end
15
- puts
16
- end
9
+ if ARGV.length.positive?
10
+ c.lookup(ARGV).each do |res|
11
+ sep = ''
12
+ res.members.each do |member|
13
+ print sep
14
+ print res[member]
15
+ sep = "\t"
16
+ end
17
+ puts
18
+ end
17
19
  else
18
- $stdin.each_line do |ip|
19
- ip.chomp!
20
- c.lookup(ip).each do |res|
21
- sep = ""
22
- res.members.each do |member|
23
- print sep
24
- print res[member]
25
- sep = "\t"
26
- end
27
- puts
28
- end
29
- end
30
- end
20
+ $stdin.each_line do |ip|
21
+ ip.chomp!
22
+ c.lookup(ip).each do |res|
23
+ sep = ''
24
+ res.members.each do |member|
25
+ print sep
26
+ print res[member]
27
+ sep = "\t"
28
+ end
29
+ puts
30
+ end
31
+ end
32
+ end
data/data/dnsbl.yaml CHANGED
@@ -178,7 +178,7 @@ PROJECTHONEYPOT:
178
178
  type: ip
179
179
  apikey: abcdefghijkl
180
180
  disabled: true
181
- decoder: phpot_decoder
181
+ decoder: phpot
182
182
  TOREXITNODE:
183
183
  domain: torexit.dan.me.uk
184
184
  type: ip
@@ -186,5 +186,5 @@ TOREXITNODE:
186
186
  SPFBL:
187
187
  domain: dnsbl.spfbl.net
188
188
  type: ip
189
- 127.0.0.2: Ignoring complaints of spamming by customers.
189
+ 127.0.0.2: Ignoring complaints of spamming by customers.
190
190
  127.0.0.3: Dynamic IP, generic rDNS, no rDNS or invalid FCrDNS.
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DNSBL # :nodoc:
2
4
  class Client
3
5
  # Current version of the dnsbl-client gem
4
- VERSION = "1.0.7"
6
+ VERSION = '1.1.0'
5
7
  end
6
8
  end
data/lib/dnsbl/client.rb CHANGED
@@ -1,277 +1,276 @@
1
- require "dnsbl/client/version"
1
+ # frozen_string_literal: true
2
+
3
+ require 'dnsbl/client/version'
2
4
 
3
5
  # DESCRIPTION: is a module that queries dnsbls. The configuration is in a YAML file.
4
6
  require 'resolv'
5
7
  require 'socket'
6
- require 'thread'
7
8
  require 'yaml'
8
9
  require 'ipaddr'
9
10
 
10
- # This is a monkeypatch for the built-in Ruby DNS resolver to specify nameservers
11
- class Resolv::DNS::Config
12
- # Monkeypatch the nameservers to set a default if there are no defined nameservers
13
- def nameservers
14
- return @nameservers if defined?(@nameservers)
15
-
16
- lazy_initialize
17
- if self.respond_to? :nameserver_port
18
- @nameservers = nameserver_port
19
- else
20
- @nameserver ||= ['4.2.2.2','4.2.2.5','8.8.4.4','8.8.8.8','208.67.222.222','208.67.220.220'].sort {rand}
21
- @nameservers ||= @nameserver.map {|i| [i, 53] }
22
- end
23
- @nameservers
24
- end
11
+ # This is a monkeypatch for the built-in Ruby DNS resolver to specify nameservers
12
+ class Resolv
13
+ class DNS
14
+ class Config
15
+ # Monkeypatch the nameservers to set a default if there are no defined nameservers
16
+ def nameservers
17
+ return @nameservers if defined?(@nameservers)
18
+
19
+ lazy_initialize
20
+ if respond_to? :nameserver_port
21
+ @nameservers = nameserver_port
22
+ else
23
+ @nameserver ||= ['4.2.2.2',
24
+ '4.2.2.5',
25
+ '8.8.4.4',
26
+ '8.8.8.8',
27
+ '208.67.222.222',
28
+ '208.67.220.220'].shuffle
29
+ @nameservers ||= @nameserver.map { |i| [i, 53] }
30
+ end
31
+ @nameservers
32
+ end
33
+ end
34
+ end
25
35
  end
26
36
 
27
37
  module DNSBL # :nodoc:
28
- # DNSBLResult holds the result of a DNSBL lookup
29
- # dnsbl: name of the DNSBL that returned the answer
30
- # item: the item queried, an IP or a domain
31
- # result: the result code, e.g., 127.0.0.2
32
- # meaning: the mapping of the result code to the meaning from the configuration file
33
- # timing: the time between starting to send queries to the DNSBLs and when the result from this DNSBL returned
34
- class DNSBLResult < Struct.new(:dnsbl,:item,:query,:result,:meaning,:timing); end
35
-
36
- # Client actually handles the sending of queries to a recursive DNS server and places any replies into DNSBLResults
37
- class Client
38
- # initialize a new DNSBL::Client object
39
- # the config file automatically points to a YAML file containing the list of DNSBLs and their return codes
40
- # the two-level-tlds file lists most of the two level tlds, needed for hostname to domain normalization
41
- def initialize(config = YAML.load(File.open(File.expand_path('../../../data', __FILE__)+"/dnsbl.yaml").read),
42
- two_level_tldfile = File.expand_path('../../../data', __FILE__)+"/two-level-tlds",
43
- three_level_tldfile = File.expand_path('../../../data', __FILE__)+"/three-level-tlds")
44
- @dnsbls = config
38
+ # DNSBLResult holds the result of a DNSBL lookup
39
+ # dnsbl: name of the DNSBL that returned the answer
40
+ # item: the item queried, an IP or a domain
41
+ # result: the result code, e.g., 127.0.0.2
42
+ # meaning: the mapping of the result code to the meaning from the configuration file
43
+ # timing: the time between starting to send queries to the DNSBLs and when the result from this DNSBL returned
44
+ DNSBLResult = Struct.new :dnsbl, :item, :query, :result, :meaning, :timing
45
+
46
+ # Client actually handles the sending of queries to a recursive DNS server and places any replies into DNSBLResults
47
+ class Client
48
+ attr_writer :first_only,
49
+ :timeout
50
+
51
+ # initialize a new DNSBL::Client object
52
+ # the config file automatically points to a YAML file containing the list of DNSBLs and their return codes
53
+ # the two-level-tlds file lists most of the two level tlds, needed for hostname to domain normalization
54
+ def initialize(config = YAML.safe_load(File.read("#{File.expand_path '../../data', __dir__}/dnsbl.yaml")),
55
+ two_level_tldfile = "#{File.expand_path '../../data', __dir__}/two-level-tlds",
56
+ three_level_tldfile = "#{File.expand_path '../../data', __dir__}/three-level-tlds")
57
+ @dnsbls = config
45
58
  @timeout = 1.5
46
59
  @first_only = false
47
- @two_level_tld = []
48
- @three_level_tld = []
49
- File.open(two_level_tldfile).readlines.each do |l|
50
- @two_level_tld << l.strip
51
- end
52
- File.open(three_level_tldfile).readlines.each do |l|
53
- @three_level_tld << l.strip
54
- end
55
- @sockets = []
56
- config = Resolv::DNS::Config.new
57
- config.nameservers.each do |ip,port|
58
- sock = UDPSocket.new
59
- sock.connect(ip,port)
60
- @sockets << sock
61
- break # let's just the first nameserver in this version of the library
62
- end
63
- @socket_index = 0
64
- end
65
-
66
- def timeout=(timeout_seconds)
67
- @timeout = timeout_seconds
60
+ @two_level_tld = []
61
+ @three_level_tld = []
62
+ File.open(two_level_tldfile).readlines.each do |l|
63
+ @two_level_tld << l.strip
64
+ end
65
+ File.open(three_level_tldfile).readlines.each do |l|
66
+ @three_level_tld << l.strip
67
+ end
68
+ @sockets = []
69
+ config = Resolv::DNS::Config.new
70
+
71
+ # let's just the first nameserver in this version of the library
72
+ ip, port = config.nameservers.first
73
+
74
+ sock = UDPSocket.new
75
+ sock.connect ip, port
76
+ @sockets << sock
77
+ @socket_index = 0
78
+ end
79
+
80
+ # sets the nameservers used for performing DNS lookups in round-robin fashion
81
+ def nameservers=(nss = Resolv::DNS::Config.new.nameservers)
82
+ @sockets.each(&:close)
83
+ @sockets = []
84
+
85
+ # let's just the first nameserver in this version of the library
86
+ ip, port = nss.first
87
+
88
+ sock = UDPSocket.new
89
+ sock.connect ip, port
90
+ @sockets << sock
91
+ @socket_index = 0
92
+ end
93
+
94
+ # Converts a hostname to the domain: e.g., www.google.com => google.com, science.somewhere.co.uk => somewhere.co.uk
95
+ def normalize(domain)
96
+ # strip off the protocol (\w{1,20}://), the URI (/), parameters (?), port number (:), and username (.*@)
97
+ # then split into parts via the .
98
+ parts = domain.gsub(%r{^\w{1,20}://}, '').gsub(%r{[/?:].*}, '').gsub(/.*?@/, '').split('.')
99
+ # grab the last two parts of the domain
100
+ dom = parts[-2, 2].join '.'
101
+ # if the dom is in the two_level_tld list, then use three parts
102
+ dom = parts[-3, 3].join '.' if @two_level_tld.index dom
103
+ dom = parts[-4, 4].join '.' if @three_level_tld.index dom
104
+ dom
105
+ end
106
+
107
+ # allows the adding of a new DNSBL to the set of configured DNSBLs
108
+ def add_dnsbl(name, domain, type = 'ip', codes = { '0' => 'OK', '127.0.0.2' => 'Blacklisted' })
109
+ @dnsbls[name] = codes
110
+ @dnsbls[name]['domain'] = domain
111
+ @dnsbls[name]['type'] = type
68
112
  end
69
-
70
- def first_only=(first_only_boolean)
71
- @first_only = first_only_boolean
113
+
114
+ # returns a list of DNSBL names currently configured
115
+ def dnsbls
116
+ @dnsbls.keys
72
117
  end
73
-
74
- # sets the nameservers used for performing DNS lookups in round-robin fashion
75
- def nameservers=(ns=Resolv::DNS::Config.new.nameservers)
76
- @sockets.each do |s|
77
- s.close
78
- end
79
- @sockets = []
80
- ns.each do |ip,port|
81
- sock = UDPSocket.new
82
- sock.connect(ip,port)
83
- @sockets << sock
84
- break # let's just the first nameserver in this version of the library
85
- end
86
- @socket_index = 0
87
- end
88
-
89
- # Converts a hostname to the domain: e.g., www.google.com => google.com, science.somewhere.co.uk => somewhere.co.uk
90
- def normalize(domain)
91
- # strip off the protocol (\w{1,20}://), the URI (/), parameters (?), port number (:), and username (.*@)
92
- # then split into parts via the .
93
- parts = domain.gsub(/^\w{1,20}:\/\//,'').gsub(/[\/\?\:].*/,'').gsub(/.*?\@/,'').split(/\./)
94
- # grab the last two parts of the domain
95
- dom = parts[-2,2].join(".")
96
- # if the dom is in the two_level_tld list, then use three parts
97
- if @two_level_tld.index(dom)
98
- dom = parts[-3,3].join(".")
99
- end
100
- if @three_level_tld.index(dom)
101
- dom = parts[-4,4].join(".")
102
- end
103
- dom
104
- end
105
-
106
- # allows the adding of a new DNSBL to the set of configured DNSBLs
107
- def add_dnsbl(name,domain,type='ip',codes={"0"=>"OK","127.0.0.2"=>"Blacklisted"})
108
- @dnsbls[name] = codes
109
- @dnsbls[name]['domain'] = domain
110
- @dnsbls[name]['type'] = type
111
- end
112
-
113
- # returns a list of DNSBL names currently configured
114
- def dnsbls
115
- @dnsbls.keys
116
- end
117
-
118
- # converts an ip or a hostname into the DNS query packet requires to lookup the result
119
- def _encode_query(item,itemtype,domain,apikey=nil)
120
- label = nil
121
- if itemtype == 'ip'
122
- ip = IPAddr.new(item)
123
- label = ip.reverse.gsub('.ip6.arpa', '').gsub('.in-addr.arpa', '')
124
- elsif itemtype == 'domain'
125
- label = normalize(item)
126
- end
127
- lookup = "#{label}.#{domain}"
128
- if apikey
129
- lookup = "#{apikey}.#{lookup}"
130
- end
131
- txid = lookup.sum
132
- message = Resolv::DNS::Message.new(txid)
133
- message.rd = 1
134
- message.add_question(lookup,Resolv::DNS::Resource::IN::A)
135
- message.encode
136
- end
137
-
138
-
139
- # lookup performs the sending of DNS queries for the given items
118
+
119
+ # lookup performs the sending of DNS queries for the given items
140
120
  # returns an array of DNSBLResult
141
- def lookup(item)
142
- # if item is an array, use it, otherwise make it one
143
- items = item
144
- if item.is_a? String
145
- items = [item]
146
- end
147
- # place the results in the results array
148
- results = []
149
- # for each ip or hostname
150
- items.each do |item|
151
- # sent is used to determine when we have all the answers
152
- sent = 0
153
- # record the start time
154
- @starttime = Time.now.to_f
155
- # determine the type of query
156
- itemtype = (item =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) ? 'ip' : 'domain'
157
- itemtype = (item =~ /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/) ? 'ip' : itemtype
121
+ def lookup(loopup_item)
122
+ # if item is an array, use it, otherwise make it one
123
+ items = Array loopup_item
124
+
125
+ # place the results in the results array
126
+ results = []
127
+ # for each ip or hostname
128
+ items.each do |item|
129
+ # sent is used to determine when we have all the answers
130
+ sent = 0
131
+ # record the start time
132
+ @starttime = Time.now.to_f
133
+ # determine the type of query
134
+ itemtype = item.match?(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) ? 'ip' : 'domain'
135
+ if item.match?(/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/) # rubocop: disable Layout/LineLength
136
+ itemtype = 'ip'
137
+ end
138
+
139
+ # for each dnsbl that supports our type, create the DNS query packet and send it
140
+ # rotate across our configured name servers and increment sent
141
+ @dnsbls.each do |name, config|
142
+ next if config['disabled']
143
+ next unless config['type'] == itemtype
144
+
145
+ begin
146
+ msg = encode_query item, itemtype, config['domain'], config['apikey']
147
+ @sockets[@socket_index].send msg, 0
148
+ @socket_index += 1
149
+ @socket_index %= @sockets.length
150
+ sent += 1
151
+ rescue StandardError => e
152
+ puts "error for #{name}: e"
153
+ puts e.backtrace.join("\n")
154
+ end
155
+ end
156
+
157
+ # while we still expect answers
158
+ while sent.positive?
159
+ # wait on the socket for maximally @timeout seconds
160
+ r, = IO.select @sockets, nil, nil, @timeout
161
+ # if we time out, break out of the loop
162
+ break unless r
158
163
 
159
- # for each dnsbl that supports our type, create the DNS query packet and send it
160
- # rotate across our configured name servers and increment sent
161
- @dnsbls.each do |name,config|
162
- next if config['disabled']
163
- next unless config['type'] == itemtype
164
- begin
165
- msg = _encode_query(item,itemtype,config['domain'],config['apikey'])
166
- @sockets[@socket_index].send(msg,0)
167
- @socket_index += 1
168
- @socket_index %= @sockets.length
169
- sent += 1
170
- rescue Exception => e
171
- puts e
172
- puts e.backtrace.join("\n")
173
- end
174
- end
175
- # while we still expect answers
176
- while sent > 0
177
- # wait on the socket for maximally @timeout seconds
178
- r,_,_ = IO.select(@sockets,nil,nil,@timeout)
179
- # if we time out, break out of the loop
180
- break unless r
181
- # for each reply, decode it and receive results, decrement the pending answers
164
+ # for each reply, decode it and receive results, decrement the pending answers
182
165
  first_only = false
183
- r.each do |s|
184
- begin
185
- response = _decode_response(s.recv(4096))
186
- results += response
187
- rescue Exception => e
188
- puts e
189
- puts e.backtrace.join("\n")
190
- end
191
- sent -= 1
166
+ r.each do |s|
167
+ begin
168
+ response = decode_response(s.recv(4096))
169
+ results += response
170
+ rescue StandardError => e
171
+ puts e
172
+ puts e.backtrace.join("\n")
173
+ end
174
+ sent -= 1
192
175
  if @first_only
193
176
  first_only = true
194
177
  break
195
178
  end
196
- end
197
- if first_only
198
- break
199
179
  end
200
- end
201
- end
202
- results
203
- end
204
-
180
+ break if first_only
181
+ end
182
+ end
183
+ results
184
+ end
185
+
205
186
  private
206
-
207
- # takes a DNS response and converts it into a DNSBLResult
208
- def _decode_response(buf)
209
- reply = Resolv::DNS::Message.decode(buf)
210
- results = []
211
- reply.each_answer do |name,ttl,data|
212
- if name.to_s =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(.+)$/
213
- ip = [$4,$3,$2,$1].join(".")
214
- domain = $5
215
- @dnsbls.each do |dnsblname, config|
216
- next unless data.is_a? Resolv::DNS::Resource::IN::A
217
- if domain == config['domain']
218
- meaning = config[data.address.to_s] || data.address.to_s
219
- results << DNSBLResult.new(dnsblname, ip, name.to_s, data.address.to_s, meaning, Time.now.to_f - @starttime)
220
- break
221
- end
222
- end
223
- else
224
- @dnsbls.each do |dnsblname, config|
225
- if name.to_s.end_with?(config['domain'])
226
- meaning = nil
227
- if config['decoder']
228
- meaning = self.send(("__"+config['decoder']).to_sym, data.address.to_s)
229
- elsif config[data.address.to_s]
230
- meaning = config[data.address.to_s]
231
- else
232
- meaning = data.address.to_s
233
- end
234
- results << DNSBLResult.new(dnsblname, name.to_s.gsub("."+config['domain'],''), name.to_s, data.address.to_s, meaning, Time.now.to_f - @starttime)
235
- break
236
- end
237
- end
238
- end
239
- end
240
- results
241
- end
242
-
187
+
188
+ # converts an ip or a hostname into the DNS query packet requires to lookup the result
189
+ def encode_query(item, itemtype, domain, apikey = nil)
190
+ label = case itemtype
191
+ when 'ip'
192
+ ip = IPAddr.new item
193
+ ip.reverse.gsub('.ip6.arpa', '').gsub('.in-addr.arpa', '')
194
+ when 'domain'
195
+ normalize item
196
+ end
197
+
198
+ lookup = "#{label}.#{domain}"
199
+ lookup = "#{apikey}.#{lookup}" if apikey
200
+ txid = lookup.sum
201
+ message = Resolv::DNS::Message.new txid
202
+ message.rd = 1
203
+ message.add_question lookup, Resolv::DNS::Resource::IN::A
204
+ message.encode
205
+ end
206
+
207
+ # takes a DNS response and converts it into a DNSBLResult
208
+ def decode_response(buf)
209
+ reply = Resolv::DNS::Message.decode buf
210
+ results = []
211
+ reply.each_answer do |name, _ttl, data|
212
+ if name.to_s =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(.+)$/
213
+ ip = [Regexp.last_match(4),
214
+ Regexp.last_match(3),
215
+ Regexp.last_match(2),
216
+ Regexp.last_match(1)].join '.'
217
+ domain = Regexp.last_match 5
218
+ @dnsbls.each do |dnsblname, config|
219
+ next unless data.is_a? Resolv::DNS::Resource::IN::A
220
+ next unless domain == config['domain']
221
+
222
+ meaning = config[data.address.to_s] || data.address.to_s
223
+ results << DNSBLResult.new(dnsblname, ip, name.to_s, data.address.to_s, meaning, Time.now.to_f - @starttime)
224
+ break
225
+ end
226
+ else
227
+ @dnsbls.each do |dnsblname, config|
228
+ next unless name.to_s.end_with? config['domain']
229
+
230
+ meaning = if config['decoder']
231
+ send "#{config['decoder']}_decoder".to_sym, data.address.to_s
232
+ elsif config[data.address.to_s]
233
+ config[data.address.to_s]
234
+ else
235
+ data.address.to_s
236
+ end
237
+
238
+ results << DNSBLResult.new(dnsblname, name.to_s.gsub(".#{config['domain']}", ''),
239
+ name.to_s,
240
+ data.address.to_s,
241
+ meaning,
242
+ Time.now.to_f - @starttime)
243
+ break
244
+ end
245
+ end
246
+ end
247
+ results
248
+ end
249
+
243
250
  # decodes the response from Project Honey Pot's service
244
- def __phpot_decoder(ip)
245
- octets = ip.split(/\./)
246
- if octets.length != 4 or octets[0] != "127"
247
- return "invalid response"
248
- elsif octets[3] == "0"
249
- search_engines = ["undocumented", "AltaVista", "Ask", "Baidu", "Excite", "Google", "Looksmart", "Lycos", "MSN", "Yahoo", "Cuil", "InfoSeek", "Miscellaneous"]
250
- sindex = octets[2].to_i
251
- if sindex >= search_engines.length
252
- return "type=search engine,engine=unknown"
253
- else
254
- return "type=search engine,engine=#{search_engines[sindex]}"
255
- end
256
- else
257
- days, threatscore, flags = octets[1,3]
258
- flags = flags.to_i
259
- types = []
260
- if (flags & 0x1) == 0x1
261
- types << "suspicious"
262
- end
263
- if (flags & 0x2) == 0x2
264
- types << "harvester"
265
- end
266
- if (flags & 0x4) == 0x4
267
- types << "comment spammer"
268
- end
269
- if (flags & 0xf8) > 0
270
- types << "reserved"
271
- end
272
- type = types.join(",")
273
- return "days=#{days},score=#{threatscore},type=#{type}"
274
- end
275
- end
276
- end
251
+ def phpot_decoder(ip)
252
+ octets = ip.split '.'
253
+ if octets.length != 4 || octets[0] != '127'
254
+ 'invalid response'
255
+ elsif octets[3] == '0'
256
+ search_engines = %w[undocumented AltaVista Ask Baidu Excite Google Looksmart Lycos MSN Yahoo Cuil InfoSeek Miscellaneous]
257
+ sindex = octets[2].to_i
258
+ if sindex >= search_engines.length
259
+ 'type=search engine,engine=unknown'
260
+ else
261
+ "type=search engine,engine=#{search_engines[sindex]}"
262
+ end
263
+ else
264
+ days, threatscore, flags = octets[1, 3]
265
+ flags = flags.to_i
266
+ types = []
267
+ types << 'suspicious' if (flags & 0x1) == 0x1
268
+ types << 'harvester' if (flags & 0x2) == 0x2
269
+ types << 'comment spammer' if (flags & 0x4) == 0x4
270
+ types << 'reserved' if (flags & 0xf8).positive?
271
+ type = types.join ','
272
+ "days=#{days},score=#{threatscore},type=#{type}"
273
+ end
274
+ end
275
+ end
277
276
  end
data/test/helper.rb CHANGED
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
- require 'dnsbl/client'
3
4
 
5
+ require 'dnsbl/client'
4
6
  require 'minitest/autorun'
@@ -1,203 +1,209 @@
1
- unless Kernel.respond_to?(:require_relative)
1
+ # frozen_string_literal: true
2
+
3
+ unless Kernel.respond_to? :require_relative
2
4
  module Kernel
3
5
  def require_relative(path)
4
- require File.join(File.dirname(caller[0]), path.to_str)
6
+ require File.join(File.dirname(caller(1..1).first), path.to_str)
5
7
  end
6
8
  end
7
9
  end
8
10
 
9
11
  require_relative 'helper'
10
12
 
11
- $nameservers = [['4.2.2.2',53]]
12
-
13
13
  class TestDNSBLClient < Minitest::Test
14
+ NAME_SERVERS = [['4.2.2.2', 53]].freeze
15
+
14
16
  def test_return_no_hits_for_0_0_0_254
15
17
  c = DNSBL::Client.new
16
- c.nameservers = $nameservers
18
+ c.nameservers = NAME_SERVERS
17
19
  # for some reason DRONEBL returns 127.0.0.255 when queried for 127.0.0.255, so I'll use 127.0.0.254
18
20
  # spfbl started returning 127.0.0.254 for 127.0.0.254, so I'll try 0.0.0.254
19
- res = c.lookup("0.0.0.254")
20
- if res.length > 0
21
- puts(res)
22
- end
23
- assert_equal(0,res.length)
21
+ res = c.lookup '0.0.0.254'
22
+ puts res if res.length.positive?
23
+ assert res.length.zero?
24
24
  end
25
+
25
26
  def test_return_all_lists_for_127_0_0_2
26
- # this test doesn't work anymore
27
- #c = DNSBL::Client.new
28
- #c.nameservers = $nameservers
29
- #res = c.lookup("127.0.0.2")
30
- #puts res
31
- #puts c.dnsbls
32
- #assert(res.length >= c.dnsbls.length)
27
+ skip 'not work anymore'
28
+
29
+ c = DNSBL::Client.new
30
+ c.nameservers = NAME_SERVERS
31
+ res = c.lookup '127.0.0.2'
32
+ c.dnsbls.each do |bls|
33
+ assert (res.detect { |ci| ci.dnsbl == bls }), "#{bls} missing"
34
+ end
35
+ assert res.count >= c.dnsbls.count
33
36
  end
37
+
34
38
  def test_return_results_for_bad_domains
35
39
  c = DNSBL::Client.new
36
- c.nameservers = $nameservers
37
- res = c.lookup("pfizer.viagra.aqybasej.gurdoctor.com")
38
- assert(res.length >= 0)
40
+ c.nameservers = NAME_SERVERS
41
+ res = c.lookup 'pfizer.viagra.aqybasej.gurdoctor.com'
42
+ assert res.length >= 0
39
43
  end
44
+
40
45
  def test_interpret_project_honeypot_results
41
- refute_nil(ENV['PHPAPIKEY'], "Project Honeypot API Key Required. Please set PHPAPIKEY.")
42
- apikey = ENV['PHPAPIKEY']
43
- config = YAML.load("---
46
+ apikey = ENV.fetch 'PHPAPIKEY', nil
47
+ skip 'Project Honeypot API Key Required for this test. Please set PHPAPIKEY.' unless apikey
48
+
49
+ config = YAML.safe_load("---
44
50
  PROJECTHONEYPOT:
45
51
  domain: dnsbl.httpbl.org
46
52
  type: ip
47
53
  apikey: #{apikey}
48
- decoder: phpot_decoder")
49
- c = DNSBL::Client.new(config)
50
- c.nameservers = $nameservers
51
- res = c.lookup("127.0.0.1")
52
- assert_equal(0,res.length)
53
- res = c.lookup("127.1.1.0")
54
- assert_equal(1,res.length)
55
- assert_equal("#{apikey}.0.1.1.127.dnsbl.httpbl.org",res[0].query)
56
- assert_equal("127.1.1.0",res[0].result)
57
- assert_equal("type=search engine,engine=AltaVista",res[0].meaning)
58
- res = c.lookup("127.1.1.1")
59
- assert_equal(1,res.length)
60
- assert_equal("#{apikey}.1.1.1.127",res[0].item)
61
- assert_equal("#{apikey}.1.1.1.127.dnsbl.httpbl.org",res[0].query)
62
- assert_equal("127.1.1.1",res[0].result)
63
- assert_equal("days=1,score=1,type=suspicious",res[0].meaning)
64
- res = c.lookup("127.1.1.2")
65
- assert_equal(1,res.length)
66
- assert_equal("#{apikey}.2.1.1.127",res[0].item)
67
- assert_equal("#{apikey}.2.1.1.127.dnsbl.httpbl.org",res[0].query)
68
- assert_equal("127.1.1.2",res[0].result)
69
- assert_equal("days=1,score=1,type=harvester",res[0].meaning)
70
- res = c.lookup("127.1.1.3")
71
- assert_equal(1,res.length)
72
- assert_equal("#{apikey}.3.1.1.127",res[0].item)
73
- assert_equal("#{apikey}.3.1.1.127.dnsbl.httpbl.org",res[0].query)
74
- assert_equal("127.1.1.3",res[0].result)
75
- assert_equal("days=1,score=1,type=suspicious,harvester",res[0].meaning)
76
- res = c.lookup("127.1.1.4")
77
- assert_equal(1,res.length)
78
- assert_equal("#{apikey}.4.1.1.127",res[0].item)
79
- assert_equal("#{apikey}.4.1.1.127.dnsbl.httpbl.org",res[0].query)
80
- assert_equal("127.1.1.4",res[0].result)
81
- assert_equal("days=1,score=1,type=comment spammer",res[0].meaning)
82
- res = c.lookup("127.1.1.5")
83
- assert_equal(1,res.length)
84
- assert_equal("#{apikey}.5.1.1.127",res[0].item)
85
- assert_equal("#{apikey}.5.1.1.127.dnsbl.httpbl.org",res[0].query)
86
- assert_equal("127.1.1.5",res[0].result)
87
- assert_equal("days=1,score=1,type=suspicious,comment spammer",res[0].meaning)
88
- res = c.lookup("127.1.1.6")
89
- assert_equal(1,res.length)
90
- assert_equal("#{apikey}.6.1.1.127",res[0].item)
91
- assert_equal("#{apikey}.6.1.1.127.dnsbl.httpbl.org",res[0].query)
92
- assert_equal("127.1.1.6",res[0].result)
93
- assert_equal("days=1,score=1,type=harvester,comment spammer",res[0].meaning)
94
- res = c.lookup("127.1.1.7")
95
- assert_equal(1,res.length)
96
- assert_equal("#{apikey}.7.1.1.127",res[0].item)
97
- assert_equal("#{apikey}.7.1.1.127.dnsbl.httpbl.org",res[0].query)
98
- assert_equal("127.1.1.7",res[0].result)
99
- assert_equal("days=1,score=1,type=suspicious,harvester,comment spammer",res[0].meaning)
100
- res = c.lookup("127.1.10.1")
101
- assert_equal(1,res.length)
102
- assert_equal("#{apikey}.1.10.1.127",res[0].item)
103
- assert_equal("#{apikey}.1.10.1.127.dnsbl.httpbl.org",res[0].query)
104
- assert_equal("127.1.10.1",res[0].result)
105
- assert_equal("days=1,score=10,type=suspicious",res[0].meaning)
106
- res = c.lookup("127.1.20.1")
107
- assert_equal(1,res.length)
108
- assert_equal("#{apikey}.1.20.1.127",res[0].item)
109
- assert_equal("#{apikey}.1.20.1.127.dnsbl.httpbl.org",res[0].query)
110
- assert_equal("127.1.20.1",res[0].result)
111
- assert_equal("days=1,score=20,type=suspicious",res[0].meaning)
112
- res = c.lookup("127.1.40.1")
113
- assert_equal(1,res.length)
114
- assert_equal("#{apikey}.1.40.1.127",res[0].item)
115
- assert_equal("#{apikey}.1.40.1.127.dnsbl.httpbl.org",res[0].query)
116
- assert_equal("127.1.40.1",res[0].result)
117
- assert_equal("days=1,score=40,type=suspicious",res[0].meaning)
118
- res = c.lookup("127.1.80.1")
119
- assert_equal(1,res.length)
120
- assert_equal("#{apikey}.1.80.1.127",res[0].item)
121
- assert_equal("#{apikey}.1.80.1.127.dnsbl.httpbl.org",res[0].query)
122
- assert_equal("127.1.80.1",res[0].result)
123
- assert_equal("days=1,score=80,type=suspicious",res[0].meaning)
124
- res = c.lookup("127.10.1.1")
125
- assert_equal(1,res.length)
126
- assert_equal("#{apikey}.1.1.10.127",res[0].item)
127
- assert_equal("#{apikey}.1.1.10.127.dnsbl.httpbl.org",res[0].query)
128
- assert_equal("127.10.1.1",res[0].result)
129
- assert_equal("days=10,score=1,type=suspicious",res[0].meaning)
130
- res = c.lookup("127.20.1.1")
131
- assert_equal(1,res.length)
132
- assert_equal("#{apikey}.1.1.20.127",res[0].item)
133
- assert_equal("#{apikey}.1.1.20.127.dnsbl.httpbl.org",res[0].query)
134
- assert_equal("127.20.1.1",res[0].result)
135
- assert_equal("days=20,score=1,type=suspicious",res[0].meaning)
136
- res = c.lookup("127.40.1.1")
137
- assert_equal(1,res.length)
138
- assert_equal("#{apikey}.1.1.40.127",res[0].item)
139
- assert_equal("#{apikey}.1.1.40.127.dnsbl.httpbl.org",res[0].query)
140
- assert_equal("127.40.1.1",res[0].result)
141
- assert_equal("days=40,score=1,type=suspicious",res[0].meaning)
142
- res = c.lookup("127.80.1.1")
143
- assert_equal(1,res.length)
144
- assert_equal("#{apikey}.1.1.80.127",res[0].item)
145
- assert_equal("#{apikey}.1.1.80.127.dnsbl.httpbl.org",res[0].query)
146
- assert_equal("127.80.1.1", res[0].result)
147
- assert_equal("days=80,score=1,type=suspicious",res[0].meaning)
148
- res = c.__phpot_decoder("127.0.0.0")
149
- assert_equal("type=search engine,engine=undocumented",res)
150
- res = c.__phpot_decoder("127.0.1.0")
151
- assert_equal("type=search engine,engine=AltaVista",res)
152
- res = c.__phpot_decoder("127.0.2.0")
153
- assert_equal("type=search engine,engine=Ask",res)
154
- res = c.__phpot_decoder("127.0.3.0")
155
- assert_equal("type=search engine,engine=Baidu",res)
156
- res = c.__phpot_decoder("127.0.4.0")
157
- assert_equal("type=search engine,engine=Excite",res)
158
- res = c.__phpot_decoder("127.0.5.0")
159
- assert_equal("type=search engine,engine=Google",res)
160
- res = c.__phpot_decoder("127.0.6.0")
161
- assert_equal("type=search engine,engine=Looksmart",res)
162
- res = c.__phpot_decoder("127.0.7.0")
163
- assert_equal("type=search engine,engine=Lycos",res)
164
- res = c.__phpot_decoder("127.0.8.0")
165
- assert_equal("type=search engine,engine=MSN",res)
166
- res = c.__phpot_decoder("127.0.9.0")
167
- assert_equal("type=search engine,engine=Yahoo",res)
168
- res = c.__phpot_decoder("127.0.10.0")
169
- assert_equal("type=search engine,engine=Cuil",res)
170
- res = c.__phpot_decoder("127.0.11.0")
171
- assert_equal("type=search engine,engine=InfoSeek",res)
172
- res = c.__phpot_decoder("127.0.12.0")
173
- assert_equal("type=search engine,engine=Miscellaneous",res)
54
+ decoder: phpot")
55
+ c = DNSBL::Client.new config
56
+ c.nameservers = NAME_SERVERS
57
+ res = c.lookup '127.0.0.1'
58
+ assert_equal 0, res.length
59
+ res = c.lookup '127.1.1.0'
60
+ assert_equal 1, res.length
61
+ assert_equal "#{apikey}.0.1.1.127.dnsbl.httpbl.org", res[0].query
62
+ assert_equal '127.1.1.0', res[0].result
63
+ assert_equal 'type=search engine,engine=AltaVista', res[0].meaning
64
+ res = c.lookup '127.1.1.1'
65
+ assert_equal 1, res.length
66
+ assert_equal "#{apikey}.1.1.1.127", res[0].item
67
+ assert_equal "#{apikey}.1.1.1.127.dnsbl.httpbl.org", res[0].query
68
+ assert_equal '127.1.1.1', res[0].result
69
+ assert_equal 'days=1,score=1,type=suspicious', res[0].meaning
70
+ res = c.lookup '127.1.1.2'
71
+ assert_equal 1, res.length
72
+ assert_equal "#{apikey}.2.1.1.127", res[0].item
73
+ assert_equal "#{apikey}.2.1.1.127.dnsbl.httpbl.org", res[0].query
74
+ assert_equal '127.1.1.2', res[0].result
75
+ assert_equal 'days=1,score=1,type=harvester', res[0].meaning
76
+ res = c.lookup '127.1.1.3'
77
+ assert_equal 1, res.length
78
+ assert_equal "#{apikey}.3.1.1.127", res[0].item
79
+ assert_equal "#{apikey}.3.1.1.127.dnsbl.httpbl.org", res[0].query
80
+ assert_equal '127.1.1.3', res[0].result
81
+ assert_equal 'days=1,score=1,type=suspicious,harvester', res[0].meaning
82
+ res = c.lookup '127.1.1.4'
83
+ assert_equal 1, res.length
84
+ assert_equal "#{apikey}.4.1.1.127", res[0].item
85
+ assert_equal "#{apikey}.4.1.1.127.dnsbl.httpbl.org", res[0].query
86
+ assert_equal '127.1.1.4', res[0].result
87
+ assert_equal 'days=1,score=1,type=comment spammer', res[0].meaning
88
+ res = c.lookup '127.1.1.5'
89
+ assert_equal 1, res.length
90
+ assert_equal "#{apikey}.5.1.1.127", res[0].item
91
+ assert_equal "#{apikey}.5.1.1.127.dnsbl.httpbl.org", res[0].query
92
+ assert_equal '127.1.1.5', res[0].result
93
+ assert_equal 'days=1,score=1,type=suspicious,comment spammer', res[0].meaning
94
+ res = c.lookup '127.1.1.6'
95
+ assert_equal 1, res.length
96
+ assert_equal "#{apikey}.6.1.1.127", res[0].item
97
+ assert_equal "#{apikey}.6.1.1.127.dnsbl.httpbl.org", res[0].query
98
+ assert_equal '127.1.1.6', res[0].result
99
+ assert_equal 'days=1,score=1,type=harvester,comment spammer', res[0].meaning
100
+ res = c.lookup '127.1.1.7'
101
+ assert_equal 1, res.length
102
+ assert_equal "#{apikey}.7.1.1.127", res[0].item
103
+ assert_equal "#{apikey}.7.1.1.127.dnsbl.httpbl.org", res[0].query
104
+ assert_equal '127.1.1.7', res[0].result
105
+ assert_equal 'days=1,score=1,type=suspicious,harvester,comment spammer', res[0].meaning
106
+ res = c.lookup '127.1.10.1'
107
+ assert_equal 1, res.length
108
+ assert_equal "#{apikey}.1.10.1.127", res[0].item
109
+ assert_equal "#{apikey}.1.10.1.127.dnsbl.httpbl.org", res[0].query
110
+ assert_equal '127.1.10.1', res[0].result
111
+ assert_equal 'days=1,score=10,type=suspicious', res[0].meaning
112
+ res = c.lookup '127.1.20.1'
113
+ assert_equal 1, res.length
114
+ assert_equal "#{apikey}.1.20.1.127", res[0].item
115
+ assert_equal "#{apikey}.1.20.1.127.dnsbl.httpbl.org", res[0].query
116
+ assert_equal '127.1.20.1', res[0].result
117
+ assert_equal 'days=1,score=20,type=suspicious', res[0].meaning
118
+ res = c.lookup '127.1.40.1'
119
+ assert_equal 1, res.length
120
+ assert_equal "#{apikey}.1.40.1.127", res[0].item
121
+ assert_equal "#{apikey}.1.40.1.127.dnsbl.httpbl.org", res[0].query
122
+ assert_equal '127.1.40.1', res[0].result
123
+ assert_equal 'days=1,score=40,type=suspicious', res[0].meaning
124
+ res = c.lookup '127.1.80.1'
125
+ assert_equal 1, res.length
126
+ assert_equal "#{apikey}.1.80.1.127", res[0].item
127
+ assert_equal "#{apikey}.1.80.1.127.dnsbl.httpbl.org", res[0].query
128
+ assert_equal '127.1.80.1', res[0].result
129
+ assert_equal 'days=1,score=80,type=suspicious', res[0].meaning
130
+ res = c.lookup '127.10.1.1'
131
+ assert_equal 1, res.length
132
+ assert_equal "#{apikey}.1.1.10.127", res[0].item
133
+ assert_equal "#{apikey}.1.1.10.127.dnsbl.httpbl.org", res[0].query
134
+ assert_equal '127.10.1.1', res[0].result
135
+ assert_equal 'days=10,score=1,type=suspicious', res[0].meaning
136
+ res = c.lookup '127.20.1.1'
137
+ assert_equal 1, res.length
138
+ assert_equal "#{apikey}.1.1.20.127", res[0].item
139
+ assert_equal "#{apikey}.1.1.20.127.dnsbl.httpbl.org", res[0].query
140
+ assert_equal '127.20.1.1', res[0].result
141
+ assert_equal 'days=20,score=1,type=suspicious', res[0].meaning
142
+ res = c.lookup '127.40.1.1'
143
+ assert_equal 1, res.length
144
+ assert_equal "#{apikey}.1.1.40.127", res[0].item
145
+ assert_equal "#{apikey}.1.1.40.127.dnsbl.httpbl.org", res[0].query
146
+ assert_equal '127.40.1.1', res[0].result
147
+ assert_equal 'days=40,score=1,type=suspicious', res[0].meaning
148
+ res = c.lookup '127.80.1.1'
149
+ assert_equal 1, res.length
150
+ assert_equal "#{apikey}.1.1.80.127", res[0].item
151
+ assert_equal "#{apikey}.1.1.80.127.dnsbl.httpbl.org", res[0].query
152
+ assert_equal '127.80.1.1', res[0].result
153
+ assert_equal 'days=80,score=1,type=suspicious', res[0].meaning
154
+ res = c.send :phpot_decoder, '127.0.0.0'
155
+ assert_equal 'type=search engine,engine=undocumented', res
156
+ res = c.send :phpot_decoder, '127.0.1.0'
157
+ assert_equal 'type=search engine,engine=AltaVista', res
158
+ res = c.send :phpot_decoder, '127.0.2.0'
159
+ assert_equal 'type=search engine,engine=Ask', res
160
+ res = c.send :phpot_decoder, '127.0.3.0'
161
+ assert_equal 'type=search engine,engine=Baidu', res
162
+ res = c.send :phpot_decoder, '127.0.4.0'
163
+ assert_equal 'type=search engine,engine=Excite', res
164
+ res = c.send :phpot_decoder, '127.0.5.0'
165
+ assert_equal 'type=search engine,engine=Google', res
166
+ res = c.send :phpot_decoder, '127.0.6.0'
167
+ assert_equal 'type=search engine,engine=Looksmart', res
168
+ res = c.send :phpot_decoder, '127.0.7.0'
169
+ assert_equal 'type=search engine,engine=Lycos', res
170
+ res = c.send :phpot_decoder, '127.0.8.0'
171
+ assert_equal 'type=search engine,engine=MSN', res
172
+ res = c.send :phpot_decoder, '127.0.9.0'
173
+ assert_equal 'type=search engine,engine=Yahoo', res
174
+ res = c.send :phpot_decoder, '127.0.10.0'
175
+ assert_equal 'type=search engine,engine=Cuil', res
176
+ res = c.send :phpot_decoder, '127.0.11.0'
177
+ assert_equal 'type=search engine,engine=InfoSeek', res
178
+ res = c.send :phpot_decoder, '127.0.12.0'
179
+ assert_equal 'type=search engine,engine=Miscellaneous', res
174
180
  end
175
181
 
176
182
  def test_normalize_domains_to_two_levels_if_it_s_neither_in_two_level_nor_three_level_list
177
183
  c = DNSBL::Client.new
178
- c.nameservers = $nameservers
184
+ c.nameservers = NAME_SERVERS
179
185
 
180
- assert_equal("example.org", c.normalize("example.org"))
181
- assert_equal("example.org", c.normalize("www.example.org"))
182
- assert_equal("example.org", c.normalize("foo.bar.baz.example.org"))
186
+ assert_equal 'example.org', c.normalize('example.org')
187
+ assert_equal 'example.org', c.normalize('www.example.org')
188
+ assert_equal 'example.org', c.normalize('foo.bar.baz.example.org')
183
189
  end
184
190
 
185
191
  def test_normaize_domains_to_three_levels_if_it_s_in_two_level_list
186
192
  c = DNSBL::Client.new
187
- c.nameservers = $nameservers
193
+ c.nameservers = NAME_SERVERS
188
194
 
189
- assert_equal("example.co.uk", c.normalize("example.co.uk"))
190
- assert_equal("example.co.uk", c.normalize("www.example.co.uk"))
191
- assert_equal("example.co.uk", c.normalize("foo.bar.baz.example.co.uk"))
192
- assert_equal("example.blogspot.com", c.normalize("example.blogspot.com"))
195
+ assert_equal 'example.co.uk', c.normalize('example.co.uk')
196
+ assert_equal 'example.co.uk', c.normalize('www.example.co.uk')
197
+ assert_equal 'example.co.uk', c.normalize('foo.bar.baz.example.co.uk')
198
+ assert_equal 'example.blogspot.com', c.normalize('example.blogspot.com')
193
199
  end
194
200
 
195
201
  def test_normalize_domains_to_four_levels_if_it_s_in_three_level_list
196
202
  c = DNSBL::Client.new
197
- c.nameservers = $nameservers
203
+ c.nameservers = NAME_SERVERS
198
204
 
199
- assert_equal("example.act.edu.au", c.normalize("example.act.edu.au"))
200
- assert_equal("example.act.edu.au", c.normalize("www.example.act.edu.au"))
201
- assert_equal("example.act.edu.au", c.normalize("foo.bar.example.act.edu.au"))
205
+ assert_equal 'example.act.edu.au', c.normalize('example.act.edu.au')
206
+ assert_equal 'example.act.edu.au', c.normalize('www.example.act.edu.au')
207
+ assert_equal 'example.act.edu.au', c.normalize('foo.bar.example.act.edu.au')
202
208
  end
203
209
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dnsbl-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - chrislee35
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-19 00:00:00.000000000 Z
11
+ date: 2022-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,48 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-performance
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
41
83
  description: simple interface to lookup blacklists results
42
84
  email:
43
85
  - rubygems@chrislee.dhs.org
@@ -66,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
108
  requirements:
67
109
  - - ">="
68
110
  - !ruby/object:Gem::Version
69
- version: '0'
111
+ version: '2.7'
70
112
  required_rubygems_version: !ruby/object:Gem::Requirement
71
113
  requirements:
72
114
  - - ">="