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,102 @@
1
+ RSpec.describe RubySMB::SMB1::BitField::HeaderFlags do
2
+ subject(:flags) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :reply }
5
+ it { is_expected.to respond_to :opbatch }
6
+ it { is_expected.to respond_to :oplock }
7
+ it { is_expected.to respond_to :canonicalized_paths }
8
+ it { is_expected.to respond_to :case_insensitive }
9
+ it { is_expected.to respond_to :reserved }
10
+ it { is_expected.to respond_to :buf_avail }
11
+ it { is_expected.to respond_to :lock_and_read_ok }
12
+
13
+ it 'is little endian' do
14
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
15
+ end
16
+
17
+ describe '#reply' do
18
+ it 'should be a 1-bit field per the SMB spec' do
19
+ expect(flags.reply).to be_a BinData::Bit1
20
+ end
21
+
22
+ it_behaves_like 'bit field with one flag set', :reply, 'C', 0x80
23
+ end
24
+
25
+ describe '#opbatch' do
26
+ it 'should be a 1-bit field per the SMB spec' do
27
+ expect(flags.opbatch).to be_a BinData::Bit1
28
+ end
29
+
30
+ it 'should have a default value of 0' do
31
+ expect(flags.opbatch).to eq 0
32
+ end
33
+
34
+ it_behaves_like 'bit field with one flag set', :opbatch, 'C', 0x40
35
+ end
36
+
37
+ describe '#oplock' do
38
+ it 'should be a 1-bit field per the SMB spec' do
39
+ expect(flags.oplock).to be_a BinData::Bit1
40
+ end
41
+
42
+ it 'should have a default value of 0' do
43
+ expect(flags.oplock).to eq 0
44
+ end
45
+
46
+ it_behaves_like 'bit field with one flag set', :oplock, 'C', 0x20
47
+ end
48
+
49
+ describe '#canonicalized_paths' do
50
+ it 'should be a 1-bit field per the SMB spec' do
51
+ expect(flags.canonicalized_paths).to be_a BinData::Bit1
52
+ end
53
+
54
+ it 'should have a default value of 1' do
55
+ expect(flags.canonicalized_paths).to eq 1
56
+ end
57
+
58
+ it_behaves_like 'bit field with one flag set', :canonicalized_paths, 'C', 0x10
59
+ end
60
+
61
+ describe '#case_insensitive' do
62
+ it 'should be a 1-bit field per the SMB spec' do
63
+ expect(flags.case_insensitive).to be_a BinData::Bit1
64
+ end
65
+
66
+ it 'should have a default value of 1' do
67
+ expect(flags.case_insensitive).to eq 1
68
+ end
69
+
70
+ it_behaves_like 'bit field with one flag set', :case_insensitive, 'C', 0x08
71
+ end
72
+
73
+ describe '#reserved' do
74
+ it 'should be a 1-bit field per the SMB spec' do
75
+ expect(flags.reserved).to be_a BinData::Bit1
76
+ end
77
+
78
+ it 'should have a default value of 0' do
79
+ expect(flags.reserved).to eq 0
80
+ end
81
+ end
82
+
83
+ describe '#buf_avail' do
84
+ it 'should be a 1-bit field per the SMB spec' do
85
+ expect(flags.buf_avail).to be_a BinData::Bit1
86
+ end
87
+
88
+ it 'should have a default value of 0' do
89
+ expect(flags.buf_avail).to eq 0
90
+ end
91
+
92
+ it_behaves_like 'bit field with one flag set', :buf_avail, 'C', 0x02
93
+ end
94
+
95
+ describe '#lock_and_read_ok' do
96
+ it 'should be a 1-bit field per the SMB spec' do
97
+ expect(flags.lock_and_read_ok).to be_a BinData::Bit1
98
+ end
99
+
100
+ it_behaves_like 'bit field with one flag set', :lock_and_read_ok, 'C', 0x01
101
+ end
102
+ end
@@ -0,0 +1,44 @@
1
+ RSpec.describe RubySMB::SMB1::BitField::SecurityMode do
2
+ subject(:security_mode) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :user_security }
5
+ it { is_expected.to respond_to :encrypt_passwords }
6
+ it { is_expected.to respond_to :security_signatures_enabled }
7
+ it { is_expected.to respond_to :security_signatures_required }
8
+
9
+ it 'is little endian' do
10
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
11
+ end
12
+
13
+ describe '#user_security' do
14
+ it 'is a 1-bit flag' do
15
+ expect(security_mode.user_security).to be_a BinData::Bit1
16
+ end
17
+
18
+ it_behaves_like 'bit field with one flag set', :user_security, 'C', 0x01
19
+ end
20
+
21
+ describe '#encrypt_passwords' do
22
+ it 'is a 1-bit flag' do
23
+ expect(security_mode.encrypt_passwords).to be_a BinData::Bit1
24
+ end
25
+
26
+ it_behaves_like 'bit field with one flag set', :encrypt_passwords, 'C', 0x02
27
+ end
28
+
29
+ describe '#security_signatures_enabled' do
30
+ it 'is a 1-bit flag' do
31
+ expect(security_mode.security_signatures_enabled).to be_a BinData::Bit1
32
+ end
33
+
34
+ it_behaves_like 'bit field with one flag set', :security_signatures_enabled, 'C', 0x04
35
+ end
36
+
37
+ describe '#security_signatures_required' do
38
+ it 'is a 1-bit flag' do
39
+ expect(security_mode.security_signatures_required).to be_a BinData::Bit1
40
+ end
41
+
42
+ it_behaves_like 'bit field with one flag set', :security_signatures_required, 'C', 0x08
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ RSpec.describe RubySMB::SMB1::DataBlock do
2
+ subject(:data_block) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :byte_count }
5
+
6
+ describe 'byte_count' do
7
+ it 'should be a 16-bit field per the SMB spec' do
8
+ expect(data_block.byte_count).to be_a BinData::Uint16le
9
+ end
10
+
11
+ it 'should equal the size of the rest of the block in bytes' do
12
+ remaining_size = data_block.do_num_bytes - 2
13
+ expect(data_block.byte_count).to eq remaining_size
14
+ end
15
+ end
16
+
17
+ describe 'class method #calculate_byte_count' do
18
+ it 'always returns 0' do
19
+ expect(described_class.calculate_byte_count).to eq 0
20
+ end
21
+ end
22
+
23
+ it 'is little endian' do
24
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ RSpec.describe RubySMB::SMB1::Dialect do
2
+ subject(:dialect) { described_class.new }
3
+
4
+ it { is_expected.to respond_to :buffer_format }
5
+ it { is_expected.to respond_to :dialect_string }
6
+
7
+ it 'is little endian' do
8
+ expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
9
+ end
10
+
11
+ describe 'buffer_format' do
12
+ it 'should be a 8-bit field per the SMB spec' do
13
+ expect(dialect.buffer_format).to be_a BinData::Bit8
14
+ end
15
+
16
+ it 'should be hardcoded to 0x2 by default per the SMB spec' do
17
+ expect(dialect.buffer_format).to eq 0x2
18
+ end
19
+ end
20
+
21
+ describe 'dialect_string' do
22
+ it 'should be a null terminated string per the SMB spec' do
23
+ expect(dialect.dialect_string).to be_a BinData::Stringz
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RubySMB::SMB1::Packet::ErrorPacket do
4
+ subject(:packet) { described_class.new }
5
+
6
+ describe '#smb_header' do
7
+ subject(:header) { packet.smb_header }
8
+
9
+ it 'is a standard SMB Header' do
10
+ expect(header).to be_a RubySMB::SMB1::SMBHeader
11
+ end
12
+
13
+ end
14
+
15
+ describe '#parameter_block' do
16
+ subject(:parameter_block) { packet.parameter_block }
17
+
18
+ it 'is a standard ParameterBlock' do
19
+ expect(parameter_block).to be_a RubySMB::SMB1::ParameterBlock
20
+ end
21
+
22
+ it 'should be empty' do
23
+ expect(parameter_block.to_binary_s).to eq "\x00"
24
+ end
25
+ end
26
+
27
+ describe '#data_block' do
28
+ subject(:data_block) { packet.data_block }
29
+
30
+ it 'is a standard DataBlock' do
31
+ expect(data_block).to be_a RubySMB::SMB1::DataBlock
32
+ end
33
+
34
+ it 'should be empty' do
35
+ expect(data_block.to_binary_s).to eq "\x00\x00"
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,77 @@
1
+ RSpec.describe RubySMB::SMB1::Packet::NegotiateRequest do
2
+ subject(:packet) { described_class.new }
3
+ let(:dialect_string) { 'NT LM 0.12' }
4
+
5
+ before(:each) do
6
+ packet.add_dialect(dialect_string)
7
+ end
8
+
9
+ describe '#smb_header' do
10
+ subject(:header) { packet.smb_header }
11
+
12
+ it 'is a standard SMB Header' do
13
+ expect(header).to be_a RubySMB::SMB1::SMBHeader
14
+ end
15
+
16
+ it 'should have the command set to SMB_COM_NEGOTIATE' do
17
+ expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_NEGOTIATE
18
+ end
19
+
20
+ it 'should not have the response flag set' do
21
+ expect(header.flags.reply).to eq 0
22
+ end
23
+ end
24
+
25
+ describe '#parameter_block' do
26
+ subject(:parameter_block) { packet.parameter_block }
27
+
28
+ it 'is a standard ParameterBlock' do
29
+ expect(parameter_block).to be_a RubySMB::SMB1::ParameterBlock
30
+ end
31
+ end
32
+
33
+ describe '#data_block' do
34
+ subject(:data_block) { packet.data_block }
35
+
36
+ it 'is a standard DataBlock' do
37
+ expect(data_block).to be_a RubySMB::SMB1::DataBlock
38
+ end
39
+
40
+ it { is_expected.to respond_to :dialects }
41
+
42
+ describe '#dialects' do
43
+ it 'is an array field as per the SMB spec' do
44
+ expect(data_block.dialects).to be_a BinData::Array
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#add_dialect' do
50
+ it 'adds a Dialect to the packet' do
51
+ expect { packet.add_dialect('foo') }.to change { packet.data_block.dialects.count }.by(1)
52
+ end
53
+
54
+ it 'uses the argument as the Dialect String' do
55
+ packet.add_dialect('bar')
56
+ dialects = packet.data_block.dialects.to_a
57
+ expect(dialects.last.dialect_string).to eq 'bar'
58
+ end
59
+ end
60
+
61
+ describe '#set_dialects' do
62
+ it 'clears out any existing dialects' do
63
+ expect { packet.set_dialects([]) }.to change { packet.data_block.dialects.count }.to(0)
64
+ end
65
+
66
+ it 'calls #add_dialect once for each string in the array' do
67
+ expect(packet).to receive(:add_dialect).exactly(3).times
68
+ packet.set_dialects(%w(foo bar baz))
69
+ end
70
+ end
71
+
72
+ describe '#dialects' do
73
+ it 'returns a ruby array of the dialect hashes' do
74
+ expect(packet.dialects).to eq [{:buffer_format=>2, :dialect_string=>"NT LM 0.12"}]
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,149 @@
1
+ RSpec.describe RubySMB::SMB1::Packet::NegotiateResponseExtended do
2
+ subject(:packet) { described_class.new }
3
+
4
+ describe '#smb_header' do
5
+ subject(:header) { packet.smb_header }
6
+
7
+ it 'is a standard SMB Header' do
8
+ expect(header).to be_a RubySMB::SMB1::SMBHeader
9
+ end
10
+
11
+ it 'should have the command set to SMB_COM_NEGOTIATE' do
12
+ expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_NEGOTIATE
13
+ end
14
+
15
+ it 'should have the response flag set' do
16
+ expect(header.flags.reply).to eq 1
17
+ end
18
+ end
19
+
20
+ describe '#parameter_block' do
21
+ subject(:parameter_block) { packet.parameter_block }
22
+
23
+ it 'is a standard ParameterBlock' do
24
+ expect(parameter_block).to be_a RubySMB::SMB1::ParameterBlock
25
+ end
26
+
27
+ it { is_expected.to respond_to :dialect_index }
28
+ it { is_expected.to respond_to :security_mode }
29
+ it { is_expected.to respond_to :max_mpx_count }
30
+ it { is_expected.to respond_to :max_number_vcs }
31
+ it { is_expected.to respond_to :max_buffer_size }
32
+ it { is_expected.to respond_to :max_raw_size }
33
+ it { is_expected.to respond_to :session_key }
34
+ it { is_expected.to respond_to :capabilities }
35
+ it { is_expected.to respond_to :system_time }
36
+ it { is_expected.to respond_to :server_time_zone }
37
+ it { is_expected.to respond_to :challenge_length }
38
+
39
+ describe '#dialect_index' do
40
+ it 'is a 16-bit Unsigned Integer' do
41
+ expect(parameter_block.dialect_index).to be_a BinData::Uint16le
42
+ end
43
+ end
44
+
45
+ describe '#security_mode' do
46
+ it 'is a SecurityMode bit-field' do
47
+ expect(parameter_block.security_mode).to be_a RubySMB::SMB1::BitField::SecurityMode
48
+ end
49
+ end
50
+
51
+ describe '#max_mpx_count' do
52
+ it 'is a 16-bit Unsigned Integer' do
53
+ expect(parameter_block.max_mpx_count).to be_a BinData::Uint16le
54
+ end
55
+ end
56
+
57
+ describe '#max_number_vcs' do
58
+ it 'is a 16-bit Unsigned Integer' do
59
+ expect(parameter_block.max_number_vcs).to be_a BinData::Uint16le
60
+ end
61
+ end
62
+
63
+ describe '#max_buffer_size' do
64
+ it 'is a 32-bit Unsigned Integer' do
65
+ expect(parameter_block.max_buffer_size).to be_a BinData::Uint32le
66
+ end
67
+ end
68
+
69
+ describe '#max_raw_size' do
70
+ it 'is a 32-bit Unsigned Integer' do
71
+ expect(parameter_block.max_raw_size).to be_a BinData::Uint32le
72
+ end
73
+ end
74
+
75
+ describe '#session_key' do
76
+ it 'is a 32-bit Unsigned Integer' do
77
+ expect(parameter_block.session_key).to be_a BinData::Uint32le
78
+ end
79
+ end
80
+
81
+ describe '#capabilities' do
82
+ it 'is a Capabilities bit-field' do
83
+ expect(parameter_block.capabilities).to be_a RubySMB::SMB1::BitField::Capabilities
84
+ end
85
+ end
86
+
87
+ describe '#system_time' do
88
+ it 'is a FileTime field' do
89
+ expect(parameter_block.system_time).to be_a RubySMB::Field::FileTime
90
+ end
91
+ end
92
+
93
+ describe '#server_time_zone' do
94
+ it 'is a 16-bit Signed Integer' do
95
+ expect(parameter_block.server_time_zone).to be_a BinData::Int16le
96
+ end
97
+ end
98
+
99
+ describe '#challenge_length' do
100
+ it 'is a 8-bit Unsigned Integer' do
101
+ expect(parameter_block.challenge_length).to be_a BinData::Uint8
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '#data_block' do
107
+ subject(:data_block) { packet.data_block }
108
+
109
+ it 'is a standard DataBlock' do
110
+ expect(data_block).to be_a RubySMB::SMB1::DataBlock
111
+ end
112
+
113
+ it { is_expected.to respond_to :server_guid }
114
+ it { is_expected.to respond_to :security_blob }
115
+
116
+ describe '#server_guid' do
117
+ it 'is binary string field' do
118
+ expect(data_block.server_guid).to be_a BinData::String
119
+ end
120
+
121
+ it 'is exactly 16-bytes long' do
122
+ expect(data_block.server_guid.length).to eq 16
123
+ end
124
+ end
125
+
126
+ describe '#security_blob' do
127
+ it 'is a variable length "rest" field' do
128
+ expect(data_block.security_blob).to be_a BinData::Rest
129
+ end
130
+ end
131
+ end
132
+
133
+ describe '#valid?' do
134
+ it 'should return true if the command value ix 0x72' do
135
+ packet.parameter_block.capabilities.extended_security = 1
136
+ expect(packet.valid?).to be true
137
+ end
138
+
139
+ it 'should return false if the command value is not 0x72' do
140
+ packet.smb_header.command = 0xff
141
+ expect(packet.valid?).to be false
142
+ end
143
+
144
+ it 'should return false if the capabilities do not include extended security' do
145
+ packet.parameter_block.capabilities.extended_security = 0
146
+ expect(packet.valid?).to be false
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,150 @@
1
+ RSpec.describe RubySMB::SMB1::Packet::NegotiateResponse do
2
+ subject(:packet) { described_class.new }
3
+
4
+ describe '#smb_header' do
5
+ subject(:header) { packet.smb_header }
6
+
7
+ it 'is a standard SMB Header' do
8
+ expect(header).to be_a RubySMB::SMB1::SMBHeader
9
+ end
10
+
11
+ it 'should have the command set to SMB_COM_NEGOTIATE' do
12
+ expect(header.command).to eq RubySMB::SMB1::Commands::SMB_COM_NEGOTIATE
13
+ end
14
+
15
+ it 'should have the response flag set' do
16
+ expect(header.flags.reply).to eq 1
17
+ end
18
+ end
19
+
20
+ describe '#parameter_block' do
21
+ subject(:parameter_block) { packet.parameter_block }
22
+
23
+ it 'is a standard ParameterBlock' do
24
+ expect(parameter_block).to be_a RubySMB::SMB1::ParameterBlock
25
+ end
26
+
27
+ it { is_expected.to respond_to :dialect_index }
28
+ it { is_expected.to respond_to :security_mode }
29
+ it { is_expected.to respond_to :max_mpx_count }
30
+ it { is_expected.to respond_to :max_number_vcs }
31
+ it { is_expected.to respond_to :max_buffer_size }
32
+ it { is_expected.to respond_to :max_raw_size }
33
+ it { is_expected.to respond_to :session_key }
34
+ it { is_expected.to respond_to :capabilities }
35
+ it { is_expected.to respond_to :system_time }
36
+ it { is_expected.to respond_to :server_time_zone }
37
+ it { is_expected.to respond_to :challenge_length }
38
+
39
+ describe '#dialect_index' do
40
+ it 'is a 16-bit Unsigned Integer' do
41
+ expect(parameter_block.dialect_index).to be_a BinData::Uint16le
42
+ end
43
+ end
44
+
45
+ describe '#security_mode' do
46
+ it 'is a SecurityMode bit-field' do
47
+ expect(parameter_block.security_mode).to be_a RubySMB::SMB1::BitField::SecurityMode
48
+ end
49
+ end
50
+
51
+ describe '#max_mpx_count' do
52
+ it 'is a 16-bit Unsigned Integer' do
53
+ expect(parameter_block.max_mpx_count).to be_a BinData::Uint16le
54
+ end
55
+ end
56
+
57
+ describe '#max_number_vcs' do
58
+ it 'is a 16-bit Unsigned Integer' do
59
+ expect(parameter_block.max_number_vcs).to be_a BinData::Uint16le
60
+ end
61
+ end
62
+
63
+ describe '#max_buffer_size' do
64
+ it 'is a 32-bit Unsigned Integer' do
65
+ expect(parameter_block.max_buffer_size).to be_a BinData::Uint32le
66
+ end
67
+ end
68
+
69
+ describe '#max_raw_size' do
70
+ it 'is a 32-bit Unsigned Integer' do
71
+ expect(parameter_block.max_raw_size).to be_a BinData::Uint32le
72
+ end
73
+ end
74
+
75
+ describe '#session_key' do
76
+ it 'is a 32-bit Unsigned Integer' do
77
+ expect(parameter_block.session_key).to be_a BinData::Uint32le
78
+ end
79
+ end
80
+
81
+ describe '#capabilities' do
82
+ it 'is a Capabilities bit-field' do
83
+ expect(parameter_block.capabilities).to be_a RubySMB::SMB1::BitField::Capabilities
84
+ end
85
+ end
86
+
87
+ describe '#system_time' do
88
+ it 'is a FileTime field' do
89
+ expect(parameter_block.system_time).to be_a RubySMB::Field::FileTime
90
+ end
91
+ end
92
+
93
+ describe '#server_time_zone' do
94
+ it 'is a 16-bit Signed Integer' do
95
+ expect(parameter_block.server_time_zone).to be_a BinData::Int16le
96
+ end
97
+ end
98
+
99
+ describe '#challenge_length' do
100
+ it 'is a 8-bit Unsigned Integer' do
101
+ expect(parameter_block.challenge_length).to be_a BinData::Uint8
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '#data_block' do
107
+ subject(:data_block) { packet.data_block }
108
+
109
+ it 'is a standard DataBlock' do
110
+ expect(data_block).to be_a RubySMB::SMB1::DataBlock
111
+ end
112
+
113
+ it { is_expected.to respond_to :challenge }
114
+ it { is_expected.to respond_to :domain_name }
115
+ it { is_expected.to respond_to :server_name }
116
+
117
+ describe '#challenge' do
118
+ it 'is a sized string of bytes' do
119
+ expect(data_block.challenge).to be_a BinData::String
120
+ end
121
+
122
+ it 'is exactly 8-bytes long' do
123
+ expect(data_block.challenge.length).to eq 8
124
+ end
125
+ end
126
+
127
+ describe '#domain_name' do
128
+ it 'is a Unicode Null-terminated string' do
129
+ expect(data_block.domain_name).to be_a RubySMB::Field::Stringz16
130
+ end
131
+ end
132
+
133
+ describe '#server_name' do
134
+ it 'is a Unicode Null-terminated string' do
135
+ expect(data_block.server_name).to be_a RubySMB::Field::Stringz16
136
+ end
137
+ end
138
+ end
139
+
140
+ describe '#valid?' do
141
+ it 'should return true if the command value ix 0x72' do
142
+ expect(packet.valid?).to be true
143
+ end
144
+
145
+ it 'should return false if the command value is not 0x72' do
146
+ packet.smb_header.command = 0xff
147
+ expect(packet.valid?).to be false
148
+ end
149
+ end
150
+ end