ruby_smb 2.0.2 → 2.0.7
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/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 +3 -4
- 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 +37 -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 +37 -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 +32 -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 +174 -68
- 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 +107 -18
- metadata.gz.sig +0 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
RSpec.describe RubySMB::Dcerpc::Winreg::SaveKeyResponse do
|
2
|
+
subject(:packet) { described_class.new }
|
3
|
+
|
4
|
+
it { is_expected.to respond_to :error_status }
|
5
|
+
|
6
|
+
it 'is little endian' do
|
7
|
+
expect(described_class.fields.instance_variable_get(:@hints)[:endian]).to eq :little
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#error_status' do
|
11
|
+
it 'is a 32-bit unsigned integer' do
|
12
|
+
expect(packet.error_status).to be_a BinData::Uint32le
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#initialize_instance' do
|
17
|
+
it 'sets #opnum to REG_CREATE_KEY constant' do
|
18
|
+
expect(packet.opnum).to eq(RubySMB::Dcerpc::Winreg::REG_CREATE_KEY)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -132,8 +132,7 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
132
132
|
describe '#query_value' do
|
133
133
|
let(:handle) { double('Handle') }
|
134
134
|
let(:value_name) { double('Value Name') }
|
135
|
-
let(:
|
136
|
-
let(:query_value_request_packet2) { double('Query Value Request Packet #2') }
|
135
|
+
let(:query_value_request_packet) { double('Query Value Request Packet #1') }
|
137
136
|
let(:lp_data1) { double('LpData #1') }
|
138
137
|
let(:lp_data2) { double('LpData #2') }
|
139
138
|
let(:response1) { double('Response #1') }
|
@@ -142,26 +141,28 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
142
141
|
let(:query_value_response2) { double('Query Value Response #2') }
|
143
142
|
let(:data) { double('Data') }
|
144
143
|
let(:lpcb_data) { double('LpcbData') }
|
145
|
-
let(:lpcb_data_referent) { double('
|
144
|
+
let(:lpcb_data_referent) { double('LpcbData Referent') }
|
145
|
+
let(:lp_data2_referent) { double('LpData Referent') }
|
146
146
|
before :example do
|
147
|
+
allow(described_class::QueryValueRequest).to receive(:new).and_return(query_value_request_packet)
|
148
|
+
allow(query_value_request_packet).to receive_messages(
|
149
|
+
:lp_type= => nil,
|
150
|
+
:lpcb_data= => nil,
|
151
|
+
:lpcb_len= => nil,
|
152
|
+
:lp_data= => nil,
|
153
|
+
:lp_data => lp_data2,
|
154
|
+
)
|
155
|
+
allow(lp_data2).to receive(:referent).and_return(lp_data2_referent)
|
156
|
+
allow(lp_data2_referent).to receive(:max_count=)
|
147
157
|
first_request = true
|
148
|
-
allow(
|
158
|
+
allow(winreg).to receive(:dcerpc_request) do |arg|
|
149
159
|
if first_request
|
150
160
|
first_request = false
|
151
|
-
|
161
|
+
response1
|
152
162
|
else
|
153
|
-
|
163
|
+
response2
|
154
164
|
end
|
155
165
|
end
|
156
|
-
allow(query_value_request_packet1).to receive(:lp_data).and_return(lp_data1)
|
157
|
-
allow(query_value_request_packet2).to receive_messages(
|
158
|
-
:lp_data => lp_data2,
|
159
|
-
:lpcb_data= => nil
|
160
|
-
)
|
161
|
-
allow(lp_data1).to receive(:referent_identifier=)
|
162
|
-
allow(lp_data2).to receive(:max_count=)
|
163
|
-
allow(winreg).to receive(:dcerpc_request).with(query_value_request_packet1).and_return(response1)
|
164
|
-
allow(winreg).to receive(:dcerpc_request).with(query_value_request_packet2).and_return(response2)
|
165
166
|
allow(described_class::QueryValueResponse).to receive(:read).with(response1).and_return(query_value_response1)
|
166
167
|
allow(described_class::QueryValueResponse).to receive(:read).with(response2).and_return(query_value_response2)
|
167
168
|
allow(query_value_response1).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
|
@@ -175,24 +176,22 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
175
176
|
|
176
177
|
it 'create the expected QueryValueRequest packets' do
|
177
178
|
winreg.query_value(handle, value_name)
|
178
|
-
expect(described_class::QueryValueRequest).to have_received(:new).with(hkey: handle, lp_value_name: value_name)
|
179
|
-
end
|
180
|
-
|
181
|
-
it 'sets the expected user rights on the first request packet' do
|
182
|
-
winreg.query_value(handle, value_name)
|
183
|
-
expect(lp_data1).to have_received(:referent_identifier=).with(0)
|
179
|
+
expect(described_class::QueryValueRequest).to have_received(:new).with(hkey: handle, lp_value_name: value_name)
|
184
180
|
end
|
185
181
|
|
186
|
-
it 'sets the expected
|
182
|
+
it 'sets the expected fields on the request packet' do
|
187
183
|
winreg.query_value(handle, value_name)
|
188
|
-
expect(
|
189
|
-
expect(
|
184
|
+
expect(query_value_request_packet).to have_received(:lp_type=).with(0)
|
185
|
+
expect(query_value_request_packet).to have_received(:lpcb_data=).with(0)
|
186
|
+
expect(query_value_request_packet).to have_received(:lpcb_len=).with(0)
|
187
|
+
expect(query_value_request_packet).to have_received(:lpcb_data=).with(lpcb_data)
|
188
|
+
expect(query_value_request_packet).to have_received(:lp_data=).with([])
|
189
|
+
expect(lp_data2_referent).to have_received(:max_count=).with(lpcb_data_referent)
|
190
190
|
end
|
191
191
|
|
192
192
|
it 'sends the expected dcerpc requests' do
|
193
193
|
winreg.query_value(handle, value_name)
|
194
|
-
expect(winreg).to have_received(:dcerpc_request).with(
|
195
|
-
expect(winreg).to have_received(:dcerpc_request).with(query_value_request_packet2).once.ordered
|
194
|
+
expect(winreg).to have_received(:dcerpc_request).with(query_value_request_packet).twice
|
196
195
|
end
|
197
196
|
|
198
197
|
context 'when receiving the first response' do
|
@@ -293,8 +292,20 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
293
292
|
let(:query_info_key_request_packet) { double('CloseKey Request Packet') }
|
294
293
|
let(:response) { double('Response') }
|
295
294
|
let(:query_info_key_response) { double('CloseKey Response') }
|
295
|
+
let(:lp_class) { double('LpClass') }
|
296
|
+
let(:lp_class_referent) { double('LpClass referent') }
|
297
|
+
let(:lp_class_buf_ref) { double('LpClass buffer referent') }
|
296
298
|
before :example do
|
297
299
|
allow(described_class::QueryInfoKeyRequest).to receive(:new).and_return(query_info_key_request_packet)
|
300
|
+
allow(query_info_key_request_packet).to receive_messages(
|
301
|
+
:lp_class= => nil,
|
302
|
+
:lp_class => lp_class,
|
303
|
+
)
|
304
|
+
allow(lp_class).to receive(:referent).and_return(lp_class_referent)
|
305
|
+
allow(lp_class_referent).to receive(:actual_count=)
|
306
|
+
allow(lp_class).to receive(:maximum_length=)
|
307
|
+
allow(lp_class).to receive_message_chain(:buffer, :referent => lp_class_buf_ref)
|
308
|
+
allow(lp_class_buf_ref).to receive(:max_count=)
|
298
309
|
allow(winreg).to receive(:dcerpc_request).and_return(response)
|
299
310
|
allow(described_class::QueryInfoKeyResponse).to receive(:read).and_return(query_info_key_response)
|
300
311
|
allow(query_info_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
|
@@ -310,6 +321,14 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
310
321
|
expect(winreg).to have_received(:dcerpc_request).with(query_info_key_request_packet)
|
311
322
|
end
|
312
323
|
|
324
|
+
it 'sets the expected fields on the request packet' do
|
325
|
+
winreg.query_info_key(handle)
|
326
|
+
expect(query_info_key_request_packet).to have_received(:lp_class=).with('')
|
327
|
+
expect(lp_class_referent).to have_received(:actual_count=).with(0)
|
328
|
+
expect(lp_class).to have_received(:maximum_length=).with(1024)
|
329
|
+
expect(lp_class_buf_ref).to have_received(:max_count=).with(1024 / 2)
|
330
|
+
end
|
331
|
+
|
313
332
|
it 'creates a QueryInfoKeyResponse structure from the expected dcerpc response' do
|
314
333
|
winreg.query_info_key(handle)
|
315
334
|
expect(described_class::QueryInfoKeyResponse).to have_received(:read).with(response)
|
@@ -338,25 +357,27 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
338
357
|
let(:handle) { double('Handle') }
|
339
358
|
let(:index) { double('Index') }
|
340
359
|
let(:enum_key_request_packet) { double('enum_key Request Packet') }
|
341
|
-
let(:lp_class) { double('Lp Class') }
|
342
360
|
let(:lp_name) { double('Lp Name') }
|
343
361
|
let(:buffer) { double('Buffer') }
|
344
|
-
let(:lp_class_buffer_referent) { double('Lp Class buffer referent') }
|
345
362
|
let(:lp_name_buffer_referent) { double('Lp Name buffer referent') }
|
346
363
|
let(:response) { double('Response') }
|
347
364
|
let(:enum_key_response) { double('enum_key Response') }
|
348
365
|
let(:result_str) { double('Result String') }
|
366
|
+
let(:lp_class) { double('Lp Class') }
|
367
|
+
let(:lp_class_buffer_referent) { double('Lp Class buffer referent') }
|
349
368
|
before :example do
|
350
369
|
allow(described_class::EnumKeyRequest).to receive(:new).and_return(enum_key_request_packet)
|
351
370
|
allow(enum_key_request_packet).to receive_messages(
|
352
371
|
:lpft_last_write_time= => nil,
|
353
|
-
:lp_class
|
354
|
-
:lp_name => lp_name
|
372
|
+
:lp_class= => nil,
|
373
|
+
:lp_name => lp_name,
|
374
|
+
:lp_class => lp_class
|
355
375
|
)
|
356
376
|
allow(lp_class).to receive(:referent).and_return(lp_class_buffer_referent)
|
377
|
+
allow(lp_class_buffer_referent).to receive(:buffer=)
|
357
378
|
allow(lp_name).to receive(:buffer).and_return(buffer)
|
379
|
+
allow(lp_name).to receive(:buffer=)
|
358
380
|
allow(buffer).to receive(:referent).and_return(lp_name_buffer_referent)
|
359
|
-
allow(lp_class_buffer_referent).to receive(:buffer=)
|
360
381
|
allow(lp_name_buffer_referent).to receive(:max_count=)
|
361
382
|
allow(winreg).to receive(:dcerpc_request).and_return(response)
|
362
383
|
allow(described_class::EnumKeyResponse).to receive(:read).and_return(enum_key_response)
|
@@ -369,10 +390,12 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
369
390
|
expect(described_class::EnumKeyRequest).to have_received(:new).with(hkey: handle, dw_index: index)
|
370
391
|
end
|
371
392
|
|
372
|
-
it 'sets the expected
|
393
|
+
it 'sets the expected parameters on the request packet' do
|
373
394
|
winreg.enum_key(handle, index)
|
374
395
|
expect(enum_key_request_packet).to have_received(:lpft_last_write_time=).with(0)
|
375
|
-
expect(
|
396
|
+
expect(enum_key_request_packet).to have_received(:lp_class=).with('')
|
397
|
+
expect(lp_class_buffer_referent).to have_received(:buffer=).with(:null)
|
398
|
+
expect(lp_name).to have_received(:buffer=).with('')
|
376
399
|
expect(lp_name_buffer_referent).to have_received(:max_count=).with(256)
|
377
400
|
end
|
378
401
|
|
@@ -410,7 +433,6 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
410
433
|
let(:index) { double('Index') }
|
411
434
|
let(:enum_value_request_packet) { double('EnumValue Request Packet') }
|
412
435
|
let(:lp_value_name) { double('Lp Value Name') }
|
413
|
-
let(:lp_data) { double('Lp Data') }
|
414
436
|
let(:buffer) { double('Buffer') }
|
415
437
|
let(:referent) { double('Referent') }
|
416
438
|
let(:response) { double('Response') }
|
@@ -418,14 +440,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
418
440
|
let(:result_str) { double('Result String') }
|
419
441
|
before :example do
|
420
442
|
allow(described_class::EnumValueRequest).to receive(:new).and_return(enum_value_request_packet)
|
421
|
-
allow(enum_value_request_packet).to
|
422
|
-
:lp_value_name => lp_value_name,
|
423
|
-
:lp_data => lp_data
|
424
|
-
)
|
443
|
+
allow(enum_value_request_packet).to receive(:lp_value_name).and_return(lp_value_name)
|
425
444
|
allow(lp_value_name).to receive(:buffer).and_return(buffer)
|
445
|
+
allow(lp_value_name).to receive(:buffer=)
|
426
446
|
allow(buffer).to receive(:referent).and_return(referent)
|
427
447
|
allow(referent).to receive(:max_count=)
|
428
|
-
allow(lp_data).to receive(:referent_identifier=)
|
429
448
|
allow(winreg).to receive(:dcerpc_request).and_return(response)
|
430
449
|
allow(described_class::EnumValueResponse).to receive(:read).and_return(enum_value_response)
|
431
450
|
allow(enum_value_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
|
@@ -437,10 +456,10 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
437
456
|
expect(described_class::EnumValueRequest).to have_received(:new).with(hkey: handle, dw_index: index)
|
438
457
|
end
|
439
458
|
|
440
|
-
it 'sets the expected
|
459
|
+
it 'sets the expected buffer on the request packet' do
|
441
460
|
winreg.enum_value(handle, index)
|
442
461
|
expect(referent).to have_received(:max_count=).with(256)
|
443
|
-
expect(
|
462
|
+
expect(lp_value_name).to have_received(:buffer=).with('')
|
444
463
|
end
|
445
464
|
|
446
465
|
it 'sends the expected dcerpc request' do
|
@@ -492,6 +511,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
492
511
|
expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
|
493
512
|
end
|
494
513
|
|
514
|
+
it 'does not bind a DCERPC connection if #bind argument is false' do
|
515
|
+
winreg.has_registry_key?(key, bind: false)
|
516
|
+
expect(winreg).to_not have_received(:bind)
|
517
|
+
end
|
518
|
+
|
495
519
|
it 'opens the expected root key' do
|
496
520
|
winreg.has_registry_key?(key)
|
497
521
|
expect(winreg).to have_received(:open_root_key).with(root_key)
|
@@ -519,6 +543,7 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
519
543
|
it 'closes the key' do
|
520
544
|
winreg.has_registry_key?(key)
|
521
545
|
expect(winreg).to have_received(:close_key).with(subkey_handle)
|
546
|
+
expect(winreg).to have_received(:close_key).with(root_key_handle)
|
522
547
|
end
|
523
548
|
|
524
549
|
it 'returns true when no error occurs' do
|
@@ -549,6 +574,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
549
574
|
expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
|
550
575
|
end
|
551
576
|
|
577
|
+
it 'does not bind a DCERPC connection if #bind argument is false' do
|
578
|
+
winreg.read_registry_key_value(key, value_name, bind: false)
|
579
|
+
expect(winreg).to_not have_received(:bind)
|
580
|
+
end
|
581
|
+
|
552
582
|
it 'opens the expected root key' do
|
553
583
|
winreg.read_registry_key_value(key, value_name)
|
554
584
|
expect(winreg).to have_received(:open_root_key).with(root_key)
|
@@ -567,6 +597,7 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
567
597
|
it 'closes the key' do
|
568
598
|
winreg.read_registry_key_value(key, value_name)
|
569
599
|
expect(winreg).to have_received(:close_key).with(subkey_handle)
|
600
|
+
expect(winreg).to have_received(:close_key).with(root_key_handle)
|
570
601
|
end
|
571
602
|
|
572
603
|
it 'returns expect registry key value' do
|
@@ -600,6 +631,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
600
631
|
expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
|
601
632
|
end
|
602
633
|
|
634
|
+
it 'does not bind a DCERPC connection if #bind argument is false' do
|
635
|
+
winreg.enum_registry_key(key, bind: false)
|
636
|
+
expect(winreg).to_not have_received(:bind)
|
637
|
+
end
|
638
|
+
|
603
639
|
it 'opens the expected root key' do
|
604
640
|
winreg.enum_registry_key(key)
|
605
641
|
expect(winreg).to have_received(:open_root_key).with(root_key)
|
@@ -630,6 +666,13 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
630
666
|
it 'closes the key' do
|
631
667
|
winreg.enum_registry_key(key)
|
632
668
|
expect(winreg).to have_received(:close_key).with(subkey_handle)
|
669
|
+
expect(winreg).to have_received(:close_key).with(root_key_handle)
|
670
|
+
end
|
671
|
+
|
672
|
+
it 'only closes the key once when there is no subkey' do
|
673
|
+
winreg.enum_registry_key(root_key)
|
674
|
+
expect(winreg).to have_received(:close_key).once
|
675
|
+
expect(winreg).to have_received(:close_key).with(root_key_handle)
|
633
676
|
end
|
634
677
|
|
635
678
|
it 'returns the expected array of enumerated keys' do
|
@@ -667,6 +710,11 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
667
710
|
expect(winreg).to have_received(:bind).with(endpoint: RubySMB::Dcerpc::Winreg)
|
668
711
|
end
|
669
712
|
|
713
|
+
it 'does not bind a DCERPC connection if #bind argument is false' do
|
714
|
+
winreg.enum_registry_values(key, bind: false)
|
715
|
+
expect(winreg).to_not have_received(:bind)
|
716
|
+
end
|
717
|
+
|
670
718
|
it 'opens the expected root key' do
|
671
719
|
winreg.enum_registry_values(key)
|
672
720
|
expect(winreg).to have_received(:open_root_key).with(root_key)
|
@@ -697,6 +745,13 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
697
745
|
it 'closes the key' do
|
698
746
|
winreg.enum_registry_values(key)
|
699
747
|
expect(winreg).to have_received(:close_key).with(subkey_handle)
|
748
|
+
expect(winreg).to have_received(:close_key).with(root_key_handle)
|
749
|
+
end
|
750
|
+
|
751
|
+
it 'only closes the key once when there is no subkey' do
|
752
|
+
winreg.enum_registry_values(root_key)
|
753
|
+
expect(winreg).to have_received(:close_key).once
|
754
|
+
expect(winreg).to have_received(:close_key).with(root_key_handle)
|
700
755
|
end
|
701
756
|
|
702
757
|
it 'returns the expected array of enumerated keys' do
|
@@ -707,4 +762,135 @@ RSpec.describe RubySMB::Dcerpc::Winreg do
|
|
707
762
|
expect(winreg.enum_registry_values(key)).to eq([value1, value2])
|
708
763
|
end
|
709
764
|
end
|
765
|
+
|
766
|
+
describe '#create_key' do
|
767
|
+
let(:handle) { double('Handle') }
|
768
|
+
let(:sub_key) { double('Sub key') }
|
769
|
+
let(:create_key_request) { double('CreateKey Request') }
|
770
|
+
let(:response) { double('Response') }
|
771
|
+
let(:create_key_response) { double('CreateKey Response') }
|
772
|
+
let(:hkey) { double('hkey') }
|
773
|
+
before :example do
|
774
|
+
allow(described_class::CreateKeyRequest).to receive(:new).and_return(create_key_request)
|
775
|
+
allow(winreg).to receive(:dcerpc_request).and_return(response)
|
776
|
+
allow(described_class::CreateKeyResponse).to receive(:read).and_return(create_key_response)
|
777
|
+
allow(create_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
|
778
|
+
allow(create_key_response).to receive(:hkey).and_return(hkey)
|
779
|
+
end
|
780
|
+
|
781
|
+
it 'create the expected CreateKeyRequest packet with the default options' do
|
782
|
+
opts = {
|
783
|
+
hkey: handle,
|
784
|
+
lp_sub_key: sub_key,
|
785
|
+
lp_class: :null,
|
786
|
+
dw_options: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_KEY_TYPE_VOLATILE,
|
787
|
+
sam_desired: RubySMB::Dcerpc::Winreg::Regsam.new(maximum: 1),
|
788
|
+
lp_security_attributes: RubySMB::Dcerpc::RpcSecurityAttributes.new,
|
789
|
+
lpdw_disposition: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_CREATED_NEW_KEY
|
790
|
+
}
|
791
|
+
winreg.create_key(handle, sub_key)
|
792
|
+
expect(described_class::CreateKeyRequest).to have_received(:new).with(opts)
|
793
|
+
end
|
794
|
+
|
795
|
+
it 'create the expected CreateKeyRequest packet with custom options' do
|
796
|
+
opts = {
|
797
|
+
hkey: handle,
|
798
|
+
lp_sub_key: sub_key,
|
799
|
+
lp_class: 'MyClass',
|
800
|
+
dw_options: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_KEY_TYPE_SYMLINK,
|
801
|
+
sam_desired: RubySMB::Dcerpc::Winreg::Regsam.new(key_set_value: 1),
|
802
|
+
lp_security_attributes: RubySMB::Dcerpc::RpcSecurityAttributes.new(n_length: 3),
|
803
|
+
lpdw_disposition: RubySMB::Dcerpc::Winreg::CreateKeyRequest::REG_OPENED_EXISTING_KEY
|
804
|
+
}
|
805
|
+
winreg.create_key(handle, sub_key, opts)
|
806
|
+
expect(described_class::CreateKeyRequest).to have_received(:new).with(opts)
|
807
|
+
end
|
808
|
+
|
809
|
+
it 'sends the expected dcerpc request' do
|
810
|
+
winreg.create_key(handle, sub_key)
|
811
|
+
expect(winreg).to have_received(:dcerpc_request).with(create_key_request)
|
812
|
+
end
|
813
|
+
|
814
|
+
it 'creates a CreateKeyResponse structure from the expected dcerpc response' do
|
815
|
+
winreg.create_key(handle, sub_key)
|
816
|
+
expect(described_class::CreateKeyResponse).to have_received(:read).with(response)
|
817
|
+
end
|
818
|
+
|
819
|
+
context 'when an IOError occurs while parsing the response' do
|
820
|
+
it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
|
821
|
+
allow(described_class::CreateKeyResponse).to receive(:read).and_raise(IOError)
|
822
|
+
expect { winreg.create_key(handle, sub_key) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
826
|
+
context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
|
827
|
+
it 'raises a RubySMB::Dcerpc::Error::WinregError' do
|
828
|
+
allow(create_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
|
829
|
+
expect { winreg.create_key(handle, sub_key) }.to raise_error(RubySMB::Dcerpc::Error::WinregError)
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
833
|
+
it 'returns the expected key name' do
|
834
|
+
expect(winreg.create_key(handle, sub_key)).to eq(hkey)
|
835
|
+
end
|
836
|
+
end
|
837
|
+
|
838
|
+
describe '#save_key' do
|
839
|
+
let(:handle) { double('Handle') }
|
840
|
+
let(:filename) { double('Filename') }
|
841
|
+
let(:save_key_request) { double('CreateKey Request') }
|
842
|
+
let(:response) { double('Response') }
|
843
|
+
let(:save_key_response) { double('CreateKey Response') }
|
844
|
+
let(:hkey) { double('hkey') }
|
845
|
+
before :example do
|
846
|
+
allow(described_class::SaveKeyRequest).to receive(:new).and_return(save_key_request)
|
847
|
+
allow(winreg).to receive(:dcerpc_request).and_return(response)
|
848
|
+
allow(described_class::SaveKeyResponse).to receive(:read).and_return(save_key_response)
|
849
|
+
allow(save_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_SUCCESS)
|
850
|
+
end
|
851
|
+
|
852
|
+
it 'create the expected SaveKeyRequest packet with the default options' do
|
853
|
+
opts = {
|
854
|
+
hkey: handle,
|
855
|
+
lp_file: filename,
|
856
|
+
lp_security_attributes: :null,
|
857
|
+
}
|
858
|
+
winreg.save_key(handle, filename)
|
859
|
+
expect(described_class::SaveKeyRequest).to have_received(:new).with(opts)
|
860
|
+
end
|
861
|
+
|
862
|
+
it 'create the expected SaveKeyRequest packet with custom options' do
|
863
|
+
opts = {
|
864
|
+
hkey: handle,
|
865
|
+
lp_file: filename,
|
866
|
+
lp_security_attributes: RubySMB::Dcerpc::RpcSecurityAttributes.new,
|
867
|
+
}
|
868
|
+
winreg.save_key(handle, filename, opts)
|
869
|
+
expect(described_class::SaveKeyRequest).to have_received(:new).with(opts)
|
870
|
+
end
|
871
|
+
|
872
|
+
it 'sends the expected dcerpc request' do
|
873
|
+
winreg.save_key(handle, filename)
|
874
|
+
expect(winreg).to have_received(:dcerpc_request).with(save_key_request)
|
875
|
+
end
|
876
|
+
|
877
|
+
it 'creates a SaveKeyResponse structure from the expected dcerpc response' do
|
878
|
+
winreg.save_key(handle, filename)
|
879
|
+
expect(described_class::SaveKeyResponse).to have_received(:read).with(response)
|
880
|
+
end
|
881
|
+
|
882
|
+
context 'when an IOError occurs while parsing the response' do
|
883
|
+
it 'raises a RubySMB::Dcerpc::Error::InvalidPacket' do
|
884
|
+
allow(described_class::SaveKeyResponse).to receive(:read).and_raise(IOError)
|
885
|
+
expect { winreg.save_key(handle, filename) }.to raise_error(RubySMB::Dcerpc::Error::InvalidPacket)
|
886
|
+
end
|
887
|
+
end
|
888
|
+
|
889
|
+
context 'when the response error status is not WindowsError::Win32::ERROR_SUCCESS' do
|
890
|
+
it 'raises a RubySMB::Dcerpc::Error::WinregError' do
|
891
|
+
allow(save_key_response).to receive(:error_status).and_return(WindowsError::Win32::ERROR_INVALID_DATA)
|
892
|
+
expect { winreg.save_key(handle, filename) }.to raise_error(RubySMB::Dcerpc::Error::WinregError)
|
893
|
+
end
|
894
|
+
end
|
895
|
+
end
|
710
896
|
end
|
@@ -102,26 +102,26 @@ RSpec.describe RubySMB::Dispatcher::Socket do
|
|
102
102
|
end
|
103
103
|
|
104
104
|
it 'reads the number of bytes specified in the nbss header' do
|
105
|
-
|
106
|
-
session_header.
|
105
|
+
stream_protocol_length = 10
|
106
|
+
session_header.stream_protocol_length = stream_protocol_length
|
107
107
|
allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
|
108
108
|
expect(response_socket).to receive(:read).with(4).and_return(session_header)
|
109
|
-
expect(response_socket).to receive(:read).with(
|
109
|
+
expect(response_socket).to receive(:read).with(stream_protocol_length).and_return('A' * stream_protocol_length)
|
110
110
|
smb_socket.recv_packet
|
111
111
|
end
|
112
112
|
|
113
113
|
context 'when the socket does not return everything the first time' do
|
114
114
|
it 'calls #read several times until everything is returned' do
|
115
|
-
|
115
|
+
stream_protocol_length = 67
|
116
116
|
returned_length = 10
|
117
|
-
session_header.
|
117
|
+
session_header.stream_protocol_length = stream_protocol_length
|
118
118
|
allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
|
119
119
|
|
120
120
|
expect(response_socket).to receive(:read).with(4).and_return(session_header)
|
121
121
|
loop do
|
122
|
-
expect(response_socket).to receive(:read).with(
|
123
|
-
|
124
|
-
break if
|
122
|
+
expect(response_socket).to receive(:read).with(stream_protocol_length).and_return('A' * returned_length).once
|
123
|
+
stream_protocol_length -= returned_length
|
124
|
+
break if stream_protocol_length <= 0
|
125
125
|
end
|
126
126
|
smb_socket.recv_packet
|
127
127
|
end
|
@@ -134,7 +134,7 @@ RSpec.describe RubySMB::Dispatcher::Socket do
|
|
134
134
|
|
135
135
|
context 'when the SMB packet is empty' do
|
136
136
|
it 'returns the nbss header only' do
|
137
|
-
session_header.
|
137
|
+
session_header.stream_protocol_length = 0
|
138
138
|
allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
|
139
139
|
expect(smb_socket.recv_packet(full_response: true)).to eq(session_header.to_binary_s)
|
140
140
|
end
|
@@ -148,7 +148,7 @@ RSpec.describe RubySMB::Dispatcher::Socket do
|
|
148
148
|
|
149
149
|
context 'when the SMB packet is empty' do
|
150
150
|
it 'returns an empty string' do
|
151
|
-
session_header.
|
151
|
+
session_header.stream_protocol_length = 0
|
152
152
|
allow(RubySMB::Nbss::SessionHeader).to receive(:read).and_return(session_header)
|
153
153
|
expect(smb_socket.recv_packet(full_response: false)).to eq('')
|
154
154
|
end
|