ronin-scanners 0.1.4 → 1.0.0.pre1
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.
- data/.document +4 -0
- data/.gemtest +0 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.yardopts +2 -0
- data/COPYING.txt +339 -0
- data/{History.txt → ChangeLog.md} +7 -7
- data/Gemfile +45 -0
- data/README.md +125 -0
- data/Rakefile +39 -14
- data/bin/ronin-scan-dork +20 -0
- data/bin/ronin-scan-nmap +20 -0
- data/bin/ronin-scan-proxies +20 -0
- data/bin/ronin-scan-spider +20 -0
- data/bin/ronin-scanner +20 -0
- data/bin/ronin-scanners +13 -5
- data/gemspec.yml +31 -0
- data/lib/ronin/database/migrations/scanners.rb +25 -0
- data/lib/ronin/database/migrations/scanners/1.0.0.rb +51 -0
- data/lib/ronin/scanners.rb +7 -5
- data/lib/ronin/scanners/dork.rb +173 -0
- data/lib/ronin/scanners/host_name_scanner.rb +67 -0
- data/lib/ronin/scanners/http_scanner.rb +195 -0
- data/lib/ronin/scanners/ip_scanner.rb +75 -0
- data/lib/ronin/scanners/nmap.rb +303 -5
- data/lib/ronin/scanners/{nikto/nikto.rb → proxies.rb} +11 -26
- data/lib/ronin/scanners/resolv_scanner.rb +73 -0
- data/lib/ronin/scanners/reverse_lookup_scanner.rb +76 -0
- data/lib/ronin/scanners/scanner.rb +371 -0
- data/lib/ronin/scanners/{nikto.rb → scanners.rb} +8 -5
- data/lib/ronin/scanners/site_map.rb +62 -0
- data/lib/ronin/scanners/spider.rb +117 -0
- data/lib/ronin/scanners/tcp_port_scanner.rb +72 -0
- data/lib/ronin/scanners/udp_port_scanner.rb +72 -0
- data/lib/ronin/scanners/url_scanner.rb +79 -0
- data/lib/ronin/scanners/version.rb +3 -4
- data/lib/ronin/ui/cli/commands/scan/dork.rb +39 -0
- data/lib/ronin/ui/cli/commands/scan/nmap.rb +105 -0
- data/lib/ronin/ui/cli/commands/scan/proxies.rb +82 -0
- data/lib/ronin/ui/cli/commands/scan/spider.rb +71 -0
- data/lib/ronin/ui/cli/commands/scanner.rb +43 -0
- data/lib/ronin/ui/cli/scanner_command.rb +118 -0
- data/ronin-scanners.gemspec +60 -0
- data/spec/scanners/host_name_scanner_spec.rb +24 -0
- data/spec/scanners/ip_scanner_spec.rb +24 -0
- data/spec/scanners/resolv_scanner_spec.rb +26 -0
- data/spec/scanners/reverse_lookup_scanner_spec.rb +26 -0
- data/spec/scanners/scanner_spec.rb +89 -0
- data/spec/scanners/scanners_spec.rb +9 -0
- data/spec/scanners/tcp_port_scanner_spec.rb +27 -0
- data/spec/scanners/udp_port_scanner_spec.rb +27 -0
- data/spec/scanners/url_scanner_spec.rb +37 -0
- data/spec/spec_helper.rb +4 -3
- metadata +261 -116
- data.tar.gz.sig +0 -1
- data/Manifest.txt +0 -16
- data/README.txt +0 -106
- data/lib/ronin/scanners/nikto/nikto_task.rb +0 -183
- data/lib/ronin/scanners/nmap/nmap.rb +0 -74
- data/lib/ronin/scanners/nmap/nmap_task.rb +0 -290
- data/spec/scanners_spec.rb +0 -11
- data/tasks/spec.rb +0 -9
- metadata.gz.sig +0 -0
@@ -1,9 +1,8 @@
|
|
1
1
|
#
|
2
|
-
#--
|
3
2
|
# Ronin Scanners - A Ruby library for Ronin that provides Ruby interfaces to
|
4
3
|
# various third-party security scanners.
|
5
4
|
#
|
6
|
-
# Copyright (c) 2008-
|
5
|
+
# Copyright (c) 2008-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
|
7
6
|
#
|
8
7
|
# This program is free software; you can redistribute it and/or modify
|
9
8
|
# it under the terms of the GNU General Public License as published by
|
@@ -18,37 +17,23 @@
|
|
18
17
|
# You should have received a copy of the GNU General Public License
|
19
18
|
# along with this program; if not, write to the Free Software
|
20
19
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
-
#++
|
22
20
|
#
|
23
21
|
|
24
|
-
require 'ronin/scanners/
|
25
|
-
|
26
|
-
require 'rprogram/program'
|
22
|
+
require 'ronin/scanners/nmap'
|
27
23
|
|
28
24
|
module Ronin
|
29
25
|
module Scanners
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
#
|
27
|
+
# The {Proxies} scanner scans known proxy ports.
|
28
|
+
#
|
29
|
+
class Proxies < Nmap
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def self.scan(options={},&block)
|
41
|
-
self.find.scan(options,&block)
|
42
|
-
end
|
31
|
+
parameter :ports, :description => 'The ports to scan for proxies',
|
32
|
+
:default => [
|
33
|
+
80, 280, 443, 591, 593, 808, 3128, 5800..5803,
|
34
|
+
8008, 8080, 8888, 8443, 9050, 9999
|
35
|
+
]
|
43
36
|
|
44
|
-
#
|
45
|
-
# Perform a Nikto scan using the given _options_ and _block_.
|
46
|
-
# If a _block_ is given, it will be passed a newly created
|
47
|
-
# NiktoTask object.
|
48
|
-
#
|
49
|
-
def scan(options={},&block)
|
50
|
-
run_task(NiktoTask.new(options,&block))
|
51
|
-
end
|
52
37
|
end
|
53
38
|
end
|
54
39
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#
|
2
|
+
# Ronin Scanners - A Ruby library for Ronin that provides Ruby interfaces to
|
3
|
+
# various third-party security scanners.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2008-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation; either version 2 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'ronin/scanners/ip_scanner'
|
23
|
+
|
24
|
+
require 'resolv'
|
25
|
+
|
26
|
+
module Ronin
|
27
|
+
module Scanners
|
28
|
+
#
|
29
|
+
# The {ResolvScanner} scans the IP addresses associated with a
|
30
|
+
# host-name.
|
31
|
+
#
|
32
|
+
class ResolvScanner < IPScanner
|
33
|
+
|
34
|
+
parameter :host, :description => 'The host to resolv'
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
#
|
39
|
+
# Resolvs the IP addresses for the host.
|
40
|
+
#
|
41
|
+
# @yield [ip]
|
42
|
+
# The given block will be passed each IP address associated with the
|
43
|
+
# host.
|
44
|
+
#
|
45
|
+
# @yieldparam [String] ip
|
46
|
+
# An IP address of the host.
|
47
|
+
#
|
48
|
+
def scan(&block)
|
49
|
+
Resolv.getaddresses(self.host).each(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Queries or creates a new IPAddress resource for the given result.
|
54
|
+
#
|
55
|
+
# @param [IPAddr] result
|
56
|
+
# The ip address.
|
57
|
+
#
|
58
|
+
# @return [IPAddress]
|
59
|
+
# The IPAddress resource from the Database.
|
60
|
+
#
|
61
|
+
def new_resource(result)
|
62
|
+
# get an IP address
|
63
|
+
ip = IPAddress.first_or_new(:address => result)
|
64
|
+
|
65
|
+
# associate the IP address with the host we are resolving
|
66
|
+
ip.host_names.first_or_new(:address => self.host.to_s)
|
67
|
+
|
68
|
+
return ip
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#
|
2
|
+
# Ronin Scanners - A Ruby library for Ronin that provides Ruby interfaces to
|
3
|
+
# various third-party security scanners.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2008-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation; either version 2 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'ronin/scanners/host_name_scanner'
|
23
|
+
|
24
|
+
require 'resolv'
|
25
|
+
|
26
|
+
module Ronin
|
27
|
+
module Scanners
|
28
|
+
#
|
29
|
+
# The {ReverseLookupScanner} scans the host-name(s) associated with
|
30
|
+
# an IP address.
|
31
|
+
#
|
32
|
+
class ReverseLookupScanner < HostNameScanner
|
33
|
+
|
34
|
+
parameter :host, :description => 'The IP address to reverse lookup'
|
35
|
+
|
36
|
+
protected
|
37
|
+
|
38
|
+
#
|
39
|
+
# Performs a reverse lookup on an IP address.
|
40
|
+
#
|
41
|
+
# @yield [host]
|
42
|
+
# The host name associated with the IP address.
|
43
|
+
#
|
44
|
+
# @yieldparam [String] host
|
45
|
+
# A host name associated with the IP address.
|
46
|
+
#
|
47
|
+
# @since 1.0.0
|
48
|
+
#
|
49
|
+
def scan(&block)
|
50
|
+
Resolv.getnames(self.host).each(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Queries or creates a new HostName resource for the result.
|
55
|
+
#
|
56
|
+
# @param [String] result
|
57
|
+
# The host name.
|
58
|
+
#
|
59
|
+
# @return [HostName]
|
60
|
+
# The HostName resource from the Database.
|
61
|
+
#
|
62
|
+
# @since 1.0.0
|
63
|
+
#
|
64
|
+
def new_resource(result)
|
65
|
+
# get a host name
|
66
|
+
host_name = HostName.first_or_new(:address => result)
|
67
|
+
|
68
|
+
# associate the host name with the IP address we are looking up
|
69
|
+
host_name.ip_addresses.first_or_new(:address => self.host.to_s)
|
70
|
+
|
71
|
+
return host_name
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,371 @@
|
|
1
|
+
#
|
2
|
+
# Ronin Scanners - A Ruby library for Ronin that provides Ruby interfaces to
|
3
|
+
# various third-party security scanners.
|
4
|
+
#
|
5
|
+
# Copyright (c) 2008-2012 Hal Brodigan (postmodern.mod3 at gmail.com)
|
6
|
+
#
|
7
|
+
# This program is free software; you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation; either version 2 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program; if not, write to the Free Software
|
19
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'ronin/script'
|
23
|
+
|
24
|
+
module Ronin
|
25
|
+
module Scanners
|
26
|
+
#
|
27
|
+
# The {Scanner} base class allows for defining various types of
|
28
|
+
# scanners. All scanners are Enumerable, have Parameters and are
|
29
|
+
# Cacheable.
|
30
|
+
#
|
31
|
+
# # Metadata
|
32
|
+
#
|
33
|
+
# A {Scanner} can be described by metadata, which is cached into the
|
34
|
+
# Ronin Database. The cacheable metadata must be defined within a
|
35
|
+
# `cache` block, so that the metadata is set only before the scanner
|
36
|
+
# is cached:
|
37
|
+
#
|
38
|
+
# cache do
|
39
|
+
# self.name = 'ZIP Scanner'
|
40
|
+
# self.description = %{
|
41
|
+
# A scanner which finds ZIP files on a system.
|
42
|
+
# }
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# ## License
|
46
|
+
#
|
47
|
+
# A {Scanner} may be associated with a specific software license using
|
48
|
+
# the `license!` method:
|
49
|
+
#
|
50
|
+
# cache do
|
51
|
+
# # ...
|
52
|
+
#
|
53
|
+
# self.license! :mit
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# # Methods
|
57
|
+
#
|
58
|
+
# The primary method which will perform the scanning and yielding back
|
59
|
+
# of results is {#scan}.
|
60
|
+
#
|
61
|
+
# The {Scanner} class defines three other methods for enumerating
|
62
|
+
# results using {#scan}:
|
63
|
+
#
|
64
|
+
# * {#each} - enumerates over the normalized results, using
|
65
|
+
# {#normalize_result} to normalize the results.
|
66
|
+
# * {#each_resource} - enumerates over resources that were
|
67
|
+
# created from the results, using {#new_resource}.
|
68
|
+
# * {#import} - saves the resources into the Database, while
|
69
|
+
# enumerating over the resources.
|
70
|
+
#
|
71
|
+
# # Scanner Base Classes
|
72
|
+
#
|
73
|
+
# * {IPScanner}
|
74
|
+
# * {HostNameScanner}
|
75
|
+
# * {TCPPortScanner}
|
76
|
+
# * {UDPPortScanner}
|
77
|
+
# * {URLScanner}
|
78
|
+
#
|
79
|
+
# # Specialized Scanner Classes
|
80
|
+
#
|
81
|
+
# * {ResolvScanner}
|
82
|
+
# * {ReverseLookupScanner}
|
83
|
+
# * {SiteMap}
|
84
|
+
# * {Spider}
|
85
|
+
# * {Nmap}
|
86
|
+
# * {Proxies}
|
87
|
+
#
|
88
|
+
class Scanner
|
89
|
+
|
90
|
+
include Script
|
91
|
+
include Enumerable
|
92
|
+
|
93
|
+
# The primary-key of the scanner
|
94
|
+
property :id, Serial
|
95
|
+
|
96
|
+
#
|
97
|
+
# Creates a new {Scanner} object.
|
98
|
+
#
|
99
|
+
# @param [Hash] options
|
100
|
+
# Additional options for the scanner.
|
101
|
+
#
|
102
|
+
# @since 1.0.0
|
103
|
+
#
|
104
|
+
# @api public
|
105
|
+
#
|
106
|
+
def initialize(options={})
|
107
|
+
super(options)
|
108
|
+
|
109
|
+
initialize_params(options)
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Initializes the scanner and imports the scan results.
|
114
|
+
#
|
115
|
+
# @param [Hash] options
|
116
|
+
# Options for the scanner.
|
117
|
+
#
|
118
|
+
# @yield [result]
|
119
|
+
# The given block will be passed each "result" from the scan.
|
120
|
+
#
|
121
|
+
# @yieldparam [Object] result
|
122
|
+
# A "result" from the scan.
|
123
|
+
#
|
124
|
+
# @return [Enumerator]
|
125
|
+
# If no block is given, an Enumerator will be returned.
|
126
|
+
#
|
127
|
+
# @see #each
|
128
|
+
#
|
129
|
+
# @since 1.0.0
|
130
|
+
#
|
131
|
+
# @api public
|
132
|
+
#
|
133
|
+
def self.each(options={},&block)
|
134
|
+
new(options).each(&block)
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Initializes the scanner and performs a scan.
|
139
|
+
#
|
140
|
+
# @param [Hash] options
|
141
|
+
# Options for the scanner.
|
142
|
+
#
|
143
|
+
# @yield [resource]
|
144
|
+
# The given block will be passed every scanned resource.
|
145
|
+
#
|
146
|
+
# @yieldparam [DataMapper::Resource] resource
|
147
|
+
# A resource found by the scanner.
|
148
|
+
#
|
149
|
+
# @return [Array<DataMapper::Resource>]
|
150
|
+
# If no block is given, an Array of scanned resources will be returned.
|
151
|
+
#
|
152
|
+
# @see #each_resource
|
153
|
+
#
|
154
|
+
# @since 1.0.0
|
155
|
+
#
|
156
|
+
# @api public
|
157
|
+
#
|
158
|
+
def self.scan(options={},&block)
|
159
|
+
scanner = new(options)
|
160
|
+
|
161
|
+
if block then scanner.each_resource(&block)
|
162
|
+
else scanner.each_resource.to_a
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
#
|
167
|
+
# Initializes the scanner and imports the scan results.
|
168
|
+
#
|
169
|
+
# @param [Hash] options
|
170
|
+
# Options for the scanner.
|
171
|
+
#
|
172
|
+
# @yield [resource]
|
173
|
+
# The given block will be passed every saved scanner result.
|
174
|
+
#
|
175
|
+
# @yieldparam [DataMapper::Resource] resource
|
176
|
+
# A resource saved by the scanner.
|
177
|
+
#
|
178
|
+
# @return [Array<DataMapper::Resource>]
|
179
|
+
# If no block is given, an Array of saved scanner resources will be
|
180
|
+
# returned.
|
181
|
+
#
|
182
|
+
# @see #import
|
183
|
+
#
|
184
|
+
# @since 1.0.0
|
185
|
+
#
|
186
|
+
# @api public
|
187
|
+
#
|
188
|
+
def self.import(options={},&block)
|
189
|
+
scanner = new(options)
|
190
|
+
|
191
|
+
if block then scanner.import(&block)
|
192
|
+
else scanner.import.to_a
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
#
|
197
|
+
# Performs the scan.
|
198
|
+
#
|
199
|
+
# @yield [result]
|
200
|
+
# The given block will be passed each "result" from the scan.
|
201
|
+
#
|
202
|
+
# @yieldparam [Object] result
|
203
|
+
# A "result" from the scan.
|
204
|
+
#
|
205
|
+
# @return [Scanner, Enumerator]
|
206
|
+
# If no block was given, an `Enumerator` object will be returned.
|
207
|
+
#
|
208
|
+
# @since 1.0.0
|
209
|
+
#
|
210
|
+
# @api public
|
211
|
+
#
|
212
|
+
def each
|
213
|
+
return enum_for(__method__) unless block_given?
|
214
|
+
|
215
|
+
scan do |result|
|
216
|
+
if result
|
217
|
+
if (result = normalize_result(result))
|
218
|
+
yield result
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
return self
|
224
|
+
end
|
225
|
+
|
226
|
+
#
|
227
|
+
# Creates new resource objects from the scan results.
|
228
|
+
#
|
229
|
+
# @yield [resource]
|
230
|
+
# The given block will be passed each resource.
|
231
|
+
#
|
232
|
+
# @yieldparam [DataMapper::Resource] resource
|
233
|
+
# A new or pre-existing resource.
|
234
|
+
#
|
235
|
+
# @return [Scanner, Enumerator]
|
236
|
+
# If no block was given, an `Enumerator` object will be returned.
|
237
|
+
#
|
238
|
+
# @since 1.0.0
|
239
|
+
#
|
240
|
+
# @api public
|
241
|
+
#
|
242
|
+
def each_resource
|
243
|
+
return enum_for(__method__) unless block_given?
|
244
|
+
|
245
|
+
scan do |result|
|
246
|
+
if result
|
247
|
+
if (result = normalize_result(result))
|
248
|
+
if (resource = new_resource(result))
|
249
|
+
yield resource
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
#
|
257
|
+
# Imports the scan results into the Database.
|
258
|
+
#
|
259
|
+
# @yield [resource]
|
260
|
+
# The given block will be passed each resource, after it has
|
261
|
+
# been saved into the Database.
|
262
|
+
#
|
263
|
+
# @yieldparam [DataMapper::Resource] resource
|
264
|
+
# A resource that exists in the Database.
|
265
|
+
#
|
266
|
+
# @return [Scanner, Enumerator]
|
267
|
+
# If no block was given, an `Enumerator` object will be returned.
|
268
|
+
#
|
269
|
+
# @since 1.0.0
|
270
|
+
#
|
271
|
+
# @api public
|
272
|
+
#
|
273
|
+
def import
|
274
|
+
return enum_for(__method__) unless block_given?
|
275
|
+
|
276
|
+
each_resource do |resource|
|
277
|
+
yield resource if resource.save
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
#
|
282
|
+
# Runs the scanner.
|
283
|
+
#
|
284
|
+
# @param [Hash] options
|
285
|
+
# Additional options to run the scanner with.
|
286
|
+
#
|
287
|
+
# @option options [Integer] :first
|
288
|
+
# Only print the first n results.
|
289
|
+
#
|
290
|
+
# @option options [Boolean] :import
|
291
|
+
# Specifies whether to save the results in the Database.
|
292
|
+
#
|
293
|
+
# @see #each
|
294
|
+
# @see #import
|
295
|
+
#
|
296
|
+
# @since 1.0.0
|
297
|
+
#
|
298
|
+
# @api public
|
299
|
+
#
|
300
|
+
def run(options={})
|
301
|
+
first_n = options.fetch(:first,Float::INFINITY)
|
302
|
+
enum = if options[:import] then import
|
303
|
+
else each
|
304
|
+
end
|
305
|
+
|
306
|
+
print_info "[#{self}] Scanning ..."
|
307
|
+
|
308
|
+
count = 0
|
309
|
+
|
310
|
+
enum.each_with_index do |result|
|
311
|
+
count += 1
|
312
|
+
|
313
|
+
puts result
|
314
|
+
yield result if block_given?
|
315
|
+
|
316
|
+
break if count >= first_n
|
317
|
+
end
|
318
|
+
|
319
|
+
print_info "[#{self}] Scan complete."
|
320
|
+
end
|
321
|
+
|
322
|
+
protected
|
323
|
+
|
324
|
+
#
|
325
|
+
# The default method which normalizes results.
|
326
|
+
#
|
327
|
+
# @param [Object] result
|
328
|
+
# The incoming result.
|
329
|
+
#
|
330
|
+
# @return [Object]
|
331
|
+
# The normalized result.
|
332
|
+
#
|
333
|
+
# @since 1.0.0
|
334
|
+
#
|
335
|
+
# @api semipublic
|
336
|
+
#
|
337
|
+
def normalize_result(result)
|
338
|
+
result
|
339
|
+
end
|
340
|
+
|
341
|
+
#
|
342
|
+
# Creates a new Database resource.
|
343
|
+
#
|
344
|
+
# @param [Object] result
|
345
|
+
# A result from the scan.
|
346
|
+
#
|
347
|
+
# @return [DataMapper::Resource, nil]
|
348
|
+
# The resource created from the result, or `nil` if a resource
|
349
|
+
# could not be created from the result.
|
350
|
+
#
|
351
|
+
# @since 1.0.0
|
352
|
+
#
|
353
|
+
# @api semipublic
|
354
|
+
#
|
355
|
+
def new_resource(result)
|
356
|
+
nil
|
357
|
+
end
|
358
|
+
|
359
|
+
#
|
360
|
+
# The default method which will actually perform the scanning.
|
361
|
+
#
|
362
|
+
# @since 1.0.0
|
363
|
+
#
|
364
|
+
# @api semipublic
|
365
|
+
#
|
366
|
+
def scan(&block)
|
367
|
+
end
|
368
|
+
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|