opt_address_local_spec.rb 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. # -*- coding:binary -*-
  2. require 'spec_helper'
  3. RSpec.describe Msf::OptAddressLocal do
  4. iface = NetworkInterface.interfaces.collect do |iface|
  5. ip_address = NetworkInterface.addresses(iface).values.flatten.collect { |x| x['addr'] }.select do |addr|
  6. IPAddr.new(addr).ipv4? && !addr[/^127.*/]
  7. rescue IPAddr::InvalidAddressError
  8. false
  9. end.sort_by do |addr|
  10. ip_addr = IPAddr.new(addr)
  11. [ip_addr.ipv4? ? 0 : 1, ip_addr.to_i]
  12. end.first
  13. { name: iface, addr: ip_address }
  14. end.select { |name_addr| name_addr[:addr] }.sort_by do |name_addr|
  15. ip_addr = IPAddr.new(name_addr[:addr])
  16. [ip_addr.ipv4? ? 0 : 1, ip_addr.to_i]
  17. end.first
  18. valid_values = [
  19. { value: '192.0.2.0', normalized: '192.0.2.0' },
  20. { value: '127.0.0.1', normalized: '127.0.0.1' },
  21. { value: '2001:db8::', normalized: '2001:db8::' },
  22. { value: '::1', normalized: '::1' },
  23. { value: iface[:name], normalized: iface[:addr] }
  24. ]
  25. invalid_values = [
  26. # Too many dots
  27. { value: '192.0.2.0.0' },
  28. # Not enough
  29. { value: '192.0.2' },
  30. # Non-string values
  31. { value: true },
  32. { value: 5 },
  33. { value: [] },
  34. { value: [1, 2] },
  35. { value: {} },
  36. ]
  37. it_behaves_like 'an option', valid_values, invalid_values, 'address'
  38. let(:required_opt) { Msf::OptAddressLocal.new('LHOST', [true, 'local address', '']) }
  39. describe '#normalize' do
  40. context 'when on a darwin host' do
  41. context 'and multiple ipv4 and ipv6 addresses are returned' do
  42. let(:mock_adapter_name) { 'mock-adapter' }
  43. let(:darwin_addresses) do
  44. {
  45. # Darwin AF_INET6
  46. 30 => [
  47. {
  48. 'addr' => 'fe80::146f:d90e:5c71:fea4%bridge101',
  49. 'netmask' => 'ffff:ffff:ffff:ffff::',
  50. 'broadcast' => nil
  51. },
  52. {
  53. 'addr' => '2001:db8::',
  54. 'netmask' => 'ffff::',
  55. 'broadcast' => nil
  56. }
  57. ],
  58. # Darwin AF_LINK
  59. 18 => [
  60. {
  61. 'addr' => '',
  62. 'netmask' => nil,
  63. 'broadcast' => nil
  64. }
  65. ],
  66. # Darwin AF_INET
  67. 2 => [
  68. {
  69. 'addr' => '233.252.1.1',
  70. 'netmask' => '255.255.255.0',
  71. 'broadcast' => '233.252.1.255'
  72. },
  73. {
  74. 'addr' => '192.0.2.1',
  75. 'netmask' => '255.255.255.0',
  76. 'broadcast' => '192.0.2.255'
  77. }
  78. ],
  79. }
  80. end
  81. before(:each) do
  82. allow(NetworkInterface).to receive(:interfaces).and_return([mock_adapter_name])
  83. allow(NetworkInterface).to receive(:addresses).with(mock_adapter_name).and_return(darwin_addresses)
  84. end
  85. it 'preferences the lowest ipv4 address' do
  86. expect(required_opt.normalize(mock_adapter_name)).to eq '192.0.2.1'
  87. end
  88. end
  89. end
  90. end
  91. describe '#interfaces' do
  92. context 'getting errors' do
  93. before(:each) do
  94. allow(NetworkInterface).to receive(:interfaces).and_raise(NetworkInterface::Error)
  95. end
  96. it 'rescues and returns an empty array' do
  97. expect(required_opt).to receive(:elog).with(an_instance_of(NetworkInterface::Error))
  98. result = required_opt.interfaces()
  99. expect(result).to eq([])
  100. end
  101. end
  102. end
  103. end