ronin 0.0.9

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.
Files changed (157) hide show
  1. data/COPYING.txt +339 -0
  2. data/History.txt +34 -0
  3. data/Manifest.txt +157 -0
  4. data/README.txt +131 -0
  5. data/Rakefile +23 -0
  6. data/TODO.txt +6 -0
  7. data/bin/ronin +12 -0
  8. data/lib/ronin.rb +35 -0
  9. data/lib/ronin/arch.rb +86 -0
  10. data/lib/ronin/author.rb +88 -0
  11. data/lib/ronin/cache.rb +27 -0
  12. data/lib/ronin/cache/config.rb +34 -0
  13. data/lib/ronin/cache/exceptions.rb +25 -0
  14. data/lib/ronin/cache/exceptions/extension_not_found.rb +29 -0
  15. data/lib/ronin/cache/exceptions/overlay_cached.rb +29 -0
  16. data/lib/ronin/cache/exceptions/overlay_not_found.rb +29 -0
  17. data/lib/ronin/cache/extension.rb +706 -0
  18. data/lib/ronin/cache/extension_cache.rb +108 -0
  19. data/lib/ronin/cache/overlay.rb +418 -0
  20. data/lib/ronin/cache/overlay_cache.rb +228 -0
  21. data/lib/ronin/cache/ronin.rb +50 -0
  22. data/lib/ronin/chars.rb +25 -0
  23. data/lib/ronin/chars/char_set.rb +121 -0
  24. data/lib/ronin/chars/chars.rb +180 -0
  25. data/lib/ronin/config.rb +31 -0
  26. data/lib/ronin/console.rb +127 -0
  27. data/lib/ronin/context.rb +233 -0
  28. data/lib/ronin/database.rb +122 -0
  29. data/lib/ronin/environment.rb +39 -0
  30. data/lib/ronin/exceptions/context_not_found.rb +27 -0
  31. data/lib/ronin/exceptions/invalid_database_config.rb +27 -0
  32. data/lib/ronin/exceptions/object_context_not_found.rb +27 -0
  33. data/lib/ronin/exceptions/unknown_context.rb +27 -0
  34. data/lib/ronin/exceptions/unknown_object_context.rb +27 -0
  35. data/lib/ronin/extensions.rb +28 -0
  36. data/lib/ronin/extensions/hash.rb +62 -0
  37. data/lib/ronin/extensions/kernel.rb +34 -0
  38. data/lib/ronin/extensions/meta.rb +24 -0
  39. data/lib/ronin/extensions/meta/object.rb +24 -0
  40. data/lib/ronin/extensions/string.rb +37 -0
  41. data/lib/ronin/extensions/uri.rb +24 -0
  42. data/lib/ronin/extensions/uri/http.rb +78 -0
  43. data/lib/ronin/extensions/uri/query_params.rb +97 -0
  44. data/lib/ronin/formatting.rb +29 -0
  45. data/lib/ronin/formatting/binary.rb +24 -0
  46. data/lib/ronin/formatting/digest.rb +24 -0
  47. data/lib/ronin/formatting/extensions.rb +26 -0
  48. data/lib/ronin/formatting/extensions/binary.rb +25 -0
  49. data/lib/ronin/formatting/extensions/binary/integer.rb +59 -0
  50. data/lib/ronin/formatting/extensions/binary/string.rb +73 -0
  51. data/lib/ronin/formatting/extensions/digest.rb +24 -0
  52. data/lib/ronin/formatting/extensions/digest/string.rb +65 -0
  53. data/lib/ronin/formatting/extensions/html.rb +24 -0
  54. data/lib/ronin/formatting/extensions/html/string.rb +75 -0
  55. data/lib/ronin/formatting/extensions/http.rb +24 -0
  56. data/lib/ronin/formatting/extensions/http/string.rb +69 -0
  57. data/lib/ronin/formatting/extensions/text.rb +24 -0
  58. data/lib/ronin/formatting/extensions/text/string.rb +96 -0
  59. data/lib/ronin/formatting/html.rb +24 -0
  60. data/lib/ronin/formatting/http.rb +24 -0
  61. data/lib/ronin/formatting/text.rb +24 -0
  62. data/lib/ronin/license.rb +87 -0
  63. data/lib/ronin/model.rb +44 -0
  64. data/lib/ronin/models.rb +34 -0
  65. data/lib/ronin/network.rb +31 -0
  66. data/lib/ronin/network/esmtp.rb +24 -0
  67. data/lib/ronin/network/extensions.rb +31 -0
  68. data/lib/ronin/network/extensions/esmtp.rb +24 -0
  69. data/lib/ronin/network/extensions/esmtp/net.rb +68 -0
  70. data/lib/ronin/network/extensions/http.rb +24 -0
  71. data/lib/ronin/network/extensions/http/net.rb +303 -0
  72. data/lib/ronin/network/extensions/imap.rb +24 -0
  73. data/lib/ronin/network/extensions/imap/net.rb +92 -0
  74. data/lib/ronin/network/extensions/pop3.rb +24 -0
  75. data/lib/ronin/network/extensions/pop3/net.rb +65 -0
  76. data/lib/ronin/network/extensions/smtp.rb +24 -0
  77. data/lib/ronin/network/extensions/smtp/net.rb +80 -0
  78. data/lib/ronin/network/extensions/tcp.rb +24 -0
  79. data/lib/ronin/network/extensions/tcp/net.rb +94 -0
  80. data/lib/ronin/network/extensions/telnet.rb +24 -0
  81. data/lib/ronin/network/extensions/telnet/net.rb +132 -0
  82. data/lib/ronin/network/extensions/udp.rb +24 -0
  83. data/lib/ronin/network/extensions/udp/net.rb +99 -0
  84. data/lib/ronin/network/http.rb +128 -0
  85. data/lib/ronin/network/http/exceptions.rb +24 -0
  86. data/lib/ronin/network/http/exceptions/unknown_request.rb +31 -0
  87. data/lib/ronin/network/imap.rb +47 -0
  88. data/lib/ronin/network/pop3.rb +47 -0
  89. data/lib/ronin/network/smtp.rb +26 -0
  90. data/lib/ronin/network/smtp/email.rb +126 -0
  91. data/lib/ronin/network/smtp/smtp.rb +55 -0
  92. data/lib/ronin/network/tcp.rb +24 -0
  93. data/lib/ronin/network/telnet.rb +95 -0
  94. data/lib/ronin/network/udp.rb +24 -0
  95. data/lib/ronin/object_context.rb +257 -0
  96. data/lib/ronin/objects.rb +29 -0
  97. data/lib/ronin/parameters.rb +27 -0
  98. data/lib/ronin/parameters/class_param.rb +45 -0
  99. data/lib/ronin/parameters/exceptions.rb +25 -0
  100. data/lib/ronin/parameters/exceptions/missing_param.rb +29 -0
  101. data/lib/ronin/parameters/exceptions/param_not_found.rb +29 -0
  102. data/lib/ronin/parameters/instance_param.rb +57 -0
  103. data/lib/ronin/parameters/param.rb +45 -0
  104. data/lib/ronin/parameters/parameters.rb +275 -0
  105. data/lib/ronin/path.rb +70 -0
  106. data/lib/ronin/pending_context.rb +42 -0
  107. data/lib/ronin/persistence.rb +32 -0
  108. data/lib/ronin/platform.rb +95 -0
  109. data/lib/ronin/product.rb +56 -0
  110. data/lib/ronin/ronin.rb +49 -0
  111. data/lib/ronin/rpc.rb +27 -0
  112. data/lib/ronin/rpc/call.rb +75 -0
  113. data/lib/ronin/rpc/client.rb +91 -0
  114. data/lib/ronin/rpc/console.rb +79 -0
  115. data/lib/ronin/rpc/exceptions.rb +25 -0
  116. data/lib/ronin/rpc/exceptions/not_implemented.rb +29 -0
  117. data/lib/ronin/rpc/exceptions/response_missing.rb +29 -0
  118. data/lib/ronin/rpc/interactive.rb +55 -0
  119. data/lib/ronin/rpc/interactive_console.rb +58 -0
  120. data/lib/ronin/rpc/interactive_shell.rb +59 -0
  121. data/lib/ronin/rpc/response.rb +57 -0
  122. data/lib/ronin/rpc/service.rb +69 -0
  123. data/lib/ronin/rpc/shell.rb +66 -0
  124. data/lib/ronin/runner.rb +24 -0
  125. data/lib/ronin/runner/program.rb +26 -0
  126. data/lib/ronin/runner/program/command.rb +204 -0
  127. data/lib/ronin/runner/program/commands.rb +33 -0
  128. data/lib/ronin/runner/program/commands/add.rb +73 -0
  129. data/lib/ronin/runner/program/commands/help.rb +52 -0
  130. data/lib/ronin/runner/program/commands/install.rb +65 -0
  131. data/lib/ronin/runner/program/commands/list.rb +81 -0
  132. data/lib/ronin/runner/program/commands/remove.rb +57 -0
  133. data/lib/ronin/runner/program/commands/uninstall.rb +57 -0
  134. data/lib/ronin/runner/program/commands/update.rb +55 -0
  135. data/lib/ronin/runner/program/exceptions.rb +24 -0
  136. data/lib/ronin/runner/program/exceptions/unknown_command.rb +31 -0
  137. data/lib/ronin/runner/program/options.rb +205 -0
  138. data/lib/ronin/runner/program/program.rb +173 -0
  139. data/lib/ronin/runner/program/runner.rb +35 -0
  140. data/lib/ronin/sessions.rb +32 -0
  141. data/lib/ronin/sessions/esmtp.rb +76 -0
  142. data/lib/ronin/sessions/imap.rb +73 -0
  143. data/lib/ronin/sessions/pop3.rb +70 -0
  144. data/lib/ronin/sessions/session.rb +52 -0
  145. data/lib/ronin/sessions/smtp.rb +76 -0
  146. data/lib/ronin/sessions/tcp.rb +111 -0
  147. data/lib/ronin/sessions/telnet.rb +76 -0
  148. data/lib/ronin/sessions/udp.rb +99 -0
  149. data/lib/ronin/sessions/web.rb +83 -0
  150. data/lib/ronin/shell.rb +81 -0
  151. data/lib/ronin/target.rb +40 -0
  152. data/lib/ronin/version.rb +27 -0
  153. data/lib/ronin/web.rb +24 -0
  154. data/lib/ronin/web/web.rb +265 -0
  155. data/spec/spec_helper.rb +9 -0
  156. data/tasks/spec.rb +7 -0
  157. metadata +324 -0
@@ -0,0 +1,108 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/cache/extension'
25
+ require 'ronin/cache/exceptions/extension_not_found'
26
+
27
+ module Ronin
28
+ module Cache
29
+ class ExtensionCache < Hash
30
+
31
+ #
32
+ # Creates a new empty ExtensionCache object. If a _block_ is given
33
+ # it will be passed the newly created ExtensionCache object.
34
+ #
35
+ def initialize(&block)
36
+ super() do |hash,key|
37
+ hash[name] = load_extension(key.to_s)
38
+ end
39
+
40
+ catch('EXIT') do
41
+ each_extension do |ext|
42
+ ext.perform_teardown
43
+ end
44
+ end
45
+
46
+ block.call(self) if block
47
+ end
48
+
49
+ #
50
+ # Returns the names of all extensions within the cache.
51
+ #
52
+ def names
53
+ keys
54
+ end
55
+
56
+ #
57
+ # Returns the extensions within the cache.
58
+ #
59
+ def extensions
60
+ values
61
+ end
62
+
63
+ #
64
+ # Iterates over each extension within the cache, passing each to the
65
+ # specified _block_.
66
+ #
67
+ def each_extension(&block)
68
+ each_value(&block)
69
+ end
70
+
71
+ #
72
+ # Selects the extensions within the cache that match the specified
73
+ # _block_.
74
+ #
75
+ def extensions_with(&block)
76
+ values.select(&block)
77
+ end
78
+
79
+ #
80
+ # Returns +true+ if the cache contains the extension with the
81
+ # specified _name_, returns +false+ otherwise.
82
+ #
83
+ def has_extension?(name)
84
+ has_key?(name.to_s)
85
+ end
86
+
87
+ #
88
+ # Loads the extension with the specified _name_. If no such extension
89
+ # exists an ExtensionNotFound exception will be raised. If a _block_
90
+ # is given, it will be passed the loaded extension.
91
+ #
92
+ def load_extension(name,&block)
93
+ name = name.to_s
94
+
95
+ unless Extension.exists?(name)
96
+ raise(ExtensionNotFound,"extension #{name.dump} does not eixst",caller)
97
+ end
98
+
99
+ return Extension.load(name) do |ext|
100
+ ext.perform_setup
101
+
102
+ block.call(ext) if block
103
+ end
104
+ end
105
+
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,418 @@
1
+ #
2
+ #--
3
+ # Ronin - A Ruby platform designed for information security and data
4
+ # exploration tasks.
5
+ #
6
+ # Copyright (c) 2006-2008 Hal Brodigan (postmodern.mod3 at gmail.com)
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This program is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with this program; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ #++
22
+ #
23
+
24
+ require 'ronin/cache/extension'
25
+ require 'ronin/cache/exceptions/extension_not_found'
26
+ require 'ronin/cache/overlay_cache'
27
+ require 'ronin/cache/config'
28
+ require 'ronin/persistence'
29
+
30
+ require 'rexml/document'
31
+ require 'repertoire'
32
+
33
+ module Ronin
34
+ module Cache
35
+ class Overlay < Repertoire::Repository
36
+
37
+ # Overlay metadata XML file name
38
+ METADATA_FILE = 'ronin.xml'
39
+
40
+ # Overlay objects directory
41
+ OBJECTS_DIR = 'objects'
42
+
43
+ # Local path to the overlay
44
+ attr_reader :path
45
+
46
+ # Source URI of the overlay source
47
+ attr_reader :uri
48
+
49
+ # Name of the overlay
50
+ attr_reader :name
51
+
52
+ # Authors of the overlay
53
+ attr_reader :authors
54
+
55
+ # License that the overlay contents is under
56
+ attr_reader :license
57
+
58
+ # Description
59
+ attr_reader :description
60
+
61
+ #
62
+ # Creates a new Overlay object with the specified _path_, _media_type_
63
+ # and _uri_.
64
+ #
65
+ def initialize(path,media_type=:nil,uri=nil,&block)
66
+ @path = File.expand_path(path)
67
+ @uri = uri
68
+
69
+ super(@path,Repertoire::Media.types[media_type])
70
+
71
+ load_metadata(&block)
72
+ end
73
+
74
+ #
75
+ # Load the Overlay Cache from the given _path_. If _path is not
76
+ # given, it will default to <tt>Config::REPOSITORY_CACHE_PATH</tt>.
77
+ # If a _block_ is given it will be passed the loaded Overlay Cache.
78
+ #
79
+ # Overlay.load_cache # => Cache
80
+ #
81
+ # Overlay.load_cache('/custom/cache') # => Cache
82
+ #
83
+ def Overlay.load_cache(path=Config::OVERLAY_CACHE_PATH,&block)
84
+ @@cache = OverlayCache.new(path,&block)
85
+ end
86
+
87
+ #
88
+ # Returns the current OverlayCache, or loads the default Cache
89
+ # if not already loaded.
90
+ #
91
+ def Overlay.cache
92
+ @@cache ||= load_cache
93
+ end
94
+
95
+ #
96
+ # Saves the overlay cache. If a _block_ is given, it will be passed
97
+ # the overlay cache before being saved.
98
+ #
99
+ # Overlay.save_cache # => OverlayCache
100
+ #
101
+ # Overlay.save_cahce do |cache|
102
+ # puts "Saving cache #{cache}"
103
+ # end
104
+ #
105
+ def Overlay.save_cache(&block)
106
+ Overlay.cache.save(&block)
107
+ end
108
+
109
+ #
110
+ # Returns the overlay with the specified _name_ from the overlay
111
+ # cache. If no such overlay exists, +nil+ is returned.
112
+ #
113
+ # Overlay['awesome']
114
+ #
115
+ def Overlay.[](name)
116
+ Overlay.cache[name]
117
+ end
118
+
119
+ #
120
+ # Returns +true+ if there is a overlay with the specified _name_
121
+ # in the overlay cache, returns +false+ otherwise.
122
+ #
123
+ def Overlay.exists?(name)
124
+ Overlay.cache.has_overlay?(name)
125
+ end
126
+
127
+ #
128
+ # Returns the overlay with the specified _name_ from the overlay
129
+ # cache. If no such overlay exists in the overlay cache,
130
+ # a OverlayNotFound exception will be raised.
131
+ #
132
+ def Overlay.get(name)
133
+ Overlay.cache.get_overlay(name)
134
+ end
135
+
136
+ #
137
+ # Installs the Overlay specified by _options_ into the
138
+ # <tt>Config::REPOSITORY_DIR</tt>. If a _block_ is given, it will be
139
+ # passed the newly created Overlay after it has been added to
140
+ # the Overlay cache.
141
+ #
142
+ # _options_ must contain the following key:
143
+ # <tt>:uri</tt>:: The URI of the Overlay.
144
+ #
145
+ # _options_ may contain the following key:
146
+ # <tt>:media</tt>:: The media of the Overlay.
147
+ #
148
+ def Overlay.install(options={},&block)
149
+ Repertoire.checkout(:media => options[:media], :uri => options[:uri], :into => Config::REPOSITORY_DIR) do |path,media,uri|
150
+ return Overlay.add(path,media,uri,&block)
151
+ end
152
+ end
153
+
154
+ #
155
+ # Adds the Overlay at the specified _path_, the given _uri_
156
+ # and given the _uri_ to the Overlay cache. If a _block is given, it
157
+ # will be passed the newly created Overlay after it has been added to
158
+ # the cache.
159
+ #
160
+ def Overlay.add(path,media=nil,uri=nil,&block)
161
+ Overlay.new(path,media,uri).add(&block)
162
+ end
163
+
164
+ #
165
+ # Updates the overlay with the specified _name_. If there is no
166
+ # overlay with the specified _name_ in the overlay cache
167
+ # a OverlayNotFound exception will be raised. If a _block_ is
168
+ # given it will be passed the updated overlay.
169
+ #
170
+ def Overlay.update(name,&block)
171
+ Overlay.get(name).update(&block)
172
+ end
173
+
174
+ #
175
+ # Removes the overlay with the specified _name_. If there is no
176
+ # overlay with the specified _name_ in the overlay cache
177
+ # a OverlayNotFound exception will be raised. If a _block_ is
178
+ # given it will be passed the overlay before removal.
179
+ #
180
+ def Overlay.remove(name,&block)
181
+ Overlay.get(name).remove(&block)
182
+ end
183
+
184
+ #
185
+ # Uninstall the overlay with the specified _name_. If there is no
186
+ # overlay with the specified _name_ in the overlay cache
187
+ # a OverlayNotFound exception will be raised. If a _block_ is
188
+ # given it will be passed the overlay before uninstalling it.
189
+ #
190
+ def Overlay.uninstall(name,&block)
191
+ Overlay.get(name).uninstall(&block)
192
+ end
193
+
194
+ #
195
+ # See OverlayCache#each_overlay.
196
+ #
197
+ def Overlay.each(&block)
198
+ Overlay.cache.each_overlay(&block)
199
+ end
200
+
201
+ #
202
+ # See OverlayCache#overlays_with?.
203
+ #
204
+ def Overlay.with(&block)
205
+ Overlay.cache.overlays_with(&block)
206
+ end
207
+
208
+ #
209
+ # Returns the overlays which contain the extension with the
210
+ # matching _name_.
211
+ #
212
+ # Overlay.with_extension?('exploits') # => [...]
213
+ #
214
+ def Overlay.with_extension(name)
215
+ Overlay.with { |repo| repo.has_extension?(name) }
216
+ end
217
+
218
+ #
219
+ # Returns +true+ if the cache has the extension with the matching
220
+ # _name_, returns +false+ otherwise.
221
+ #
222
+ def Overlay.has_extension?(name)
223
+ Overlay.each do |repo|
224
+ return true if repo.has_extension?(name)
225
+ end
226
+
227
+ return false
228
+ end
229
+
230
+ #
231
+ # Media type of the overlay.
232
+ #
233
+ def media_type
234
+ if @media
235
+ return @media.name
236
+ else
237
+ return nil
238
+ end
239
+ end
240
+
241
+ #
242
+ # Returns the path to the objects directory of the overlay.
243
+ #
244
+ def objects_dir
245
+ File.expand_path(File.join(@path,OBJECTS_DIR))
246
+ end
247
+
248
+ #
249
+ # Caches the objects contained within overlay.
250
+ #
251
+ def cache_objects
252
+ ObjectContext.cache_objects_in(objects_dir)
253
+ end
254
+
255
+ #
256
+ # Mirror the objects contained within the overlay.
257
+ #
258
+ def mirror_objects
259
+ ObjectContext.mirror_objects_in(objects_dir)
260
+ end
261
+
262
+ #
263
+ # Delete all objects that existed within the overlay.
264
+ #
265
+ def expunge_objects
266
+ ObjectContext.expunge_objects_from(objects_dir)
267
+ end
268
+
269
+ #
270
+ # Adds the overlay to the overlay cache. If a _block is given,
271
+ # it will be passed the newly created Overlay after it has been
272
+ # added to the cache.
273
+ #
274
+ def add(&block)
275
+ Overlay.cache.add(self) do
276
+ cache_objects
277
+ end
278
+
279
+ block.call(self) if block
280
+ return self
281
+ end
282
+
283
+ #
284
+ # Updates the overlay and reloads it's metadata. If a _block_
285
+ # is given it will be called after the overlay has been updated.
286
+ #
287
+ def update(&block)
288
+ mirror_objects
289
+
290
+ if media_type
291
+ Repertoire.update(:media => media_type, :path => @path, :uri => @uri)
292
+ end
293
+
294
+ return load_metadata(&block)
295
+ end
296
+
297
+ #
298
+ # Removes the overlay from the overlay cache. If a _block_ is
299
+ # given, it will be passed the overlay after it has been removed.
300
+ #
301
+ def remove(&block)
302
+ Overlay.cache.remove(self)
303
+
304
+ expunge_objects
305
+
306
+ block.call(self) if block
307
+ return self
308
+ end
309
+
310
+ #
311
+ # Deletes the overlay then removes it from the overlay cache.
312
+ # If a _block_ is given, it will be passed the overlay after it
313
+ # has been uninstalled.
314
+ #
315
+ def uninstall(&block)
316
+ Repertoire.delete(@path) do
317
+ return remove(&block)
318
+ end
319
+ end
320
+
321
+ #
322
+ # Returns the paths of all extensions within the overlay.
323
+ #
324
+ def extension_paths
325
+ directories
326
+ end
327
+
328
+ #
329
+ # Passes each extension path to the specified _block_.
330
+ #
331
+ def each_extension_path(&block)
332
+ extension_paths.each(&block)
333
+ end
334
+
335
+ #
336
+ # Returns the names of all extensions within the overlay.
337
+ #
338
+ def extensions
339
+ extension_paths.map { |dir| File.basename(dir) }
340
+ end
341
+
342
+ #
343
+ # Passes each extension name to the specified _block_.
344
+ #
345
+ def each_extension(&block)
346
+ extensions.each(&block)
347
+ end
348
+
349
+ #
350
+ # Returns +true+ if the overlay contains the extension with the
351
+ # specified _name_, returns +false+ otherwise.
352
+ #
353
+ def has_extension?(name)
354
+ extensions.include?(name.to_s)
355
+ end
356
+
357
+ #
358
+ # Loads an extension with the specified _name_ from the overlay.
359
+ # If a _block_ is given, it will be passed the newly created
360
+ # extension.
361
+ #
362
+ # repo.extension('awesome') # => Extension
363
+ #
364
+ # repo.extension('shellcode') do |ext|
365
+ # ...
366
+ # end
367
+ #
368
+ def extension(name,&block)
369
+ name = name.to_s
370
+
371
+ unless has_extension?(name)
372
+ raise(ExtensionNotfound,"overlay #{name.dump} does not contain the extension #{name.dump}",caller)
373
+ end
374
+
375
+ return Extension.load_extension(File.join(@path,name),&block)
376
+ end
377
+
378
+ #
379
+ # Returns the +name+ of the Overlay.
380
+ #
381
+ def to_s
382
+ @name.to_s
383
+ end
384
+
385
+ protected
386
+
387
+ #
388
+ # Loads the overlay metadata from the METADATA_FILE within the
389
+ # overlay +path+. If a _block_ is given, it will be passed the
390
+ # overlay after the metadata has been loaded.
391
+ #
392
+ def load_metadata(&block)
393
+ metadata_path = File.join(@path,METADATA_FILE)
394
+
395
+ if File.file?(metadata_path)
396
+ metadata = REXML::Document.new(open(metadata_path))
397
+
398
+ #@authors = Author.from_xml(metadata,'/ronin-overlay/contributors/author')
399
+
400
+ metadata.elements.each('/ronin-overlay') do |repo|
401
+ @name = repo.elements['name'].get_text.to_s.strip
402
+ @license = repo.elements['license'].get_text.to_s.strip
403
+ @description = repo.elements['description'].get_text.to_s.strip
404
+ end
405
+ else
406
+ @name = File.basename(@path)
407
+ @authors = []
408
+ @license = nil
409
+ @description = ''
410
+ end
411
+
412
+ block.call(self) if block
413
+ return self
414
+ end
415
+
416
+ end
417
+ end
418
+ end