dnsbl-client 1.0.7 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  - - ">="