dns-sniper 0.0.1.pre4 → 0.0.1.pre5

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: 0d15d70b6571fb7db1cd3b4e53c4eac7a6041c0d08072c47309d8202dc5569d3
4
- data.tar.gz: 5dadb99daabfd7896735c94ac8981a70df077f73daa3f52f4bbc50570c6efd32
3
+ metadata.gz: 61bc06052722d5ac53448692a1c4cfb8e52a86ebe41fe2ef3973b5f36a0ff1da
4
+ data.tar.gz: '058667f512cdaa447c377325a0cc17df712f05c0d1aac2d82c09337f1faa2b3b'
5
5
  SHA512:
6
- metadata.gz: 4eac165aa45a6056690e69f2a5ebe939996a8b7364d0ebecd953827c8d3c20f112e9e8fd4cf42421d16771d0084fdb23c12e52dddba50911dbd9d8e61f8797e7
7
- data.tar.gz: 6e6a4e723a92e90ce128e893172395fc3f66333aac3e9d0eda03c7f2f98fbb8f5d559cde4c25540b78b476c032e9e78af698cfc52e156b5dbabbbf5ba5697a3e
6
+ metadata.gz: a2ab89c5edd6fa0ee2be7fee4078859ee15b4af1f8598ea12cc4925103d6155d0ddc1d2da313ada9b055635ec76dcf5c6cab1a2be3d3a1a45e6bd12f2fcb53f2
7
+ data.tar.gz: 05d1dc924c958d1172da20cce2795498c60c33278db0738fbf0b1bed4539b28ab291a8f6fd7aa3b64db010b3ffa1a7f58ee872cb936705114e4c7819b43ae225
@@ -5,19 +5,16 @@ require 'optparse'
5
5
  require 'set'
6
6
  require 'dns-sniper'
7
7
 
8
- VALID_FORMATS = DNSSniper::Formatters.all.inject([]) { |arr, f| arr << f.name.to_s.sub('DNSSniper::', '').downcase }
9
- Options = Struct.new(:blacklist_urls_file, :whitelisted_hosts_file, :format)
8
+ VALID_FORMATS = DNSSniper::Exporters.all.inject([]) { |arr, f| arr << f.name.to_s.sub('DNSSniper::', '').sub('Exporter', '').downcase }
9
+ Options = Struct.new(:conf_path, :format)
10
10
 
11
11
  class Parser
12
12
  def self.parse(options)
13
13
  args = Options.new('world')
14
14
  opt_parser = OptionParser.new do |opts|
15
15
  opts.banner = "Usage: #{File.basename(__FILE__)} -f PATH -o FORMAT [options]\n#{File.basename(__FILE__)} combines online DNS blacklists and combines them into the desired configuration FORMAT.\n\n"
16
- opts.on('-f', '--blacklist=PATH', 'PATH to file with line-separated list of URL’s of blacklists') do |path|
17
- args.blacklist_urls_file = path
18
- end
19
- opts.on('-w', '--whitelist=path', 'Path to file with line-separated list of whitelisted hostnames') do |path|
20
- args.whitelisted_hosts_file = path
16
+ opts.on('-c', '--conf=PATH', 'PATH to YAML configuration file') do |path|
17
+ args.conf_path = path
21
18
  end
22
19
  opts.on('-o', '--output=FORMAT', "FORMAT to output — one of #{VALID_FORMATS.join(', ')}") do |format|
23
20
  args.format = format
@@ -34,20 +31,20 @@ end
34
31
 
35
32
  options = Parser.parse ARGV
36
33
 
37
- unless VALID_FORMATS.include?(options[:format])
38
- warn options[:format].blank? ? 'Error: Format not defined' : "Error: Invalid format \"#{options[:format]}\""
34
+ unless File.exist?(options[:conf_path])
35
+ warn "Error: Unable to access ”#{options[:conf_path]}"
39
36
  exit(-1)
40
37
  end
41
38
 
42
- unless File.exist?(options[:blacklist_urls_file])
43
- warn "Error: Unable to access ”#{options[:blacklist_urls_file]}”"
44
- exit(-1)
45
- end
46
-
47
- if options[:whitelisted_hosts_file] && !File.exist?(options[:whitelisted_hosts_file])
48
- warn "Error: Unable to access ”#{options[:whitelisted_hosts_file]}”"
39
+ exporter = DNSSniper.const_get("#{options[:format].to_s.split('_').map(&:capitalize).join}Exporter")
40
+ if !exporter
41
+ warn "Error: Invalid format #{options[:format]}"
49
42
  exit(-1)
50
43
  end
51
44
 
52
45
  hostnames = DNSSniper::Hostnames.new
53
- puts hostnames.add_from(File.open(options[:blacklist_urls_file]).readlines).remove_from(options[:whitelisted_hosts_file]).to_format(options[:format])
46
+ hostnames.blacklist += DNSSniper::ConfigurationImporter.new(options[:conf_path], list: :reject).hostnames
47
+ hostnames.whitelist += DNSSniper::ConfigurationImporter.new(options[:conf_path], list: :allow).hostnames
48
+
49
+ exporter = exporter.new(hostnames.blocklist)
50
+ puts exporter.data
@@ -3,8 +3,8 @@
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'dns-sniper'
5
5
  spec.license = 'MIT'
6
- spec.version = '0.0.1.pre4'
7
- spec.date = '2020-11-01'
6
+ spec.version = '0.0.1.pre5'
7
+ spec.date = '2020-11-10'
8
8
 
9
9
  spec.authors = ['Brody Hoskins']
10
10
  spec.email = ['brody@brody.digital']
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'resolv'
4
+ require 'yaml'
5
+
6
+ require 'dns-sniper/exporter'
7
+ require 'dns-sniper/exporters'
3
8
  require 'dns-sniper/hostnames'
4
- require 'dns-sniper/formatter'
5
- require 'dns-sniper/formatters'
9
+ require 'dns-sniper/importer'
10
+ require 'dns-sniper/importers'
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Formatter
4
+ class Exporter
5
+ attr_accessor :data, :hostnames
6
+
5
7
  def initialize(hostnames, options = {})
6
8
  @hostnames = hostnames
7
- @options = options
9
+ @data = output(options)
8
10
  end
9
11
 
10
- def output
12
+ def output(*)
11
13
  raise NotImplementedError, "Error: #output isn’t supported by #{self.class.name}"
12
14
  end
13
15
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ module Exporters
5
+ module_function
6
+
7
+ attr_reader :registered
8
+ @registered = []
9
+
10
+ def register(class_name, autoload_require)
11
+ DNSSniper.autoload(class_name, autoload_require)
12
+ @registered << class_name
13
+ end
14
+
15
+ def all
16
+ @registered.map { |name| DNSSniper.const_get(name) }
17
+ end
18
+
19
+ def find(name)
20
+ all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "Unknown exporter \"#{name}\""
21
+ end
22
+ end
23
+ end
24
+
25
+ DNSSniper::Exporters.register :Bind8Exporter, 'dns-sniper/exporters/bind8_exporter'
26
+ DNSSniper::Exporters.register :DnsmasqExporter, 'dns-sniper/exporters/dnsmasq_exporter'
27
+ DNSSniper::Exporters.register :HostsExporter, 'dns-sniper/exporters/hosts_exporter'
28
+ DNSSniper::Exporters.register :NetgearExporter, 'dns-sniper/exporters/netgear_exporter'
29
+ DNSSniper::Exporters.register :TextExporter, 'dns-sniper/exporters/text_exporter'
30
+ DNSSniper::Exporters.register :UnboundExporter, 'dns-sniper/exporters/unbound_exporter'
@@ -1,12 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Bind8 < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
4
+ class Bind8Exporter < Exporter
10
5
  def output(options = {})
11
6
  raise ArgumentError, 'zone_file is required' unless defined?(options[:zone_file])
12
7
 
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Dnsmasq < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class DnsmasqExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  @hostnames.each do |hostname|
13
8
  str << "server=/#{hostname}/#{$/}"
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Hosts < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class HostsExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  @hostnames.each do |hostname|
13
8
  str << "127.0.0.1\t#{hostname}#{$/}"
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Netgear < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class NetgearExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  @hostnames.each_with_index do |hostname, i|
13
8
  str << "[517003_e]: #{i + 1}) #{hostname}\n"
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class TextExporter < Exporter
5
+ def output(_options = {})
6
+ @hostnames.to_a.join($/)
7
+ end
8
+ end
9
+ end
@@ -1,13 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DNSSniper
4
- class Unbound < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
4
+ class UnboundExporter < Exporter
5
+ def output(*)
11
6
  str = ''.dup
12
7
  str << "server:#{$/}"
13
8
  @hostnames.each do |hostname|
@@ -7,152 +7,28 @@ require 'resolv'
7
7
 
8
8
  module DNSSniper
9
9
  class Hostnames
10
- def initialize(_options = {})
11
- @hostnames = [].to_set
12
- self
13
- end
10
+ attr_accessor :blacklist
11
+ attr_accessor :whitelist
14
12
 
15
- def add(hostnames)
16
- hostnames = clean(hostnames.class == String ? [hostnames] : hostnames)
17
- @hostnames += hostnames unless hostnames.empty?
13
+ def initialize
14
+ @blacklist = [].to_set
15
+ @whitelist = [].to_set
18
16
  self
19
17
  end
20
18
 
21
- def add_from(paths_or_urls)
22
- return self unless paths_or_urls
23
-
24
- paths_or_urls = [paths_or_urls] if paths_or_urls.class == String
25
-
26
- paths_or_urls.each do |path_or_url|
27
- path_or_url.chomp!
28
-
29
- if File.exist?(path_or_url)
30
- contents = File.open(path_or_url).readlines(chomp: true)
31
- else
32
- begin
33
- down = Down.download(path_or_url)
34
- path_or_url = down.path
35
- contents = down.readlines(chomp: true)
36
- rescue Down::InvalidUrl
37
- warn "\"#{path_or_url}\" does not exist, nor is it a valid URL"
38
- rescue Down::NotFound
39
- warn "\"#{path_or_url}\" does not exist"
40
- return self
41
- rescue Down::ResponseError
42
- warn "\"#{path_or_url}\": No data from server"
43
- return self
44
- end
45
- end
19
+ def blocklist
20
+ blacklist = @blacklist
21
+ whitelist = @whitelist
46
22
 
47
- case syntax(path_or_url, contents)
48
- when nil
49
- warn "Error: Syntax: Syntax of \"#{path_or_url}\" not recognized, ignored"
50
- return self
51
- when 'hosts'
52
- add from_hosts_file(path_or_url)
53
- when 'hostnames'
54
- add from_hostnames_file(contents)
23
+ whitelist.each do |domain|
24
+ domain_parts = domain.split('.')
25
+ domain_parts.count.times do |count|
26
+ next if count == 1
27
+ whitelist += [domain_parts[count - 1, domain_parts.length].join('.')]
55
28
  end
56
29
  end
57
30
 
58
- self
59
- end
60
-
61
- def remove(hostnames)
62
- hostnames = clean(hostnames.class == String ? [hostnames] : hostnames)
63
- @hostnames -= hostnames unless hostnames.empty?
64
- self
65
- end
66
-
67
- def remove_from(paths_or_urls)
68
- return self unless paths_or_urls
69
-
70
- paths_or_urls = [paths_or_urls] if paths_or_urls.class == String
71
-
72
- paths_or_urls.each do |path_or_url|
73
- path_or_url = path_or_url.strip
74
-
75
- if File.exist?(path_or_url)
76
- contents = File.open(path_or_url).readlines
77
- else
78
- begin
79
- down = Down.download(path_or_url)
80
- path_or_url = down.path
81
- contents = down.readlines
82
- rescue Down::NotFound
83
- warn "\"#{path_or_url}\" does not exist"
84
- return self
85
- rescue Down::ResponseError
86
- warn "\"#{path_or_url}\": No data from server"
87
- return self
88
- end
89
- end
90
-
91
- case syntax(path_or_url, contents)
92
- when nil
93
- warn "Error: Syntax: Syntax of \"#{path_or_url}\" not recognized, ignored"
94
- return self
95
- when 'hosts'
96
- remove from_hosts_file(path_or_url)
97
- when 'hostnames'
98
- remove from_hostnames_file(contents)
99
- end
100
- end
101
-
102
- self
103
- end
104
-
105
- def to_format(format, options = {})
106
- format = format.capitalize
107
- begin
108
- klass = DNSSniper.const_get(format)
109
- klass.new(@hostnames.to_a).output(options)
110
- rescue NameError
111
- false
112
- end
113
- end
114
-
115
- def to_a
116
- @hostnames.to_a
117
- end
118
-
119
- private
120
-
121
- def clean(hostnames)
122
- cleaned_hostnames = []
123
- hostnames.each do |hostname|
124
- hostname = hostname.downcase.strip
125
- hostname = hostname.sub('www.', '')
126
- hostname_top_domain = "#{hostname.split('.')[-2]}.#{hostname.split('.')[-1]}"
127
-
128
- if !hostname.include?('#') && !['broadcasthost', 'localhost', ''].include?(hostname) && !@hostnames.include?(hostname_top_domain)
129
- cleaned_hostnames << hostname
130
- end
131
- end
132
- cleaned_hostnames
133
- end
134
-
135
- def syntax(path_or_url, contents)
136
- contents.each do |line|
137
- next if line.include?('#')
138
-
139
- line = line.downcase
140
- if line.strip.split(/\s/).first =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex])
141
- return 'hosts'
142
- elsif line.include?('.') && !URI.parse(line).is_a?(URI::HTTP)
143
- return 'hostnames'
144
- end
145
- end
146
- nil
147
- end
148
-
149
- def from_hosts_file(path_or_url)
150
- # TODO: Remove downloading file twice
151
- HostsFile.load(path_or_url).map(&:name)
152
- end
153
-
154
- def from_hostnames_file(contents)
155
- contents.each { |line| add(line) }
31
+ blacklist - whitelist
156
32
  end
157
33
  end
158
34
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class Importer
5
+ attr_accessor :uri, :hostnames
6
+
7
+ def initialize(uri, *)
8
+ @uri = uri
9
+ @hostnames = File.exist?(uri) ? import_file(uri) : import_uri(uri)
10
+ end
11
+
12
+ def import_file(*)
13
+ raise NotImplementedError, "#{self.class.name}: #import_file not supported"
14
+ end
15
+
16
+ def import_uri(*)
17
+ raise NotImplementedError, "#{self.class.name}: #import_uri not supported"
18
+ end
19
+
20
+ # Helper methods
21
+
22
+ def clean(domain)
23
+ domain = domain.split('#')[0] if domain[0] != '#' && domain.include?('#')
24
+ domain = domain.split(':')[0] if domain.include?(':') && !ip_addr?(domain)
25
+ domain = domain.sub('www.', '') if domain.start_with?('www.') && domain.scan('www.').count == 1
26
+
27
+ domain.chomp.gsub(/\s+/, '').downcase
28
+ end
29
+
30
+ def rejector(domain)
31
+ !domain?(domain)
32
+ end
33
+
34
+ def domain?(domain)
35
+ return false if domain == ''
36
+ return false if domain.gsub('#', '').gsub(/\s+/, '').empty?
37
+ return false if domain[0] == '#'
38
+ return false unless domain.include?('.')
39
+ return false if domain.include?(':')
40
+ return false if ip_addr?(domain)
41
+ return false unless /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/.match?(domain)
42
+
43
+ begin
44
+ return false if URI.parse(domain).is_a?(URI::HTTP)
45
+ rescue URI::InvalidURIError; end
46
+ true
47
+ end
48
+
49
+ def ip_addr?(domain)
50
+ domain =~ Regexp.union([Resolv::IPv4::Regex, Resolv::IPv6::Regex])
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ module Importers
5
+ module_function
6
+
7
+ attr_reader :registered
8
+ @registered = []
9
+
10
+ def register(class_name, autoload_require)
11
+ DNSSniper.autoload(class_name, autoload_require)
12
+ @registered << class_name
13
+ end
14
+
15
+ def all
16
+ @registered.map { |name| DNSSniper.const_get(name) }
17
+ end
18
+
19
+ def find(name)
20
+ all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "Unknown Importer \"#{name}\""
21
+ end
22
+ end
23
+ end
24
+
25
+ DNSSniper::Importers.register :ConfigurationImporter, 'dns-sniper/importers/configuration_importer'
26
+ DNSSniper::Importers.register :DomainsImporter, 'dns-sniper/importers/domains_importer'
27
+ DNSSniper::Importers.register :HostsImporter, 'dns-sniper/importers/hosts_importer'
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class ConfigurationImporter < Importer
5
+ def initialize(uri, list:)
6
+ @uri = uri
7
+ @hostnames = File.exist?(uri) ? import_file(uri, list: list) : import_uri(uri, list: list)
8
+ end
9
+
10
+ def import_file(path, list:)
11
+ raise ArgumentError, "#{self.class.name}: #from_path requies list to be defined" unless list
12
+ return [].to_set unless File.exist?(path)
13
+
14
+ yaml = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
15
+ return [].to_set unless yaml.dig(:sources)&.dig(list.to_sym)
16
+
17
+ hostnames = [].to_set
18
+ yaml.dig(:sources).dig(list.to_sym).each do |source|
19
+ return [].to_set unless source.dig(:importer)
20
+ return [].to_set unless source.dig(:uri)
21
+
22
+ importer = DNSSniper.const_get("#{source.dig(:importer).to_s.split('_').map(&:capitalize).join}Importer")
23
+ if !importer
24
+ next
25
+ else
26
+ importer = importer.new(source.dig(:uri))
27
+ hostnames += importer.hostnames
28
+ end
29
+ end
30
+
31
+ hostnames
32
+ end
33
+
34
+ def import_uri(_uri, list:)
35
+ raise NotImplementedError, "#{self.class.name}: #from_uri not supported"
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class DomainsImporter < Importer
5
+ def import_file(path)
6
+ return [].to_set unless File.exist?(path)
7
+
8
+ File.open(path).readlines(chomp: true).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
9
+ end
10
+
11
+ def import_uri(uri)
12
+ begin
13
+ down = Down.download(uri)
14
+ return down.readlines(chomp: true).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
15
+ rescue Down::InvalidUrl => e
16
+ warn "#{self.class.name}: #{e}"
17
+ end
18
+
19
+ [].to_set
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DNSSniper
4
+ class HostsImporter < Importer
5
+ def import_file(path, *)
6
+ return [].to_set unless File.exist?(path)
7
+
8
+ HostsFile.load(path).map(&:name).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
9
+ end
10
+
11
+ def import_uri(uri, *)
12
+ begin
13
+ down = Down.download(uri)
14
+ path = down.path
15
+ rescue Down::InvalidUrl => e
16
+ warn "#{self.class.name}: #{e}"
17
+ end
18
+
19
+ if path
20
+ return HostsFile.load(path).map(&:name).map { |hostname| clean(hostname) }.reject { |hostname| rejector(hostname) }.to_set
21
+ end
22
+
23
+ [].to_set
24
+ end
25
+ end
26
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dns-sniper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.pre4
4
+ version: 0.0.1.pre5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brody Hoskins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-01 00:00:00.000000000 Z
11
+ date: 2020-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: down
@@ -56,15 +56,20 @@ files:
56
56
  - bin/dns-sniper
57
57
  - dns-sniper.gemspec
58
58
  - lib/dns-sniper.rb
59
- - lib/dns-sniper/formatter.rb
60
- - lib/dns-sniper/formatters.rb
61
- - lib/dns-sniper/formatters/bind8.rb
62
- - lib/dns-sniper/formatters/dnsmasq.rb
63
- - lib/dns-sniper/formatters/hosts.rb
64
- - lib/dns-sniper/formatters/netgear.rb
65
- - lib/dns-sniper/formatters/text.rb
66
- - lib/dns-sniper/formatters/unbound.rb
59
+ - lib/dns-sniper/exporter.rb
60
+ - lib/dns-sniper/exporters.rb
61
+ - lib/dns-sniper/exporters/bind8_exporter.rb
62
+ - lib/dns-sniper/exporters/dnsmasq_exporter.rb
63
+ - lib/dns-sniper/exporters/hosts_exporter.rb
64
+ - lib/dns-sniper/exporters/netgear_exporter.rb
65
+ - lib/dns-sniper/exporters/text_exporter.rb
66
+ - lib/dns-sniper/exporters/unbound_exporter.rb
67
67
  - lib/dns-sniper/hostnames.rb
68
+ - lib/dns-sniper/importer.rb
69
+ - lib/dns-sniper/importers.rb
70
+ - lib/dns-sniper/importers/configuration_importer.rb
71
+ - lib/dns-sniper/importers/domains_importer.rb
72
+ - lib/dns-sniper/importers/hosts_importer.rb
68
73
  homepage: https://github.com/brodyhoskins/dns-sniper
69
74
  licenses:
70
75
  - MIT
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DNSSniper
4
- module Formatters
5
- extend self
6
-
7
- attr_reader :registered
8
- @registered = []
9
-
10
- def register(class_name, autoload_require)
11
- DNSSniper.autoload(class_name, autoload_require)
12
- @registered << class_name
13
- end
14
-
15
- def all
16
- @registered.map { |name| DNSSniper.const_get(name) }
17
- end
18
-
19
- def find(name)
20
- all.find { |c| c.name.downcase == name.to_s.downcase } or raise NameError, "Unknown formatter \"#{name}\""
21
- end
22
- end
23
- end
24
-
25
- DNSSniper::Formatters.register :Bind8, 'dns-sniper/formatters/bind8'
26
- DNSSniper::Formatters.register :Dnsmasq, 'dns-sniper/formatters/dnsmasq'
27
- DNSSniper::Formatters.register :Hosts, 'dns-sniper/formatters/hosts'
28
- DNSSniper::Formatters.register :Netgear, 'dns-sniper/formatters/netgear'
29
- DNSSniper::Formatters.register :Text, 'dns-sniper/formatters/text'
30
- DNSSniper::Formatters.register :Unbound, 'dns-sniper/formatters/unbound'
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module DNSSniper
4
- class Text < Formatter
5
- def initialize(hostnames, options = {})
6
- @hostnames = hostnames
7
- @options = options
8
- end
9
-
10
- def output(_options = {})
11
- @hostnames.to_a.join($/)
12
- end
13
- end
14
- end