ruby_smb 2.0.1 → 2.0.6
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 +2 -1
- data/examples/anonymous_auth.rb +3 -3
- data/examples/append_file.rb +10 -8
- data/examples/authenticate.rb +9 -5
- data/examples/delete_file.rb +8 -6
- data/examples/enum_registry_key.rb +5 -4
- data/examples/enum_registry_values.rb +5 -4
- data/examples/list_directory.rb +8 -6
- data/examples/negotiate_with_netbios_service.rb +9 -5
- data/examples/net_share_enum_all.rb +6 -4
- data/examples/pipes.rb +11 -12
- data/examples/query_service_status.rb +64 -0
- data/examples/read_file.rb +8 -6
- data/examples/read_registry_key_value.rb +6 -5
- data/examples/rename_file.rb +9 -7
- data/examples/tree_connect.rb +7 -5
- data/examples/write_file.rb +9 -7
- data/lib/ruby_smb/client.rb +81 -48
- data/lib/ruby_smb/client/authentication.rb +5 -10
- data/lib/ruby_smb/client/echo.rb +2 -4
- data/lib/ruby_smb/client/negotiation.rb +21 -14
- data/lib/ruby_smb/client/tree_connect.rb +2 -4
- data/lib/ruby_smb/client/utils.rb +16 -10
- data/lib/ruby_smb/client/winreg.rb +1 -1
- data/lib/ruby_smb/dcerpc.rb +4 -0
- data/lib/ruby_smb/dcerpc/error.rb +3 -0
- data/lib/ruby_smb/dcerpc/ndr.rb +306 -44
- data/lib/ruby_smb/dcerpc/netlogon.rb +101 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request.rb +28 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response.rb +24 -0
- data/lib/ruby_smb/dcerpc/request.rb +19 -0
- data/lib/ruby_smb/dcerpc/rpc_security_attributes.rb +34 -0
- data/lib/ruby_smb/dcerpc/rrp_unicode_string.rb +9 -6
- data/lib/ruby_smb/dcerpc/svcctl.rb +479 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request.rb +48 -0
- data/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_request.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/control_service_response.rb +26 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request.rb +35 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_request.rb +31 -0
- data/lib/ruby_smb/dcerpc/svcctl/open_service_w_response.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response.rb +44 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_request.rb +23 -0
- data/lib/ruby_smb/dcerpc/svcctl/query_service_status_response.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/service_status.rb +25 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_request.rb +27 -0
- data/lib/ruby_smb/dcerpc/svcctl/start_service_w_response.rb +25 -0
- data/lib/ruby_smb/dcerpc/winreg.rb +98 -17
- data/lib/ruby_smb/dcerpc/winreg/create_key_request.rb +73 -0
- data/lib/ruby_smb/dcerpc/winreg/create_key_response.rb +36 -0
- data/lib/ruby_smb/dcerpc/winreg/enum_key_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/enum_value_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/enum_value_response.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/open_root_key_request.rb +4 -4
- data/lib/ruby_smb/dcerpc/winreg/query_info_key_request.rb +1 -1
- data/lib/ruby_smb/dcerpc/winreg/query_value_request.rb +7 -6
- data/lib/ruby_smb/dcerpc/winreg/query_value_response.rb +10 -10
- data/lib/ruby_smb/dcerpc/winreg/save_key_request.rb +37 -0
- data/lib/ruby_smb/dcerpc/winreg/save_key_response.rb +23 -0
- data/lib/ruby_smb/dispatcher/base.rb +1 -1
- data/lib/ruby_smb/dispatcher/socket.rb +1 -1
- data/lib/ruby_smb/error.rb +21 -5
- data/lib/ruby_smb/field/stringz16.rb +17 -1
- data/lib/ruby_smb/generic_packet.rb +11 -1
- data/lib/ruby_smb/nbss/session_header.rb +4 -4
- data/lib/ruby_smb/smb1/file.rb +10 -25
- data/lib/ruby_smb/smb1/packet/trans2/find_first2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/find_next2_response.rb +0 -1
- data/lib/ruby_smb/smb1/packet/trans2/open2_response.rb +1 -2
- data/lib/ruby_smb/smb1/packet/trans2/set_file_information_response.rb +1 -13
- data/lib/ruby_smb/smb1/pipe.rb +8 -6
- data/lib/ruby_smb/smb1/tree.rb +13 -9
- data/lib/ruby_smb/smb2/file.rb +33 -33
- data/lib/ruby_smb/smb2/pipe.rb +9 -6
- data/lib/ruby_smb/smb2/tree.rb +21 -11
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/client_spec.rb +195 -101
- data/spec/lib/ruby_smb/dcerpc/ndr_spec.rb +1396 -77
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_authenticate3_response_spec.rb +53 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_request_spec.rb +69 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_password_set2_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_request_spec.rb +45 -0
- data/spec/lib/ruby_smb/dcerpc/netlogon/netr_server_req_challenge_response_spec.rb +37 -0
- data/spec/lib/ruby_smb/dcerpc/rpc_security_attributes_spec.rb +161 -0
- data/spec/lib/ruby_smb/dcerpc/rrp_unicode_string_spec.rb +49 -12
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_request_spec.rb +191 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/change_service_config_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/close_service_handle_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_request_spec.rb +39 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/control_service_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_request_spec.rb +78 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_sc_manager_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_request_spec.rb +59 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/open_service_w_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_request_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_config_w_response_spec.rb +152 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_request_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/query_service_status_response_spec.rb +38 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/service_status_spec.rb +72 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_request_spec.rb +46 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl/start_service_w_response_spec.rb +30 -0
- data/spec/lib/ruby_smb/dcerpc/svcctl_spec.rb +512 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_request_spec.rb +110 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/create_key_response_spec.rb +44 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_key_request_spec.rb +0 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_request_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/enum_value_response_spec.rb +2 -2
- data/spec/lib/ruby_smb/dcerpc/winreg/open_root_key_request_spec.rb +9 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/query_info_key_request_spec.rb +0 -4
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_request_spec.rb +17 -17
- data/spec/lib/ruby_smb/dcerpc/winreg/query_value_response_spec.rb +11 -23
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_request_spec.rb +57 -0
- data/spec/lib/ruby_smb/dcerpc/winreg/save_key_response_spec.rb +22 -0
- data/spec/lib/ruby_smb/dcerpc/winreg_spec.rb +227 -41
- data/spec/lib/ruby_smb/dispatcher/socket_spec.rb +10 -10
- data/spec/lib/ruby_smb/error_spec.rb +34 -5
- data/spec/lib/ruby_smb/field/stringz16_spec.rb +12 -0
- data/spec/lib/ruby_smb/generic_packet_spec.rb +7 -0
- data/spec/lib/ruby_smb/nbss/session_header_spec.rb +4 -11
- data/spec/lib/ruby_smb/smb1/file_spec.rb +2 -4
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_first2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/find_next2_response_spec.rb +0 -1
- data/spec/lib/ruby_smb/smb1/packet/trans2/open2_response_spec.rb +0 -5
- data/spec/lib/ruby_smb/smb1/packet/trans2/set_file_information_response_spec.rb +0 -6
- data/spec/lib/ruby_smb/smb1/pipe_spec.rb +30 -5
- data/spec/lib/ruby_smb/smb1/tree_spec.rb +22 -0
- data/spec/lib/ruby_smb/smb2/file_spec.rb +61 -9
- data/spec/lib/ruby_smb/smb2/pipe_spec.rb +9 -5
- data/spec/lib/ruby_smb/smb2/tree_spec.rb +58 -1
- metadata +91 -2
- metadata.gz.sig +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
RSpec.describe RubySMB::Dcerpc::Ndr::
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Ndr::NdrPointer do
|
2
2
|
subject(:packet) do
|
3
3
|
Class.new(described_class) do
|
4
4
|
endian :little
|
@@ -6,48 +6,190 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrTopLevelFullPointer do
|
|
6
6
|
end.new
|
7
7
|
end
|
8
8
|
|
9
|
-
it { is_expected.to respond_to :
|
9
|
+
it { is_expected.to respond_to :referent_id }
|
10
10
|
|
11
11
|
it 'is little endian' do
|
12
12
|
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
13
13
|
end
|
14
14
|
|
15
|
-
describe '#
|
15
|
+
describe '#referent_id' do
|
16
16
|
it 'is a 32-bit unsigned integer' do
|
17
|
-
expect(packet.
|
17
|
+
expect(packet.referent_id).to be_a BinData::Uint32le
|
18
18
|
end
|
19
19
|
|
20
|
-
it 'has an initial value of
|
21
|
-
expect(packet.
|
20
|
+
it 'has an initial value of 0' do
|
21
|
+
expect(packet.referent_id).to eq(0)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe '#get' do
|
26
|
-
it 'returns
|
27
|
-
packet.
|
28
|
-
expect(packet.get).to eq(
|
26
|
+
it 'returns :null when #referent_id is 0' do
|
27
|
+
packet.referent_id = 0
|
28
|
+
expect(packet.get).to eq(:null)
|
29
29
|
end
|
30
30
|
|
31
|
-
it 'returns #referent when #
|
31
|
+
it 'returns #referent when #referent_id is not 0' do
|
32
32
|
packet.set('spec_test')
|
33
33
|
expect(packet.get).to eq(packet.referent)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe '#set' do
|
38
|
-
context 'when the value is
|
39
|
-
it '
|
40
|
-
packet.
|
41
|
-
|
38
|
+
context 'when the value is :null' do
|
39
|
+
it 'clears #referent' do
|
40
|
+
expect(packet.referent).to receive(:clear)
|
41
|
+
packet.set(:null)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'sets #referent_id to 0' do
|
45
|
+
packet.set(:null)
|
46
|
+
expect(packet.referent_id).to eq(0)
|
42
47
|
end
|
43
48
|
end
|
44
49
|
|
45
50
|
context 'when the value is a string' do
|
51
|
+
let(:str) { 'spec_test' }
|
52
|
+
|
46
53
|
it 'sets #referent to the value' do
|
47
|
-
str = 'spec_test'
|
48
54
|
packet.set(str)
|
49
55
|
expect(packet.referent).to eq(str)
|
50
56
|
end
|
57
|
+
|
58
|
+
it 'calls #set when #referent support it' do
|
59
|
+
module TestSet; def set(v); end; end
|
60
|
+
packet.referent.extend(TestSet)
|
61
|
+
expect(packet.referent).to receive(:set).with(str)
|
62
|
+
packet.set(str)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'assigns directly to #referent when it does not support #set' do
|
66
|
+
expect(packet).to receive(:referent=).with(str)
|
67
|
+
packet.set(str)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'sets #referent_id to a random value' do
|
71
|
+
rnd = double('Random Value')
|
72
|
+
allow(packet).to receive(:rand).and_return(rnd)
|
73
|
+
expect(packet).to receive(:referent_id=).with(rnd)
|
74
|
+
packet.set(str)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does not change #referent_id if it is already set' do
|
78
|
+
packet.referent_id = 0xCCCCCC
|
79
|
+
packet.set(str)
|
80
|
+
expect(packet.referent_id).to eq(0xCCCCCC)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#do_read' do
|
86
|
+
let(:io) { StringIO.new }
|
87
|
+
|
88
|
+
it 'asks referent_id to read the io stream' do
|
89
|
+
expect(packet.referent_id).to receive(:do_read).with(io)
|
90
|
+
packet.do_read(io)
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when it can process #referent' do
|
94
|
+
before :example do
|
95
|
+
allow(packet).to receive(:process_referent?).and_return(true)
|
96
|
+
allow(packet.referent_id).to receive(:do_read)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'asks referent to read the io stream if referent_id is not 0' do
|
100
|
+
packet.referent_id = 0xCCCC
|
101
|
+
expect(packet.referent).to receive(:do_read).with(io)
|
102
|
+
packet.do_read(io)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'does not ask referent to read the io stream if referent_id is 0' do
|
106
|
+
packet.referent_id = 0
|
107
|
+
expect(packet.referent).to_not receive(:do_read).with(io)
|
108
|
+
packet.do_read(io)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#do_write' do
|
114
|
+
let(:io) { StringIO.new }
|
115
|
+
|
116
|
+
it 'asks referent_id to write the io stream' do
|
117
|
+
expect(packet.referent_id).to receive(:do_write).with(io)
|
118
|
+
packet.do_write(io)
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'when it can process #referent' do
|
122
|
+
before :example do
|
123
|
+
allow(packet).to receive(:process_referent?).and_return(true)
|
124
|
+
allow(packet.referent_id).to receive(:do_write)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'asks referent to write the io stream if referent_id is not 0' do
|
128
|
+
packet.referent_id = 0xCCCC
|
129
|
+
expect(packet.referent).to receive(:do_write).with(io)
|
130
|
+
packet.do_write(io)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'does not ask referent to write the io stream if referent_id is 0' do
|
134
|
+
packet.referent_id = 0
|
135
|
+
expect(packet.referent).to_not receive(:do_write).with(io)
|
136
|
+
packet.do_write(io)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe '#process_referent?' do
|
142
|
+
let(:ndr_struct) { RubySMB::Dcerpc::Ndr::NdrStruct.new }
|
143
|
+
it 'returns false if the parent is a NdrStruct' do
|
144
|
+
obj = described_class.new(nil, {}, ndr_struct)
|
145
|
+
expect(obj.process_referent?).to be false
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'returns false if one of the parents is a NdrStruct' do
|
149
|
+
obj1 = described_class.new(nil, {}, ndr_struct)
|
150
|
+
obj2 = described_class.new(nil, {}, obj1)
|
151
|
+
obj3 = described_class.new(nil, {}, obj2)
|
152
|
+
obj4 = described_class.new(nil, {}, obj3)
|
153
|
+
obj5 = described_class.new(nil, {}, obj4)
|
154
|
+
expect(obj5.process_referent?).to be false
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'returns true if none of the parents is a NdrStruct' do
|
158
|
+
obj1 = described_class.new
|
159
|
+
obj2 = described_class.new(nil, {}, obj1)
|
160
|
+
obj3 = described_class.new(nil, {}, obj2)
|
161
|
+
obj4 = described_class.new(nil, {}, obj3)
|
162
|
+
obj5 = described_class.new(nil, {}, obj4)
|
163
|
+
expect(obj5.process_referent?).to be true
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#read' do
|
168
|
+
let(:struct) do
|
169
|
+
Class.new(described_class) do
|
170
|
+
attr_accessor :str_length
|
171
|
+
endian :little
|
172
|
+
string :referent, read_length: -> { self.str_length }
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'with a null string' do
|
177
|
+
it 'reads its own binary representation' do
|
178
|
+
raw = packet.to_binary_s
|
179
|
+
expect(struct.read(raw)).to eq(packet)
|
180
|
+
expect(struct.read(raw).to_binary_s).to eq(raw)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'with a normal string' do
|
185
|
+
it 'reads its own binary representation' do
|
186
|
+
packet.set('testing')
|
187
|
+
raw = packet.to_binary_s
|
188
|
+
struct_obj = struct.new
|
189
|
+
struct_obj.str_length = 'testing'.size
|
190
|
+
expect(struct_obj.read(raw)).to eq(packet)
|
191
|
+
expect(struct_obj.read(raw).to_binary_s).to eq(raw)
|
192
|
+
end
|
51
193
|
end
|
52
194
|
end
|
53
195
|
end
|
@@ -120,6 +262,24 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrString do
|
|
120
262
|
packet.set(0)
|
121
263
|
expect(packet.actual_count).to eq(0)
|
122
264
|
end
|
265
|
+
|
266
|
+
it 'clears #str' do
|
267
|
+
expect(packet.str).to receive(:clear)
|
268
|
+
packet.set(0)
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'keeps #actual_count set to 0 when called from #to_binary_s' do
|
272
|
+
packet.set(0)
|
273
|
+
packet.to_binary_s
|
274
|
+
expect(packet.actual_count).to eq(0)
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'keeps #actual_count set to 0 when called from #do_num_bytes' do
|
278
|
+
packet.set(0)
|
279
|
+
packet.to_binary_s
|
280
|
+
packet.do_num_bytes
|
281
|
+
expect(packet.actual_count).to eq(0)
|
282
|
+
end
|
123
283
|
end
|
124
284
|
|
125
285
|
context 'when the value is a string' do
|
@@ -136,13 +296,123 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrString do
|
|
136
296
|
expect(packet.max_count).to eq(str.length + 1)
|
137
297
|
expect(packet.actual_count).to eq(str.length + 1)
|
138
298
|
end
|
299
|
+
|
300
|
+
it 'sets #actual_count to 0 when the value is an empty string' do
|
301
|
+
packet.actual_count = 10
|
302
|
+
packet.set('')
|
303
|
+
expect(packet.actual_count).to eq(0)
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'keeps custom #max_count and #offset values when called from #to_binary_s' do
|
307
|
+
packet.set(str)
|
308
|
+
packet.max_count = 3
|
309
|
+
packet.offset = 10
|
310
|
+
packet.to_binary_s
|
311
|
+
expect(packet.max_count).to eq(3)
|
312
|
+
expect(packet.offset).to eq(10)
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'keeps custom #max_count value when called from #do_num_bytes' do
|
316
|
+
packet.set(str)
|
317
|
+
packet.max_count = 3
|
318
|
+
packet.offset = 10
|
319
|
+
packet.do_num_bytes
|
320
|
+
expect(packet.max_count).to eq(3)
|
321
|
+
expect(packet.offset).to eq(10)
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'sets #max_count to the number of elements set after setting custom #max_count value' do
|
325
|
+
packet.set(str)
|
326
|
+
packet.max_count = 3
|
327
|
+
packet.set(str * 2)
|
328
|
+
expect(packet.max_count).to eq(str.size * 2 + 1)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe '#clear' do
|
334
|
+
it 'clears #str' do
|
335
|
+
expect(packet.str).to receive(:clear)
|
336
|
+
packet.clear
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'clears #actual_count' do
|
340
|
+
expect(packet.actual_count).to receive(:clear)
|
341
|
+
packet.clear
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'does to clear out #max_count and #offset' do
|
345
|
+
expect(packet.max_count).to_not receive(:clear)
|
346
|
+
expect(packet.offset).to_not receive(:clear)
|
347
|
+
packet.clear
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
describe '#to_s' do
|
352
|
+
it 'calls str#to_s' do
|
353
|
+
expect(packet.str).to receive(:to_s)
|
354
|
+
packet.to_s
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'outputs the expected string with the correct encoding' do
|
358
|
+
str = 'testing'
|
359
|
+
packet.assign(str)
|
360
|
+
expect(packet.to_s.encoding).to eq(Encoding::UTF_16LE)
|
361
|
+
expect(packet.to_s).to eq(str.encode(Encoding::UTF_16LE))
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe '#read' do
|
366
|
+
context 'with a null string' do
|
367
|
+
it 'reads its own binary representation' do
|
368
|
+
packet.set(0)
|
369
|
+
raw = packet.to_binary_s
|
370
|
+
expect(described_class.read(raw)).to eq(packet)
|
371
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
context 'with a normal string' do
|
376
|
+
it 'reads its own binary representation' do
|
377
|
+
packet.set('testing')
|
378
|
+
raw = packet.to_binary_s
|
379
|
+
expect(described_class.read(raw)).to eq(packet)
|
380
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
context 'with different #offset and #max_count values' do
|
385
|
+
it 'reads its own binary representation' do
|
386
|
+
packet.set('testing')
|
387
|
+
packet.max_count = 256
|
388
|
+
packet.offset = 40
|
389
|
+
raw = packet.to_binary_s
|
390
|
+
expect(described_class.read(raw)).to eq(packet)
|
391
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
context 'with #actual_count less than elements size' do
|
396
|
+
it 'reads its own binary representation reduced to #actual_count elements' do
|
397
|
+
str = '12345'
|
398
|
+
packet.set(str)
|
399
|
+
packet.actual_count = 4
|
400
|
+
max_count = packet.max_count.to_i
|
401
|
+
raw = packet.to_binary_s
|
402
|
+
packet2 = described_class.read(raw)
|
403
|
+
expect(packet2.max_count).to eq(max_count)
|
404
|
+
expect(packet2.offset).to eq(0)
|
405
|
+
expect(packet2.actual_count).to eq(4)
|
406
|
+
expect(packet2.str).to eq(str[0,3].encode(Encoding::UTF_16LE))
|
407
|
+
expect(packet2.to_binary_s).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x001\x002\x003\x00\x00\x00".b)
|
408
|
+
end
|
139
409
|
end
|
140
410
|
end
|
141
411
|
end
|
142
412
|
|
143
413
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpStr do
|
144
|
-
it 'is
|
145
|
-
expect(described_class).to be < RubySMB::Dcerpc::Ndr::
|
414
|
+
it 'is NdrPointer subclass' do
|
415
|
+
expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrPointer
|
146
416
|
end
|
147
417
|
|
148
418
|
subject(:packet) { described_class.new }
|
@@ -158,25 +428,33 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpStr do
|
|
158
428
|
expect(packet.referent).to be_a RubySMB::Dcerpc::Ndr::NdrString
|
159
429
|
end
|
160
430
|
|
161
|
-
it 'exists if superclass #
|
431
|
+
it 'exists if superclass #referent_id is not zero' do
|
432
|
+
packet.referent_id = 0xCCCC
|
162
433
|
expect(packet.referent?).to be true
|
163
434
|
end
|
164
435
|
|
165
|
-
it 'does not exist if superclass #
|
166
|
-
packet.
|
436
|
+
it 'does not exist if superclass #referent_id is zero' do
|
437
|
+
packet.referent_id = 0
|
167
438
|
expect(packet.referent?).to be false
|
168
439
|
end
|
169
440
|
end
|
170
441
|
|
171
|
-
describe '#
|
172
|
-
|
173
|
-
|
174
|
-
|
442
|
+
describe '#read' do
|
443
|
+
context 'with a null pointer' do
|
444
|
+
it 'reads its own binary representation' do
|
445
|
+
raw = packet.to_binary_s
|
446
|
+
expect(described_class.read(raw)).to eq(packet)
|
447
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
448
|
+
end
|
175
449
|
end
|
176
450
|
|
177
|
-
|
178
|
-
|
179
|
-
|
451
|
+
context 'with a normal string' do
|
452
|
+
it 'reads its own binary representation' do
|
453
|
+
packet.set('testing')
|
454
|
+
raw = packet.to_binary_s
|
455
|
+
expect(described_class.read(raw)).to eq(packet)
|
456
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
457
|
+
end
|
180
458
|
end
|
181
459
|
end
|
182
460
|
end
|
@@ -242,11 +520,42 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrContextHandle do
|
|
242
520
|
end
|
243
521
|
end
|
244
522
|
end
|
523
|
+
|
524
|
+
describe '#read' do
|
525
|
+
context 'with a hash' do
|
526
|
+
it 'reads its own binary representation' do
|
527
|
+
packet.set({context_handle_attributes: attr, context_handle_uuid: uuid})
|
528
|
+
raw = packet.to_binary_s
|
529
|
+
expect(described_class.read(raw)).to eq(packet)
|
530
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
context 'with a NdrContextHandle' do
|
535
|
+
it 'reads its own binary representation' do
|
536
|
+
nch = described_class.new
|
537
|
+
nch.set({context_handle_attributes: attr, context_handle_uuid: uuid})
|
538
|
+
packet.set(nch)
|
539
|
+
raw = packet.to_binary_s
|
540
|
+
expect(described_class.read(raw)).to eq(packet)
|
541
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
context 'with a binary string' do
|
546
|
+
it 'reads its own binary representation' do
|
547
|
+
packet.set("{\x00\x00\x00\r\xE7\xBC\xC3UQ+G\x9F/\xB8$\xE5\xFC\x9B`".b)
|
548
|
+
raw = packet.to_binary_s
|
549
|
+
expect(described_class.read(raw)).to eq(packet)
|
550
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
245
554
|
end
|
246
555
|
|
247
556
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpDword do
|
248
|
-
it 'is
|
249
|
-
expect(described_class).to be < RubySMB::Dcerpc::Ndr::
|
557
|
+
it 'is NdrPointer subclass' do
|
558
|
+
expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrPointer
|
250
559
|
end
|
251
560
|
|
252
561
|
subject(:packet) { described_class.new }
|
@@ -262,40 +571,251 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpDword do
|
|
262
571
|
expect(packet.referent).to be_a BinData::Uint32le
|
263
572
|
end
|
264
573
|
|
265
|
-
it 'exists if superclass #
|
574
|
+
it 'exists if superclass #referent_id is not zero' do
|
575
|
+
packet.referent_id = 0xCCCC
|
576
|
+
expect(packet.referent?).to be true
|
577
|
+
end
|
578
|
+
|
579
|
+
it 'does not exist if superclass #referent_id is zero' do
|
580
|
+
packet.referent_id = 0
|
581
|
+
expect(packet.referent?).to be false
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
describe '#read' do
|
586
|
+
context 'with a null pointer' do
|
587
|
+
it 'reads its own binary representation' do
|
588
|
+
raw = packet.to_binary_s
|
589
|
+
expect(described_class.read(raw)).to eq(packet)
|
590
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
591
|
+
end
|
592
|
+
end
|
593
|
+
|
594
|
+
context 'with a normal integer' do
|
595
|
+
it 'reads its own binary representation' do
|
596
|
+
packet.set(123)
|
597
|
+
raw = packet.to_binary_s
|
598
|
+
expect(described_class.read(raw)).to eq(packet)
|
599
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpByteArray do
|
606
|
+
it 'is NdrPointer subclass' do
|
607
|
+
expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrPointer
|
608
|
+
end
|
609
|
+
|
610
|
+
subject(:packet) { described_class.new }
|
611
|
+
|
612
|
+
it { is_expected.to respond_to :referent }
|
613
|
+
|
614
|
+
it 'is little endian' do
|
615
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
616
|
+
end
|
617
|
+
|
618
|
+
describe '#referent' do
|
619
|
+
it 'is a NdrByteArray structure' do
|
620
|
+
expect(packet.referent).to be_a RubySMB::Dcerpc::Ndr::NdrByteArray
|
621
|
+
end
|
622
|
+
|
623
|
+
it 'exists if superclass #referent_id is not zero' do
|
624
|
+
packet.referent_id = 0xCCCC
|
266
625
|
expect(packet.referent?).to be true
|
267
626
|
end
|
268
627
|
|
269
|
-
it 'does not exist if superclass #
|
270
|
-
packet.
|
628
|
+
it 'does not exist if superclass #referent_id is zero' do
|
629
|
+
packet.referent_id = 0
|
271
630
|
expect(packet.referent?).to be false
|
272
631
|
end
|
273
632
|
end
|
633
|
+
|
634
|
+
describe '#set' do
|
635
|
+
it 'accepts a NdrLpByteArray structure' do
|
636
|
+
struct = described_class.new([1, 2, 3])
|
637
|
+
packet.set(struct)
|
638
|
+
expect(packet).to eq(struct)
|
639
|
+
end
|
640
|
+
|
641
|
+
it 'accepts a NdrLpByteArray null pointer' do
|
642
|
+
struct = described_class.new
|
643
|
+
packet.set(struct)
|
644
|
+
expect(packet).to eq(:null)
|
645
|
+
end
|
646
|
+
|
647
|
+
it 'accepts a BinData::Array' do
|
648
|
+
struct = BinData::Array.new([1, 2, 3], type: :uint8)
|
649
|
+
packet.set(struct)
|
650
|
+
expect(packet).to eq(struct)
|
651
|
+
end
|
652
|
+
|
653
|
+
it 'accepts an Array' do
|
654
|
+
struct = Array.new([1, 2, 3])
|
655
|
+
packet.set(struct)
|
656
|
+
expect(packet).to eq(struct)
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
describe '#read' do
|
661
|
+
context 'with a null pointer' do
|
662
|
+
it 'reads its own binary representation' do
|
663
|
+
raw = packet.to_binary_s
|
664
|
+
expect(described_class.read(raw)).to eq(packet)
|
665
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
context 'with a normal array of bytes' do
|
670
|
+
it 'reads its own binary representation' do
|
671
|
+
packet.set([1, 2, 3])
|
672
|
+
raw = packet.to_binary_s
|
673
|
+
expect(described_class.read(raw)).to eq(packet)
|
674
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
675
|
+
end
|
676
|
+
end
|
677
|
+
end
|
274
678
|
end
|
275
679
|
|
276
680
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpByte do
|
277
681
|
subject(:packet) { described_class.new }
|
278
682
|
|
279
|
-
it { is_expected.to respond_to :referent_identifier }
|
280
683
|
it { is_expected.to respond_to :max_count }
|
281
|
-
it { is_expected.to respond_to :
|
282
|
-
it { is_expected.to respond_to :actual_count }
|
283
|
-
it { is_expected.to respond_to :bytes }
|
684
|
+
it { is_expected.to respond_to :elements }
|
284
685
|
|
285
686
|
it 'is little endian' do
|
286
687
|
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
287
688
|
end
|
288
689
|
|
289
|
-
describe '#
|
690
|
+
describe '#max_count' do
|
290
691
|
it 'is a 32-bit unsigned integer' do
|
291
|
-
expect(packet.
|
692
|
+
expect(packet.max_count).to be_a BinData::Uint32le
|
693
|
+
end
|
694
|
+
|
695
|
+
it 'has an initial value equal to #elements size' do
|
696
|
+
packet.elements = [1, 2, 3]
|
697
|
+
expect(packet.max_count).to eq(3)
|
698
|
+
end
|
699
|
+
end
|
700
|
+
|
701
|
+
describe '#elements' do
|
702
|
+
it 'is a Bindata::Array' do
|
703
|
+
expect(packet.elements).to be_a BinData::Array
|
704
|
+
end
|
705
|
+
|
706
|
+
it 'is 8-bit unsigned integer elements' do
|
707
|
+
expect(packet.elements[0]).to be_a BinData::Uint8
|
708
|
+
end
|
709
|
+
|
710
|
+
it 'exists if #max_count is greater than 0' do
|
711
|
+
packet.max_count = 2
|
712
|
+
expect(packet.elements?).to be true
|
713
|
+
end
|
714
|
+
|
715
|
+
it 'does not exist if #max_count is 0' do
|
716
|
+
packet.max_count = 0
|
717
|
+
expect(packet.elements?).to be false
|
718
|
+
end
|
719
|
+
|
720
|
+
it 'reads at most #max_counts elements' do
|
721
|
+
bin = "ABCDEFG".b
|
722
|
+
packet.max_count = 3
|
723
|
+
packet.elements.read(bin)
|
724
|
+
expect(packet.elements).to eq(bin.bytes[0,3])
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
describe '#get' do
|
729
|
+
it 'returns the elements' do
|
730
|
+
packet.elements = [1, 2, 3]
|
731
|
+
expect(packet.get).to eq([1, 2, 3])
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
describe '#set' do
|
736
|
+
it 'sets #elements as expected' do
|
737
|
+
packet.set([1, 2, 3])
|
738
|
+
expect(packet.elements).to eq([1, 2, 3])
|
739
|
+
end
|
740
|
+
|
741
|
+
it 'sets #max_count to the number of elements set' do
|
742
|
+
packet.set([1, 2, 3])
|
743
|
+
expect(packet.max_count).to eq(3)
|
292
744
|
end
|
293
745
|
|
294
|
-
it '
|
295
|
-
|
746
|
+
it 'calls #to_ary before setting the elements' do
|
747
|
+
ary = BinData::Array.new([1, 2, 3], type: :uint8)
|
748
|
+
expect(ary).to receive(:to_ary).and_call_original
|
749
|
+
packet.set(ary)
|
750
|
+
expect(packet.elements).to eq([1, 2, 3])
|
751
|
+
end
|
752
|
+
|
753
|
+
it 'keeps custom #max_count value when called from #to_binary_s' do
|
754
|
+
packet.set([1, 2, 3, 4, 5])
|
755
|
+
packet.max_count = 3
|
756
|
+
packet.to_binary_s
|
757
|
+
expect(packet.max_count).to eq(3)
|
758
|
+
end
|
759
|
+
|
760
|
+
it 'keeps custom #max_count value when called from #do_num_bytes' do
|
761
|
+
packet.set([1, 2, 3, 4, 5])
|
762
|
+
packet.max_count = 3
|
763
|
+
packet.do_num_bytes
|
764
|
+
expect(packet.max_count).to eq(3)
|
765
|
+
end
|
766
|
+
|
767
|
+
it 'sets #max_count to the number of elements set after setting custom #max_count value' do
|
768
|
+
packet.set([1, 2, 3, 4, 5])
|
769
|
+
packet.max_count = 3
|
770
|
+
packet.set([1, 2, 3, 4, 5])
|
771
|
+
expect(packet.max_count).to eq(5)
|
296
772
|
end
|
297
773
|
end
|
298
774
|
|
775
|
+
describe '#read' do
|
776
|
+
context 'with a no elements' do
|
777
|
+
it 'reads its own binary representation' do
|
778
|
+
raw = packet.to_binary_s
|
779
|
+
expect(described_class.read(raw)).to eq(packet)
|
780
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
781
|
+
end
|
782
|
+
end
|
783
|
+
|
784
|
+
context 'with some elements' do
|
785
|
+
it 'reads its own binary representation' do
|
786
|
+
packet.set([1, 2, 3])
|
787
|
+
raw = packet.to_binary_s
|
788
|
+
expect(described_class.read(raw)).to eq(packet)
|
789
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
793
|
+
context 'with #max_count less than elements size' do
|
794
|
+
it 'reads its own binary representation reduced to #max_count elements' do
|
795
|
+
packet.set([1, 2, 3, 4, 5])
|
796
|
+
packet.max_count = 3
|
797
|
+
raw = packet.to_binary_s
|
798
|
+
packet2 = described_class.new([1, 2, 3])
|
799
|
+
raw2 = packet2.to_binary_s
|
800
|
+
expect(described_class.read(raw)).to eq(packet2)
|
801
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw2)
|
802
|
+
end
|
803
|
+
end
|
804
|
+
end
|
805
|
+
end
|
806
|
+
|
807
|
+
RSpec.describe RubySMB::Dcerpc::Ndr::NdrByteArray do
|
808
|
+
subject(:packet) { described_class.new }
|
809
|
+
|
810
|
+
it { is_expected.to respond_to :max_count }
|
811
|
+
it { is_expected.to respond_to :offset }
|
812
|
+
it { is_expected.to respond_to :actual_count }
|
813
|
+
it { is_expected.to respond_to :bytes }
|
814
|
+
|
815
|
+
it 'is little endian' do
|
816
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
817
|
+
end
|
818
|
+
|
299
819
|
describe '#max_count' do
|
300
820
|
it 'is a 32-bit unsigned integer' do
|
301
821
|
expect(packet.max_count).to be_a BinData::Uint32le
|
@@ -305,15 +825,6 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpByte do
|
|
305
825
|
packet.actual_count = 345
|
306
826
|
expect(packet.max_count).to eq(345)
|
307
827
|
end
|
308
|
-
|
309
|
-
it 'exists if #referent_identifier is not zero' do
|
310
|
-
expect(packet.max_count?).to be true
|
311
|
-
end
|
312
|
-
|
313
|
-
it 'does not exist if #referent_identifier is zero' do
|
314
|
-
packet.referent_identifier = 0
|
315
|
-
expect(packet.max_count?).to be false
|
316
|
-
end
|
317
828
|
end
|
318
829
|
|
319
830
|
describe '#offset' do
|
@@ -324,15 +835,6 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpByte do
|
|
324
835
|
it 'has an initial value of 0' do
|
325
836
|
expect(packet.offset).to eq(0)
|
326
837
|
end
|
327
|
-
|
328
|
-
it 'exists if #referent_identifier is not zero' do
|
329
|
-
expect(packet.offset?).to be true
|
330
|
-
end
|
331
|
-
|
332
|
-
it 'does not exist if #referent_identifier is zero' do
|
333
|
-
packet.referent_identifier = 0
|
334
|
-
expect(packet.offset?).to be false
|
335
|
-
end
|
336
838
|
end
|
337
839
|
|
338
840
|
describe '#actual_count' do
|
@@ -344,15 +846,6 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpByte do
|
|
344
846
|
packet.bytes << 2 << 3 << 4 << 5
|
345
847
|
expect(packet.actual_count).to eq(4)
|
346
848
|
end
|
347
|
-
|
348
|
-
it 'exists if #referent_identifier is not zero' do
|
349
|
-
expect(packet.actual_count?).to be true
|
350
|
-
end
|
351
|
-
|
352
|
-
it 'does not exist if #referent_identifier is zero' do
|
353
|
-
packet.referent_identifier = 0
|
354
|
-
expect(packet.actual_count?).to be false
|
355
|
-
end
|
356
849
|
end
|
357
850
|
|
358
851
|
describe '#bytes' do
|
@@ -368,21 +861,98 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpByte do
|
|
368
861
|
it 'is 8-bit unsigned integer elements' do
|
369
862
|
expect(packet.bytes[0]).to be_a BinData::Uint8
|
370
863
|
end
|
864
|
+
end
|
865
|
+
|
866
|
+
describe '#get' do
|
867
|
+
it 'returns bytes' do
|
868
|
+
packet.bytes = [1, 2, 3]
|
869
|
+
expect(packet.get).to eq([1, 2, 3])
|
870
|
+
end
|
871
|
+
end
|
872
|
+
|
873
|
+
describe '#set' do
|
874
|
+
it 'sets #bytes as expected' do
|
875
|
+
packet.set([1, 2, 3])
|
876
|
+
expect(packet.bytes).to eq([1, 2, 3])
|
877
|
+
end
|
878
|
+
|
879
|
+
it 'sets #actual_count and #max_count to the number of bytes set' do
|
880
|
+
packet.set([1, 2, 3])
|
881
|
+
expect(packet.max_count).to eq(3)
|
882
|
+
expect(packet.actual_count).to eq(3)
|
883
|
+
end
|
884
|
+
|
885
|
+
it 'calls #to_ary before setting the elements' do
|
886
|
+
ary = BinData::Array.new([1, 2, 3], type: :uint8)
|
887
|
+
expect(ary).to receive(:to_ary).and_call_original
|
888
|
+
packet.set(ary)
|
889
|
+
expect(packet.bytes).to eq([1, 2, 3])
|
890
|
+
end
|
891
|
+
|
892
|
+
it 'keeps custom #max_count and #offset values when called from #to_binary_s' do
|
893
|
+
packet.set([1, 2, 3, 4, 5])
|
894
|
+
packet.max_count = 3
|
895
|
+
packet.offset = 40
|
896
|
+
packet.to_binary_s
|
897
|
+
expect(packet.max_count).to eq(3)
|
898
|
+
expect(packet.offset).to eq(40)
|
899
|
+
end
|
900
|
+
|
901
|
+
it 'keeps custom #max_count and #offset values when called from #do_num_bytes' do
|
902
|
+
packet.set([1, 2, 3, 4, 5])
|
903
|
+
packet.max_count = 3
|
904
|
+
packet.offset = 40
|
905
|
+
packet.do_num_bytes
|
906
|
+
expect(packet.max_count).to eq(3)
|
907
|
+
expect(packet.offset).to eq(40)
|
908
|
+
end
|
909
|
+
|
910
|
+
it 'sets #max_count to the number of bytes set after setting custom #max_count value' do
|
911
|
+
packet.set([1, 2, 3, 4, 5])
|
912
|
+
packet.max_count = 3
|
913
|
+
packet.set([1, 2, 3, 4, 5])
|
914
|
+
expect(packet.max_count).to eq(5)
|
915
|
+
end
|
916
|
+
end
|
917
|
+
|
918
|
+
describe '#read' do
|
919
|
+
context 'with a no elements' do
|
920
|
+
it 'reads its own binary representation' do
|
921
|
+
raw = packet.to_binary_s
|
922
|
+
expect(described_class.read(raw)).to eq(packet)
|
923
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
924
|
+
end
|
925
|
+
end
|
371
926
|
|
372
|
-
|
373
|
-
|
927
|
+
context 'with some elements' do
|
928
|
+
it 'reads its own binary representation' do
|
929
|
+
packet.set([1, 2, 3])
|
930
|
+
raw = packet.to_binary_s
|
931
|
+
expect(described_class.read(raw)).to eq(packet)
|
932
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
933
|
+
end
|
374
934
|
end
|
375
935
|
|
376
|
-
|
377
|
-
|
378
|
-
|
936
|
+
context 'with #max_count less than elements size' do
|
937
|
+
it 'reads its own binary representation reduced to #max_count elements' do
|
938
|
+
packet.set([1, 2, 3, 4, 5])
|
939
|
+
packet.actual_count = 3
|
940
|
+
max_count = packet.max_count.to_i
|
941
|
+
raw = packet.to_binary_s
|
942
|
+
packet2 = described_class.read(raw)
|
943
|
+
expect(packet2.max_count).to eq(max_count)
|
944
|
+
expect(packet2.offset).to eq(0)
|
945
|
+
expect(packet2.actual_count).to eq(3)
|
946
|
+
expect(packet2.bytes).to eq([1, 2, 3])
|
947
|
+
expect(packet2.to_binary_s).to eq("\x05\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x02\x03".b)
|
948
|
+
end
|
379
949
|
end
|
380
950
|
end
|
381
951
|
end
|
382
952
|
|
383
953
|
RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpFileTime do
|
384
|
-
it 'is
|
385
|
-
expect(described_class).to be < RubySMB::Dcerpc::Ndr::
|
954
|
+
it 'is NdrPointer subclass' do
|
955
|
+
expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrPointer
|
386
956
|
end
|
387
957
|
|
388
958
|
subject(:packet) { described_class.new }
|
@@ -398,13 +968,762 @@ RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpFileTime do
|
|
398
968
|
expect(packet.referent).to be_a RubySMB::Field::FileTime
|
399
969
|
end
|
400
970
|
|
401
|
-
it 'exists if superclass #
|
971
|
+
it 'exists if superclass #referent_id is not zero' do
|
972
|
+
packet.referent_id = 0xCCCC
|
402
973
|
expect(packet.referent?).to be true
|
403
974
|
end
|
404
975
|
|
405
|
-
it 'does not exist if superclass #
|
406
|
-
packet.
|
976
|
+
it 'does not exist if superclass #referent_id is zero' do
|
977
|
+
packet.referent_id = 0
|
407
978
|
expect(packet.referent?).to be false
|
408
979
|
end
|
409
980
|
end
|
981
|
+
|
982
|
+
describe '#read' do
|
983
|
+
context 'with a null pointer' do
|
984
|
+
it 'reads its own binary representation' do
|
985
|
+
raw = packet.to_binary_s
|
986
|
+
expect(described_class.read(raw)).to eq(packet)
|
987
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
988
|
+
end
|
989
|
+
end
|
990
|
+
|
991
|
+
context 'with a normal FileTime' do
|
992
|
+
it 'reads its own binary representation' do
|
993
|
+
time = RubySMB::Field::FileTime.new(Time.now)
|
994
|
+
packet.set(time)
|
995
|
+
raw = packet.to_binary_s
|
996
|
+
expect(described_class.read(raw)).to eq(packet)
|
997
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
998
|
+
end
|
999
|
+
end
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
RSpec.describe RubySMB::Dcerpc::Ndr::NdrStruct do
|
1004
|
+
describe '#do_read' do
|
1005
|
+
let(:io) { BinData::IO::Read.new(bin_str) }
|
1006
|
+
context 'with a structure containg an array of pointers to integer' do
|
1007
|
+
subject(:struct) do
|
1008
|
+
Class.new(described_class) do
|
1009
|
+
endian :little
|
1010
|
+
uint32 :a
|
1011
|
+
array :b, type: :ndr_lp_dword, read_until: -> { index == a - 1 }
|
1012
|
+
uint32 :c
|
1013
|
+
end.new
|
1014
|
+
end
|
1015
|
+
|
1016
|
+
context 'without null pointers' do
|
1017
|
+
let(:bin_str) do
|
1018
|
+
"\x03\x00\x00\x00" + # a
|
1019
|
+
"\xA8\xC9\x1D\x9D" + # b[0] referent_id
|
1020
|
+
"&_>=" + # b[1] referent_id
|
1021
|
+
"T\r%\x18" + # b[2] referent_id
|
1022
|
+
"7\x00\x00\x00" + # c
|
1023
|
+
"\x01\x00\x00\x00" + # b[0]
|
1024
|
+
"\x02\x00\x00\x00" + # b[1]
|
1025
|
+
"\x03\x00\x00\x00" # b[2]
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
it 'reads as expected' do
|
1029
|
+
struct.do_read(io)
|
1030
|
+
expect(struct.a).to eq(3)
|
1031
|
+
expect(struct.b).to eq([1, 2, 3])
|
1032
|
+
expect(struct.b[0].referent_id).to eq(2635975080)
|
1033
|
+
expect(struct.b[0].referent).to eq(1)
|
1034
|
+
expect(struct.b[1].referent_id).to eq(1027497766)
|
1035
|
+
expect(struct.b[1].referent).to eq(2)
|
1036
|
+
expect(struct.b[2].referent_id).to eq(405081428)
|
1037
|
+
expect(struct.b[2].referent).to eq(3)
|
1038
|
+
expect(struct.c).to eq(55)
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
context 'with null pointers' do
|
1043
|
+
let(:bin_str) do
|
1044
|
+
"\x03\x00\x00\x00" + # a
|
1045
|
+
"\xA8\xC9\x1D\x9D" + # b[0] referent_id
|
1046
|
+
"\x00\x00\x00\x00" + # b[1] referent_id (null)
|
1047
|
+
"T\r%\x18" + # b[2] referent_id
|
1048
|
+
"7\x00\x00\x00" + # c
|
1049
|
+
"\x01\x00\x00\x00" + # b[0]
|
1050
|
+
"\x03\x00\x00\x00" # b[2]
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
it 'reads as expected' do
|
1054
|
+
struct.do_read(io)
|
1055
|
+
expect(struct.a).to eq(3)
|
1056
|
+
expect(struct.b).to eq([1, :null, 3])
|
1057
|
+
expect(struct.b[0].referent_id).to eq(2635975080)
|
1058
|
+
expect(struct.b[0].referent).to eq(1)
|
1059
|
+
expect(struct.b[1].referent_id).to eq(0)
|
1060
|
+
expect(struct.b[2].referent_id).to eq(405081428)
|
1061
|
+
expect(struct.b[2].referent).to eq(3)
|
1062
|
+
expect(struct.c).to eq(55)
|
1063
|
+
end
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
context 'with a structure containg an array of pointers to strings' do
|
1068
|
+
subject(:struct) do
|
1069
|
+
Class.new(described_class) do
|
1070
|
+
endian :little
|
1071
|
+
uint32 :a
|
1072
|
+
array :b, type: :ndr_lp_str, read_until: -> { index == a - 1 }
|
1073
|
+
uint32 :c
|
1074
|
+
end.new
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
context 'without null pointers' do
|
1078
|
+
let(:bin_str) do
|
1079
|
+
"\x03\x00\x00\x00" + # a
|
1080
|
+
"\xA8\xC9\x1D\x9D" + # b[0] referent_id
|
1081
|
+
"&_>=" + # b[1] referent_id
|
1082
|
+
"T\r%\x18" + # b[2] referent_id
|
1083
|
+
"7\x00\x00\x00" + # c
|
1084
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00" + # b[0]
|
1085
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x002\x00\x00\x00" + # b[1]
|
1086
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # b[2]
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
it 'reads as expected' do
|
1090
|
+
struct.do_read(io)
|
1091
|
+
str1 = 'test1'.encode(Encoding::UTF_16LE)
|
1092
|
+
str2 = 'test2'.encode(Encoding::UTF_16LE)
|
1093
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1094
|
+
expect(struct.a).to eq(3)
|
1095
|
+
expect(struct.b).to eq([str1, str2, str3])
|
1096
|
+
expect(struct.b[0].referent_id).to eq(2635975080)
|
1097
|
+
expect(struct.b[0].referent).to eq(str1)
|
1098
|
+
expect(struct.b[1].referent_id).to eq(1027497766)
|
1099
|
+
expect(struct.b[1].referent).to eq(str2)
|
1100
|
+
expect(struct.b[2].referent_id).to eq(405081428)
|
1101
|
+
expect(struct.b[2].referent).to eq(str3)
|
1102
|
+
expect(struct.c).to eq(55)
|
1103
|
+
end
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
context 'with null pointers' do
|
1107
|
+
let(:bin_str) do
|
1108
|
+
"\x03\x00\x00\x00" + # a
|
1109
|
+
"\xA8\xC9\x1D\x9D" + # b[0] referent_id
|
1110
|
+
"\x00\x00\x00\x00" + # b[1] referent_id (null)
|
1111
|
+
"T\r%\x18" + # b[2] referent_id
|
1112
|
+
"7\x00\x00\x00" + # c
|
1113
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00" + # b[0]
|
1114
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # b[2]
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
it 'reads as expected' do
|
1118
|
+
struct.do_read(io)
|
1119
|
+
str1 = 'test1'.encode(Encoding::UTF_16LE)
|
1120
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1121
|
+
expect(struct.a).to eq(3)
|
1122
|
+
expect(struct.b).to eq([str1, :null, str3])
|
1123
|
+
expect(struct.b[0].referent_id).to eq(2635975080)
|
1124
|
+
expect(struct.b[0].referent).to eq(str1)
|
1125
|
+
expect(struct.b[1].referent_id).to eq(0)
|
1126
|
+
expect(struct.b[2].referent_id).to eq(405081428)
|
1127
|
+
expect(struct.b[2].referent).to eq(str3)
|
1128
|
+
expect(struct.c).to eq(55)
|
1129
|
+
end
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
context 'with null strings' do
|
1133
|
+
let(:bin_str) do
|
1134
|
+
"\x03\x00\x00\x00" + # a
|
1135
|
+
"\xA8\xC9\x1D\x9D" + # b[0] referent_id
|
1136
|
+
"&_>=" + # b[1] referent_id
|
1137
|
+
"T\r%\x18" + # b[2] referent_id
|
1138
|
+
"7\x00\x00\x00" + # c
|
1139
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00" + # b[0]
|
1140
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + # b[1] null string
|
1141
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # b[2]
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
it 'reads as expected' do
|
1145
|
+
struct.do_read(io)
|
1146
|
+
str1 = 'test1'.encode(Encoding::UTF_16LE)
|
1147
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1148
|
+
expect(struct.a).to eq(3)
|
1149
|
+
expect(struct.b).to eq([str1, 0, str3])
|
1150
|
+
expect(struct.b[0].referent_id).to eq(2635975080)
|
1151
|
+
expect(struct.b[0].referent).to eq(str1)
|
1152
|
+
expect(struct.b[1].referent_id).to eq(1027497766)
|
1153
|
+
expect(struct.b[1].referent).to eq(0)
|
1154
|
+
expect(struct.b[2].referent_id).to eq(405081428)
|
1155
|
+
expect(struct.b[2].referent).to eq(str3)
|
1156
|
+
expect(struct.c).to eq(55)
|
1157
|
+
end
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
context 'with padding' do
|
1161
|
+
let(:bin_str) do
|
1162
|
+
"\x03\x00\x00\x00" + # a
|
1163
|
+
"\xA8\xC9\x1D\x9D" + # b[0] referent_id
|
1164
|
+
"&_>=" + # b[1] referent_id
|
1165
|
+
"T\r%\x18" + # b[2] referent_id
|
1166
|
+
"7\x00\x00\x00" + # c
|
1167
|
+
"\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00t\x00e\x00s\x00t\x00\x00\x00" + # b[0]
|
1168
|
+
"\x00\x00" + # pad
|
1169
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x002\x00\x00\x00" + # b[1]
|
1170
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # b[2]
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
it 'reads as expected' do
|
1174
|
+
struct.do_read(io)
|
1175
|
+
str1 = 'test'.encode(Encoding::UTF_16LE)
|
1176
|
+
str2 = 'test2'.encode(Encoding::UTF_16LE)
|
1177
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1178
|
+
expect(struct.a).to eq(3)
|
1179
|
+
expect(struct.b).to eq([str1, str2, str3])
|
1180
|
+
expect(struct.b[0].referent_id).to eq(2635975080)
|
1181
|
+
expect(struct.b[0].referent).to eq(str1)
|
1182
|
+
expect(struct.b[1].referent_id).to eq(1027497766)
|
1183
|
+
expect(struct.b[1].referent).to eq(str2)
|
1184
|
+
expect(struct.b[2].referent_id).to eq(405081428)
|
1185
|
+
expect(struct.b[2].referent).to eq(str3)
|
1186
|
+
expect(struct.c).to eq(55)
|
1187
|
+
end
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
context 'with a structure containg an pointers to strings' do
|
1192
|
+
subject(:struct) do
|
1193
|
+
Class.new(described_class) do
|
1194
|
+
endian :little
|
1195
|
+
uint32 :a
|
1196
|
+
ndr_lp_str :b
|
1197
|
+
ndr_lp_str :c
|
1198
|
+
ndr_lp_str :d
|
1199
|
+
uint32 :e
|
1200
|
+
end.new
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
context 'without null pointers' do
|
1204
|
+
let(:bin_str) do
|
1205
|
+
"\x03\x00\x00\x00" + # a
|
1206
|
+
"\xA8\xC9\x1D\x9D" + # b referent_id
|
1207
|
+
"&_>=" + # c referent_id
|
1208
|
+
"T\r%\x18" + # d referent_id
|
1209
|
+
"7\x00\x00\x00" + # c
|
1210
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00" + # b
|
1211
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x002\x00\x00\x00" + # c
|
1212
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # d
|
1213
|
+
end
|
1214
|
+
|
1215
|
+
it 'reads as expected' do
|
1216
|
+
struct.do_read(io)
|
1217
|
+
str1 = 'test1'.encode(Encoding::UTF_16LE)
|
1218
|
+
str2 = 'test2'.encode(Encoding::UTF_16LE)
|
1219
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1220
|
+
expect(struct.a).to eq(3)
|
1221
|
+
expect(struct.b).to eq(str1)
|
1222
|
+
expect(struct.c).to eq(str2)
|
1223
|
+
expect(struct.d).to eq(str3)
|
1224
|
+
expect(struct.b.referent_id).to eq(2635975080)
|
1225
|
+
expect(struct.b.referent).to eq(str1)
|
1226
|
+
expect(struct.c.referent_id).to eq(1027497766)
|
1227
|
+
expect(struct.c.referent).to eq(str2)
|
1228
|
+
expect(struct.d.referent_id).to eq(405081428)
|
1229
|
+
expect(struct.d.referent).to eq(str3)
|
1230
|
+
expect(struct.e).to eq(55)
|
1231
|
+
end
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
context 'with null pointers' do
|
1235
|
+
let(:bin_str) do
|
1236
|
+
"\x03\x00\x00\x00" + # a
|
1237
|
+
"\xA8\xC9\x1D\x9D" + # b referent_id
|
1238
|
+
"\x00\x00\x00\x00" + # c referent_id (null)
|
1239
|
+
"T\r%\x18" + # d referent_id
|
1240
|
+
"7\x00\x00\x00" + # c
|
1241
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00" + # b
|
1242
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # d
|
1243
|
+
end
|
1244
|
+
|
1245
|
+
it 'reads as expected' do
|
1246
|
+
struct.do_read(io)
|
1247
|
+
str1 = 'test1'.encode(Encoding::UTF_16LE)
|
1248
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1249
|
+
expect(struct.a).to eq(3)
|
1250
|
+
expect(struct.b).to eq(str1)
|
1251
|
+
expect(struct.c).to eq(:null)
|
1252
|
+
expect(struct.d).to eq(str3)
|
1253
|
+
expect(struct.b.referent_id).to eq(2635975080)
|
1254
|
+
expect(struct.b.referent).to eq(str1)
|
1255
|
+
expect(struct.c.referent_id).to eq(0)
|
1256
|
+
expect(struct.d.referent_id).to eq(405081428)
|
1257
|
+
expect(struct.d.referent).to eq(str3)
|
1258
|
+
expect(struct.e).to eq(55)
|
1259
|
+
end
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
context 'with null strings' do
|
1263
|
+
let(:bin_str) do
|
1264
|
+
"\x03\x00\x00\x00" + # a
|
1265
|
+
"\xA8\xC9\x1D\x9D" + # b referent_id
|
1266
|
+
"&_>=" + # c referent_id
|
1267
|
+
"T\r%\x18" + # d referent_id
|
1268
|
+
"7\x00\x00\x00" + # c
|
1269
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00" + # b
|
1270
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + # c null string
|
1271
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # d
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
it 'reads as expected' do
|
1275
|
+
struct.do_read(io)
|
1276
|
+
str1 = 'test1'.encode(Encoding::UTF_16LE)
|
1277
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1278
|
+
expect(struct.a).to eq(3)
|
1279
|
+
expect(struct.b).to eq(str1)
|
1280
|
+
expect(struct.c).to eq(0)
|
1281
|
+
expect(struct.d).to eq(str3)
|
1282
|
+
expect(struct.b.referent_id).to eq(2635975080)
|
1283
|
+
expect(struct.b.referent).to eq(str1)
|
1284
|
+
expect(struct.c.referent_id).to eq(1027497766)
|
1285
|
+
expect(struct.c.referent).to eq(0)
|
1286
|
+
expect(struct.d.referent_id).to eq(405081428)
|
1287
|
+
expect(struct.d.referent).to eq(str3)
|
1288
|
+
expect(struct.e).to eq(55)
|
1289
|
+
end
|
1290
|
+
end
|
1291
|
+
|
1292
|
+
context 'with padding' do
|
1293
|
+
let(:bin_str) do
|
1294
|
+
"\x03\x00\x00\x00" + # a
|
1295
|
+
"\xA8\xC9\x1D\x9D" + # b referent_id
|
1296
|
+
"&_>=" + # c referent_id
|
1297
|
+
"T\r%\x18" + # d referent_id
|
1298
|
+
"7\x00\x00\x00" + # c
|
1299
|
+
"\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00t\x00e\x00s\x00t\x00\x00\x00" + # b
|
1300
|
+
"\x00\x00" + # pad
|
1301
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x002\x00\x00\x00" + # c
|
1302
|
+
"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00" # d
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
it 'reads as expected' do
|
1306
|
+
struct.do_read(io)
|
1307
|
+
str1 = 'test'.encode(Encoding::UTF_16LE)
|
1308
|
+
str2 = 'test2'.encode(Encoding::UTF_16LE)
|
1309
|
+
str3 = 'test3'.encode(Encoding::UTF_16LE)
|
1310
|
+
expect(struct.a).to eq(3)
|
1311
|
+
expect(struct.b).to eq(str1)
|
1312
|
+
expect(struct.c).to eq(str2)
|
1313
|
+
expect(struct.d).to eq(str3)
|
1314
|
+
expect(struct.b.referent_id).to eq(2635975080)
|
1315
|
+
expect(struct.b.referent).to eq(str1)
|
1316
|
+
expect(struct.c.referent_id).to eq(1027497766)
|
1317
|
+
expect(struct.c.referent).to eq(str2)
|
1318
|
+
expect(struct.d.referent_id).to eq(405081428)
|
1319
|
+
expect(struct.d.referent).to eq(str3)
|
1320
|
+
expect(struct.e).to eq(55)
|
1321
|
+
end
|
1322
|
+
end
|
1323
|
+
end
|
1324
|
+
end
|
1325
|
+
|
1326
|
+
describe '#do_write' do
|
1327
|
+
let(:raw_io) { BinData::IO.create_string_io }
|
1328
|
+
let(:io) { BinData::IO::Write.new(raw_io) }
|
1329
|
+
context 'with a structure containg an array of pointers to integer' do
|
1330
|
+
subject(:struct) do
|
1331
|
+
Class.new(described_class) do
|
1332
|
+
endian :little
|
1333
|
+
uint32 :a
|
1334
|
+
array :b, type: :ndr_lp_dword, read_until: -> { index == a - 1 }
|
1335
|
+
uint32 :c
|
1336
|
+
end.new
|
1337
|
+
end
|
1338
|
+
|
1339
|
+
context 'without null pointers' do
|
1340
|
+
let(:packet) do
|
1341
|
+
struct.new(a: 3, b: [1, 2, 3], c: 55)
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
it 'writes as expected' do
|
1345
|
+
packet.do_write(io)
|
1346
|
+
raw_io.rewind
|
1347
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1348
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[0] referent_id (random but not null)
|
1349
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[1] referent_id (random but not null)
|
1350
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[2] referent_id (random but not null)
|
1351
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # c
|
1352
|
+
expect(raw_io.read(4)).to eq("\x01\x00\x00\x00".b) # b[0]
|
1353
|
+
expect(raw_io.read(4)).to eq("\x02\x00\x00\x00".b) # b[1]
|
1354
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # b[2]
|
1355
|
+
expect(raw_io.eof).to be true
|
1356
|
+
end
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
context 'with null pointers' do
|
1360
|
+
let(:packet) do
|
1361
|
+
struct.new(a: 3, b: [1, :null, 3], c: 55)
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
it 'writes as expected' do
|
1365
|
+
packet.do_write(io)
|
1366
|
+
raw_io.rewind
|
1367
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1368
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[0] referent_id (random but not null)
|
1369
|
+
expect(raw_io.read(4)).to eq("\x00\x00\x00\x00".b) # b[1] referent_id (null)
|
1370
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[2] referent_id (random but not null)
|
1371
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # c
|
1372
|
+
expect(raw_io.read(4)).to eq("\x01\x00\x00\x00".b) # b[0]
|
1373
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # b[2]
|
1374
|
+
expect(raw_io.eof).to be true
|
1375
|
+
end
|
1376
|
+
end
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
context 'with a structure containg an array of pointers to strings' do
|
1380
|
+
subject(:struct) do
|
1381
|
+
Class.new(described_class) do
|
1382
|
+
endian :little
|
1383
|
+
uint32 :a
|
1384
|
+
array :b, type: :ndr_lp_str, read_until: -> { index == a - 1 }
|
1385
|
+
uint32 :c
|
1386
|
+
end.new
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
context 'without null pointers' do
|
1390
|
+
let(:packet) do
|
1391
|
+
struct.new(a: 3, b: ['test1', 'test2', 'test3'], c: 55)
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
it 'writes as expected' do
|
1395
|
+
packet.do_write(io)
|
1396
|
+
raw_io.rewind
|
1397
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1398
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[0] referent_id (random but not null)
|
1399
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[1] referent_id (random but not null)
|
1400
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[2] referent_id (random but not null)
|
1401
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # c
|
1402
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b[0]
|
1403
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x002\x00\x00\x00".b) # b[1]
|
1404
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # b[2]
|
1405
|
+
expect(raw_io.eof).to be true
|
1406
|
+
end
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
context 'with null pointers' do
|
1410
|
+
let(:packet) do
|
1411
|
+
struct.new(a: 3, b: ['test1', :null, 'test3'], c: 55)
|
1412
|
+
end
|
1413
|
+
|
1414
|
+
it 'writes as expected' do
|
1415
|
+
packet.do_write(io)
|
1416
|
+
raw_io.rewind
|
1417
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1418
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[0] referent_id (random but not null)
|
1419
|
+
expect(raw_io.read(4)).to eq("\x00\x00\x00\x00".b) # b[1] referent_id (null)
|
1420
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[2] referent_id (random but not null)
|
1421
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # c
|
1422
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b[0]
|
1423
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # b[2]
|
1424
|
+
expect(raw_io.eof).to be true
|
1425
|
+
end
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
context 'with null strings' do
|
1429
|
+
let(:packet) do
|
1430
|
+
struct.new(a: 3, b: ['test1', 0, 'test3'], c: 55)
|
1431
|
+
end
|
1432
|
+
|
1433
|
+
it 'writes as expected' do
|
1434
|
+
packet.do_write(io)
|
1435
|
+
raw_io.rewind
|
1436
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1437
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[0] referent_id (random but not null)
|
1438
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[1] referent_id (random but not null)
|
1439
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[2] referent_id (random but not null)
|
1440
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # c
|
1441
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b[0]
|
1442
|
+
expect(raw_io.read(12)).to eq("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".b) # b[1] null string
|
1443
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # b[2]
|
1444
|
+
expect(raw_io.eof).to be true
|
1445
|
+
end
|
1446
|
+
end
|
1447
|
+
|
1448
|
+
context 'with padding' do
|
1449
|
+
let(:packet) do
|
1450
|
+
struct.new(a: 3, b: ['test1', 'test', 'test3'], c: 55)
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
it 'writes as expected' do
|
1454
|
+
packet.do_write(io)
|
1455
|
+
raw_io.rewind
|
1456
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1457
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[0] referent_id (random but not null)
|
1458
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[1] referent_id (random but not null)
|
1459
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b[2] referent_id (random but not null)
|
1460
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # c
|
1461
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b[0]
|
1462
|
+
expect(raw_io.read(22)).to eq("\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00t\x00e\x00s\x00t\x00\x00\x00".b) # b[1]
|
1463
|
+
expect(raw_io.read(2)).to eq("\x00\x00".b) # pad
|
1464
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # b[2]
|
1465
|
+
expect(raw_io.eof).to be true
|
1466
|
+
end
|
1467
|
+
end
|
1468
|
+
end
|
1469
|
+
|
1470
|
+
context 'with a structure containg pointers to strings' do
|
1471
|
+
subject(:struct) do
|
1472
|
+
Class.new(described_class) do
|
1473
|
+
endian :little
|
1474
|
+
uint32 :a
|
1475
|
+
ndr_lp_str :b
|
1476
|
+
ndr_lp_str :c
|
1477
|
+
ndr_lp_str :d
|
1478
|
+
uint32 :e
|
1479
|
+
end.new
|
1480
|
+
end
|
1481
|
+
|
1482
|
+
context 'without null pointers' do
|
1483
|
+
let(:packet) do
|
1484
|
+
struct.new(a: 3, b: 'test1', c: 'test2', d: 'test3', e: 55)
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
it 'writes as expected' do
|
1488
|
+
packet.do_write(io)
|
1489
|
+
raw_io.rewind
|
1490
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1491
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b referent_id (random but not null)
|
1492
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # c referent_id (random but not null)
|
1493
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # d referent_id (random but not null)
|
1494
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # e
|
1495
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b
|
1496
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x002\x00\x00\x00".b) # c
|
1497
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # d
|
1498
|
+
expect(raw_io.eof).to be true
|
1499
|
+
end
|
1500
|
+
end
|
1501
|
+
|
1502
|
+
context 'with null pointers' do
|
1503
|
+
let(:packet) do
|
1504
|
+
struct.new(a: 3, b: 'test1', c: :null, d: 'test3', e: 55)
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
it 'writes as expected' do
|
1508
|
+
packet.do_write(io)
|
1509
|
+
raw_io.rewind
|
1510
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1511
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b referent_id (random but not null)
|
1512
|
+
expect(raw_io.read(4)).to eq("\x00\x00\x00\x00".b) # c referent_id (null)
|
1513
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # d referent_id (random but not null)
|
1514
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # e
|
1515
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b
|
1516
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # d
|
1517
|
+
expect(raw_io.eof).to be true
|
1518
|
+
end
|
1519
|
+
end
|
1520
|
+
|
1521
|
+
context 'with null strings' do
|
1522
|
+
let(:packet) do
|
1523
|
+
struct.new(a: 3, b: 'test1', c: 0, d: 'test3', e: 55)
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
it 'writes as expected' do
|
1527
|
+
packet.do_write(io)
|
1528
|
+
raw_io.rewind
|
1529
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1530
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b referent_id (random but not null)
|
1531
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # c referent_id (random but not null)
|
1532
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # d referent_id (random but not null)
|
1533
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # e
|
1534
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b
|
1535
|
+
expect(raw_io.read(12)).to eq("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".b) # c
|
1536
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # d
|
1537
|
+
expect(raw_io.eof).to be true
|
1538
|
+
end
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
context 'with padding' do
|
1542
|
+
let(:packet) do
|
1543
|
+
struct.new(a: 3, b: 'test1', c: 'test', d: 'test3', e: 55)
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
it 'writes as expected' do
|
1547
|
+
packet.do_write(io)
|
1548
|
+
raw_io.rewind
|
1549
|
+
expect(raw_io.read(4)).to eq("\x03\x00\x00\x00".b) # a
|
1550
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # b referent_id (random but not null)
|
1551
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # c referent_id (random but not null)
|
1552
|
+
expect(raw_io.read(4)).to_not eq("\x00\x00\x00\x00".b) # d referent_id (random but not null)
|
1553
|
+
expect(raw_io.read(4)).to eq("7\x00\x00\x00".b) # e
|
1554
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x001\x00\x00\x00".b) # b
|
1555
|
+
expect(raw_io.read(22)).to eq("\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00t\x00e\x00s\x00t\x00\x00\x00".b) # c
|
1556
|
+
expect(raw_io.read(2)).to eq("\x00\x00".b) # pad
|
1557
|
+
expect(raw_io.read(24)).to eq("\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00t\x00e\x00s\x00t\x003\x00\x00\x00".b) # d
|
1558
|
+
expect(raw_io.eof).to be true
|
1559
|
+
end
|
1560
|
+
end
|
1561
|
+
end
|
1562
|
+
end
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
RSpec.describe RubySMB::Dcerpc::Ndr::NdrStringPtrsw do
|
1566
|
+
subject(:packet) { described_class.new }
|
1567
|
+
|
1568
|
+
it { is_expected.to respond_to :max_count }
|
1569
|
+
it { is_expected.to respond_to :elements }
|
1570
|
+
|
1571
|
+
it 'is little endian' do
|
1572
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
1573
|
+
end
|
1574
|
+
|
1575
|
+
describe '#max_count' do
|
1576
|
+
it 'is a 32-bit unsigned integer' do
|
1577
|
+
expect(packet.max_count).to be_a BinData::Uint32le
|
1578
|
+
end
|
1579
|
+
|
1580
|
+
it 'has an initial value equal to #elements size' do
|
1581
|
+
packet.elements = ['A', 'B', 'C']
|
1582
|
+
expect(packet.max_count).to eq(3)
|
1583
|
+
end
|
1584
|
+
end
|
1585
|
+
|
1586
|
+
describe '#elements' do
|
1587
|
+
it 'is a Bindata::Array' do
|
1588
|
+
expect(packet.elements).to be_a BinData::Array
|
1589
|
+
end
|
1590
|
+
|
1591
|
+
it 'is an array of NdrLpStr' do
|
1592
|
+
expect(packet.elements[0]).to be_a RubySMB::Dcerpc::Ndr::NdrLpStr
|
1593
|
+
end
|
1594
|
+
|
1595
|
+
it 'exists if #max_count is greater than 0' do
|
1596
|
+
packet.max_count = 2
|
1597
|
+
expect(packet.elements?).to be true
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
it 'does not exist if #max_count is 0' do
|
1601
|
+
packet.max_count = 0
|
1602
|
+
expect(packet.elements?).to be false
|
1603
|
+
end
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
describe '#get' do
|
1607
|
+
it 'returns elements' do
|
1608
|
+
packet.elements = ['1', '2', '3']
|
1609
|
+
expect(packet.get).to eq(['1', '2', '3'].map {|e| e.encode(Encoding::UTF_16LE)})
|
1610
|
+
end
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
describe '#set' do
|
1614
|
+
it 'sets #elements as expected' do
|
1615
|
+
packet.set(['1', '2', '3'])
|
1616
|
+
expect(packet.elements).to eq(['1', '2', '3'].map {|e| e.encode(Encoding::UTF_16LE)})
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
it 'sets #max_count to the number of elements set' do
|
1620
|
+
packet.set(['1', '2', '3'])
|
1621
|
+
expect(packet.max_count).to eq(3)
|
1622
|
+
end
|
1623
|
+
|
1624
|
+
it 'calls #to_ary before setting the elements' do
|
1625
|
+
ary = BinData::Array.new(['1','2', '3'], type: :ndr_lp_str)
|
1626
|
+
expect(ary).to receive(:to_ary).and_call_original
|
1627
|
+
packet.set(ary)
|
1628
|
+
expect(packet.elements).to eq(['1', '2', '3'].map {|e| e.encode(Encoding::UTF_16LE)})
|
1629
|
+
end
|
1630
|
+
|
1631
|
+
it 'keeps custom #max_count value when called from #to_binary_s' do
|
1632
|
+
packet.set(['1', '2', '3', '4', '5'])
|
1633
|
+
packet.max_count = 3
|
1634
|
+
packet.to_binary_s
|
1635
|
+
expect(packet.max_count).to eq(3)
|
1636
|
+
end
|
1637
|
+
|
1638
|
+
it 'keeps custom #max_count and #offset values when called from #do_num_bytes' do
|
1639
|
+
packet.set(['1', '2', '3', '4', '5'])
|
1640
|
+
packet.max_count = 3
|
1641
|
+
packet.do_num_bytes
|
1642
|
+
expect(packet.max_count).to eq(3)
|
1643
|
+
end
|
1644
|
+
|
1645
|
+
it 'sets #max_count to the number of elements set after setting custom #max_count value' do
|
1646
|
+
packet.set(['1', '2', '3', '4', '5'])
|
1647
|
+
packet.max_count = 3
|
1648
|
+
packet.set(['1', '2', '3', '4', '5'])
|
1649
|
+
expect(packet.max_count).to eq(5)
|
1650
|
+
end
|
1651
|
+
end
|
1652
|
+
|
1653
|
+
describe '#read' do
|
1654
|
+
context 'with a no elements' do
|
1655
|
+
it 'reads its own binary representation' do
|
1656
|
+
raw = packet.to_binary_s
|
1657
|
+
expect(described_class.read(raw)).to eq(packet)
|
1658
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
1659
|
+
end
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
context 'with some elements' do
|
1663
|
+
it 'reads its own binary representation' do
|
1664
|
+
packet.set(['1', '2', '3'])
|
1665
|
+
raw = packet.to_binary_s
|
1666
|
+
expect(described_class.read(raw)).to eq(packet)
|
1667
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
1668
|
+
end
|
1669
|
+
end
|
1670
|
+
end
|
1671
|
+
end
|
1672
|
+
|
1673
|
+
RSpec.describe RubySMB::Dcerpc::Ndr::NdrLpStringPtrsw do
|
1674
|
+
it 'is NdrPointer subclass' do
|
1675
|
+
expect(described_class).to be < RubySMB::Dcerpc::Ndr::NdrPointer
|
1676
|
+
end
|
1677
|
+
|
1678
|
+
subject(:packet) { described_class.new }
|
1679
|
+
|
1680
|
+
it { is_expected.to respond_to :referent }
|
1681
|
+
|
1682
|
+
it 'is little endian' do
|
1683
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
1684
|
+
end
|
1685
|
+
|
1686
|
+
describe '#referent' do
|
1687
|
+
it 'is a NdrStringPtrsw structure' do
|
1688
|
+
expect(packet.referent).to be_a RubySMB::Dcerpc::Ndr::NdrStringPtrsw
|
1689
|
+
end
|
1690
|
+
|
1691
|
+
it 'exists if superclass #referent_id is not zero' do
|
1692
|
+
packet.referent_id = 0xCCCC
|
1693
|
+
expect(packet.referent?).to be true
|
1694
|
+
end
|
1695
|
+
|
1696
|
+
it 'does not exist if superclass #referent_id is zero' do
|
1697
|
+
packet.referent_id = 0
|
1698
|
+
expect(packet.referent?).to be false
|
1699
|
+
end
|
1700
|
+
end
|
1701
|
+
|
1702
|
+
describe '#set' do
|
1703
|
+
it 'calls #to_ary before setting the elements, if supported' do
|
1704
|
+
ary = BinData::Array.new(['1', '2', '3'], type: :ndr_lp_str)
|
1705
|
+
expect(ary).to receive(:to_ary).and_call_original
|
1706
|
+
packet.set(ary)
|
1707
|
+
expect(packet.elements).to eq(['1', '2', '3'].map {|e| e.encode(Encoding::UTF_16LE)})
|
1708
|
+
end
|
1709
|
+
end
|
1710
|
+
|
1711
|
+
describe '#read' do
|
1712
|
+
context 'with a null pointer' do
|
1713
|
+
it 'reads its own binary representation' do
|
1714
|
+
raw = packet.to_binary_s
|
1715
|
+
expect(described_class.read(raw)).to eq(packet)
|
1716
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
1717
|
+
end
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
context 'with a normal NdrStringPtrsw structure' do
|
1721
|
+
it 'reads its own binary representation' do
|
1722
|
+
packet.set(['1', '2', '3'])
|
1723
|
+
raw = packet.to_binary_s
|
1724
|
+
expect(described_class.read(raw)).to eq(packet)
|
1725
|
+
expect(described_class.read(raw).to_binary_s).to eq(raw)
|
1726
|
+
end
|
1727
|
+
end
|
1728
|
+
end
|
410
1729
|
end
|