ruby_smb 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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