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.
- data/COPYING.txt +339 -0
- data/History.txt +34 -0
- data/Manifest.txt +157 -0
- data/README.txt +131 -0
- data/Rakefile +23 -0
- data/TODO.txt +6 -0
- data/bin/ronin +12 -0
- data/lib/ronin.rb +35 -0
- data/lib/ronin/arch.rb +86 -0
- data/lib/ronin/author.rb +88 -0
- data/lib/ronin/cache.rb +27 -0
- data/lib/ronin/cache/config.rb +34 -0
- data/lib/ronin/cache/exceptions.rb +25 -0
- data/lib/ronin/cache/exceptions/extension_not_found.rb +29 -0
- data/lib/ronin/cache/exceptions/overlay_cached.rb +29 -0
- data/lib/ronin/cache/exceptions/overlay_not_found.rb +29 -0
- data/lib/ronin/cache/extension.rb +706 -0
- data/lib/ronin/cache/extension_cache.rb +108 -0
- data/lib/ronin/cache/overlay.rb +418 -0
- data/lib/ronin/cache/overlay_cache.rb +228 -0
- data/lib/ronin/cache/ronin.rb +50 -0
- data/lib/ronin/chars.rb +25 -0
- data/lib/ronin/chars/char_set.rb +121 -0
- data/lib/ronin/chars/chars.rb +180 -0
- data/lib/ronin/config.rb +31 -0
- data/lib/ronin/console.rb +127 -0
- data/lib/ronin/context.rb +233 -0
- data/lib/ronin/database.rb +122 -0
- data/lib/ronin/environment.rb +39 -0
- data/lib/ronin/exceptions/context_not_found.rb +27 -0
- data/lib/ronin/exceptions/invalid_database_config.rb +27 -0
- data/lib/ronin/exceptions/object_context_not_found.rb +27 -0
- data/lib/ronin/exceptions/unknown_context.rb +27 -0
- data/lib/ronin/exceptions/unknown_object_context.rb +27 -0
- data/lib/ronin/extensions.rb +28 -0
- data/lib/ronin/extensions/hash.rb +62 -0
- data/lib/ronin/extensions/kernel.rb +34 -0
- data/lib/ronin/extensions/meta.rb +24 -0
- data/lib/ronin/extensions/meta/object.rb +24 -0
- data/lib/ronin/extensions/string.rb +37 -0
- data/lib/ronin/extensions/uri.rb +24 -0
- data/lib/ronin/extensions/uri/http.rb +78 -0
- data/lib/ronin/extensions/uri/query_params.rb +97 -0
- data/lib/ronin/formatting.rb +29 -0
- data/lib/ronin/formatting/binary.rb +24 -0
- data/lib/ronin/formatting/digest.rb +24 -0
- data/lib/ronin/formatting/extensions.rb +26 -0
- data/lib/ronin/formatting/extensions/binary.rb +25 -0
- data/lib/ronin/formatting/extensions/binary/integer.rb +59 -0
- data/lib/ronin/formatting/extensions/binary/string.rb +73 -0
- data/lib/ronin/formatting/extensions/digest.rb +24 -0
- data/lib/ronin/formatting/extensions/digest/string.rb +65 -0
- data/lib/ronin/formatting/extensions/html.rb +24 -0
- data/lib/ronin/formatting/extensions/html/string.rb +75 -0
- data/lib/ronin/formatting/extensions/http.rb +24 -0
- data/lib/ronin/formatting/extensions/http/string.rb +69 -0
- data/lib/ronin/formatting/extensions/text.rb +24 -0
- data/lib/ronin/formatting/extensions/text/string.rb +96 -0
- data/lib/ronin/formatting/html.rb +24 -0
- data/lib/ronin/formatting/http.rb +24 -0
- data/lib/ronin/formatting/text.rb +24 -0
- data/lib/ronin/license.rb +87 -0
- data/lib/ronin/model.rb +44 -0
- data/lib/ronin/models.rb +34 -0
- data/lib/ronin/network.rb +31 -0
- data/lib/ronin/network/esmtp.rb +24 -0
- data/lib/ronin/network/extensions.rb +31 -0
- data/lib/ronin/network/extensions/esmtp.rb +24 -0
- data/lib/ronin/network/extensions/esmtp/net.rb +68 -0
- data/lib/ronin/network/extensions/http.rb +24 -0
- data/lib/ronin/network/extensions/http/net.rb +303 -0
- data/lib/ronin/network/extensions/imap.rb +24 -0
- data/lib/ronin/network/extensions/imap/net.rb +92 -0
- data/lib/ronin/network/extensions/pop3.rb +24 -0
- data/lib/ronin/network/extensions/pop3/net.rb +65 -0
- data/lib/ronin/network/extensions/smtp.rb +24 -0
- data/lib/ronin/network/extensions/smtp/net.rb +80 -0
- data/lib/ronin/network/extensions/tcp.rb +24 -0
- data/lib/ronin/network/extensions/tcp/net.rb +94 -0
- data/lib/ronin/network/extensions/telnet.rb +24 -0
- data/lib/ronin/network/extensions/telnet/net.rb +132 -0
- data/lib/ronin/network/extensions/udp.rb +24 -0
- data/lib/ronin/network/extensions/udp/net.rb +99 -0
- data/lib/ronin/network/http.rb +128 -0
- data/lib/ronin/network/http/exceptions.rb +24 -0
- data/lib/ronin/network/http/exceptions/unknown_request.rb +31 -0
- data/lib/ronin/network/imap.rb +47 -0
- data/lib/ronin/network/pop3.rb +47 -0
- data/lib/ronin/network/smtp.rb +26 -0
- data/lib/ronin/network/smtp/email.rb +126 -0
- data/lib/ronin/network/smtp/smtp.rb +55 -0
- data/lib/ronin/network/tcp.rb +24 -0
- data/lib/ronin/network/telnet.rb +95 -0
- data/lib/ronin/network/udp.rb +24 -0
- data/lib/ronin/object_context.rb +257 -0
- data/lib/ronin/objects.rb +29 -0
- data/lib/ronin/parameters.rb +27 -0
- data/lib/ronin/parameters/class_param.rb +45 -0
- data/lib/ronin/parameters/exceptions.rb +25 -0
- data/lib/ronin/parameters/exceptions/missing_param.rb +29 -0
- data/lib/ronin/parameters/exceptions/param_not_found.rb +29 -0
- data/lib/ronin/parameters/instance_param.rb +57 -0
- data/lib/ronin/parameters/param.rb +45 -0
- data/lib/ronin/parameters/parameters.rb +275 -0
- data/lib/ronin/path.rb +70 -0
- data/lib/ronin/pending_context.rb +42 -0
- data/lib/ronin/persistence.rb +32 -0
- data/lib/ronin/platform.rb +95 -0
- data/lib/ronin/product.rb +56 -0
- data/lib/ronin/ronin.rb +49 -0
- data/lib/ronin/rpc.rb +27 -0
- data/lib/ronin/rpc/call.rb +75 -0
- data/lib/ronin/rpc/client.rb +91 -0
- data/lib/ronin/rpc/console.rb +79 -0
- data/lib/ronin/rpc/exceptions.rb +25 -0
- data/lib/ronin/rpc/exceptions/not_implemented.rb +29 -0
- data/lib/ronin/rpc/exceptions/response_missing.rb +29 -0
- data/lib/ronin/rpc/interactive.rb +55 -0
- data/lib/ronin/rpc/interactive_console.rb +58 -0
- data/lib/ronin/rpc/interactive_shell.rb +59 -0
- data/lib/ronin/rpc/response.rb +57 -0
- data/lib/ronin/rpc/service.rb +69 -0
- data/lib/ronin/rpc/shell.rb +66 -0
- data/lib/ronin/runner.rb +24 -0
- data/lib/ronin/runner/program.rb +26 -0
- data/lib/ronin/runner/program/command.rb +204 -0
- data/lib/ronin/runner/program/commands.rb +33 -0
- data/lib/ronin/runner/program/commands/add.rb +73 -0
- data/lib/ronin/runner/program/commands/help.rb +52 -0
- data/lib/ronin/runner/program/commands/install.rb +65 -0
- data/lib/ronin/runner/program/commands/list.rb +81 -0
- data/lib/ronin/runner/program/commands/remove.rb +57 -0
- data/lib/ronin/runner/program/commands/uninstall.rb +57 -0
- data/lib/ronin/runner/program/commands/update.rb +55 -0
- data/lib/ronin/runner/program/exceptions.rb +24 -0
- data/lib/ronin/runner/program/exceptions/unknown_command.rb +31 -0
- data/lib/ronin/runner/program/options.rb +205 -0
- data/lib/ronin/runner/program/program.rb +173 -0
- data/lib/ronin/runner/program/runner.rb +35 -0
- data/lib/ronin/sessions.rb +32 -0
- data/lib/ronin/sessions/esmtp.rb +76 -0
- data/lib/ronin/sessions/imap.rb +73 -0
- data/lib/ronin/sessions/pop3.rb +70 -0
- data/lib/ronin/sessions/session.rb +52 -0
- data/lib/ronin/sessions/smtp.rb +76 -0
- data/lib/ronin/sessions/tcp.rb +111 -0
- data/lib/ronin/sessions/telnet.rb +76 -0
- data/lib/ronin/sessions/udp.rb +99 -0
- data/lib/ronin/sessions/web.rb +83 -0
- data/lib/ronin/shell.rb +81 -0
- data/lib/ronin/target.rb +40 -0
- data/lib/ronin/version.rb +27 -0
- data/lib/ronin/web.rb +24 -0
- data/lib/ronin/web/web.rb +265 -0
- data/spec/spec_helper.rb +9 -0
- data/tasks/spec.rb +7 -0
- metadata +324 -0
|
@@ -0,0 +1,25 @@
|
|
|
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/exceptions/extension_not_found'
|
|
25
|
+
require 'ronin/cache/exceptions/overlay_not_found'
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
module Ronin
|
|
25
|
+
module Cache
|
|
26
|
+
class ExtensionNotFound < RuntimeError
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
module Ronin
|
|
25
|
+
module Cache
|
|
26
|
+
class OverlayCached < RuntimeError
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
module Ronin
|
|
25
|
+
module Cache
|
|
26
|
+
class OverlayNotFound < RuntimeError
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,706 @@
|
|
|
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_cache'
|
|
25
|
+
require 'ronin/cache/overlay'
|
|
26
|
+
require 'ronin/context'
|
|
27
|
+
|
|
28
|
+
module Ronin
|
|
29
|
+
module Cache
|
|
30
|
+
class Extension
|
|
31
|
+
|
|
32
|
+
include Context
|
|
33
|
+
|
|
34
|
+
# Extension file name
|
|
35
|
+
EXTENSION_FILE = 'extension.rb'
|
|
36
|
+
|
|
37
|
+
# Extension lib directory
|
|
38
|
+
LIB_DIR = 'lib'
|
|
39
|
+
|
|
40
|
+
contextify :extension
|
|
41
|
+
|
|
42
|
+
# Name of extension
|
|
43
|
+
attr_reader :name
|
|
44
|
+
|
|
45
|
+
# Paths of similar extensions
|
|
46
|
+
attr_reader :paths
|
|
47
|
+
|
|
48
|
+
# Dependency extensions
|
|
49
|
+
attr_reader :dependencies
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Creates a new Extension with the specified _name_. If a
|
|
53
|
+
# _block_ is given, it will be passed the newly created
|
|
54
|
+
# Extension.
|
|
55
|
+
#
|
|
56
|
+
# Extension.new('exploits')
|
|
57
|
+
#
|
|
58
|
+
# Extension.new('awesome') do |ext|
|
|
59
|
+
# ...
|
|
60
|
+
# end
|
|
61
|
+
#
|
|
62
|
+
def initialize(name,&block)
|
|
63
|
+
@name = name.to_s
|
|
64
|
+
@paths = []
|
|
65
|
+
@dependencies = {}
|
|
66
|
+
|
|
67
|
+
@setup = false
|
|
68
|
+
@toredown = true
|
|
69
|
+
|
|
70
|
+
@setup_blocks = []
|
|
71
|
+
@action_blocks = {}
|
|
72
|
+
@teardown_blocks = []
|
|
73
|
+
|
|
74
|
+
block.call(self) if block
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Returns the names of all extensions within the overlay cache.
|
|
79
|
+
#
|
|
80
|
+
def Extension.names
|
|
81
|
+
Overlay.cache.overlays.map { |overlay| overlay.extensions }.flatten.uniq
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Returns +true+ if an extension exists with the specified _name_,
|
|
86
|
+
# returns +false+ otherwise.
|
|
87
|
+
#
|
|
88
|
+
def Extension.exists?(name)
|
|
89
|
+
Extension.names.include?(name.to_s)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
#
|
|
93
|
+
# Iterates through the extension names passing each to the specified
|
|
94
|
+
# _block_.
|
|
95
|
+
#
|
|
96
|
+
# Extension.each_name do |name|
|
|
97
|
+
# puts name
|
|
98
|
+
# end
|
|
99
|
+
#
|
|
100
|
+
def Extension.each_name(&block)
|
|
101
|
+
Extension.names.each(&block)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
#
|
|
105
|
+
# Returns the paths of all extensions.
|
|
106
|
+
#
|
|
107
|
+
def Extension.paths
|
|
108
|
+
paths = []
|
|
109
|
+
|
|
110
|
+
Overlay.each { |repo| paths += repo.extension_paths }
|
|
111
|
+
|
|
112
|
+
return paths
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# Iterates over the paths of all extensions with the specified
|
|
117
|
+
# _name_, passing each to the specified _block_.
|
|
118
|
+
#
|
|
119
|
+
def Extension.each_path(&block)
|
|
120
|
+
Extension.paths.each(&block)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
#
|
|
124
|
+
# Returns the paths of all extensions with the specified _name_.
|
|
125
|
+
#
|
|
126
|
+
def Extension.paths_for(name)
|
|
127
|
+
Overlay.with_extension(name).map do |repo|
|
|
128
|
+
File.expand_path(File.join(repo.path,name))
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
#
|
|
133
|
+
# Iterates over the paths of all extensions with the specified
|
|
134
|
+
# _name_, passing each to the specified _block_.
|
|
135
|
+
#
|
|
136
|
+
def Extension.each_path_for(name,&block)
|
|
137
|
+
Extension.paths_for(name).each(&block)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
#
|
|
141
|
+
# Adds the lib/ directory from within the specified _path_ to
|
|
142
|
+
# $LOAD_PATH, only if the lib/ directory exists within the
|
|
143
|
+
# specified _path_ and the directory has not already been
|
|
144
|
+
# added to $LOAD_PATH. If a _block_ is given, it will be called
|
|
145
|
+
# after $LOAD_PATH may or maynot have been modified.
|
|
146
|
+
#
|
|
147
|
+
def Extension.load_path(path,&block)
|
|
148
|
+
lib_dir = File.expand_path(File.join(path,LIB_DIR))
|
|
149
|
+
|
|
150
|
+
if File.directory?(lib_dir)
|
|
151
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
block.call if block
|
|
155
|
+
return nil
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
#
|
|
159
|
+
# Similar to load_path, but adds the lib/ directories from the
|
|
160
|
+
# paths of all extensions with the specified _name_ to $LOAD_PATH.
|
|
161
|
+
# If a _block_ is given, it will be called after $LOAD_PATH may or
|
|
162
|
+
# maynot have been modified.
|
|
163
|
+
#
|
|
164
|
+
def Extension.load_paths(name,&block)
|
|
165
|
+
Extension.each_path_for(name) do |path|
|
|
166
|
+
Extension.load_path(path)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
block.call if block
|
|
170
|
+
return nil
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
#
|
|
174
|
+
# Loads an extension at the specified _path_ into a newly created
|
|
175
|
+
# Extension object. If a _block_ is given, it will be passed the
|
|
176
|
+
# newly created Extension object.
|
|
177
|
+
#
|
|
178
|
+
def Extension.load_from(path,&block)
|
|
179
|
+
Extension.new(File.basename(name)) do |ext|
|
|
180
|
+
ext.include_path(path,&block)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
#
|
|
185
|
+
# Loads an extension at the specified _path_ into a newly created
|
|
186
|
+
# Extension object and then runs it with the specified _block_.
|
|
187
|
+
#
|
|
188
|
+
# Extension.run_from('lab/exploits') do |ext|
|
|
189
|
+
# puts ext.search('apache')
|
|
190
|
+
# end
|
|
191
|
+
#
|
|
192
|
+
def Extension.run_from(path,&block)
|
|
193
|
+
Extension.load_from(path) do |ext|
|
|
194
|
+
ext.run(&block)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
#
|
|
199
|
+
# Loads all extensions with the specified _name_ into a newly created
|
|
200
|
+
# Extension object. If a _block_ is given, it will be passed the
|
|
201
|
+
# newly created Extension object.
|
|
202
|
+
#
|
|
203
|
+
# Extension.load('shellcode') do |ext|
|
|
204
|
+
# puts ext.search('moon_lander')
|
|
205
|
+
# end
|
|
206
|
+
#
|
|
207
|
+
def Extension.load(name,&block)
|
|
208
|
+
Extension.new(name) do |ext|
|
|
209
|
+
ext.include(name,&block)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
#
|
|
214
|
+
# Loads all extensions with the specified _name_ into a newly created
|
|
215
|
+
# Extension object and then runs it with the specified _block_.
|
|
216
|
+
#
|
|
217
|
+
# Extension.run('exploits') do |ext|
|
|
218
|
+
# puts ext.search(:product => 'Apache')
|
|
219
|
+
# end
|
|
220
|
+
#
|
|
221
|
+
def Extension.run(name,&block)
|
|
222
|
+
Extension.load(name) do |ext|
|
|
223
|
+
ext.run(&block)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
#
|
|
228
|
+
# Returns the current ExtensionCache.
|
|
229
|
+
#
|
|
230
|
+
def Extension.cache
|
|
231
|
+
@@cache ||= ExtensionCache.new
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
#
|
|
235
|
+
# Returns the extension with the specified _name_ from the extension
|
|
236
|
+
# cache. If no extension exists with the specified _name_ an
|
|
237
|
+
# ExtensionNotFound exception will be raised.
|
|
238
|
+
#
|
|
239
|
+
def Extension.[](name)
|
|
240
|
+
Extension.cache[name]
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
#
|
|
244
|
+
# Returns +true+ if the extension with the specified _name_ has been
|
|
245
|
+
# loaded into the extension cache, returns +false+ otherwise.
|
|
246
|
+
#
|
|
247
|
+
def Extension.loaded?(name)
|
|
248
|
+
Extension.cache.has_extension?(name)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
#
|
|
252
|
+
# Includes all extensions of the specified _name_ into the extension.
|
|
253
|
+
# If a _block_ is given, it will be passed the newly created
|
|
254
|
+
# extension after the extensions of _name_ have been included.
|
|
255
|
+
#
|
|
256
|
+
def include(name,&block)
|
|
257
|
+
Extension.load_paths(name) do
|
|
258
|
+
Extension.each_path_for(name) do |path|
|
|
259
|
+
include_path(path)
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
block.call(self) if block
|
|
264
|
+
return self
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
#
|
|
268
|
+
# Includes the extension at the specified _path_ into the extension.
|
|
269
|
+
# If a _block_ is given, it will be passed the newly created
|
|
270
|
+
# extension.
|
|
271
|
+
#
|
|
272
|
+
def include_path(path,&block)
|
|
273
|
+
path = File.expand_path(path)
|
|
274
|
+
|
|
275
|
+
unless File.directory?(path)
|
|
276
|
+
raise(ExtensionNotFound,"extension #{path.dump} is not a valid extension",caller)
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# add to the search paths
|
|
280
|
+
@paths << path
|
|
281
|
+
|
|
282
|
+
Extension.load_path(path) do
|
|
283
|
+
extension_file = File.join(path,EXTENSION_FILE)
|
|
284
|
+
|
|
285
|
+
if File.file?(extension_file)
|
|
286
|
+
# instance_eval the extension block
|
|
287
|
+
context_block = Extension.load_context_block(extension_file)
|
|
288
|
+
|
|
289
|
+
instance_eval(&context_block) if context_block
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
block.call(self) if block
|
|
294
|
+
return self
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
#
|
|
298
|
+
# Loads all similar extensions with the specified _name_ into a
|
|
299
|
+
# newly created Extension object and adds it to the extensions
|
|
300
|
+
# dependencies.
|
|
301
|
+
#
|
|
302
|
+
# depend 'shellcode'
|
|
303
|
+
#
|
|
304
|
+
def depend(name)
|
|
305
|
+
name = name.to_s
|
|
306
|
+
|
|
307
|
+
unless Extension.exists?(name)
|
|
308
|
+
raise(ExtensionNotFound,"extension #{name.dump} is not in the overlay cache",caller)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
@dependencies[name] ||= Extension.load(name)
|
|
312
|
+
return self
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
#
|
|
316
|
+
# Returns +true+ if the extension has the dependency of the specified
|
|
317
|
+
# _name_, returns +false+ otherwise.
|
|
318
|
+
#
|
|
319
|
+
def depends_on?(name)
|
|
320
|
+
@dependencies.has_key?(name.to_s)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
#
|
|
324
|
+
# Passes all the extension's dependencies and the extension itself to
|
|
325
|
+
# the specified _block_ using the given _options_.
|
|
326
|
+
#
|
|
327
|
+
# _options_ may include the following keys:
|
|
328
|
+
# <tt>:top_down</tt>:: Indicates that distribute will recurse through
|
|
329
|
+
# the extensions and their elements in a
|
|
330
|
+
# top-down manner. This is distributes default
|
|
331
|
+
# behavior.
|
|
332
|
+
# <tt>:bottom_up</tt>:: Indictates that distribute will recurse
|
|
333
|
+
# through the extensions and their dependencies
|
|
334
|
+
# in a bottom-up manner. Mutually exclusive with
|
|
335
|
+
# the <tt>:top_down</tt> option.
|
|
336
|
+
#
|
|
337
|
+
def distribute(options={},&block)
|
|
338
|
+
distribute_deps = lambda {
|
|
339
|
+
@dependencies.map { |ext|
|
|
340
|
+
ext.distribute(options,&block)
|
|
341
|
+
}.flatten
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if options[:bottom_up]
|
|
345
|
+
return distribute_deps.call + [block.call(self)]
|
|
346
|
+
else
|
|
347
|
+
return [block.call(self)] + distribute_deps.call
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
#
|
|
352
|
+
# Returns +true+ if the app context has a public instance method
|
|
353
|
+
# of the matching _name_, returns +false+ otherwise.
|
|
354
|
+
#
|
|
355
|
+
# ext.has_method?(:console) # => true
|
|
356
|
+
#
|
|
357
|
+
def has_method?(name)
|
|
358
|
+
public_methods.include?(name.to_s)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
#
|
|
362
|
+
# Returns an +Array+ of extensions that have the specified _method_.
|
|
363
|
+
# If a _block_ is given, it will be passed each extension with the
|
|
364
|
+
# specified _method_.
|
|
365
|
+
#
|
|
366
|
+
# ext.extensions_with_method(:console) # => [...]
|
|
367
|
+
#
|
|
368
|
+
# ext.extensions_with_method(:console) do |ext|
|
|
369
|
+
# ext.console(ARGV)
|
|
370
|
+
# end
|
|
371
|
+
#
|
|
372
|
+
def extensions_with_method(method,&block)
|
|
373
|
+
extensions = distribute { |ext|
|
|
374
|
+
ext if ext.has_method?(method)
|
|
375
|
+
}.compact
|
|
376
|
+
|
|
377
|
+
extensions.each(&block) if block
|
|
378
|
+
return extensions
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
#
|
|
382
|
+
# Calls the setup blocks of the extension's dependencies and the
|
|
383
|
+
# extension itself. If a _block_ is given, it will be passed the
|
|
384
|
+
# extension after it has been setup.
|
|
385
|
+
#
|
|
386
|
+
# ext.perform_setup # => Extension
|
|
387
|
+
#
|
|
388
|
+
# ext.perform_setup do |ext|
|
|
389
|
+
# puts "Extension #{ext} has been setup..."
|
|
390
|
+
# end
|
|
391
|
+
#
|
|
392
|
+
def perform_setup(&block)
|
|
393
|
+
unless @setup
|
|
394
|
+
distribute(:bottom_up => true) do |ext|
|
|
395
|
+
ext.instance_eval do
|
|
396
|
+
@setup_blocks.each do |setup_block|
|
|
397
|
+
setup_block.call(self) if setup_block
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
@setup = true
|
|
403
|
+
@toredown = false
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
block.call(self) if block
|
|
407
|
+
return self
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
#
|
|
411
|
+
# Returns +true+ if the extension has been setup, returns +false+
|
|
412
|
+
# otherwise.
|
|
413
|
+
#
|
|
414
|
+
def was_setup?
|
|
415
|
+
@setup == true
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
#
|
|
419
|
+
# Run the teardown blocks of the extension and it's dependencies.
|
|
420
|
+
# If a _block_ is given, it will be passed the extension before it
|
|
421
|
+
# has been tore down.
|
|
422
|
+
#
|
|
423
|
+
# ext.perform_teardown # => Extension
|
|
424
|
+
#
|
|
425
|
+
# ext.perform_teardown do |ext|
|
|
426
|
+
# puts "Extension #{ext} is being tore down..."
|
|
427
|
+
# end
|
|
428
|
+
#
|
|
429
|
+
def perform_teardown(&block)
|
|
430
|
+
block.call(self) if block
|
|
431
|
+
|
|
432
|
+
unless @toredown
|
|
433
|
+
distribute(:top_down => true) do |ext|
|
|
434
|
+
ext.instance_eval do
|
|
435
|
+
@teardown_blocks.each do |teardown_block|
|
|
436
|
+
teardown_block.call(self) if teardown_block
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
@toredown = true
|
|
442
|
+
@setup = false
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
return self
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
#
|
|
449
|
+
# Returns +true+ if the extension has been toredown, returns +false+
|
|
450
|
+
# otherwise.
|
|
451
|
+
#
|
|
452
|
+
def was_toredown?
|
|
453
|
+
@toredown == true
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
#
|
|
457
|
+
# Sets up the extension, passes the extension to the specified
|
|
458
|
+
# _block_ and then tears down the extension.
|
|
459
|
+
#
|
|
460
|
+
# ext.run do |ext|
|
|
461
|
+
# ext.console(ARGV)
|
|
462
|
+
# end
|
|
463
|
+
#
|
|
464
|
+
def run(&block)
|
|
465
|
+
perform_setup
|
|
466
|
+
|
|
467
|
+
block.call(self) if block
|
|
468
|
+
|
|
469
|
+
perform_teardown
|
|
470
|
+
return self
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
#
|
|
474
|
+
# Returns an +Array+ of the names of all actions defined in the
|
|
475
|
+
# extension.
|
|
476
|
+
#
|
|
477
|
+
# ext.actions # => [...]
|
|
478
|
+
#
|
|
479
|
+
def actions
|
|
480
|
+
@action_blocks.keys
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
#
|
|
484
|
+
# Returns +true+ if the extension has the action of the specified
|
|
485
|
+
# _name_, returns +false+ otherwise.
|
|
486
|
+
#
|
|
487
|
+
def has_action?(name)
|
|
488
|
+
@action_blocks.has_key?(name.to_sym)
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
#
|
|
492
|
+
# Runs the action of the specified _name_ with the given _args_.
|
|
493
|
+
# If no action of the specified name exists, then an UnknownAction
|
|
494
|
+
# exception will be raised.
|
|
495
|
+
#
|
|
496
|
+
def perform_action(name,*args)
|
|
497
|
+
name = name.to_s
|
|
498
|
+
|
|
499
|
+
unless has_action?(name)
|
|
500
|
+
raise(UnknownAction,"action #{name.dump} is not defined",caller)
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
return run do
|
|
504
|
+
@action_blocks[name.to_sym].call(*args)
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
#
|
|
509
|
+
# Find the specified _path_ from within all similar extensions.
|
|
510
|
+
# If a _block_ is given, it will be passed the full path if found.
|
|
511
|
+
#
|
|
512
|
+
# ext.find_path('data/test')
|
|
513
|
+
#
|
|
514
|
+
# ext.find_path('data/test') do |path|
|
|
515
|
+
# puts Dir[File.join(path,'*')]
|
|
516
|
+
# end
|
|
517
|
+
#
|
|
518
|
+
def find_path(path,&block)
|
|
519
|
+
@paths.each do |ext_path|
|
|
520
|
+
full_path = File.expand_path(File.join(ext_path,path))
|
|
521
|
+
|
|
522
|
+
if File.exists?(full_path)
|
|
523
|
+
block.call(full_path) if block
|
|
524
|
+
return full_path
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
return nil
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
#
|
|
532
|
+
# Find the specified file _path_ from within all similar extensions.
|
|
533
|
+
# If a _block_ is given, it will be passed the full file path if
|
|
534
|
+
# found.
|
|
535
|
+
#
|
|
536
|
+
# ext.find_file('data/test/file.xml')
|
|
537
|
+
#
|
|
538
|
+
# ext.find_file('data/test/file.xml') do |file|
|
|
539
|
+
# REXML::Document.new(open(file))
|
|
540
|
+
# ...
|
|
541
|
+
# end
|
|
542
|
+
#
|
|
543
|
+
def find_file(path,&block)
|
|
544
|
+
find_path(path) do |full_path|
|
|
545
|
+
if File.file?(full_path)
|
|
546
|
+
block.call(full_path) if block
|
|
547
|
+
return full_path
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
#
|
|
553
|
+
# Find the specified directory _path_ from within all similar
|
|
554
|
+
# extensions. If a _block_ is given, it will be passed the full
|
|
555
|
+
# directory path if found.
|
|
556
|
+
#
|
|
557
|
+
# ext.find_directory('data/test')
|
|
558
|
+
#
|
|
559
|
+
# ext.find_directory('data/test') do |dir|
|
|
560
|
+
# puts Dir[File.join(dir,'*')]
|
|
561
|
+
# end
|
|
562
|
+
#
|
|
563
|
+
def find_dir(path,&block)
|
|
564
|
+
find_path(path) do |full_path|
|
|
565
|
+
if File.directory?(full_path)
|
|
566
|
+
block.call(full_path) if block
|
|
567
|
+
return full_path
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
#
|
|
573
|
+
# Find the paths that match the given pattern from within all similar
|
|
574
|
+
# extensions. If a _block_ is given, it will be passed each matching
|
|
575
|
+
# full path.
|
|
576
|
+
#
|
|
577
|
+
# ext.glob_paths('data/*') # => [...]
|
|
578
|
+
#
|
|
579
|
+
# ext.glob_paths('data/*') do |path|
|
|
580
|
+
# puts path
|
|
581
|
+
# end
|
|
582
|
+
#
|
|
583
|
+
def glob_paths(pattern,&block)
|
|
584
|
+
full_paths = @paths.inject([]) do |paths,ext_path|
|
|
585
|
+
paths + Dir[File.join(ext_path,pattern)]
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
full_paths.each(&block) if block
|
|
589
|
+
return full_paths
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
#
|
|
593
|
+
# Find the file paths that match the given pattern from within all
|
|
594
|
+
# similar extensions. If a _block_ is given, it will be passed each
|
|
595
|
+
# matching full file path.
|
|
596
|
+
#
|
|
597
|
+
# ext.glob_files('data/*.xml') # => [...]
|
|
598
|
+
#
|
|
599
|
+
# ext.glob_files('data/*.xml') do |file|
|
|
600
|
+
# puts file
|
|
601
|
+
# end
|
|
602
|
+
#
|
|
603
|
+
def glob_files(pattern,&block)
|
|
604
|
+
full_paths = glob_paths(pattern).select do |path|
|
|
605
|
+
File.file?(path)
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
full_paths.each(&block) if block
|
|
609
|
+
return full_paths
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
#
|
|
613
|
+
# Find the directory paths that match the given pattern from within
|
|
614
|
+
# all similar extensions. If a _block_ is given, it will be passed
|
|
615
|
+
# each matching full directory path.
|
|
616
|
+
#
|
|
617
|
+
# ext.glob_dirs('builds/*') # => [...]
|
|
618
|
+
#
|
|
619
|
+
# ext.glob_dirs('builds/*') do |dir|
|
|
620
|
+
# puts dir
|
|
621
|
+
# end
|
|
622
|
+
#
|
|
623
|
+
def glob_dirs(pattern,&block)
|
|
624
|
+
full_paths = glob_paths(pattern).select do |path|
|
|
625
|
+
File.directory?(path)
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
full_paths.each(&block) if block
|
|
629
|
+
return full_paths
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
#
|
|
633
|
+
# Returns the name of the app context in string form.
|
|
634
|
+
#
|
|
635
|
+
def to_s
|
|
636
|
+
@name.to_s
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
protected
|
|
640
|
+
|
|
641
|
+
#
|
|
642
|
+
# Adds the specified _block_ to the list of blocks to run in order
|
|
643
|
+
# to properly setup the extension.
|
|
644
|
+
#
|
|
645
|
+
def setup(&block)
|
|
646
|
+
@setup_blocks << block if block
|
|
647
|
+
return self
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
#
|
|
651
|
+
# Defines a new action with the specified _name_ and the given
|
|
652
|
+
# _block_. If an action of the same _name_ has already been defined
|
|
653
|
+
# then an ActionRedefined exception will be raised.
|
|
654
|
+
#
|
|
655
|
+
def action(name,&block)
|
|
656
|
+
name = name.to_s
|
|
657
|
+
|
|
658
|
+
if has_action?(name)
|
|
659
|
+
raise(ActionRedefined,"action #{name.dump} previously defined",caller)
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
@action_blocks[name.to_sym] = block
|
|
663
|
+
return self
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
#
|
|
667
|
+
# Adds the specified _block_ to the list of blocks to run in order
|
|
668
|
+
# to properly tear-down the extension.
|
|
669
|
+
#
|
|
670
|
+
def teardown(&block)
|
|
671
|
+
@teardown_blocks << block if block
|
|
672
|
+
return self
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
#
|
|
676
|
+
# Provides transparent access to the performing of actions
|
|
677
|
+
# and extensions dependencies.
|
|
678
|
+
#
|
|
679
|
+
# ext.scan('localhost') # => Extension
|
|
680
|
+
#
|
|
681
|
+
# ext.shellcode # => Extension
|
|
682
|
+
#
|
|
683
|
+
# ext.shellcode do |dep|
|
|
684
|
+
# puts "#{ext} has the dependency #{dep}"
|
|
685
|
+
# end
|
|
686
|
+
#
|
|
687
|
+
def method_missing(sym,*args,&block)
|
|
688
|
+
if (args.length==0)
|
|
689
|
+
name = sym.to_s
|
|
690
|
+
|
|
691
|
+
if (has_action?(name) && block.nil?)
|
|
692
|
+
return perform_action(name,*args)
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
if depends_on?(name)
|
|
696
|
+
block.call(@dependencies[name]) if block
|
|
697
|
+
return @dependencies[name]
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
return super(sym,*args,&block)
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
end
|