ruby_smb 0.0.8

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 (102) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.gitignore +21 -0
  4. data/.rspec +3 -0
  5. data/.simplecov +42 -0
  6. data/.travis.yml +5 -0
  7. data/.yardopts +1 -0
  8. data/CONTRIBUTING.md +119 -0
  9. data/Gemfile +13 -0
  10. data/LICENSE.txt +18 -0
  11. data/README.md +64 -0
  12. data/Rakefile +22 -0
  13. data/examples/authenticate.rb +30 -0
  14. data/examples/negotiate.rb +25 -0
  15. data/lib/ruby_smb/client/authentication.rb +236 -0
  16. data/lib/ruby_smb/client/negotiation.rb +126 -0
  17. data/lib/ruby_smb/client/signing.rb +48 -0
  18. data/lib/ruby_smb/client.rb +164 -0
  19. data/lib/ruby_smb/dispatcher/base.rb +18 -0
  20. data/lib/ruby_smb/dispatcher/socket.rb +53 -0
  21. data/lib/ruby_smb/dispatcher.rb +4 -0
  22. data/lib/ruby_smb/error.rb +17 -0
  23. data/lib/ruby_smb/field/file_time.rb +62 -0
  24. data/lib/ruby_smb/field/nt_status.rb +16 -0
  25. data/lib/ruby_smb/field/stringz16.rb +55 -0
  26. data/lib/ruby_smb/field.rb +7 -0
  27. data/lib/ruby_smb/generic_packet.rb +179 -0
  28. data/lib/ruby_smb/gss.rb +109 -0
  29. data/lib/ruby_smb/smb1/andx_block.rb +13 -0
  30. data/lib/ruby_smb/smb1/bit_field/capabilities.rb +39 -0
  31. data/lib/ruby_smb/smb1/bit_field/header_flags.rb +19 -0
  32. data/lib/ruby_smb/smb1/bit_field/header_flags2.rb +27 -0
  33. data/lib/ruby_smb/smb1/bit_field/security_mode.rb +16 -0
  34. data/lib/ruby_smb/smb1/bit_field.rb +10 -0
  35. data/lib/ruby_smb/smb1/commands.rb +9 -0
  36. data/lib/ruby_smb/smb1/data_block.rb +42 -0
  37. data/lib/ruby_smb/smb1/dialect.rb +11 -0
  38. data/lib/ruby_smb/smb1/packet/error_packet.rb +14 -0
  39. data/lib/ruby_smb/smb1/packet/negotiate_request.rb +52 -0
  40. data/lib/ruby_smb/smb1/packet/negotiate_response.rb +46 -0
  41. data/lib/ruby_smb/smb1/packet/negotiate_response_extended.rb +47 -0
  42. data/lib/ruby_smb/smb1/packet/session_setup_request.rb +71 -0
  43. data/lib/ruby_smb/smb1/packet/session_setup_response.rb +48 -0
  44. data/lib/ruby_smb/smb1/packet.rb +12 -0
  45. data/lib/ruby_smb/smb1/parameter_block.rb +42 -0
  46. data/lib/ruby_smb/smb1/smb_header.rb +21 -0
  47. data/lib/ruby_smb/smb1.rb +16 -0
  48. data/lib/ruby_smb/smb2/bit_field/session_flags.rb +17 -0
  49. data/lib/ruby_smb/smb2/bit_field/smb2_capabailities.rb +23 -0
  50. data/lib/ruby_smb/smb2/bit_field/smb2_header_flags.rb +23 -0
  51. data/lib/ruby_smb/smb2/bit_field/smb2_security_mode.rb +15 -0
  52. data/lib/ruby_smb/smb2/bit_field/smb2_security_mode_single.rb +14 -0
  53. data/lib/ruby_smb/smb2/bit_field.rb +11 -0
  54. data/lib/ruby_smb/smb2/commands.rb +25 -0
  55. data/lib/ruby_smb/smb2/packet/negotiate_request.rb +50 -0
  56. data/lib/ruby_smb/smb2/packet/negotiate_response.rb +33 -0
  57. data/lib/ruby_smb/smb2/packet/session_setup_request.rb +53 -0
  58. data/lib/ruby_smb/smb2/packet/session_setup_response.rb +38 -0
  59. data/lib/ruby_smb/smb2/packet.rb +10 -0
  60. data/lib/ruby_smb/smb2/smb2_header.rb +22 -0
  61. data/lib/ruby_smb/smb2.rb +12 -0
  62. data/lib/ruby_smb/version.rb +3 -0
  63. data/lib/ruby_smb.rb +22 -0
  64. data/ruby_smb.gemspec +38 -0
  65. data/spec/lib/ruby_smb/client_spec.rb +638 -0
  66. data/spec/lib/ruby_smb/dispatcher/dispatcher_base_spec.rb +22 -0
  67. data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +60 -0
  68. data/spec/lib/ruby_smb/field/file_time_spec.rb +59 -0
  69. data/spec/lib/ruby_smb/field/nt_status_spec.rb +19 -0
  70. data/spec/lib/ruby_smb/field/stringz16_spec.rb +50 -0
  71. data/spec/lib/ruby_smb/generic_packet_spec.rb +58 -0
  72. data/spec/lib/ruby_smb/smb1/andx_block_spec.rb +41 -0
  73. data/spec/lib/ruby_smb/smb1/bit_field/capabilities_spec.rb +245 -0
  74. data/spec/lib/ruby_smb/smb1/bit_field/header_flags2_spec.rb +146 -0
  75. data/spec/lib/ruby_smb/smb1/bit_field/header_flags_spec.rb +102 -0
  76. data/spec/lib/ruby_smb/smb1/bit_field/security_mode_spec.rb +44 -0
  77. data/spec/lib/ruby_smb/smb1/data_block_spec.rb +26 -0
  78. data/spec/lib/ruby_smb/smb1/dialect_spec.rb +26 -0
  79. data/spec/lib/ruby_smb/smb1/packet/error_packet_spec.rb +39 -0
  80. data/spec/lib/ruby_smb/smb1/packet/negotiate_request_spec.rb +77 -0
  81. data/spec/lib/ruby_smb/smb1/packet/negotiate_response_extended_spec.rb +149 -0
  82. data/spec/lib/ruby_smb/smb1/packet/negotiate_response_spec.rb +150 -0
  83. data/spec/lib/ruby_smb/smb1/packet/session_setup_request_spec.rb +100 -0
  84. data/spec/lib/ruby_smb/smb1/packet/session_setup_response_spec.rb +72 -0
  85. data/spec/lib/ruby_smb/smb1/parameter_block_spec.rb +26 -0
  86. data/spec/lib/ruby_smb/smb1/smb_header_spec.rb +96 -0
  87. data/spec/lib/ruby_smb/smb2/bit_field/header_flags_spec.rb +81 -0
  88. data/spec/lib/ruby_smb/smb2/bit_field/session_flags_spec.rb +28 -0
  89. data/spec/lib/ruby_smb/smb2/bit_field/smb2_capabilities_spec.rb +72 -0
  90. data/spec/lib/ruby_smb/smb2/bit_field/smb_secruity_mode_spec.rb +22 -0
  91. data/spec/lib/ruby_smb/smb2/packet/negotiate_request_spec.rb +122 -0
  92. data/spec/lib/ruby_smb/smb2/packet/negotiate_response_spec.rb +147 -0
  93. data/spec/lib/ruby_smb/smb2/packet/session_setup_request_spec.rb +79 -0
  94. data/spec/lib/ruby_smb/smb2/packet/session_setup_response_spec.rb +54 -0
  95. data/spec/lib/ruby_smb/smb2/smb2_header_spec.rb +127 -0
  96. data/spec/lib/ruby_smb_spec.rb +2 -0
  97. data/spec/spec_helper.rb +100 -0
  98. data/spec/support/mock_socket_dispatcher.rb +8 -0
  99. data/spec/support/shared/examples/bit_field_single_flag.rb +14 -0
  100. data.tar.gz.sig +0 -0
  101. metadata +384 -0
  102. metadata.gz.sig +0 -0
@@ -0,0 +1,60 @@
1
+ RSpec.describe RubySMB::Dispatcher::Socket do
2
+ let(:fake_tcp_socket) { StringIO.new('deadbeef') }
3
+
4
+ subject(:smb_socket) { described_class.new(fake_tcp_socket) }
5
+ let(:negotiate_response) { RubySMB::SMB2::Packet::NegotiateResponse.new }
6
+ let(:nbss) { smb_socket.nbss(negotiate_response) }
7
+ let(:response_packet) { nbss + negotiate_response.to_binary_s }
8
+
9
+ # Don't try to actually select on our StringIO fake socket
10
+ before(:each) do
11
+ allow(IO).to receive(:select).and_return(nil)
12
+ end
13
+
14
+ describe '#connect' do
15
+ it 'should support setting a custom socket object' do
16
+ socket = described_class.connect('172.16.22.165', socket: fake_tcp_socket)
17
+ expect(socket.tcp_socket).to eq(fake_tcp_socket)
18
+ end
19
+
20
+ it 'should default to setting up a TCPSocket' do
21
+ host = '172.16.22.165'
22
+ port = 445
23
+ expect(TCPSocket).to receive(:new).with(host, port)
24
+ described_class.connect(host)
25
+ end
26
+ end
27
+
28
+ describe '#recv_packet' do
29
+ let(:blank_socket) { StringIO.new('') }
30
+ let(:response_socket) { StringIO.new(response_packet) }
31
+
32
+ describe 'when reading from the socket results in a nil value' do
33
+ it 'should raise Error::NetBiosSessionService' do
34
+ smb_socket.tcp_socket = blank_socket
35
+ expect { smb_socket.recv_packet }.to raise_error(::RubySMB::Error::NetBiosSessionService)
36
+ end
37
+ end
38
+
39
+ describe 'when reading an SMB Response packet' do
40
+ it 'reads a number of bytes defined in the nbss header' do
41
+ smb_socket.tcp_socket = response_socket
42
+ expect(response_socket).to receive(:read).with(4).and_call_original
43
+ expect(response_socket).to receive(:read).with(negotiate_response.do_num_bytes).and_call_original
44
+ smb_socket.recv_packet
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#send_packet' do
50
+ it 'calls nbss to create the nbss header for the packet' do
51
+ expect(smb_socket).to receive(:nbss).with(negotiate_response).and_return(nbss)
52
+ smb_socket.send_packet(negotiate_response)
53
+ end
54
+
55
+ it 'writes the packet to the socket' do
56
+ expect(fake_tcp_socket).to receive(:write).with(response_packet).and_call_original
57
+ smb_socket.send_packet(negotiate_response)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,59 @@
1
+ RSpec.describe RubySMB::Field::FileTime do
2
+ subject(:file_time) { described_class.read(binary_filetime) }
3
+
4
+ let(:binary_filetime) { "\x36\x32\xe8\xe0\xd2\xe4\xd0\x01" }
5
+ let(:int_filetime) { binary_filetime.unpack('Q<').first }
6
+ let(:str_filetime) { '2015-09-01T11:25:56-05:00' }
7
+ let(:time_filetime) { Time.parse str_filetime }
8
+ let(:datetime_filetime) { time_filetime.to_datetime }
9
+
10
+ it { is_expected.to respond_to :val }
11
+ it { is_expected.to respond_to :get }
12
+ it { is_expected.to respond_to :set }
13
+ it { is_expected.to respond_to :to_time }
14
+ it { is_expected.to respond_to :to_datetime }
15
+
16
+ describe '#val' do
17
+ it 'should b an Unsigned 64-bit Integer' do
18
+ expect(file_time.val).to be_a BinData::Uint64le
19
+ end
20
+ end
21
+
22
+ describe '#get' do
23
+ it 'returns the expected integer value' do
24
+ expect(file_time.val).to eq int_filetime
25
+ end
26
+ end
27
+
28
+ describe '#to_time' do
29
+ it 'returns a Time object representing the correct time' do
30
+ expect(file_time.to_time).to eq time_filetime
31
+ end
32
+ end
33
+
34
+ describe '#to_datetime' do
35
+ it 'returns a DateTime object representing the correct time' do
36
+ expect(file_time.to_datetime).to eq datetime_filetime
37
+ end
38
+ end
39
+
40
+ describe '#set' do
41
+ subject(:empty_filetime) { described_class.new }
42
+ it 'will take a Time object correctly but lose Nanoseconds' do
43
+ empty_filetime.set time_filetime
44
+ val = empty_filetime.get
45
+ expect(val / 10_000_000).to eq (int_filetime / 10_000_000)
46
+ end
47
+
48
+ it 'will take a DateTime object correctly but lose Nanoseconds' do
49
+ empty_filetime.set datetime_filetime
50
+ val = empty_filetime.get
51
+ expect(val / 10_000_000).to eq (int_filetime / 10_000_000)
52
+ end
53
+
54
+ it 'will accept a raw integer value and set it' do
55
+ empty_filetime.set int_filetime
56
+ expect(empty_filetime.get).to eq int_filetime
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,19 @@
1
+ RSpec.describe RubySMB::Field::NtStatus do
2
+ subject(:nt_status) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :to_nt_status }
5
+
6
+ it 'is a Unsigned 32-bit little endian integer' do
7
+ expect(nt_status).to be_a BinData::Uint32le
8
+ end
9
+
10
+ describe '#to_nt_status' do
11
+ it 'should return a WindowsError::ErrorCode' do
12
+ expect(nt_status.to_nt_status).to be_a WindowsError::ErrorCode
13
+ end
14
+
15
+ it 'should return the correct ErrorCode' do
16
+ expect(nt_status.to_nt_status).to eq WindowsError::NTStatus::STATUS_SUCCESS
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::Field::Stringz16 do
4
+ subject(:stringz16) { described_class.new }
5
+
6
+ it 'starts as an empty string' do
7
+ expect(stringz16).to eq ""
8
+ end
9
+
10
+ context 'with a value already set' do
11
+ let(:abcd) { described_class.new("ABCD") }
12
+
13
+ it 'should be UTF-16le' do
14
+ expect(abcd).to eq "ABCD".encode("utf-16le")
15
+ end
16
+
17
+ it 'should include the NULL terminator on binary output' do
18
+ expect(abcd.to_binary_s).to eq "A\x00B\x00C\x00D\x00\x00\x00"
19
+ end
20
+ end
21
+
22
+ context 'with a null terminator in the middle' do
23
+ let(:null_terminator) { described_class.new("ABCD\x00EFG") }
24
+
25
+ it 'drops everything after the null terminator' do
26
+ expect(null_terminator).to eq "ABCD".encode("utf-16le")
27
+ end
28
+ end
29
+
30
+ context 'when reading data in' do
31
+
32
+ it 'stops at the first double null byte' do
33
+ io = StringIO.new("A\x00B\x00C\x00D\x00\x00\x00E\x00F\x00")
34
+ stringz16.read(io)
35
+ expect(stringz16.to_binary_s).to eq "A\x00B\x00C\x00D\x00\x00\x00"
36
+ end
37
+
38
+ it 'handles a zero length string' do
39
+ io = StringIO.new("\x00\x00A\x00")
40
+ stringz16.read(io)
41
+ expect(stringz16).to eq ""
42
+ end
43
+
44
+ it 'fails if no null terminator is found' do
45
+ io = StringIO.new("A\x00B\x00C\x00D\x00")
46
+ expect{ stringz16.read(io) }.to raise_error(EOFError)
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::GenericPacket do
4
+
5
+ class TestPacket < RubySMB::GenericPacket
6
+ endian :little
7
+ uint8 :first_value, initial_value: 0x01
8
+ uint16 :second_value, initial_value: 0x02
9
+ array :array_value, type: :dialect, read_until: :eof
10
+ end
11
+
12
+ class ParentTestPacket < RubySMB::GenericPacket
13
+ endian :little
14
+ uint8 :header
15
+ test_packet :test_packet
16
+ end
17
+
18
+ subject(:test_packet) { TestPacket.new(first_value: 16, second_value: 4056, array_value: [RubySMB::SMB1::Dialect.new(dialect_string: 'test')]) }
19
+ let(:parent_packet) { ParentTestPacket.new }
20
+
21
+ describe '#describe class method' do
22
+ it 'outputs a string representing the structure of the packet' do
23
+ str = "\nFirst_value (Uint8) \n"+
24
+ "Second_value (Uint16le) \n"+
25
+ "Array_value (Array) "
26
+ expect(TestPacket.describe).to eq str
27
+ end
28
+
29
+ it 'handles nested record structures as well' do
30
+ str = "\nHeader (Uint8) \n"+
31
+ "TEST_PACKET \n"+
32
+ "\tFirst_value (Uint8) \n"+
33
+ "\tSecond_value (Uint16le) \n"+
34
+ "\tArray_value (Array) "
35
+ expect(ParentTestPacket.describe).to eq str
36
+ end
37
+ end
38
+
39
+ describe '#display' do
40
+ it 'shows the actual contents of the packet fields' do
41
+ str = "\nFIRST_VALUE 16\n" +
42
+ "SECOND_VALUE 4056\n" +
43
+ "ARRAY_VALUE\n" +
44
+ "\tBuffer Format ID 2\n" +
45
+ "\tDialect Name test"
46
+ expect(test_packet.display).to eq str
47
+ end
48
+
49
+ it 'handles nested record structures as well' do
50
+ str = "\nHEADER 0\n" +
51
+ "TEST_PACKET\n" +
52
+ "\tFirst_value 1\n" +
53
+ "\tSecond_value 2\n" +
54
+ "\tARRAY_VALUE"
55
+ expect(parent_packet.display).to eq str
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,41 @@
1
+ RSpec.describe RubySMB::SMB1::AndXBlock do
2
+ subject(:andx_block) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :andx_command }
5
+ it { is_expected.to respond_to :andx_reserved }
6
+ it { is_expected.to respond_to :andx_offset }
7
+
8
+ it 'is little endian' do
9
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
10
+ end
11
+
12
+ describe 'andx_command' do
13
+ it 'should be a 8-bit field per the SMB spec' do
14
+ expect(andx_block.andx_command).to be_a BinData::Bit8
15
+ end
16
+
17
+ it 'should be hardcoded to SMB_COM_NO_ANDX_COMMAND by default per the SMB spec' do
18
+ expect(andx_block.andx_command).to eq RubySMB::SMB1::Commands::SMB_COM_NO_ANDX_COMMAND
19
+ end
20
+ end
21
+
22
+ describe 'andx_reserved' do
23
+ it 'should be a 8-bit field per the SMB spec' do
24
+ expect(andx_block.andx_reserved).to be_a BinData::Bit8
25
+ end
26
+
27
+ it 'should be hardcoded to 0 by default per the SMB spec' do
28
+ expect(andx_block.andx_reserved).to eq 0
29
+ end
30
+ end
31
+
32
+ describe 'andx_offset' do
33
+ it 'should be a 16-bit field per the SMB spec' do
34
+ expect(andx_block.andx_offset).to be_a BinData::Bit16
35
+ end
36
+
37
+ it 'should be hardcoded to 0 by default per the SMB spec' do
38
+ expect(andx_block.andx_offset).to eq 0
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,245 @@
1
+ RSpec.describe RubySMB::SMB1::BitField::Capabilities do
2
+ subject(:capabilities) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :level_2_oplocks }
5
+ it { is_expected.to respond_to :nt_status }
6
+ it { is_expected.to respond_to :rpc_remote_apis }
7
+ it { is_expected.to respond_to :nt_smbs }
8
+ it { is_expected.to respond_to :large_files }
9
+ it { is_expected.to respond_to :unicode }
10
+ it { is_expected.to respond_to :mpx_mode }
11
+ it { is_expected.to respond_to :raw_mode }
12
+ it { is_expected.to respond_to :large_writex }
13
+ it { is_expected.to respond_to :large_readx }
14
+ it { is_expected.to respond_to :info_level_passthru }
15
+ it { is_expected.to respond_to :dfs }
16
+ it { is_expected.to respond_to :reserved1 }
17
+ it { is_expected.to respond_to :bulk_transfer }
18
+ it { is_expected.to respond_to :nt_find }
19
+ it { is_expected.to respond_to :lock_and_read }
20
+ it { is_expected.to respond_to :unix }
21
+ it { is_expected.to respond_to :reserved2 }
22
+ it { is_expected.to respond_to :lwio }
23
+ it { is_expected.to respond_to :extended_security }
24
+ it { is_expected.to respond_to :reserved3 }
25
+ it { is_expected.to respond_to :dynamic_reauth }
26
+ it { is_expected.to respond_to :reserved4 }
27
+ it { is_expected.to respond_to :compressed_data }
28
+ it { is_expected.to respond_to :reserved5 }
29
+
30
+ it 'is little endian' do
31
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
32
+ end
33
+
34
+ describe '#level_2_oplocks' do
35
+ it 'is a 1-bit flag' do
36
+ expect(capabilities.level_2_oplocks).to be_a BinData::Bit1
37
+ end
38
+
39
+ it_behaves_like 'bit field with one flag set', :level_2_oplocks, 'V', 0x00000080
40
+ end
41
+
42
+ describe '#nt_status' do
43
+ it 'is a 1-bit flag' do
44
+ expect(capabilities.nt_status).to be_a BinData::Bit1
45
+ end
46
+
47
+ it_behaves_like 'bit field with one flag set', :nt_status, 'V', 0x00000040
48
+ end
49
+
50
+ describe '#rpc_remote_apis' do
51
+ it 'is a 1-bit flag' do
52
+ expect(capabilities.rpc_remote_apis).to be_a BinData::Bit1
53
+ end
54
+
55
+ it_behaves_like 'bit field with one flag set', :rpc_remote_apis, 'V', 0x00000020
56
+ end
57
+
58
+ describe '#nt_smbs' do
59
+ it 'is a 1-bit flag' do
60
+ expect(capabilities.nt_smbs).to be_a BinData::Bit1
61
+ end
62
+
63
+ it_behaves_like 'bit field with one flag set', :nt_smbs, 'V', 0x00000010
64
+ end
65
+
66
+ describe '#large_files' do
67
+ it 'is a 1-bit flag' do
68
+ expect(capabilities.large_files).to be_a BinData::Bit1
69
+ end
70
+
71
+ it_behaves_like 'bit field with one flag set', :large_files, 'V', 0x00000008
72
+ end
73
+
74
+ describe '#unicode' do
75
+ it 'is a 1-bit flag' do
76
+ expect(capabilities.unicode).to be_a BinData::Bit1
77
+ end
78
+
79
+ it_behaves_like 'bit field with one flag set', :unicode, 'V', 0x00000004
80
+ end
81
+
82
+ describe '#mpx_mode' do
83
+ it 'is a 1-bit flag' do
84
+ expect(capabilities.mpx_mode).to be_a BinData::Bit1
85
+ end
86
+
87
+ it_behaves_like 'bit field with one flag set', :mpx_mode, 'V', 0x00000002
88
+ end
89
+
90
+ describe '#raw_mode' do
91
+ it 'is a 1-bit flag' do
92
+ expect(capabilities.raw_mode).to be_a BinData::Bit1
93
+ end
94
+
95
+ it_behaves_like 'bit field with one flag set', :raw_mode, 'V', 0x00000001
96
+ end
97
+
98
+ describe '#large_writex' do
99
+ it 'is a 1-bit flag' do
100
+ expect(capabilities.large_writex).to be_a BinData::Bit1
101
+ end
102
+
103
+ it_behaves_like 'bit field with one flag set', :large_writex, 'V', 0x00008000
104
+ end
105
+
106
+ describe '#large_readx' do
107
+ it 'is a 1-bit flag' do
108
+ expect(capabilities.large_readx).to be_a BinData::Bit1
109
+ end
110
+
111
+ it_behaves_like 'bit field with one flag set', :large_readx, 'V', 0x00004000
112
+ end
113
+
114
+ describe '#info_level_passthru' do
115
+ it 'is a 1-bit flag' do
116
+ expect(capabilities.info_level_passthru).to be_a BinData::Bit1
117
+ end
118
+
119
+ it_behaves_like 'bit field with one flag set', :info_level_passthru, 'V', 0x00002000
120
+ end
121
+
122
+ describe '#dfs' do
123
+ it 'is a 1-bit flag' do
124
+ expect(capabilities.dfs).to be_a BinData::Bit1
125
+ end
126
+
127
+ it_behaves_like 'bit field with one flag set', :dfs, 'V', 0x00001000
128
+ end
129
+
130
+ describe '#reserved1' do
131
+ it 'is a 1-bit flag' do
132
+ expect(capabilities.reserved1).to be_a BinData::Bit1
133
+ end
134
+
135
+ it 'should have a default value of 0' do
136
+ expect(capabilities.reserved1).to eq 0
137
+ end
138
+ end
139
+
140
+ describe '#bulk_transfer' do
141
+ it 'is a 1-bit flag' do
142
+ expect(capabilities.bulk_transfer).to be_a BinData::Bit1
143
+ end
144
+
145
+ it 'should have a default value of 0' do
146
+ expect(capabilities.bulk_transfer).to eq 0
147
+ end
148
+ end
149
+
150
+ describe '#nt_find' do
151
+ it 'is a 1-bit flag' do
152
+ expect(capabilities.nt_find).to be_a BinData::Bit1
153
+ end
154
+
155
+ it_behaves_like 'bit field with one flag set', :nt_find, 'V', 0x00000200
156
+ end
157
+
158
+ describe '#lock_and_read' do
159
+ it 'is a 1-bit flag' do
160
+ expect(capabilities.lock_and_read).to be_a BinData::Bit1
161
+ end
162
+
163
+ it_behaves_like 'bit field with one flag set', :lock_and_read, 'V', 0x00000100
164
+ end
165
+
166
+ describe '#unix' do
167
+ it 'is a 1-bit flag' do
168
+ expect(capabilities.unix).to be_a BinData::Bit1
169
+ end
170
+
171
+ it_behaves_like 'bit field with one flag set', :unix, 'V', 0x00800000
172
+ end
173
+
174
+ describe '#reserved2' do
175
+ it 'is a 6-bit reserved space' do
176
+ expect(capabilities.reserved2).to be_a BinData::Bit6
177
+ end
178
+
179
+ it 'should have a default value of 0' do
180
+ expect(capabilities.reserved2).to eq 0
181
+ end
182
+ end
183
+
184
+ describe '#lwio' do
185
+ it 'is a 1-bit flag' do
186
+ expect(capabilities.lwio).to be_a BinData::Bit1
187
+ end
188
+
189
+ it_behaves_like 'bit field with one flag set', :lwio, 'V', 0x00010000
190
+ end
191
+
192
+ describe '#extended_security' do
193
+ it 'is a 1-bit flag' do
194
+ expect(capabilities.extended_security).to be_a BinData::Bit1
195
+ end
196
+
197
+ it_behaves_like 'bit field with one flag set', :extended_security, 'V', 0x80000000
198
+ end
199
+
200
+ describe '#reserved3' do
201
+ it 'is a 1-bit flag' do
202
+ expect(capabilities.reserved3).to be_a BinData::Bit1
203
+ end
204
+
205
+ it 'should have a default value of 0' do
206
+ expect(capabilities.reserved3).to eq 0
207
+ end
208
+ end
209
+
210
+ describe '#dynamic_reauth' do
211
+ it 'is a 1-bit flag' do
212
+ expect(capabilities.dynamic_reauth).to be_a BinData::Bit1
213
+ end
214
+
215
+ it_behaves_like 'bit field with one flag set', :dynamic_reauth, 'V', 0x20000000
216
+ end
217
+
218
+ describe '#reserved4' do
219
+ it 'is a 3-bit reserved space' do
220
+ expect(capabilities.reserved4).to be_a BinData::Bit3
221
+ end
222
+
223
+ it 'should have a default value of 0' do
224
+ expect(capabilities.reserved1).to eq 0
225
+ end
226
+ end
227
+
228
+ describe '#compressed_data' do
229
+ it 'is a 1-bit flag' do
230
+ expect(capabilities.compressed_data).to be_a BinData::Bit1
231
+ end
232
+
233
+ it_behaves_like 'bit field with one flag set', :compressed_data, 'V', 0x02000000
234
+ end
235
+
236
+ describe '#reserved5' do
237
+ it 'is a 1-bit flag' do
238
+ expect(capabilities.reserved5).to be_a BinData::Bit1
239
+ end
240
+
241
+ it 'should have a default value of 0' do
242
+ expect(capabilities.reserved5).to eq 0
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,146 @@
1
+ RSpec.describe RubySMB::SMB1::BitField::HeaderFlags2 do
2
+ subject(:flags2) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :unicode }
5
+ it { is_expected.to respond_to :nt_status }
6
+ it { is_expected.to respond_to :paging_io }
7
+ it { is_expected.to respond_to :dfs }
8
+ it { is_expected.to respond_to :extended_security }
9
+ it { is_expected.to respond_to :reparse_path }
10
+ it { is_expected.to respond_to :reserved1 }
11
+ it { is_expected.to respond_to :is_long_name }
12
+ it { is_expected.to respond_to :reserved2 }
13
+ it { is_expected.to respond_to :signature_required }
14
+ it { is_expected.to respond_to :compressed }
15
+ it { is_expected.to respond_to :security_signature }
16
+ it { is_expected.to respond_to :eas }
17
+ it { is_expected.to respond_to :long_names }
18
+
19
+ it 'is little endian' do
20
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
21
+ end
22
+
23
+ describe 'unicode' do
24
+ it 'should be a 1-bit field per the SMB spec' do
25
+ expect(flags2.unicode).to be_a BinData::Bit1
26
+ end
27
+
28
+ it 'should have a default value of 0' do
29
+ expect(flags2.unicode).to eq 0
30
+ end
31
+
32
+ it_behaves_like 'bit field with one flag set', :unicode, 'v', 0x8000
33
+ end
34
+
35
+ describe 'nt_status' do
36
+ it 'should be a 1-bit field per the SMB spec' do
37
+ expect(flags2.nt_status).to be_a BinData::Bit1
38
+ end
39
+
40
+ it 'should have a default value of 1' do
41
+ expect(flags2.nt_status).to eq 1
42
+ end
43
+
44
+ it_behaves_like 'bit field with one flag set', :nt_status, 'v', 0x4000
45
+ end
46
+
47
+ describe 'paging_io' do
48
+ it 'should be a 1-bit field per the SMB spec' do
49
+ expect(flags2.paging_io).to be_a BinData::Bit1
50
+ end
51
+
52
+ it_behaves_like 'bit field with one flag set', :paging_io, 'v', 0x2000
53
+ end
54
+
55
+ describe 'dfs' do
56
+ it 'should be a 1-bit field per the SMB spec' do
57
+ expect(flags2.dfs).to be_a BinData::Bit1
58
+ end
59
+
60
+ it_behaves_like 'bit field with one flag set', :dfs, 'v', 0x1000
61
+ end
62
+
63
+ describe 'extended_security' do
64
+ it 'should be a 1-bit field per the SMB spec' do
65
+ expect(flags2.extended_security).to be_a BinData::Bit1
66
+ end
67
+
68
+ it_behaves_like 'bit field with one flag set', :extended_security, 'v', 0x0800
69
+ end
70
+
71
+ describe 'reparse_path' do
72
+ it 'should be a 1-bit field per the SMB spec' do
73
+ expect(flags2.reparse_path).to be_a BinData::Bit1
74
+ end
75
+
76
+ it_behaves_like 'bit field with one flag set', :reparse_path, 'v', 0x0400
77
+ end
78
+
79
+ describe 'reserved1' do
80
+ it 'should be a 3-bit field per the SMB spec' do
81
+ expect(flags2.reserved1).to be_a BinData::Bit1
82
+ end
83
+
84
+ it 'should have a default value of 0' do
85
+ expect(flags2.reserved1).to eq 0
86
+ end
87
+ end
88
+
89
+ describe 'is_long_name' do
90
+ it 'should be a 1-bit field per the SMB spec' do
91
+ expect(flags2.is_long_name).to be_a BinData::Bit1
92
+ end
93
+
94
+ it_behaves_like 'bit field with one flag set', :is_long_name, 'v', 0x0040
95
+ end
96
+
97
+ describe 'reserved2' do
98
+ it 'should be a 1-bit field per the SMB spec' do
99
+ expect(flags2.reserved2).to be_a BinData::Bit1
100
+ end
101
+
102
+ it 'should have a default value of 0' do
103
+ expect(flags2.reserved2).to eq 0
104
+ end
105
+ end
106
+
107
+ describe 'signature_required' do
108
+ it 'should be a 1-bit field per the SMB spec' do
109
+ expect(flags2.signature_required).to be_a BinData::Bit1
110
+ end
111
+
112
+ it_behaves_like 'bit field with one flag set', :signature_required, 'v', 0x0010
113
+ end
114
+
115
+ describe 'compressed' do
116
+ it 'should be a 1-bit field per the SMB spec' do
117
+ expect(flags2.compressed).to be_a BinData::Bit1
118
+ end
119
+
120
+ it_behaves_like 'bit field with one flag set', :compressed, 'v', 0x0008
121
+ end
122
+
123
+ describe 'security_signature' do
124
+ it 'should be a 1-bit field per the SMB spec' do
125
+ expect(flags2.security_signature).to be_a BinData::Bit1
126
+ end
127
+
128
+ it_behaves_like 'bit field with one flag set', :security_signature, 'v', 0x0004
129
+ end
130
+
131
+ describe 'eas' do
132
+ it 'should be a 1-bit field per the SMB spec' do
133
+ expect(flags2.eas).to be_a BinData::Bit1
134
+ end
135
+
136
+ it_behaves_like 'bit field with one flag set', :eas, 'v', 0x0002
137
+ end
138
+
139
+ describe 'long_names' do
140
+ it 'should be a 1-bit field per the SMB spec' do
141
+ expect(flags2.long_names).to be_a BinData::Bit1
142
+ end
143
+
144
+ it_behaves_like 'bit field with one flag set', :long_names, 'v', 0x0001
145
+ end
146
+ end