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,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