ronin-support 0.3.0 → 0.4.0.rc1
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/ChangeLog.md +77 -7
- data/README.md +19 -3
- data/gemspec.yml +2 -2
- data/lib/ronin/extensions/regexp.rb +50 -2
- data/lib/ronin/extensions/string.rb +1 -0
- data/lib/ronin/formatting.rb +1 -0
- data/lib/ronin/formatting/extensions.rb +1 -0
- data/lib/ronin/formatting/extensions/binary/string.rb +56 -5
- data/lib/ronin/formatting/extensions/html/string.rb +6 -7
- data/lib/ronin/formatting/extensions/sql/string.rb +34 -0
- data/lib/ronin/formatting/extensions/text/string.rb +0 -180
- data/lib/ronin/fuzzing.rb +21 -0
- data/lib/ronin/fuzzing/extensions.rb +20 -0
- data/lib/ronin/fuzzing/extensions/string.rb +380 -0
- data/lib/ronin/fuzzing/fuzzing.rb +191 -0
- data/lib/ronin/network/esmtp.rb +94 -1
- data/lib/ronin/network/extensions/esmtp/net.rb +2 -82
- data/lib/ronin/network/extensions/http/net.rb +1 -736
- data/lib/ronin/network/extensions/imap/net.rb +1 -103
- data/lib/ronin/network/extensions/pop3/net.rb +1 -71
- data/lib/ronin/network/extensions/smtp/net.rb +2 -157
- data/lib/ronin/network/extensions/ssl/net.rb +1 -132
- data/lib/ronin/network/extensions/tcp/net.rb +2 -296
- data/lib/ronin/network/extensions/telnet/net.rb +1 -135
- data/lib/ronin/network/extensions/udp/net.rb +2 -214
- data/lib/ronin/network/http/http.rb +750 -5
- data/lib/ronin/network/imap.rb +105 -2
- data/lib/ronin/network/mixins.rb +1 -1
- data/lib/ronin/network/mixins/esmtp.rb +49 -52
- data/lib/ronin/network/mixins/http.rb +49 -53
- data/lib/ronin/network/mixins/imap.rb +47 -44
- data/lib/ronin/network/mixins/mixin.rb +58 -0
- data/lib/ronin/network/mixins/pop3.rb +44 -38
- data/lib/ronin/network/mixins/smtp.rb +49 -51
- data/lib/ronin/network/mixins/tcp.rb +56 -69
- data/lib/ronin/network/mixins/telnet.rb +57 -50
- data/lib/ronin/network/mixins/udp.rb +48 -52
- data/lib/ronin/network/network.rb +1 -0
- data/lib/ronin/network/pop3.rb +72 -2
- data/lib/ronin/network/smtp/email.rb +1 -0
- data/lib/ronin/network/smtp/smtp.rb +159 -3
- data/lib/ronin/network/ssl.rb +131 -2
- data/lib/ronin/network/tcp.rb +306 -1
- data/lib/ronin/network/telnet.rb +136 -2
- data/lib/ronin/network/udp.rb +229 -1
- data/lib/ronin/support.rb +2 -3
- data/lib/ronin/support/support.rb +38 -0
- data/lib/ronin/support/version.rb +1 -1
- data/lib/ronin/templates/erb.rb +2 -1
- data/lib/ronin/ui/output/helpers.rb +35 -1
- data/lib/ronin/ui/shell.rb +12 -2
- data/lib/ronin/wordlist.rb +157 -0
- data/spec/extensions/regexp_spec.rb +38 -0
- data/spec/formatting/html/string_spec.rb +1 -1
- data/spec/formatting/sql/string_spec.rb +23 -3
- data/spec/formatting/text/string_spec.rb +0 -110
- data/spec/fuzzing/string_spec.rb +158 -0
- data/spec/wordlist_spec.rb +65 -0
- metadata +35 -27
data/lib/ronin/network/imap.rb
CHANGED
@@ -17,12 +17,14 @@
|
|
17
17
|
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
19
|
|
20
|
-
require 'ronin/network/
|
20
|
+
require 'ronin/network/ssl'
|
21
|
+
|
22
|
+
require 'net/imap'
|
21
23
|
|
22
24
|
module Ronin
|
23
25
|
module Network
|
24
26
|
#
|
25
|
-
#
|
27
|
+
# Provides helper methods for communicating with IMAP services.
|
26
28
|
#
|
27
29
|
module IMAP
|
28
30
|
# Default IMAP port
|
@@ -49,6 +51,107 @@ module Ronin
|
|
49
51
|
def IMAP.default_port=(port)
|
50
52
|
@default_port = port
|
51
53
|
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Creates a connection to the IMAP server.
|
57
|
+
#
|
58
|
+
# @param [String] host
|
59
|
+
# The host to connect to.
|
60
|
+
#
|
61
|
+
# @param [Hash] options
|
62
|
+
# Additional options.
|
63
|
+
#
|
64
|
+
# @option options [Integer] :port (IMAP.default_port)
|
65
|
+
# The port the IMAP server is running on.
|
66
|
+
#
|
67
|
+
# @option options [String] :certs
|
68
|
+
# The path to the file containing CA certs of the server.
|
69
|
+
#
|
70
|
+
# @option options [Symbol] :auth
|
71
|
+
# The type of authentication to perform when connecting to the server.
|
72
|
+
# May be either `:login` or `:cram_md5`.
|
73
|
+
#
|
74
|
+
# @option options [String] :user
|
75
|
+
# The user to authenticate as when connecting to the server.
|
76
|
+
#
|
77
|
+
# @option options [String] :password
|
78
|
+
# The password to authenticate with when connecting to the server.
|
79
|
+
#
|
80
|
+
# @yield [session]
|
81
|
+
# If a block is given, it will be passed the newly created IMAP
|
82
|
+
# session.
|
83
|
+
#
|
84
|
+
# @yieldparam [Net::IMAP] session
|
85
|
+
# The newly created IMAP session object.
|
86
|
+
#
|
87
|
+
# @return [Net::IMAP]
|
88
|
+
# The newly created IMAP session object.
|
89
|
+
#
|
90
|
+
# @api public
|
91
|
+
#
|
92
|
+
def imap_connect(host,options={})
|
93
|
+
host = host.to_s
|
94
|
+
port = (options[:port] || IMAP.default_port)
|
95
|
+
certs = options[:certs]
|
96
|
+
auth = options[:auth]
|
97
|
+
user = options[:user]
|
98
|
+
passwd = options[:password]
|
99
|
+
|
100
|
+
if options[:ssl]
|
101
|
+
ssl = true
|
102
|
+
ssl_certs = options[:ssl][:certs]
|
103
|
+
ssl_verify = SSL::VERIFY[options[:ssl][:verify]]
|
104
|
+
else
|
105
|
+
ssl = false
|
106
|
+
ssl_verify = false
|
107
|
+
end
|
108
|
+
|
109
|
+
session = Net::IMAP.new(host,port,ssl,ssl_certs,ssl_verify)
|
110
|
+
|
111
|
+
if user
|
112
|
+
if auth == :cram_md5
|
113
|
+
session.authenticate('CRAM-MD5',user,passwd)
|
114
|
+
else
|
115
|
+
session.authenticate('LOGIN',user,passwd)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
yield session if block_given?
|
120
|
+
return session
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Starts an IMAP session with the IMAP server.
|
125
|
+
#
|
126
|
+
# @param [String] host
|
127
|
+
# The host to connect to.
|
128
|
+
#
|
129
|
+
# @param [Hash] options
|
130
|
+
# Additional options.
|
131
|
+
#
|
132
|
+
# @yield [session]
|
133
|
+
# If a block is given, it will be passed the newly created IMAP
|
134
|
+
# session. After the block has returned, the session will be closed.
|
135
|
+
#
|
136
|
+
# @yieldparam [Net::IMAP] session
|
137
|
+
# The newly created IMAP session object.
|
138
|
+
#
|
139
|
+
# @return [nil]
|
140
|
+
#
|
141
|
+
# @see imap_connect
|
142
|
+
#
|
143
|
+
# @api public
|
144
|
+
#
|
145
|
+
def imap_session(host,options={})
|
146
|
+
session = imap_connect(host,options)
|
147
|
+
|
148
|
+
yield session if block_given?
|
149
|
+
|
150
|
+
session.logout if options[:user]
|
151
|
+
session.close
|
152
|
+
session.disconnect
|
153
|
+
return nil
|
154
|
+
end
|
52
155
|
end
|
53
156
|
end
|
54
157
|
end
|
data/lib/ronin/network/mixins.rb
CHANGED
@@ -17,11 +17,8 @@
|
|
17
17
|
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
19
|
|
20
|
+
require 'ronin/network/mixins/mixin'
|
20
21
|
require 'ronin/network/esmtp'
|
21
|
-
require 'ronin/ui/output/helpers'
|
22
|
-
require 'ronin/mixin'
|
23
|
-
|
24
|
-
require 'parameters'
|
25
22
|
|
26
23
|
module Ronin
|
27
24
|
module Network
|
@@ -38,43 +35,30 @@ module Ronin
|
|
38
35
|
# * `esmtp_password` (`String`) - ESMTP password to login with.
|
39
36
|
#
|
40
37
|
module ESMTP
|
41
|
-
include Mixin
|
42
|
-
|
43
|
-
mixin UI::Output::Helpers, Parameters
|
38
|
+
include Mixin, Network::ESMTP
|
44
39
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
:description => 'ESMTP host'
|
40
|
+
# ESMTP host
|
41
|
+
parameter :host, :type => String,
|
42
|
+
:description => 'ESMTP host'
|
49
43
|
|
50
|
-
|
51
|
-
|
52
|
-
|
44
|
+
# ESMTP port
|
45
|
+
parameter :port, :type => Integer,
|
46
|
+
:description => 'ESMTP port'
|
53
47
|
|
54
|
-
|
55
|
-
|
56
|
-
|
48
|
+
# ESMTP authentication method to use
|
49
|
+
parameter :esmtp_login, :type => String,
|
50
|
+
:description => 'ESMTP authentication method to use'
|
57
51
|
|
58
|
-
|
59
|
-
|
60
|
-
|
52
|
+
# ESMTP user to login as
|
53
|
+
parameter :esmtp_user, :type => String,
|
54
|
+
:description => 'ESMTP user to login as'
|
61
55
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
56
|
+
# ESMTP password to login with
|
57
|
+
parameter :esmtp_password, :type => String,
|
58
|
+
:description => 'ESMTP password to login with'
|
66
59
|
|
67
60
|
protected
|
68
61
|
|
69
|
-
#
|
70
|
-
# @see Ronin::Network::SMTP.message.
|
71
|
-
#
|
72
|
-
# @api public
|
73
|
-
#
|
74
|
-
def esmtp_message(options={},&block)
|
75
|
-
Network::SMTP.message(options,&block)
|
76
|
-
end
|
77
|
-
|
78
62
|
#
|
79
63
|
# Creates a connection to the ESMTP server. The `host`, `port`,
|
80
64
|
# `esmtp_login`, `esmtp_user` and `esmtp_password` parameters
|
@@ -112,18 +96,9 @@ module Ronin
|
|
112
96
|
# @api public
|
113
97
|
#
|
114
98
|
def esmtp_connect(options={},&block)
|
115
|
-
|
116
|
-
options[:login] ||= self.esmtp_login
|
117
|
-
options[:user] ||= self.esmtp_user
|
118
|
-
options[:password] ||= self.esmtp_password
|
99
|
+
print_info "Connecting to #{host_port} ..."
|
119
100
|
|
120
|
-
|
121
|
-
print_info "Connecting to #{self.host}:#{self.port} ..."
|
122
|
-
else
|
123
|
-
print_info "Connecting to #{self.host} ..."
|
124
|
-
end
|
125
|
-
|
126
|
-
return ::Net.esmtp_connect(self.host,options,&block)
|
101
|
+
return super(self.host,esmtp_merge_options(options),&block)
|
127
102
|
end
|
128
103
|
|
129
104
|
#
|
@@ -147,17 +122,39 @@ module Ronin
|
|
147
122
|
# @api public
|
148
123
|
#
|
149
124
|
def esmtp_session(options={})
|
150
|
-
|
125
|
+
super(esmtp_merge_options(options)) do |sess|
|
151
126
|
yield sess if block_given?
|
152
127
|
|
153
|
-
|
154
|
-
|
155
|
-
if self.port
|
156
|
-
print_info "Disconnecting from #{self.host}:#{self.port}"
|
157
|
-
else
|
158
|
-
print_info "Disconnecting from #{self.host}"
|
159
|
-
end
|
128
|
+
print_info "Logging out ..."
|
160
129
|
end
|
130
|
+
|
131
|
+
print_info "Disconnected from #{host_port}"
|
132
|
+
return nil
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
#
|
138
|
+
# Merges the ESMTP parameters into the options for {Network::ESMTP}
|
139
|
+
# methods.
|
140
|
+
#
|
141
|
+
# @param [Hash] options
|
142
|
+
# The original options.
|
143
|
+
#
|
144
|
+
# @return [Hash]
|
145
|
+
# The merged options.
|
146
|
+
#
|
147
|
+
# @since 0.4.0
|
148
|
+
#
|
149
|
+
# @api private
|
150
|
+
#
|
151
|
+
def esmtp_merge_options(options={})
|
152
|
+
options[:port] ||= self.port
|
153
|
+
options[:login] ||= self.esmtp_login
|
154
|
+
options[:user] ||= self.esmtp_user
|
155
|
+
options[:password] ||= self.esmtp_password
|
156
|
+
|
157
|
+
return options
|
161
158
|
end
|
162
159
|
end
|
163
160
|
end
|
@@ -17,11 +17,8 @@
|
|
17
17
|
# along with Ronin Support. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
19
|
|
20
|
+
require 'ronin/network/mixins/mixin'
|
20
21
|
require 'ronin/network/http'
|
21
|
-
require 'ronin/ui/output/helpers'
|
22
|
-
require 'ronin/mixin'
|
23
|
-
|
24
|
-
require 'parameters'
|
25
22
|
|
26
23
|
module Ronin
|
27
24
|
module Network
|
@@ -40,38 +37,34 @@ module Ronin
|
|
40
37
|
# * `http_user_agent` (`String`) - HTTP User-Agent header to send.
|
41
38
|
#
|
42
39
|
module HTTP
|
43
|
-
include Mixin
|
44
|
-
|
45
|
-
mixin UI::Output::Helpers, Parameters
|
40
|
+
include Mixin, Network::HTTP
|
46
41
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
:description => 'HTTP host'
|
42
|
+
# HTTP host
|
43
|
+
parameter :host, :type => String,
|
44
|
+
:description => 'HTTP host'
|
51
45
|
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
# HTTP port
|
47
|
+
parameter :port, :default => Net::HTTP.default_port,
|
48
|
+
:description => 'HTTP port'
|
55
49
|
|
56
|
-
|
57
|
-
|
58
|
-
|
50
|
+
# HTTP `Host` header to send
|
51
|
+
parameter :http_vhost, :type => String,
|
52
|
+
:description => 'HTTP Host header to send'
|
59
53
|
|
60
|
-
|
61
|
-
|
62
|
-
|
54
|
+
# HTTP user to authenticate as
|
55
|
+
parameter :http_user, :type => String,
|
56
|
+
:description => 'HTTP user to authenticate as'
|
63
57
|
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
# HTTP password to authenticate with
|
59
|
+
parameter :http_password, :type => String,
|
60
|
+
:description => 'HTTP password to authenticate with'
|
67
61
|
|
68
|
-
|
69
|
-
|
62
|
+
# HTTP proxy information
|
63
|
+
parameter :http_proxy, :description => 'HTTP proxy information'
|
70
64
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
65
|
+
# HTTP `User-Agent` header to send
|
66
|
+
parameter :http_user_agent, :type => String,
|
67
|
+
:description => 'HTTP User-Agent header to send'
|
75
68
|
|
76
69
|
protected
|
77
70
|
|
@@ -122,14 +115,17 @@ module Ronin
|
|
122
115
|
#
|
123
116
|
# @api public
|
124
117
|
#
|
125
|
-
def http_session(options={})
|
118
|
+
def http_session(options={},&block)
|
126
119
|
options = http_merge_options(options)
|
127
|
-
host_port = "#{options[:host]}:#{options[:port]}"
|
128
120
|
|
129
|
-
|
121
|
+
super(options) do |http,expanded_options|
|
130
122
|
print_info "Starting HTTP Session with #{host_port}"
|
131
123
|
|
132
|
-
|
124
|
+
if block.arity == 2
|
125
|
+
block.call(sess,expanded_options)
|
126
|
+
else
|
127
|
+
block.call(sess)
|
128
|
+
end
|
133
129
|
|
134
130
|
print_info "Closing HTTP Session with #{host_port}"
|
135
131
|
end
|
@@ -168,7 +164,7 @@ module Ronin
|
|
168
164
|
options = http_merge_options(options)
|
169
165
|
print_info "HTTP #{options[:method]} #{http_options_to_s(options)}"
|
170
166
|
|
171
|
-
return
|
167
|
+
return super(options,&block)
|
172
168
|
end
|
173
169
|
|
174
170
|
#
|
@@ -192,7 +188,7 @@ module Ronin
|
|
192
188
|
def http_status(options={})
|
193
189
|
options = http_merge_options(options)
|
194
190
|
|
195
|
-
if (result =
|
191
|
+
if (result = super(options))
|
196
192
|
print_debug "HTTP #{result} #{http_options_to_s(options)}"
|
197
193
|
end
|
198
194
|
|
@@ -220,7 +216,7 @@ module Ronin
|
|
220
216
|
def http_ok?(options={})
|
221
217
|
options = http_merge_options(options)
|
222
218
|
|
223
|
-
if (result =
|
219
|
+
if (result = super(options))
|
224
220
|
print_debug "HTTP 200 OK #{http_options_to_s(options)}"
|
225
221
|
end
|
226
222
|
|
@@ -248,7 +244,7 @@ module Ronin
|
|
248
244
|
def http_server(options={})
|
249
245
|
options = http_merge_options(options)
|
250
246
|
|
251
|
-
if (result =
|
247
|
+
if (result = super(options))
|
252
248
|
print_debug "HTTP Server: #{result}"
|
253
249
|
end
|
254
250
|
|
@@ -276,7 +272,7 @@ module Ronin
|
|
276
272
|
def http_powered_by(options={})
|
277
273
|
options = http_merge_options(options)
|
278
274
|
|
279
|
-
if (result =
|
275
|
+
if (result = super(options))
|
280
276
|
print_debug "HTTP X-Powered-By: #{result}"
|
281
277
|
end
|
282
278
|
|
@@ -304,7 +300,7 @@ module Ronin
|
|
304
300
|
options = http_merge_options(options)
|
305
301
|
print_info "HTTP COPY #{http_options_to_s(options)}"
|
306
302
|
|
307
|
-
return
|
303
|
+
return super(options,&block)
|
308
304
|
end
|
309
305
|
|
310
306
|
#
|
@@ -328,7 +324,7 @@ module Ronin
|
|
328
324
|
options = http_merge_options(options)
|
329
325
|
print_info "HTTP DELETE #{http_options_to_s(options)}"
|
330
326
|
|
331
|
-
return
|
327
|
+
return super(options,&block)
|
332
328
|
end
|
333
329
|
|
334
330
|
#
|
@@ -352,7 +348,7 @@ module Ronin
|
|
352
348
|
options = http_merge_options(options)
|
353
349
|
print_info "HTTP GET #{http_options_to_s(options)}"
|
354
350
|
|
355
|
-
return
|
351
|
+
return super(options,&block)
|
356
352
|
end
|
357
353
|
|
358
354
|
#
|
@@ -376,7 +372,7 @@ module Ronin
|
|
376
372
|
options = http_merge_options(options)
|
377
373
|
print_info "HTTP GET #{http_options_to_s(options)}"
|
378
374
|
|
379
|
-
return
|
375
|
+
return super(options,&block)
|
380
376
|
end
|
381
377
|
|
382
378
|
#
|
@@ -400,7 +396,7 @@ module Ronin
|
|
400
396
|
options = http_merge_options(options)
|
401
397
|
print_info "HTTP HEAD #{http_options_to_s(options)}"
|
402
398
|
|
403
|
-
return
|
399
|
+
return super(options,&block)
|
404
400
|
end
|
405
401
|
|
406
402
|
#
|
@@ -424,7 +420,7 @@ module Ronin
|
|
424
420
|
options = http_merge_options(options)
|
425
421
|
print_info "HTTP LOCK #{http_options_to_s(options)}"
|
426
422
|
|
427
|
-
return
|
423
|
+
return super(options,&block)
|
428
424
|
end
|
429
425
|
|
430
426
|
#
|
@@ -448,7 +444,7 @@ module Ronin
|
|
448
444
|
options = http_merge_options(options)
|
449
445
|
print_info "HTTP MKCOL #{http_options_to_s(options)}"
|
450
446
|
|
451
|
-
return
|
447
|
+
return super(options,&block)
|
452
448
|
end
|
453
449
|
|
454
450
|
#
|
@@ -472,7 +468,7 @@ module Ronin
|
|
472
468
|
options = http_merge_options(options)
|
473
469
|
print_info "HTTP MOVE #{http_options_to_s(options)}"
|
474
470
|
|
475
|
-
return
|
471
|
+
return super(options,&block)
|
476
472
|
end
|
477
473
|
|
478
474
|
#
|
@@ -496,7 +492,7 @@ module Ronin
|
|
496
492
|
options = http_merge_options(options)
|
497
493
|
print_info "HTTP OPTIONS #{http_options_to_s(options)}"
|
498
494
|
|
499
|
-
return
|
495
|
+
return super(options,&block)
|
500
496
|
end
|
501
497
|
|
502
498
|
#
|
@@ -526,7 +522,7 @@ module Ronin
|
|
526
522
|
options = http_merge_options(options)
|
527
523
|
print_info "HTTP POST #{http_options_to_s(options)}"
|
528
524
|
|
529
|
-
return
|
525
|
+
return super(options,&block)
|
530
526
|
end
|
531
527
|
|
532
528
|
#
|
@@ -550,7 +546,7 @@ module Ronin
|
|
550
546
|
options = http_merge_options(options)
|
551
547
|
print_info "HTTP POST #{http_options_to_s(options)}"
|
552
548
|
|
553
|
-
return
|
549
|
+
return super(options,&block)
|
554
550
|
end
|
555
551
|
|
556
552
|
#
|
@@ -574,7 +570,7 @@ module Ronin
|
|
574
570
|
options = http_merge_options(options)
|
575
571
|
print_info "HTTP PROPFIND #{http_options_to_s(options)}"
|
576
572
|
|
577
|
-
return
|
573
|
+
return super(options,&block)
|
578
574
|
end
|
579
575
|
|
580
576
|
#
|
@@ -598,7 +594,7 @@ module Ronin
|
|
598
594
|
options = http_merge_options(options)
|
599
595
|
print_info "HTTP PROPPATCH #{http_options_to_s(options)}"
|
600
596
|
|
601
|
-
return
|
597
|
+
return super(options,&block)
|
602
598
|
end
|
603
599
|
|
604
600
|
#
|
@@ -622,7 +618,7 @@ module Ronin
|
|
622
618
|
options = http_merge_options(options)
|
623
619
|
print_info "HTTP TRACE #{http_options_to_s(options)}"
|
624
620
|
|
625
|
-
return
|
621
|
+
return super(options,&block)
|
626
622
|
end
|
627
623
|
|
628
624
|
#
|
@@ -646,7 +642,7 @@ module Ronin
|
|
646
642
|
options = http_merge_options(options)
|
647
643
|
print_info "HTTP UNLOCK #{http_options_to_s(options)}"
|
648
644
|
|
649
|
-
return
|
645
|
+
return super(options,&block)
|
650
646
|
end
|
651
647
|
|
652
648
|
private
|