ruby_smb 0.0.8 → 0.0.9
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/examples/tree_connect.rb +27 -0
- data/lib/ruby_smb/client.rb +25 -2
- data/lib/ruby_smb/client/authentication.rb +5 -6
- data/lib/ruby_smb/client/negotiation.rb +2 -3
- data/lib/ruby_smb/client/signing.rb +6 -2
- data/lib/ruby_smb/client/tree_connect.rb +86 -0
- data/lib/ruby_smb/generic_packet.rb +1 -1
- data/lib/ruby_smb/smb1.rb +1 -1
- data/lib/ruby_smb/smb1/bit_field.rb +4 -0
- data/lib/ruby_smb/smb1/bit_field/directory_access_mask.rb +38 -0
- data/lib/ruby_smb/smb1/bit_field/file_access_mask.rb +38 -0
- data/lib/ruby_smb/smb1/bit_field/optional_support.rb +19 -0
- data/lib/ruby_smb/smb1/bit_field/tree_connect_flags.rb +18 -0
- data/lib/ruby_smb/smb1/commands.rb +2 -0
- data/lib/ruby_smb/smb1/packet.rb +4 -0
- data/lib/ruby_smb/smb1/packet/tree_connect_request.rb +34 -0
- data/lib/ruby_smb/smb1/packet/tree_connect_response.rb +74 -0
- data/lib/ruby_smb/smb1/packet/tree_disconnect_request.rb +29 -0
- data/lib/ruby_smb/smb1/packet/tree_disconnect_response.rb +30 -0
- data/lib/ruby_smb/smb1/tree.rb +55 -0
- data/lib/ruby_smb/smb2.rb +1 -0
- data/lib/ruby_smb/smb2/bit_field.rb +4 -0
- data/lib/ruby_smb/smb2/bit_field/directory_access_mask.rb +38 -0
- data/lib/ruby_smb/smb2/bit_field/file_access_mask.rb +38 -0
- data/lib/ruby_smb/smb2/bit_field/share_capabailities.rb +21 -0
- data/lib/ruby_smb/smb2/bit_field/share_flags.rb +75 -0
- data/lib/ruby_smb/smb2/packet.rb +5 -0
- data/lib/ruby_smb/smb2/packet/error_packet.rb +15 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_request.rb +27 -0
- data/lib/ruby_smb/smb2/packet/tree_connect_response.rb +50 -0
- data/lib/ruby_smb/smb2/packet/tree_disconnect_request.rb +21 -0
- data/lib/ruby_smb/smb2/packet/tree_disconnect_response.rb +22 -0
- data/lib/ruby_smb/smb2/smb2_header.rb +3 -3
- data/lib/ruby_smb/smb2/tree.rb +51 -0
- data/lib/ruby_smb/version.rb +1 -1
- data/ruby_smb.gemspec +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +114 -4
- data/spec/lib/ruby_smb/smb1/bit_field/directory_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb1/bit_field/file_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb1/bit_field/optional_support_spec.rb +52 -0
- data/spec/lib/ruby_smb/smb1/bit_field/tree_connect_flags_spec.rb +37 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_request_spec.rb +53 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_connect_response_spec.rb +86 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_request_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/packet/tree_disconnect_response_spec.rb +40 -0
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +55 -0
- data/spec/lib/ruby_smb/smb2/bit_field/directory_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb2/bit_field/file_access_mask_spec.rb +190 -0
- data/spec/lib/ruby_smb/smb2/bit_field/share_capabilities_spec.rb +54 -0
- data/spec/lib/ruby_smb/smb2/bit_field/share_flags_spec.rb +184 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_request_spec.rb +49 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_connect_response_spec.rb +57 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb2/packet/tree_disconnect_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +54 -0
- metadata +63 -6
- metadata.gz.sig +0 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
RSpec.describe RubySMB::SMB2::BitField::ShareCapabilities do
|
2
|
+
subject(:capabilities) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :asymmetric }
|
5
|
+
it { is_expected.to respond_to :cluster }
|
6
|
+
it { is_expected.to respond_to :scaleout }
|
7
|
+
it { is_expected.to respond_to :continuous }
|
8
|
+
it { is_expected.to respond_to :dfs }
|
9
|
+
|
10
|
+
|
11
|
+
it 'is little endian' do
|
12
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#dfs' do
|
16
|
+
it 'is a 1-bit flag' do
|
17
|
+
expect(capabilities.dfs).to be_a BinData::Bit1
|
18
|
+
end
|
19
|
+
|
20
|
+
it_behaves_like 'bit field with one flag set', :dfs, 'V', 0x00000008
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#continuous' do
|
24
|
+
it 'is a 1-bit flag' do
|
25
|
+
expect(capabilities.continuous).to be_a BinData::Bit1
|
26
|
+
end
|
27
|
+
|
28
|
+
it_behaves_like 'bit field with one flag set', :continuous, 'V', 0x00000010
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#scaleout' do
|
32
|
+
it 'is a 1-bit flag' do
|
33
|
+
expect(capabilities.scaleout).to be_a BinData::Bit1
|
34
|
+
end
|
35
|
+
|
36
|
+
it_behaves_like 'bit field with one flag set', :scaleout, 'V', 0x00000020
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#cluster' do
|
40
|
+
it 'is a 1-bit flag' do
|
41
|
+
expect(capabilities.cluster).to be_a BinData::Bit1
|
42
|
+
end
|
43
|
+
|
44
|
+
it_behaves_like 'bit field with one flag set', :cluster, 'V', 0x00000040
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#asymmetric' do
|
48
|
+
it 'is a 1-bit flag' do
|
49
|
+
expect(capabilities.asymmetric).to be_a BinData::Bit1
|
50
|
+
end
|
51
|
+
|
52
|
+
it_behaves_like 'bit field with one flag set', :asymmetric, 'V', 0x00000080
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
RSpec.describe RubySMB::SMB2::BitField::ShareFlags do
|
2
|
+
subject(:flags) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :dfs_root }
|
5
|
+
it { is_expected.to respond_to :dfs }
|
6
|
+
it { is_expected.to respond_to :encrypt }
|
7
|
+
it { is_expected.to respond_to :hash_v2 }
|
8
|
+
it { is_expected.to respond_to :hash_v1 }
|
9
|
+
it { is_expected.to respond_to :force_oplock }
|
10
|
+
it { is_expected.to respond_to :access_based_enum }
|
11
|
+
it { is_expected.to respond_to :namespace_caching }
|
12
|
+
it { is_expected.to respond_to :shared_delete }
|
13
|
+
it { is_expected.to respond_to :restrict_exclusive_opens }
|
14
|
+
|
15
|
+
it 'is little endian' do
|
16
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#dfs' do
|
20
|
+
it 'should be a 1-bit field per the SMB spec' do
|
21
|
+
expect(flags.dfs).to be_a BinData::Bit1
|
22
|
+
end
|
23
|
+
|
24
|
+
it_behaves_like 'bit field with one flag set', :dfs, 'V', 0x00000001
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
describe '#dfs_root' do
|
29
|
+
it 'should be a 1-bit field per the SMB spec' do
|
30
|
+
expect(flags.dfs_root).to be_a BinData::Bit1
|
31
|
+
end
|
32
|
+
|
33
|
+
it_behaves_like 'bit field with one flag set', :dfs_root, 'V', 0x00000002
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#restrict_exclusive_opens' do
|
37
|
+
it 'should be a 1-bit field per the SMB spec' do
|
38
|
+
expect(flags.restrict_exclusive_opens).to be_a BinData::Bit1
|
39
|
+
end
|
40
|
+
|
41
|
+
it_behaves_like 'bit field with one flag set', :restrict_exclusive_opens, 'V', 0x00000100
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#shared_delete' do
|
45
|
+
it 'should be a 1-bit field per the SMB spec' do
|
46
|
+
expect(flags.shared_delete).to be_a BinData::Bit1
|
47
|
+
end
|
48
|
+
|
49
|
+
it_behaves_like 'bit field with one flag set', :shared_delete, 'V', 0x00000200
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#namespace_caching' do
|
53
|
+
it 'should be a 1-bit field per the SMB spec' do
|
54
|
+
expect(flags.namespace_caching).to be_a BinData::Bit1
|
55
|
+
end
|
56
|
+
|
57
|
+
it_behaves_like 'bit field with one flag set', :namespace_caching, 'V', 0x00000400
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#access_based_enum' do
|
61
|
+
it 'should be a 1-bit field per the SMB spec' do
|
62
|
+
expect(flags.access_based_enum).to be_a BinData::Bit1
|
63
|
+
end
|
64
|
+
|
65
|
+
it_behaves_like 'bit field with one flag set', :access_based_enum, 'V', 0x00000800
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#force_oplock' do
|
69
|
+
it 'should be a 1-bit field per the SMB spec' do
|
70
|
+
expect(flags.force_oplock).to be_a BinData::Bit1
|
71
|
+
end
|
72
|
+
|
73
|
+
it_behaves_like 'bit field with one flag set', :force_oplock, 'V', 0x00001000
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#hash_v1' do
|
77
|
+
it 'should be a 1-bit field per the SMB spec' do
|
78
|
+
expect(flags.hash_v1).to be_a BinData::Bit1
|
79
|
+
end
|
80
|
+
|
81
|
+
it_behaves_like 'bit field with one flag set', :hash_v1, 'V', 0x00002000
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#hash_v2' do
|
85
|
+
it 'should be a 1-bit field per the SMB spec' do
|
86
|
+
expect(flags.hash_v2).to be_a BinData::Bit1
|
87
|
+
end
|
88
|
+
|
89
|
+
it_behaves_like 'bit field with one flag set', :hash_v2, 'V', 0x00004000
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#encrypt' do
|
93
|
+
it 'should be a 1-bit field per the SMB spec' do
|
94
|
+
expect(flags.encrypt).to be_a BinData::Bit1
|
95
|
+
end
|
96
|
+
|
97
|
+
it_behaves_like 'bit field with one flag set', :encrypt, 'V', 0x00008000
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#set_manual_caching' do
|
101
|
+
it 'turns off the caching bits' do
|
102
|
+
flags.set_manual_caching
|
103
|
+
expect(flags.vdo_caching).to eq 0
|
104
|
+
expect(flags.auto_caching).to eq 0
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'has a value of 0x00000000' do
|
108
|
+
flags.set_manual_caching
|
109
|
+
flag_val = flags.to_binary_s
|
110
|
+
flag_val = flag_val.unpack('V').first
|
111
|
+
expect(flag_val).to eq 0x00000000
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#set_auto_caching' do
|
116
|
+
it 'turns on the auto_caching bit' do
|
117
|
+
flags.set_auto_caching
|
118
|
+
expect(flags.vdo_caching).to eq 0
|
119
|
+
expect(flags.auto_caching).to eq 1
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'has a value of 0x00000010' do
|
123
|
+
flags.set_auto_caching
|
124
|
+
flag_val = flags.to_binary_s
|
125
|
+
flag_val = flag_val.unpack('V').first
|
126
|
+
expect(flag_val).to eq 0x00000010
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#set_vdo_caching' do
|
131
|
+
it 'turns on the vdo_caching bits' do
|
132
|
+
flags.set_vdo_caching
|
133
|
+
expect(flags.vdo_caching).to eq 1
|
134
|
+
expect(flags.auto_caching).to eq 0
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'has a value of 0x00000020' do
|
138
|
+
flags.set_vdo_caching
|
139
|
+
flag_val = flags.to_binary_s
|
140
|
+
flag_val = flag_val.unpack('V').first
|
141
|
+
expect(flag_val).to eq 0x00000020
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#set_no_caching' do
|
146
|
+
it 'turns on all the caching bits' do
|
147
|
+
flags.set_no_caching
|
148
|
+
expect(flags.vdo_caching).to eq 1
|
149
|
+
expect(flags.auto_caching).to eq 1
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'has a value of 0x00000030' do
|
153
|
+
flags.set_no_caching
|
154
|
+
flag_val = flags.to_binary_s
|
155
|
+
flag_val = flag_val.unpack('V').first
|
156
|
+
expect(flag_val).to eq 0x00000030
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe '#caching_type' do
|
161
|
+
it 'returns VDO if only that flag is set' do
|
162
|
+
flags.vdo_caching = 1
|
163
|
+
expect(flags.caching_type).to eq :vdo
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'returns Auto if only that flag is set' do
|
167
|
+
flags.auto_caching = 1
|
168
|
+
expect(flags.caching_type).to eq :auto
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'returns No Caching if both caching flags are set' do
|
172
|
+
flags.auto_caching = 1
|
173
|
+
flags.vdo_caching = 1
|
174
|
+
expect(flags.caching_type).to eq :no_caching
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'returns Manual if neither caching flags are set' do
|
178
|
+
flags.auto_caching = 0
|
179
|
+
flags.vdo_caching = 0
|
180
|
+
expect(flags.caching_type).to eq :manual
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::TreeConnectRequest do
|
4
|
+
|
5
|
+
subject(:packet) { described_class.new }
|
6
|
+
|
7
|
+
it { is_expected.to respond_to :smb2_header }
|
8
|
+
it { is_expected.to respond_to :structure_size }
|
9
|
+
it { is_expected.to respond_to :flags }
|
10
|
+
it { is_expected.to respond_to :path_offset }
|
11
|
+
it { is_expected.to respond_to :path_length }
|
12
|
+
it { is_expected.to respond_to :path }
|
13
|
+
|
14
|
+
|
15
|
+
it 'is little endian' do
|
16
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#smb2_header' do
|
20
|
+
subject(:header) { packet.smb2_header }
|
21
|
+
|
22
|
+
it 'is a standard SMB Header' do
|
23
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should have the command set to SMB_COM_NEGOTIATE' do
|
27
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::TREE_CONNECT
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should not have the response flag set' do
|
31
|
+
expect(header.flags.reply).to eq 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#encode_path' do
|
36
|
+
let(:path) { "\\192.168.1.1\\example" }
|
37
|
+
let(:encoded_path) { path.encode("utf-16le").force_encoding("binary") }
|
38
|
+
|
39
|
+
it 'sets the path string to a UTF-16LE version of the supplied string' do
|
40
|
+
packet.encode_path(path)
|
41
|
+
expect(packet.path).to eq encoded_path
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'updates the #path_length' do
|
45
|
+
packet.encode_path(path)
|
46
|
+
expect(packet.path_length).to eq encoded_path.length
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::TreeConnectResponse do
|
4
|
+
|
5
|
+
subject(:packet) { described_class.new }
|
6
|
+
|
7
|
+
it { is_expected.to respond_to :smb2_header }
|
8
|
+
it { is_expected.to respond_to :structure_size }
|
9
|
+
it { is_expected.to respond_to :share_type }
|
10
|
+
it { is_expected.to respond_to :share_flags }
|
11
|
+
it { is_expected.to respond_to :capabilities }
|
12
|
+
it { is_expected.to respond_to :maximal_access }
|
13
|
+
|
14
|
+
it 'is little endian' do
|
15
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#smb2_header' do
|
19
|
+
subject(:header) { packet.smb2_header }
|
20
|
+
|
21
|
+
it 'is a standard SMB Header' do
|
22
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have the command set to SMB_COM_NEGOTIATE' do
|
26
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::TREE_CONNECT
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should have the response flag set' do
|
30
|
+
expect(header.flags.reply).to eq 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#is_directory?' do
|
35
|
+
it 'returns true if #share_type is 0x01' do
|
36
|
+
packet.share_type = 0x01
|
37
|
+
expect(packet.is_directory?).to be true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns false if #share_type is not 0x01' do
|
41
|
+
packet.share_type = 0x02
|
42
|
+
expect(packet.is_directory?).to be false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#access_rights' do
|
47
|
+
it 'is a DirectoryAccessMask if the Tree is a directory' do
|
48
|
+
allow(packet).to receive(:is_directory?).and_return(true)
|
49
|
+
expect(packet.access_rights).to be_a RubySMB::SMB2::BitField::DirectoryAccessMask
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'is a FileAccessMask if the Tree is not a directory' do
|
53
|
+
allow(packet).to receive(:is_directory?).and_return(false)
|
54
|
+
expect(packet.access_rights).to be_a RubySMB::SMB2::BitField::FileAccessMask
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::TreeDisconnectRequest do
|
4
|
+
|
5
|
+
subject(:packet) { described_class.new }
|
6
|
+
|
7
|
+
it { is_expected.to respond_to :smb2_header }
|
8
|
+
it { is_expected.to respond_to :structure_size }
|
9
|
+
|
10
|
+
it 'is little endian' do
|
11
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#smb2_header' do
|
15
|
+
subject(:header) { packet.smb2_header }
|
16
|
+
|
17
|
+
it 'is a standard SMB Header' do
|
18
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should have the command set to SMB_COM_NEGOTIATE' do
|
22
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::TREE_DISCONNECT
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should not have the response flag set' do
|
26
|
+
expect(header.flags.reply).to eq 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Packet::TreeDisconnectResponse do
|
4
|
+
|
5
|
+
subject(:packet) { described_class.new }
|
6
|
+
|
7
|
+
it { is_expected.to respond_to :smb2_header }
|
8
|
+
it { is_expected.to respond_to :structure_size }
|
9
|
+
|
10
|
+
it 'is little endian' do
|
11
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#smb2_header' do
|
15
|
+
subject(:header) { packet.smb2_header }
|
16
|
+
|
17
|
+
it 'is a standard SMB Header' do
|
18
|
+
expect(header).to be_a RubySMB::SMB2::SMB2Header
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should have the command set to SMB_COM_NEGOTIATE' do
|
22
|
+
expect(header.command).to eq RubySMB::SMB2::Commands::TREE_DISCONNECT
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should have the response flag set' do
|
26
|
+
expect(header.flags.reply).to eq 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe RubySMB::SMB2::Tree do
|
4
|
+
let(:dispatcher) { RubySMB::Dispatcher::Socket.new(nil) }
|
5
|
+
|
6
|
+
let(:client) { RubySMB::Client.new(dispatcher, username: 'msfadmin', password: 'msfadmin') }
|
7
|
+
let(:tree_id) { 2049 }
|
8
|
+
let(:path) { '\\192.168.1.1\example' }
|
9
|
+
let(:response) {
|
10
|
+
packet = RubySMB::SMB2::Packet::TreeConnectResponse.new
|
11
|
+
packet.smb2_header.tree_id = tree_id
|
12
|
+
packet.maximal_access.read("\xff\x01\x1f\x00")
|
13
|
+
packet.share_type = 0x01
|
14
|
+
packet
|
15
|
+
}
|
16
|
+
subject(:tree) {
|
17
|
+
described_class.new(client:client, share:path, response:response )
|
18
|
+
}
|
19
|
+
|
20
|
+
it { is_expected.to respond_to :client }
|
21
|
+
it { is_expected.to respond_to :permissions }
|
22
|
+
it { is_expected.to respond_to :share }
|
23
|
+
it { is_expected.to respond_to :id }
|
24
|
+
|
25
|
+
it 'inherits the client that spawned it' do
|
26
|
+
expect(tree.client).to eq client
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'inherits the permissions from the response packet' do
|
30
|
+
expect(tree.permissions).to eq response.maximal_access
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'inherits the Tree id from the response packet' do
|
34
|
+
expect(tree.id).to eq response.smb2_header.tree_id
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#disconnect!' do
|
38
|
+
let(:disco_req) { RubySMB::SMB2::Packet::TreeDisconnectRequest.new }
|
39
|
+
let(:disco_resp) { RubySMB::SMB2::Packet::TreeDisconnectResponse.new }
|
40
|
+
|
41
|
+
it 'sends a TreeDisconnectRequest with the Tree ID in the header' do
|
42
|
+
allow(RubySMB::SMB2::Packet::TreeDisconnectRequest).to receive(:new).and_return(disco_req)
|
43
|
+
modified_req = disco_req
|
44
|
+
modified_req.smb2_header.tree_id = tree.id
|
45
|
+
expect(client).to receive(:send_recv).with(modified_req).and_return(disco_resp.to_binary_s)
|
46
|
+
tree.disconnect!
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns the NTStatus code from the response' do
|
50
|
+
allow(client).to receive(:send_recv).and_return(disco_resp.to_binary_s)
|
51
|
+
expect(tree.disconnect!).to eq disco_resp.status_code
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|