Skip to content

Commit d493346

Browse files
committed
Land rapid7#2137, fixes and specs for Opt containers
2 parents b0c17fd + 621568b commit d493346

17 files changed

+179
-16
lines changed

lib/msf/core/option_container.rb

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ def normalize(value)
173173

174174
def valid?(value=self.value)
175175
value = normalize(value)
176+
return false unless value.kind_of?(String) or value.kind_of?(NilClass)
176177
return false if empty_required_value?(value)
177178
return super
178179
end
@@ -263,6 +264,7 @@ def type
263264

264265
def valid?(value=self.value)
265266
return false if empty_required_value?(value)
267+
return true if value.nil? and !required?
266268

267269
(value and self.enums.include?(value.to_s))
268270
end
@@ -330,10 +332,17 @@ def type
330332

331333
def valid?(value)
332334
return false if empty_required_value?(value)
335+
return false unless value.kind_of?(String) or value.kind_of?(NilClass)
333336

334337
if (value != nil and value.empty? == false)
335338
begin
336-
::Rex::Socket.getaddress(value, true)
339+
getaddr_result = ::Rex::Socket.getaddress(value, true)
340+
# Covers a wierdcase where an incomplete ipv4 address will have it's
341+
# missing octets filled in with 0's. (e.g 192.168 become 192.0.0.168)
342+
# which does not feel like a legit behaviour
343+
if value =~ /^\d{1,3}(\.\d{1,3}){1,3}$/
344+
return false unless value =~ Rex::Socket::MATCH_IPV4
345+
end
337346
rescue
338347
return false
339348
end
@@ -354,6 +363,7 @@ def type
354363
end
355364

356365
def normalize(value)
366+
return nil unless value.kind_of?(String)
357367
if (value =~ /^file:(.*)/)
358368
path = $1
359369
return false if not File.exists?(path) or File.directory?(path)
@@ -373,9 +383,12 @@ def normalize(value)
373383

374384
def valid?(value)
375385
return false if empty_required_value?(value)
386+
return false unless value.kind_of?(String) or value.kind_of?(NilClass)
376387

377388
if (value != nil and value.empty? == false)
378-
walker = Rex::Socket::RangeWalker.new(normalize(value))
389+
normalized = normalize(value)
390+
return false if normalized.nil?
391+
walker = Rex::Socket::RangeWalker.new(normalized)
379392
if (not walker or not walker.valid?)
380393
return false
381394
end
@@ -474,7 +487,7 @@ def valid?(value)
474487
Regexp.compile(value)
475488

476489
return true
477-
rescue RegexpError
490+
rescue RegexpError, TypeError
478491
return false
479492
end
480493
end

lib/rex/socket/range_walker.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,12 @@ def parse(parseme)
9595
return false if ip_part.nil? or ip_part.empty? or mask_part.nil? or mask_part.empty?
9696
return false if mask_part !~ /^[0-9]{1,2}$/ # Illegal mask -- numerals only
9797
return false if mask_part.to_i > 32 # This too -- between 0 and 32.
98+
if ip_part =~ /^\d{1,3}(\.\d{1,3}){1,3}$/
99+
return false unless ip_part =~ Rex::Socket::MATCH_IPV4
100+
end
98101
begin
99-
Rex::Socket.addr_atoi(ip_part) # This allows for "www.metasploit.com/24" which is fun.
100-
rescue Resolv::ResolvError
102+
Rex::Socket.getaddress(ip_part) # This allows for "www.metasploit.com/24" which is fun.
103+
rescue Resolv::ResolvError, ::SocketError, Errno::ENOENT
101104
return false # Can't resolve the ip_part, so bail.
102105
end
103106

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
192.168.1.1
2+
192.168.1.2
3+
192.168.1.3
4+
192.168.1.4
5+
192.168.1.5

spec/file_fixtures/string_list.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
foo
2+
bar
3+
baz

spec/lib/msf/core/options/opt_address_range_spec.rb

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,49 @@
1111
{ :value => "192.0.2.0,1-255", :normalized => "192.0.2.0,1-255" },
1212
{ :value => "192.0.2.*", :normalized => "192.0.2.*" },
1313
{ :value => "192.0.2.0-192.0.2.255", :normalized => "192.0.2.0-192.0.2.255" },
14+
{ :value => "file:#{File.expand_path('short_address_list.txt',FILE_FIXTURES_PATH)}", :normalized => '192.168.1.1 192.168.1.2 192.168.1.3 192.168.1.4 192.168.1.5'},
1415
]
1516
invalid_values = [
1617
# Too many dots
1718
{ :value => "192.0.2.0.0" },
1819
{ :value => "192.0.2.0.0,1" },
1920
{ :value => "192.0.2.0.0,1-2" },
20-
{ :pending => "Redmine #7536", :value => "192.0.2.0.0/24" },
21+
{ :value => "192.0.2.0.0/24" },
2122
# Not enough dots
2223
{ :value => "192.0.2" },
2324
{ :value => "192.0.2,1" },
2425
{ :value => "192.0.2,1-2" },
25-
{ :pending => "Redmine #7536", :value => "192.0.2/24" },
26+
{ :value => "192.0.2/24" },
2627
# Can't mix ranges and CIDR
2728
{ :value => "192.0.2.0,1/24" },
2829
{ :value => "192.0.2.0-1/24" },
2930
{ :value => "192.0.2.0,1-2/24" },
3031
{ :value => "192.0.2.0/1-24" },
31-
{ :value => "192.0.2.0-192.0.2.1-255", },
32+
{ :value => "192.0.2.0-192.0.2.1-255" },
33+
# Non-string values
34+
{ :value => true},
35+
{ :value => 5 },
36+
{ :value => []},
37+
{ :value => [1,2]},
38+
{ :value => {}},
3239
]
3340

34-
it_behaves_like "an option", valid_values, invalid_values
41+
it_behaves_like "an option", valid_values, invalid_values, 'addressrange'
42+
43+
let(:required_opt) { Msf::OptAddressRange.new('RHOSTS', [true, 'The target addresses', '']) }
44+
45+
context 'the normalizer' do
46+
it 'should handle a call for random IPs' do
47+
random_addresses = required_opt.normalize('rand:5')
48+
random_addresses.kind_of?(String).should == true
49+
ips = random_addresses.split(' ')
50+
ips.count.should == 5
51+
ips.each do |ip|
52+
(ip =~ Rex::Socket::MATCH_IPV4).should == 0
53+
end
54+
end
55+
end
56+
3557
end
3658

3759

spec/lib/msf/core/options/opt_address_spec.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,19 @@
1313
# Too many dots
1414
{ :value => "192.0.2.0.0" },
1515
# Not enough
16-
{ :pending => "Redmine #7537", :value => "192.0.2" }
16+
{ :value => "192.0.2" },
17+
# Non-string values
18+
{ :value => true},
19+
{ :value => 5 },
20+
{ :value => []},
21+
{ :value => [1,2]},
22+
{ :value => {}},
1723
]
1824

19-
it_behaves_like "an option", valid_values, invalid_values
25+
it_behaves_like "an option", valid_values, invalid_values, 'address'
26+
27+
28+
2029
end
2130

2231

spec/lib/msf/core/options/opt_bool_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
{ :value => "012" },
1818
{ :value => "123" },
1919
]
20-
it_behaves_like "an option", valid_values, invalid_values
20+
it_behaves_like "an option", valid_values, invalid_values, 'bool'
21+
2122
end
2223

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# -*- coding:binary -*-
2+
3+
require 'spec_helper'
4+
require 'msf/core/option_container'
5+
6+
describe Msf::OptEnum do
7+
8+
it_behaves_like "an option", [], [], 'enum'
9+
10+
subject do
11+
Msf::OptEnum.new('name',[true, 'A Boolean Value', 'Foo', ['Foo', 'Bar', 'Baz']])
12+
end
13+
14+
context 'the validator' do
15+
it 'should return false for a value not in the list' do
16+
subject.valid?('Snap').should == false
17+
end
18+
19+
it 'should return true for a value in the list' do
20+
subject.valid?('Bar').should == true
21+
end
22+
end
23+
end

spec/lib/msf/core/options/opt_int_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
{ :value => "FF", },
2222
]
2323

24-
it_behaves_like "an option", valid_values, invalid_values
24+
it_behaves_like "an option", valid_values, invalid_values, 'integer'
2525
end
2626

2727

spec/lib/msf/core/options/opt_path_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@
1515
{ :value => "$", },
1616
]
1717

18-
it_behaves_like "an option", valid_values, invalid_values
18+
it_behaves_like "an option", valid_values, invalid_values, 'path'
1919
end
2020

0 commit comments

Comments
 (0)